Skip to content

Commit

Permalink
refactor: deal with todos in poms.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalets committed Nov 28, 2024
1 parent bc3672d commit 9e9370d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/generate/test/decoratorFixtureResolver.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Resolves fixture names for decorator steps.
*/
import { TestPoms, UsedFixture } from './poms';
import { TestPoms, UsedFixtureInfo } from './poms';
import { exit } from '../../utils/exit';
import { PomNode } from '../../steps/decorators/pomGraph';
import { StepData } from '.';
Expand Down Expand Up @@ -68,7 +68,7 @@ function exitEmptyDecoratorFixture({ pickleStep, location }: StepData) {

function exitAmbiguousDecoratorFixture(
{ pickleStep, location }: StepData,
resolvedFixtures: UsedFixture[],
resolvedFixtures: UsedFixtureInfo[],
) {
const possibleFixturesNames = resolvedFixtures.map((f) => f.name).join(', ');
return exit(
Expand Down
53 changes: 28 additions & 25 deletions src/generate/test/poms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,27 @@ import { PomNode, getPomNodeByFixtureName } from '../../steps/decorators/pomGrap

const FIXTURE_TAG_PREFIX = '@fixture:';

export type UsedFixture = {
export type UsedFixtureInfo = {
name: string;
byTag: boolean;
};

type UsedPom = {
type PomNodeInfo = {
byTag: boolean;
fixtures?: UsedFixture[]; // todo: rename to resolvedFixtures
resolvedFixtures?: UsedFixtureInfo[];
};

export class TestPoms {
// poms used in test + info about resolved fixtures
// todo: rename to usedPomNodes
private usedPoms = new Map<PomNode, UsedPom>();
// pomNodes used in a test + info about resolved fixtures
private usedPomNodes = new Map<PomNode, PomNodeInfo>();

registerPomNode(pomNode: PomNode, { byTag = false } = {}) {
const usedPom = this.usedPoms.get(pomNode);
const usedPom = this.usedPomNodes.get(pomNode);
if (usedPom) {
// todo: optimize: if (usedPom && byTag) usedPom.byTag = true
if (byTag && !usedPom.byTag) usedPom.byTag = true;
} else {
this.usedPoms.set(pomNode, { byTag });
this.usedPomNodes.set(pomNode, { byTag });
}
}

Expand All @@ -65,7 +64,7 @@ export class TestPoms {
}

registerPomNodeByTag(tag: string) {
const fixtureName = extractFixtureName(tag);
const fixtureName = extractFixtureNameFromTag(tag);
if (!fixtureName) return;
const pomNode = getPomNodeByFixtureName(fixtureName);
if (pomNode) this.registerPomNode(pomNode, { byTag: true });
Expand All @@ -77,47 +76,51 @@ export class TestPoms {
* that does not have steps in the test, but should be considered.
*/
resolveAllFixtures() {
this.usedPoms.forEach((_, pomNode) => {
this.usedPomNodes.forEach((_, pomNode) => {
this.getResolvedFixtures(pomNode);
});
}

/**
* Returns fixtures suitable for particular pomNode (actually for step).
* Filter out pomNodes with empty fixture names (as they are not marked with @Fixture decorator)
*/
// eslint-disable-next-line visual/complexity
getResolvedFixtures(pomNode: PomNode): UsedFixture[] {
const usedPom = this.usedPoms.get(pomNode);
getResolvedFixtures(pomNode: PomNode): UsedFixtureInfo[] {
const usedPomNodeInfo = this.usedPomNodes.get(pomNode);

// fixtures already resolved
if (usedPom?.fixtures) return usedPom.fixtures;
if (usedPomNodeInfo?.resolvedFixtures) return usedPomNodeInfo.resolvedFixtures;

// Recursively resolve children fixtures as deep as possible
let childFixtures: UsedFixture[] = [...pomNode.children]
// Recursively resolve all child fixtures (as deep as possible)
let childFixtures: UsedFixtureInfo[] = [...pomNode.children]
.map((child) => this.getResolvedFixtures(child))
.flat()
// filter out pomNodes with empty fixture name as we can't use it.
// (they are not marked with @Fixture decorator -> e.g. Base class)
.filter((f) => Boolean(f.name));

const taggedFixtures = childFixtures.filter((f) => f.byTag);
// if tagged fixtures found, use only them as they have higher priority
if (taggedFixtures.length) childFixtures = taggedFixtures;

// this pomNode is not used in steps, we just return child fixtures
// this pomNode is not used in test, we just return child fixtures
// b/c no place to save child fixtures
if (!usedPom) return childFixtures;
if (!usedPomNodeInfo) return childFixtures;

// if there are deeper poms (child fixtures), use them as fixtures for current pom
// else use self as fixtures list
// If some child fixtures found, use them as fixtures for the current pom as well.
// The idea is to use as deep fixture as possible in teh pom classes inheritance chain.
if (childFixtures.length) {
// commented for now, simplify
// this.verifyChildFixtures(pomNode, usedPom, childFixtures);
usedPom.fixtures = childFixtures;
usedPomNodeInfo.resolvedFixtures = childFixtures;
} else {
usedPom.fixtures = pomNode.fixtureName
? [{ name: pomNode.fixtureName, byTag: usedPom.byTag }]
// if there is no child fixtures, else use self as fixtures list
usedPomNodeInfo.resolvedFixtures = pomNode.fixtureName
? [{ name: pomNode.fixtureName, byTag: usedPomNodeInfo.byTag }]
: [];
}

return usedPom.fixtures;
return usedPomNodeInfo.resolvedFixtures;
}

/**
Expand All @@ -137,6 +140,6 @@ export class TestPoms {
// }
}

function extractFixtureName(tag: string) {
function extractFixtureNameFromTag(tag: string) {
return tag.startsWith(FIXTURE_TAG_PREFIX) ? tag.replace(FIXTURE_TAG_PREFIX, '') : '';
}

0 comments on commit 9e9370d

Please sign in to comment.