• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.projectSystem {
2    describe("unittests:: tsserver:: events:: ProjectsUpdatedInBackground", () => {
3        function verifyFiles(caption: string, actual: readonly string[], expected: readonly string[]) {
4            assert.equal(actual.length, expected.length, `Incorrect number of ${caption}. Actual: ${actual} Expected: ${expected}`);
5            const seen = new Map<string, true>();
6            forEach(actual, f => {
7                assert.isFalse(seen.has(f), `${caption}: Found duplicate ${f}. Actual: ${actual} Expected: ${expected}`);
8                seen.set(f, true);
9                assert.isTrue(contains(expected, f), `${caption}: Expected not to contain ${f}. Actual: ${actual} Expected: ${expected}`);
10            });
11        }
12
13        function createVerifyInitialOpen(session: TestSession, verifyProjectsUpdatedInBackgroundEventHandler: (events: server.ProjectsUpdatedInBackgroundEvent[]) => void) {
14            return (file: File) => {
15                session.executeCommandSeq({
16                    command: server.CommandNames.Open,
17                    arguments: {
18                        file: file.path
19                    }
20                } as protocol.OpenRequest);
21                verifyProjectsUpdatedInBackgroundEventHandler([]);
22            };
23        }
24
25        interface ProjectsUpdatedInBackgroundEventVerifier {
26            session: TestSession;
27            verifyProjectsUpdatedInBackgroundEventHandler(events: server.ProjectsUpdatedInBackgroundEvent[]): void;
28            verifyInitialOpen(file: File): void;
29        }
30
31        function verifyProjectsUpdatedInBackgroundEvent(scenario: string, createSession: (host: TestServerHost, logger?: Logger) => ProjectsUpdatedInBackgroundEventVerifier) {
32            it("when adding new file", () => {
33                const commonFile1: File = {
34                    path: "/a/b/file1.ts",
35                    content: "export var x = 10;"
36                };
37                const commonFile2: File = {
38                    path: "/a/b/file2.ts",
39                    content: "export var y = 10;"
40                };
41                const commonFile3: File = {
42                    path: "/a/b/file3.ts",
43                    content: "export var z = 10;"
44                };
45                const configFile: File = {
46                    path: "/a/b/tsconfig.json",
47                    content: `{}`
48                };
49                const openFiles = [commonFile1.path];
50                const host = createServerHost([commonFile1, libFile, configFile]);
51                const { verifyProjectsUpdatedInBackgroundEventHandler, verifyInitialOpen } = createSession(host);
52                verifyInitialOpen(commonFile1);
53
54                host.writeFile(commonFile2.path, commonFile2.content);
55                host.runQueuedTimeoutCallbacks();
56                verifyProjectsUpdatedInBackgroundEventHandler([{
57                    eventName: server.ProjectsUpdatedInBackgroundEvent,
58                    data: {
59                        openFiles
60                    }
61                }]);
62
63                host.writeFile(commonFile3.path, commonFile3.content);
64                host.runQueuedTimeoutCallbacks();
65                verifyProjectsUpdatedInBackgroundEventHandler([{
66                    eventName: server.ProjectsUpdatedInBackgroundEvent,
67                    data: {
68                        openFiles
69                    }
70                }]);
71            });
72
73            describe("with --out or --outFile setting", () => {
74                function verifyEventWithOutSettings(compilerOptions: CompilerOptions = {}) {
75                    const config: File = {
76                        path: "/a/tsconfig.json",
77                        content: JSON.stringify({
78                            compilerOptions
79                        })
80                    };
81
82                    const f1: File = {
83                        path: "/a/a.ts",
84                        content: "export let x = 1"
85                    };
86                    const f2: File = {
87                        path: "/a/b.ts",
88                        content: "export let y = 1"
89                    };
90
91                    const openFiles = [f1.path];
92                    const files = [f1, config, libFile];
93                    const host = createServerHost(files);
94                    const { verifyInitialOpen, verifyProjectsUpdatedInBackgroundEventHandler } = createSession(host);
95                    verifyInitialOpen(f1);
96
97                    host.writeFile(f2.path, f2.content);
98                    host.runQueuedTimeoutCallbacks();
99
100                    verifyProjectsUpdatedInBackgroundEventHandler([{
101                        eventName: server.ProjectsUpdatedInBackgroundEvent,
102                        data: {
103                            openFiles
104                        }
105                    }]);
106
107                    host.writeFile(f2.path, "export let x = 11");
108                    host.runQueuedTimeoutCallbacks();
109                    verifyProjectsUpdatedInBackgroundEventHandler([{
110                        eventName: server.ProjectsUpdatedInBackgroundEvent,
111                        data: {
112                            openFiles
113                        }
114                    }]);
115                }
116
117                it("when both options are not set", () => {
118                    verifyEventWithOutSettings();
119                });
120
121                it("when --out is set", () => {
122                    const outJs = "/a/out.js";
123                    verifyEventWithOutSettings({ out: outJs });
124                });
125
126                it("when --outFile is set", () => {
127                    const outJs = "/a/out.js";
128                    verifyEventWithOutSettings({ outFile: outJs });
129                });
130            });
131
132            describe("with modules and configured project", () => {
133                const file1Consumer1Path = "/a/b/file1Consumer1.ts";
134                const moduleFile1Path = "/a/b/moduleFile1.ts";
135                const configFilePath = "/a/b/tsconfig.json";
136                interface InitialStateParams {
137                    /** custom config file options */
138                    configObj?: any;
139                    /** Additional files and folders to add */
140                    getAdditionalFileOrFolder?(): File[];
141                    /** initial list of files to reload in fs and first file in this list being the file to open */
142                    firstReloadFileList?: string[];
143                }
144                function getInitialState({ configObj = {}, getAdditionalFileOrFolder, firstReloadFileList }: InitialStateParams = {}) {
145                    const moduleFile1: File = {
146                        path: moduleFile1Path,
147                        content: "export function Foo() { };",
148                    };
149
150                    const file1Consumer1: File = {
151                        path: file1Consumer1Path,
152                        content: `import {Foo} from "./moduleFile1"; export var y = 10;`,
153                    };
154
155                    const file1Consumer2: File = {
156                        path: "/a/b/file1Consumer2.ts",
157                        content: `import {Foo} from "./moduleFile1"; let z = 10;`,
158                    };
159
160                    const moduleFile2: File = {
161                        path: "/a/b/moduleFile2.ts",
162                        content: `export var Foo4 = 10;`,
163                    };
164
165                    const globalFile3: File = {
166                        path: "/a/b/globalFile3.ts",
167                        content: `interface GlobalFoo { age: number }`
168                    };
169
170                    const additionalFiles = getAdditionalFileOrFolder ? getAdditionalFileOrFolder() : [];
171                    const configFile = {
172                        path: configFilePath,
173                        content: JSON.stringify(configObj || { compilerOptions: {} })
174                    };
175
176                    const files: File[] = [file1Consumer1, moduleFile1, file1Consumer2, moduleFile2, ...additionalFiles, globalFile3, libFile, configFile];
177
178                    const filesToReload = firstReloadFileList && getFiles(firstReloadFileList) || files;
179                    const host = createServerHost([filesToReload[0], configFile]);
180
181                    // Initial project creation
182                    const { session, verifyProjectsUpdatedInBackgroundEventHandler, verifyInitialOpen } = createSession(host);
183                    const openFiles = [filesToReload[0].path];
184                    verifyInitialOpen(filesToReload[0]);
185
186                    // Since this is first event, it will have all the files
187                    filesToReload.forEach(f => host.ensureFileOrFolder(f));
188                    if (!firstReloadFileList) host.runQueuedTimeoutCallbacks(); // Invalidated module resolutions to schedule project update
189                    verifyProjectsUpdatedInBackgroundEvent();
190
191                    return {
192                        host,
193                        moduleFile1, file1Consumer1, file1Consumer2, moduleFile2, globalFile3, configFile,
194                        updateContentOfOpenFile,
195                        verifyNoProjectsUpdatedInBackgroundEvent,
196                        verifyProjectsUpdatedInBackgroundEvent
197                    };
198
199                    function getFiles(filelist: string[]) {
200                        return map(filelist, getFile);
201                    }
202
203                    function getFile(fileName: string) {
204                        return find(files, file => file.path === fileName)!;
205                    }
206
207                    function verifyNoProjectsUpdatedInBackgroundEvent() {
208                        host.runQueuedTimeoutCallbacks();
209                        verifyProjectsUpdatedInBackgroundEventHandler([]);
210                    }
211
212                    function verifyProjectsUpdatedInBackgroundEvent() {
213                        host.runQueuedTimeoutCallbacks();
214                        verifyProjectsUpdatedInBackgroundEventHandler([{
215                            eventName: server.ProjectsUpdatedInBackgroundEvent,
216                            data: {
217                                openFiles
218                            }
219                        }]);
220                    }
221
222                    function updateContentOfOpenFile(file: File, newContent: string) {
223                        session.executeCommandSeq<protocol.ChangeRequest>({
224                            command: server.CommandNames.Change,
225                            arguments: {
226                                file: file.path,
227                                insertString: newContent,
228                                endLine: 1,
229                                endOffset: file.content.length,
230                                line: 1,
231                                offset: 1
232                            }
233                        });
234                        file.content = newContent;
235                    }
236                }
237
238                it("should contains only itself if a module file's shape didn't change, and all files referencing it if its shape changed", () => {
239                    const { host, moduleFile1, verifyProjectsUpdatedInBackgroundEvent } = getInitialState();
240
241                    // Change the content of moduleFile1 to `export var T: number;export function Foo() { };`
242                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
243                    verifyProjectsUpdatedInBackgroundEvent();
244
245                    // Change the content of moduleFile1 to `export var T: number;export function Foo() { console.log('hi'); };`
246                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { console.log('hi'); };`);
247                    verifyProjectsUpdatedInBackgroundEvent();
248                });
249
250                it("should be up-to-date with the reference map changes", () => {
251                    const { host, moduleFile1, file1Consumer1, updateContentOfOpenFile, verifyProjectsUpdatedInBackgroundEvent, verifyNoProjectsUpdatedInBackgroundEvent } = getInitialState();
252
253                    // Change file1Consumer1 content to `export let y = Foo();`
254                    updateContentOfOpenFile(file1Consumer1, "export let y = Foo();");
255                    verifyNoProjectsUpdatedInBackgroundEvent();
256
257                    // Change the content of moduleFile1 to `export var T: number;export function Foo() { };`
258                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
259                    verifyProjectsUpdatedInBackgroundEvent();
260
261                    // Add the import statements back to file1Consumer1
262                    updateContentOfOpenFile(file1Consumer1, `import {Foo} from "./moduleFile1";let y = Foo();`);
263                    verifyNoProjectsUpdatedInBackgroundEvent();
264
265                    // Change the content of moduleFile1 to `export var T: number;export var T2: string;export function Foo() { };`
266                    host.writeFile(moduleFile1.path, `export var T: number;export var T2: string;export function Foo() { };`);
267                    verifyProjectsUpdatedInBackgroundEvent();
268
269                    // Multiple file edits in one go:
270
271                    // Change file1Consumer1 content to `export let y = Foo();`
272                    // Change the content of moduleFile1 to `export var T: number;export function Foo() { };`
273                    updateContentOfOpenFile(file1Consumer1, `export let y = Foo();`);
274                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
275                    verifyProjectsUpdatedInBackgroundEvent();
276                });
277
278                it("should be up-to-date with deleted files", () => {
279                    const { host, moduleFile1, file1Consumer2, verifyProjectsUpdatedInBackgroundEvent } = getInitialState();
280
281                    // Change the content of moduleFile1 to `export var T: number;export function Foo() { };`
282                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
283
284                    // Delete file1Consumer2
285                    host.deleteFile(file1Consumer2.path);
286                    verifyProjectsUpdatedInBackgroundEvent();
287                });
288
289                it("should be up-to-date with newly created files", () => {
290                    const { host, moduleFile1, verifyProjectsUpdatedInBackgroundEvent, } = getInitialState();
291
292                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
293                    host.writeFile("/a/b/file1Consumer3.ts", `import {Foo} from "./moduleFile1"; let y = Foo();`);
294                    verifyProjectsUpdatedInBackgroundEvent();
295                });
296
297                it("should detect changes in non-root files", () => {
298                    const { host, moduleFile1, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({
299                        configObj: { files: [file1Consumer1Path] },
300                    });
301
302                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
303                    verifyProjectsUpdatedInBackgroundEvent();
304
305                    // change file1 internal, and verify only file1 is affected
306                    host.writeFile(moduleFile1.path, moduleFile1.content + "var T1: number;");
307                    verifyProjectsUpdatedInBackgroundEvent();
308                });
309
310                it("should return all files if a global file changed shape", () => {
311                    const { host, globalFile3, verifyProjectsUpdatedInBackgroundEvent } = getInitialState();
312
313                    host.writeFile(globalFile3.path, globalFile3.content + "var T2: string;");
314                    verifyProjectsUpdatedInBackgroundEvent();
315                });
316
317                it("should always return the file itself if '--isolatedModules' is specified", () => {
318                    const { host, moduleFile1, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({
319                        configObj: { compilerOptions: { isolatedModules: true } }
320                    });
321
322                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
323                    verifyProjectsUpdatedInBackgroundEvent();
324                });
325
326                it("should always return the file itself if '--out' or '--outFile' is specified", () => {
327                    const outFilePath = "/a/b/out.js";
328                    const { host, moduleFile1, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({
329                        configObj: { compilerOptions: { module: "system", outFile: outFilePath } }
330                    });
331
332                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
333                    verifyProjectsUpdatedInBackgroundEvent();
334                });
335
336                it("should return cascaded affected file list", () => {
337                    const file1Consumer1Consumer1: File = {
338                        path: "/a/b/file1Consumer1Consumer1.ts",
339                        content: `import {y} from "./file1Consumer1";`
340                    };
341                    const { host, moduleFile1, file1Consumer1, updateContentOfOpenFile, verifyNoProjectsUpdatedInBackgroundEvent, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({
342                        getAdditionalFileOrFolder: () => [file1Consumer1Consumer1]
343                    });
344
345                    updateContentOfOpenFile(file1Consumer1, file1Consumer1.content + "export var T: number;");
346                    verifyNoProjectsUpdatedInBackgroundEvent();
347
348                    // Doesnt change the shape of file1Consumer1
349                    host.writeFile(moduleFile1.path, `export var T: number;export function Foo() { };`);
350                    verifyProjectsUpdatedInBackgroundEvent();
351
352                    // Change both files before the timeout
353                    updateContentOfOpenFile(file1Consumer1, file1Consumer1.content + "export var T2: number;");
354                    host.writeFile(moduleFile1.path, `export var T2: number;export function Foo() { };`);
355                    verifyProjectsUpdatedInBackgroundEvent();
356                });
357
358                it("should work fine for files with circular references", () => {
359                    const file1: File = {
360                        path: "/a/b/file1.ts",
361                        content: `
362                    /// <reference path="./file2.ts" />
363                    export var t1 = 10;`
364                    };
365                    const file2: File = {
366                        path: "/a/b/file2.ts",
367                        content: `
368                    /// <reference path="./file1.ts" />
369                    export var t2 = 10;`
370                    };
371                    const { host, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({
372                        getAdditionalFileOrFolder: () => [file1, file2],
373                        firstReloadFileList: [file1.path, libFile.path, file2.path, configFilePath]
374                    });
375
376                    host.writeFile(file2.path, file2.content + "export var t3 = 10;");
377                    verifyProjectsUpdatedInBackgroundEvent();
378                });
379
380                it("should detect removed code file", () => {
381                    const referenceFile1: File = {
382                        path: "/a/b/referenceFile1.ts",
383                        content: `
384                    /// <reference path="./moduleFile1.ts" />
385                    export var x = Foo();`
386                    };
387                    const { host, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({
388                        getAdditionalFileOrFolder: () => [referenceFile1],
389                        firstReloadFileList: [referenceFile1.path, libFile.path, moduleFile1Path, configFilePath]
390                    });
391
392                    host.deleteFile(moduleFile1Path);
393                    verifyProjectsUpdatedInBackgroundEvent();
394                });
395
396                it("should detect non-existing code file", () => {
397                    const referenceFile1: File = {
398                        path: "/a/b/referenceFile1.ts",
399                        content: `
400                    /// <reference path="./moduleFile2.ts" />
401                    export var x = Foo();`
402                    };
403                    const { host, moduleFile2, updateContentOfOpenFile, verifyNoProjectsUpdatedInBackgroundEvent, verifyProjectsUpdatedInBackgroundEvent } = getInitialState({
404                        getAdditionalFileOrFolder: () => [referenceFile1],
405                        firstReloadFileList: [referenceFile1.path, libFile.path, configFilePath]
406                    });
407
408                    updateContentOfOpenFile(referenceFile1, referenceFile1.content + "export var yy = Foo();");
409                    verifyNoProjectsUpdatedInBackgroundEvent();
410
411                    // Create module File2 and see both files are saved
412                    host.writeFile(moduleFile2.path, moduleFile2.content);
413                    verifyProjectsUpdatedInBackgroundEvent();
414                });
415            });
416
417            describe("resolution when resolution cache size", () => {
418                function verifyWithMaxCacheLimit(subScenario: string, useSlashRootAsSomeNotRootFolderInUserDirectory: boolean) {
419                    it(subScenario, () => {
420                        const rootFolder = useSlashRootAsSomeNotRootFolderInUserDirectory ? "/user/username/rootfolder/otherfolder/" : "/";
421                        const file1: File = {
422                            path: rootFolder + "a/b/project/file1.ts",
423                            content: 'import a from "file2"'
424                        };
425                        const file2: File = {
426                            path: rootFolder + "a/b/node_modules/file2.d.ts",
427                            content: "export class a { }"
428                        };
429                        const file3: File = {
430                            path: rootFolder + "a/b/project/file3.ts",
431                            content: "export class c { }"
432                        };
433                        const configFile: File = {
434                            path: rootFolder + "a/b/project/tsconfig.json",
435                            content: JSON.stringify({ compilerOptions: { typeRoots: [] } })
436                        };
437
438                        const openFiles = [file1.path];
439                        const host = createServerHost([file1, file3, libFile, configFile]);
440                        const { session, verifyInitialOpen, verifyProjectsUpdatedInBackgroundEventHandler } = createSession(host, createLoggerWithInMemoryLogs(host));
441                        verifyInitialOpen(file1);
442
443                        file3.content += "export class d {}";
444                        host.writeFile(file3.path, file3.content);
445                        host.checkTimeoutQueueLengthAndRun(2);
446
447                        // Since this is first event
448                        verifyProjectsUpdatedInBackgroundEventHandler([{
449                            eventName: server.ProjectsUpdatedInBackgroundEvent,
450                            data: {
451                                openFiles
452                            }
453                        }]);
454
455                        host.writeFile(file2.path, file2.content);
456                        host.runQueuedTimeoutCallbacks(); // For invalidation
457                        host.runQueuedTimeoutCallbacks(); // For actual update
458
459                        verifyProjectsUpdatedInBackgroundEventHandler(useSlashRootAsSomeNotRootFolderInUserDirectory ? [{
460                            eventName: server.ProjectsUpdatedInBackgroundEvent,
461                            data: {
462                                openFiles
463                            }
464                        }] : []);
465                        baselineTsserverLogs("projectUpdatedInBackground", `${scenario} and ${subScenario}`, session);
466                    });
467                }
468                verifyWithMaxCacheLimit("project is not at root level", /*useSlashRootAsSomeNotRootFolderInUserDirectory*/ true);
469                verifyWithMaxCacheLimit("project is at root level", /*useSlashRootAsSomeNotRootFolderInUserDirectory*/ false);
470            });
471        }
472
473        describe("when event handler is set in the session", () => {
474            verifyProjectsUpdatedInBackgroundEvent("when event handler is set in the session", createSessionWithProjectChangedEventHandler);
475
476            function createSessionWithProjectChangedEventHandler(host: TestServerHost, logger: Logger | undefined): ProjectsUpdatedInBackgroundEventVerifier {
477                const { session, events: projectChangedEvents } = createSessionWithEventTracking<server.ProjectsUpdatedInBackgroundEvent>(
478                    host,
479                    server.ProjectsUpdatedInBackgroundEvent,
480                    logger && { logger }
481                );
482                return {
483                    session,
484                    verifyProjectsUpdatedInBackgroundEventHandler,
485                    verifyInitialOpen: createVerifyInitialOpen(session, verifyProjectsUpdatedInBackgroundEventHandler)
486                };
487
488                function eventToString(event: server.ProjectsUpdatedInBackgroundEvent) {
489                    return JSON.stringify(event && { eventName: event.eventName, data: event.data });
490                }
491
492                function eventsToString(events: readonly server.ProjectsUpdatedInBackgroundEvent[]) {
493                    return "[" + map(events, eventToString).join(",") + "]";
494                }
495
496                function verifyProjectsUpdatedInBackgroundEventHandler(expectedEvents: readonly server.ProjectsUpdatedInBackgroundEvent[]) {
497                    assert.equal(projectChangedEvents.length, expectedEvents.length, `Incorrect number of events Actual: ${eventsToString(projectChangedEvents)} Expected: ${eventsToString(expectedEvents)}`);
498                    forEach(projectChangedEvents, (actualEvent, i) => {
499                        const expectedEvent = expectedEvents[i];
500                        assert.strictEqual(actualEvent.eventName, expectedEvent.eventName);
501                        verifyFiles("openFiles", actualEvent.data.openFiles, expectedEvent.data.openFiles);
502                    });
503
504                    // Verified the events, reset them
505                    projectChangedEvents.length = 0;
506                }
507            }
508        });
509
510        describe("when event handler is not set but session is created with canUseEvents = true", () => {
511            describe("without noGetErrOnBackgroundUpdate, diagnostics for open files are queued", () => {
512                verifyProjectsUpdatedInBackgroundEvent("without noGetErrOnBackgroundUpdate", createSessionThatUsesEvents);
513            });
514
515            describe("with noGetErrOnBackgroundUpdate, diagnostics for open file are not queued", () => {
516                verifyProjectsUpdatedInBackgroundEvent("with noGetErrOnBackgroundUpdate", (host, logger) => createSessionThatUsesEvents(host, logger, /*noGetErrOnBackgroundUpdate*/ true));
517            });
518
519
520            function createSessionThatUsesEvents(host: TestServerHost, logger: Logger | undefined, noGetErrOnBackgroundUpdate?: boolean): ProjectsUpdatedInBackgroundEventVerifier {
521                const { session, getEvents, clearEvents } = createSessionWithDefaultEventHandler<protocol.ProjectsUpdatedInBackgroundEvent>(
522                    host,
523                    server.ProjectsUpdatedInBackgroundEvent,
524                    { noGetErrOnBackgroundUpdate, logger: logger || createHasErrorMessageLogger() }
525                );
526
527                return {
528                    session,
529                    verifyProjectsUpdatedInBackgroundEventHandler,
530                    verifyInitialOpen: createVerifyInitialOpen(session, verifyProjectsUpdatedInBackgroundEventHandler)
531                };
532
533                function verifyProjectsUpdatedInBackgroundEventHandler(expected: readonly server.ProjectsUpdatedInBackgroundEvent[]) {
534                    const expectedEvents: protocol.ProjectsUpdatedInBackgroundEventBody[] = map(expected, e => {
535                        return {
536                            openFiles: e.data.openFiles
537                        };
538                    });
539                    const events = getEvents();
540                    assert.equal(events.length, expectedEvents.length, `Incorrect number of events Actual: ${map(events, e => e.body)} Expected: ${expectedEvents}`);
541                    forEach(events, (actualEvent, i) => {
542                        const expectedEvent = expectedEvents[i];
543                        verifyFiles("openFiles", actualEvent.body.openFiles, expectedEvent.openFiles);
544                    });
545
546                    // Verified the events, reset them
547                    clearEvents();
548
549                    if (events.length) {
550                        host.checkTimeoutQueueLength(noGetErrOnBackgroundUpdate ? 0 : 1); // Error checking queued only if not noGetErrOnBackgroundUpdate
551                    }
552                }
553            }
554        });
555    });
556}
557