• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts {
2    describe("unittests:: tsbuild:: Public API with custom transformers when passed to build", () => {
3        let sys: TscCompileSystem;
4        before(() => {
5            const inputFs = loadProjectFromFiles({
6                "/src/tsconfig.json": JSON.stringify({
7                    references: [
8                        { path: "./shared/tsconfig.json" },
9                        { path: "./webpack/tsconfig.json" }
10                    ],
11                    files: []
12                }),
13                "/src/shared/tsconfig.json": JSON.stringify({
14                    compilerOptions: { composite: true },
15                }),
16                "/src/shared/index.ts": `export function f1() { }
17export class c { }
18export enum e { }
19// leading
20export function f2() { } // trailing`,
21                "/src/webpack/tsconfig.json": JSON.stringify({
22                    compilerOptions: {
23                        composite: true,
24                    },
25                    references: [{ path: "../shared/tsconfig.json" }]
26                }),
27                "/src/webpack/index.ts": `export function f2() { }
28export class c2 { }
29export enum e2 { }
30// leading
31export function f22() { } // trailing`,
32            }).makeReadonly();
33            const fs = inputFs.shadow();
34
35            // Create system
36            sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" }) as TscCompileSystem;
37            fakes.patchHostForBuildInfoReadWrite(sys);
38            const commandLineArgs = ["--b", "/src/tsconfig.json"];
39            sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`);
40            sys.exit = exitCode => sys.exitCode = exitCode;
41            const writtenFiles = sys.writtenFiles = new Set();
42            const originalWriteFile = sys.writeFile;
43            sys.writeFile = (fileName, content, writeByteOrderMark) => {
44                const path = toPathWithSystem(sys, fileName);
45                assert.isFalse(writtenFiles.has(path));
46                writtenFiles.add(path);
47                return originalWriteFile.call(sys, fileName, content, writeByteOrderMark);
48            };
49            const { cb, getPrograms } = commandLineCallbacks(sys, /*originalReadCall*/ undefined);
50            const buildHost = createSolutionBuilderHost(
51                sys,
52                    /*createProgram*/ undefined,
53                createDiagnosticReporter(sys, /*pretty*/ true),
54                createBuilderStatusReporter(sys, /*pretty*/ true),
55                (errorCount, filesInError) => sys.write(getErrorSummaryText(errorCount, filesInError, sys.newLine, sys))
56            );
57            buildHost.afterProgramEmitAndDiagnostics = cb;
58            buildHost.afterEmitBundle = cb;
59            const builder = createSolutionBuilder(buildHost, [commandLineArgs[1]], { verbose: true });
60            const exitStatus = builder.build(/*project*/ undefined, /*cancellationToken*/ undefined, /*writeFile*/ undefined, getCustomTransformers);
61            sys.exit(exitStatus);
62            sys.write(`exitCode:: ExitStatus.${ExitStatus[sys.exitCode as ExitStatus]}\n`);
63            const baseline: string[] = [];
64            tscWatch.baselinePrograms(baseline, getPrograms, emptyArray, /*baselineDependencies*/ false);
65            sys.write(baseline.join("\n"));
66            fs.makeReadonly();
67            sys.baseLine = () => {
68                const baseFsPatch = inputFs.diff(/*base*/ undefined, { baseIsNotShadowRoot: true });
69                const patch = fs.diff(inputFs, { includeChangedFileWithSameContent: true });
70                return {
71                    file: `tsbuild/publicAPI/build-with-custom-transformers.js`,
72                    text: `Input::
73${baseFsPatch ? vfs.formatPatch(baseFsPatch) : ""}
74
75Output::
76${sys.output.join("")}
77
78${patch ? vfs.formatPatch(patch) : ""}`
79                };
80            };
81
82            function getCustomTransformers(project: string): CustomTransformers {
83                const before: TransformerFactory<SourceFile> = context => {
84                    return file => visitEachChild(file, visit, context);
85                    function visit(node: Node): VisitResult<Node> {
86                        switch (node.kind) {
87                            case SyntaxKind.FunctionDeclaration:
88                                return visitFunction(node as FunctionDeclaration);
89                            default:
90                                return visitEachChild(node, visit, context);
91                        }
92                    }
93                    function visitFunction(node: FunctionDeclaration) {
94                        addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true);
95                        return node;
96                    }
97                };
98
99                const after: TransformerFactory<SourceFile> = context => {
100                    return file => visitEachChild(file, visit, context);
101                    function visit(node: Node): VisitResult<Node> {
102                        switch (node.kind) {
103                            case SyntaxKind.VariableStatement:
104                                return visitVariableStatement(node as VariableStatement);
105                            default:
106                                return visitEachChild(node, visit, context);
107                        }
108                    }
109                    function visitVariableStatement(node: VariableStatement) {
110                        addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, `@after${project}`);
111                        return node;
112                    }
113                };
114                return { before: [before], after: [after] };
115            }
116        });
117        after(() => {
118            sys = undefined!;
119        });
120        verifyTscBaseline(() => sys);
121    });
122}
123