Skip to content

Commit 76048c8

Browse files
committed
Add UnitTest
1 parent 4d7d806 commit 76048c8

3 files changed

Lines changed: 244 additions & 2 deletions

File tree

packages/cli/src/commands/info/action.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { runnerPickerOptions } from "../../runnerPickerOptions.js";
1818
import { parseServerOption } from "../parseServerOption.js";
1919
import { optimizeTargetGraph } from "../../optimizeTargetGraph.js";
2020

21-
interface InfoActionOptions extends ReporterInitOptions {
21+
export interface InfoActionOptions extends ReporterInitOptions {
2222
dependencies: boolean;
2323
dependents: boolean;
2424
since: string;
@@ -134,7 +134,7 @@ export async function infoAction(options: InfoActionOptions, command: Command) {
134134
});
135135
}
136136

137-
function generatePackageTask(
137+
export function generatePackageTask(
138138
target: Target,
139139
taskArgs: string[],
140140
config: ConfigOptions,
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`createTargetGraph Basic graph, seperate nodes 1`] = `
4+
"[
5+
{
6+
"id": "__start",
7+
"dependencies": []
8+
},
9+
{
10+
"id": "foo1#build",
11+
"dependencies": [
12+
"__start",
13+
"foo2#build"
14+
]
15+
},
16+
{
17+
"id": "foo2#build",
18+
"dependencies": [
19+
"__start"
20+
]
21+
}
22+
]"
23+
`;
24+
25+
exports[`createTargetGraph Basic graph, spanning tasks 1`] = `
26+
"[
27+
{
28+
"id": "__start",
29+
"dependencies": []
30+
},
31+
{
32+
"id": "foo1#build",
33+
"dependencies": [
34+
"__start",
35+
"foo2#build"
36+
]
37+
},
38+
{
39+
"id": "foo2#build",
40+
"dependencies": [
41+
"__start"
42+
]
43+
},
44+
{
45+
"id": "foo1#test",
46+
"dependencies": [
47+
"__start",
48+
"foo1#build"
49+
]
50+
},
51+
{
52+
"id": "foo2#test",
53+
"dependencies": [
54+
"__start",
55+
"foo2#build"
56+
]
57+
}
58+
]"
59+
`;
60+
61+
exports[`createTargetGraph PackageJsonOverrideForTargetDeps 1`] = `
62+
"[
63+
{
64+
"id": "__start",
65+
"dependencies": []
66+
},
67+
{
68+
"id": "foo1#build",
69+
"dependencies": [
70+
"__start",
71+
"foo2#build"
72+
]
73+
},
74+
{
75+
"id": "foo2#build",
76+
"dependencies": [
77+
"__start"
78+
]
79+
},
80+
{
81+
"id": "foo1#test",
82+
"dependencies": [
83+
"__start"
84+
]
85+
},
86+
{
87+
"id": "foo2#test",
88+
"dependencies": [
89+
"__start",
90+
"foo2#build"
91+
]
92+
}
93+
]"
94+
`;
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import { Logger } from "@lage-run/logger";
2+
import { getConfig, PipelineDefinition } from "@lage-run/config";
3+
import createLogger from "@lage-run/logger";
4+
import { initializeReporters } from "../src/commands/initializeReporters.js";
5+
import { generatePackageTask, type InfoActionOptions } from "../src/commands/info/action.js";
6+
import { PackageInfo, PackageInfos } from "workspace-tools";
7+
import { createTargetGraph } from "../src/commands/run/createTargetGraph.js";
8+
import { getFilteredPackages } from "../src/filter/getFilteredPackages.js";
9+
import { getBinPaths } from "../src/getBinPaths.js";
10+
11+
describe("createTargetGraph", () => {
12+
const logger = new Logger();
13+
14+
it("Basic graph, seperate nodes", async () => {
15+
const packageInfos: PackageInfos = {
16+
foo1: stubPackage({ name: "foo1", deps: ["foo2"] }),
17+
foo2: stubPackage({ name: "foo2" }),
18+
};
19+
20+
const pipeline: PipelineDefinition = {
21+
build: ["^build"],
22+
test: ["build"],
23+
};
24+
25+
const result = await createAndPrintPackageTasks(["build"], packageInfos, pipeline, ["id", "dependencies"]);
26+
expect(result).toMatchSnapshot();
27+
});
28+
29+
it("Basic graph, spanning tasks", async () => {
30+
const packageInfos: PackageInfos = {
31+
foo1: stubPackage({ name: "foo1", deps: ["foo2"] }),
32+
foo2: stubPackage({ name: "foo2" }),
33+
};
34+
35+
const pipeline: PipelineDefinition = {
36+
build: ["^build"],
37+
test: ["build"],
38+
};
39+
40+
const result = await createAndPrintPackageTasks(["build", "test"], packageInfos, pipeline, ["id", "dependencies"]);
41+
expect(result).toMatchSnapshot();
42+
});
43+
44+
it("PackageJsonOverrideForTargetDeps", async () => {
45+
const packageInfos: PackageInfos = {
46+
foo1: stubPackage({ name: "foo1", deps: ["foo2"] }),
47+
foo2: stubPackage({ name: "foo2", fields: { lage: { test: ["build"] } } }),
48+
};
49+
50+
const pipeline: PipelineDefinition = {
51+
build: ["^build"],
52+
test: [],
53+
};
54+
55+
const result = await createAndPrintPackageTasks(["build", "test"], packageInfos, pipeline, ["id", "dependencies"]);
56+
expect(result).toMatchSnapshot();
57+
});
58+
});
59+
60+
async function createAndPrintPackageTasks(
61+
tasks: string[],
62+
packageInfos: PackageInfos,
63+
pipeline: PipelineDefinition,
64+
fields: string[]
65+
): Promise<string> {
66+
const packageTasks = await createPackageTasks(tasks, packageInfos, pipeline);
67+
const expected = filterObjects(packageTasks, ["id", "dependencies"]);
68+
return JSON.stringify(expected, null, 2);
69+
}
70+
71+
function filterObjects<T extends object>(objects: T[], fields: string[]): Partial<T>[] {
72+
return objects.map((obj) => filterFields(obj, fields));
73+
}
74+
75+
function filterFields<T extends object>(obj: T, fields: string[]): Partial<T> {
76+
return <Partial<T>>Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
77+
}
78+
79+
async function createPackageTasks(tasks: string[], packageInfos: PackageInfos, pipeline: PipelineDefinition): Promise<PackageTask[]> {
80+
const root = process.cwd();
81+
const config = await getConfig(root);
82+
config.pipeline = pipeline;
83+
const logger = createLogger();
84+
const options: InfoActionOptions = {
85+
logLevel: "info",
86+
reporter: "json",
87+
dependencies: false,
88+
dependents: false,
89+
since: <string>(<any>undefined),
90+
scope: [],
91+
to: [],
92+
cache: false,
93+
nodeArg: "",
94+
ignore: [],
95+
server: "",
96+
progress: false,
97+
verbose: false,
98+
grouped: false,
99+
concurrency: 1,
100+
};
101+
102+
initializeReporters(logger, options);
103+
104+
const targetGraph = await createTargetGraph({
105+
logger,
106+
root,
107+
dependencies: options.dependencies,
108+
dependents: options.dependents && !options.to, // --to is a short hand for --scope + --no-dependents
109+
ignore: options.ignore.concat(config.ignore),
110+
pipeline: config.pipeline,
111+
repoWideChanges: config.repoWideChanges,
112+
scope: (options.scope ?? []).concat(options.to ?? []), // --to is a short hand for --scope + --no-dependents
113+
since: options.since,
114+
outputs: config.cacheOptions.outputGlob,
115+
tasks,
116+
packageInfos,
117+
});
118+
119+
const scope = getFilteredPackages({
120+
root,
121+
packageInfos,
122+
logger,
123+
includeDependencies: options.dependencies,
124+
includeDependents: options.dependents && !options.to, // --to is a short hand for --scope + --no-dependents
125+
since: options.since,
126+
scope: (options.scope ?? []).concat(options.to ?? []), // --to is a short hand for --scope + --no-dependents
127+
repoWideChanges: config.repoWideChanges,
128+
sinceIgnoreGlobs: options.ignore.concat(config.ignore),
129+
});
130+
131+
const binPaths = getBinPaths();
132+
const targets = [...targetGraph.targets.values()];
133+
const packageTasks = targets.map((target) => generatePackageTask(target, [], config, options, binPaths, packageInfos, tasks));
134+
135+
return packageTasks;
136+
}
137+
138+
function stubPackage(args: { name: string; deps?: string[]; scripts?: string[]; fields?: object }): PackageInfo {
139+
return {
140+
name: args.name,
141+
packageJsonPath: `packages/${args.name}`,
142+
version: "1.0",
143+
dependencies: (args.deps || []).reduce((depMap, dep) => ({ ...depMap, [dep]: "*" }), {}),
144+
devDependencies: {},
145+
scripts: (args.scripts || []).reduce((scriptMap, script) => ({ ...scriptMap, [script]: `echo ${script}` }), {}),
146+
...(args.fields || {}),
147+
} as PackageInfo;
148+
}

0 commit comments

Comments
 (0)