• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.tscWatch {
2    describe("unittests:: tsc:: builder cancellationToken", () => {
3        verifyCancellation(/*useBuildInfo*/ true, "when emitting buildInfo");
4        verifyCancellation(/*useBuildInfo*/ false, "when using state");
5        function verifyCancellation(useBuildInfo: boolean, scenario: string) {
6            it(scenario, () => {
7                const aFile: File = {
8                    path: `${projectRoot}/a.ts`,
9                    content: Utils.dedent`
10                    import {B} from './b';
11                    declare var console: any;
12                    let b = new B();
13                    console.log(b.c.d);`
14                };
15                const bFile: File = {
16                    path: `${projectRoot}/b.ts`,
17                    content: Utils.dedent`
18                    import {C} from './c';
19                    export class B {
20                        c = new C();
21                    }`
22                };
23                const cFile: File = {
24                    path: `${projectRoot}/c.ts`,
25                    content: Utils.dedent`
26                    export class C {
27                        d = 1;
28                    }`
29                };
30                const dFile: File = {
31                    path: `${projectRoot}/d.ts`,
32                    content: "export class D { }"
33                };
34                const config: File = {
35                    path: `${projectRoot}/tsconfig.json`,
36                    content: JSON.stringify({ compilerOptions: { incremental: true, declaration: true } })
37                };
38                const { sys, baseline, oldSnap: originalSnap } = createBaseline(createWatchedSystem(
39                    [aFile, bFile, cFile, dFile, config, libFile],
40                    { currentDirectory: projectRoot }
41                ));
42                sys.exit = exitCode => sys.exitCode = exitCode;
43                const reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true);
44                const parsedConfig = parseConfigFileWithSystem(
45                    "tsconfig.json",
46                    {},
47                 /*extendedConfigCache*/ undefined,
48                  /*watchOptionsToExtend*/ undefined,
49                    sys,
50                    reportDiagnostic
51                )!;
52                const host = createIncrementalCompilerHost(parsedConfig.options, sys);
53                let programs: CommandLineProgram[] = emptyArray;
54                let oldPrograms: CommandLineProgram[] = emptyArray;
55                let builderProgram: EmitAndSemanticDiagnosticsBuilderProgram = undefined!;
56                let oldSnap = originalSnap;
57                let cancel = false;
58                const cancellationToken: CancellationToken = {
59                    isCancellationRequested: () => cancel,
60                    throwIfCancellationRequested: () => {
61                        if (cancel) {
62                            sys.write(`Cancelled!!\r\n`);
63                            throw new OperationCanceledException();
64                        }
65                    },
66                };
67
68                // Initial build
69                baselineBuild();
70
71                // Cancel on first semantic operation
72                // Change
73                oldSnap = applyChange(
74                    sys,
75                    baseline,
76                    sys => sys.appendFile(cFile.path, "export function foo() {}"),
77                    "Add change that affects d.ts"
78                );
79                createIncrementalProgram();
80
81                // Cancel during semantic diagnostics
82                cancel = true;
83                try {
84                    builderProgram.getSemanticDiagnosticsOfNextAffectedFile(cancellationToken);
85                }
86                catch (e) {
87                    sys.write(`Operation ws cancelled:: ${e instanceof OperationCanceledException}\r\n`);
88                }
89                cancel = false;
90                builderProgram.emitBuildInfo();
91                baselineBuildInfo(builderProgram.getCompilerOptions(), sys);
92                watchBaseline({
93                    baseline,
94                    getPrograms: () => programs,
95                    oldPrograms,
96                    sys,
97                    oldSnap,
98                });
99
100                // Normal emit again
101                noChange("Normal build");
102                baselineBuild();
103
104                // Do clean build:: all the emitted files should be same
105                noChange("Clean build");
106                baselineCleanBuild();
107
108                Harness.Baseline.runBaseline(`tsc/cancellationToken/${scenario.split(" ").join("-")}.js`, baseline.join("\r\n"));
109
110                function noChange(caption: string) {
111                    oldSnap = applyChange(sys, baseline, noop, caption);
112                }
113
114                function updatePrograms() {
115                    oldPrograms = programs;
116                    programs = [[builderProgram.getProgram(), builderProgram]];
117                }
118
119                function createIncrementalProgram() {
120                    builderProgram = useBuildInfo ?
121                        ts.createIncrementalProgram({
122                            rootNames: parsedConfig.fileNames,
123                            options: parsedConfig.options,
124                            host,
125                        }) :
126                        builderProgram = builderProgram = createEmitAndSemanticDiagnosticsBuilderProgram(
127                            parsedConfig.fileNames,
128                            parsedConfig.options,
129                            host,
130                            builderProgram,
131                        /* configFileParsingDiagnostics*/ undefined,
132                        /*projectReferences*/ undefined,
133                        );
134                    updatePrograms();
135                }
136
137                function emitAndBaseline() {
138                    emitFilesAndReportErrorsAndGetExitStatus(builderProgram, reportDiagnostic);
139                    baselineBuildInfo(builderProgram.getCompilerOptions(), sys);
140                    watchBaseline({
141                        baseline,
142                        getPrograms: () => programs,
143                        oldPrograms,
144                        sys,
145                        oldSnap,
146                    });
147                }
148
149                function baselineBuild() {
150                    createIncrementalProgram();
151                    emitAndBaseline();
152                }
153
154                function baselineCleanBuild() {
155                    builderProgram = createEmitAndSemanticDiagnosticsBuilderProgram(
156                        parsedConfig.fileNames,
157                        parsedConfig.options,
158                        host,
159                    /*oldProgram*/ undefined,
160                    /* configFileParsingDiagnostics*/ undefined,
161                    /*projectReferences*/ undefined,
162                    );
163                    updatePrograms();
164                    emitAndBaseline();
165                }
166            });
167        }
168    });
169}