From 29756873996d9f36168dda5e76ea72bd023ee4d5 Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Wed, 4 Feb 2026 20:51:39 -0800 Subject: [PATCH] Fix test lint issues --- ...-8ebf3c51-ac8a-4a5c-915d-693ba8507fe0.json | 18 +++++++ .../cache/tests/BackfillCacheProvider.test.ts | 10 ++-- .../tests/RemoteFallbackCacheProvider.test.ts | 6 +-- packages/cache/tests/backfillWrapper.test.ts | 9 ++-- packages/cache/tests/chunkPromise.test.ts | 2 +- packages/cli/src/commands/info/action.ts | 2 +- packages/cli/tests/createTargetGraph.test.ts | 30 +++++------ packages/cli/tests/filterPackages.test.ts | 4 +- .../cli/tests/getFilteredPackages.test.ts | 2 +- .../cli/tests/initializeReporters.test.ts | 8 +-- packages/cli/tests/jsonReporter.test.ts | 35 ++++++------ packages/cli/tests/simulateFileAccess.test.ts | 31 +++++------ packages/config/tests/getConfig.test.ts | 2 +- .../config/tests/getMaxWorkersPerTask.test.ts | 2 +- .../tests/formatDuration.test.ts | 2 +- .../hasher/src/__tests__/PackageTree.test.ts | 5 +- .../hasher/src/__tests__/TargetHasher.test.ts | 38 ++++++------- .../src/__tests__/getPackageDeps.test.ts | 29 +++++----- .../resolveExternalDependencies.test.ts | 4 +- packages/logger/tests/logger.test.ts | 6 +-- packages/reporters/tests/AdoReporter.test.ts | 51 ++++++++++-------- .../tests/ChromeTraceEventsReporter.test.ts | 7 +-- packages/reporters/tests/JsonReporter.test.ts | 20 ++++--- packages/reporters/tests/LogReporter.test.ts | 21 ++++---- .../tests/VerboseFileLogReporter.test.ts | 19 +++---- packages/reporters/tests/writerToString.ts | 14 +++++ .../scheduler/src/workers/targetWorker.ts | 1 - .../scheduler/tests/NpmScriptRunner.test.ts | 11 ++-- .../scheduler/tests/SimpleScheduler.test.ts | 25 ++++----- .../tests/SimpleScheduler.watchmode.test.ts | 11 ++-- .../scheduler/tests/WrappedTarget.test.ts | 50 +++++++++++------ .../tests/fixtures/AbortEarlyRunner.js | 28 ---------- .../tests/fixtures/FailOnPackageRunner.js | 8 ++- .../scheduler/tests/fixtures/NoOpRunner.js | 5 -- packages/scheduler/tests/fixtures/fakeNpm.js | 8 +-- packages/scheduler/tests/fixtures/pools.ts | 7 ++- packages/scheduler/tests/fixtures/worker.js | 6 --- packages/scheduler/tests/waitFor.ts | 8 +-- .../target-graph/tests/TargetFactory.test.ts | 2 +- .../tests/TargetGraphBuilder.test.ts | 4 +- .../tests/WorkspaceTargetGraphBuilder.test.ts | 54 +++++++++---------- .../target-graph/tests/detectCycles.test.ts | 6 +-- .../target-graph/tests/prioritize.test.ts | 6 +-- packages/target-graph/tests/targetId.test.ts | 2 +- .../tests/transitiveReduction.test.ts | 6 +-- .../tests/AggregatedPool.test.ts | 2 +- .../tests/WorkerPool.test.ts | 8 +-- .../tests/fixtures/my-5mb-worker.js | 1 + .../tests/fixtures/registerWorker.fixture.js | 6 ++- .../tests/pickTaskFromQueue.test.ts | 4 +- 50 files changed, 331 insertions(+), 315 deletions(-) create mode 100644 change/change-8ebf3c51-ac8a-4a5c-915d-693ba8507fe0.json create mode 100644 packages/reporters/tests/writerToString.ts delete mode 100644 packages/scheduler/tests/fixtures/AbortEarlyRunner.js delete mode 100644 packages/scheduler/tests/fixtures/NoOpRunner.js delete mode 100644 packages/scheduler/tests/fixtures/worker.js diff --git a/change/change-8ebf3c51-ac8a-4a5c-915d-693ba8507fe0.json b/change/change-8ebf3c51-ac8a-4a5c-915d-693ba8507fe0.json new file mode 100644 index 000000000..b5eef0bf8 --- /dev/null +++ b/change/change-8ebf3c51-ac8a-4a5c-915d-693ba8507fe0.json @@ -0,0 +1,18 @@ +{ + "changes": [ + { + "type": "none", + "comment": "Fix lint issues", + "packageName": "@lage-run/cli", + "email": "elcraig@microsoft.com", + "dependentChangeType": "none" + }, + { + "type": "none", + "comment": "Fix lint issues", + "packageName": "@lage-run/scheduler", + "email": "elcraig@microsoft.com", + "dependentChangeType": "none" + } + ] +} \ No newline at end of file diff --git a/packages/cache/tests/BackfillCacheProvider.test.ts b/packages/cache/tests/BackfillCacheProvider.test.ts index 8554a975a..a0e5a4905 100644 --- a/packages/cache/tests/BackfillCacheProvider.test.ts +++ b/packages/cache/tests/BackfillCacheProvider.test.ts @@ -1,11 +1,9 @@ -import { Target } from "@lage-run/target-graph"; - -import { BackfillCacheProvider, BackfillCacheProviderOptions } from "../src/providers/BackfillCacheProvider"; +import createLogger from "@lage-run/logger"; import { Monorepo } from "@lage-run/monorepo-fixture"; -import { _testResetEnvHash } from "../src/salt"; +import type { Target } from "@lage-run/target-graph"; import path from "path"; -import createLogger from "@lage-run/logger"; -import { getCacheDirectory, getLogsCacheDirectory } from "../src/getCacheDirectory"; +import { getCacheDirectory } from "../src/getCacheDirectory.js"; +import { BackfillCacheProvider, type BackfillCacheProviderOptions } from "../src/providers/BackfillCacheProvider.js"; describe("BackfillCacheProvider", () => { it("should fetch a cache of the outputs as specified in the outputs folder in target", async () => { diff --git a/packages/cache/tests/RemoteFallbackCacheProvider.test.ts b/packages/cache/tests/RemoteFallbackCacheProvider.test.ts index aebad68cd..f117736e4 100644 --- a/packages/cache/tests/RemoteFallbackCacheProvider.test.ts +++ b/packages/cache/tests/RemoteFallbackCacheProvider.test.ts @@ -1,8 +1,8 @@ -import { CacheProvider } from "../src/types/CacheProvider"; import { Logger } from "@lage-run/logger"; -import { RemoteFallbackCacheProvider, RemoteFallbackCacheProviderOptions } from "../src/providers/RemoteFallbackCacheProvider"; -import path from "path"; import type { Target } from "@lage-run/target-graph"; +import path from "path"; +import { RemoteFallbackCacheProvider, type RemoteFallbackCacheProviderOptions } from "../src/providers/RemoteFallbackCacheProvider.js"; +import type { CacheProvider } from "../src/types/CacheProvider.js"; describe("RemoteFallbackCacheProvider", () => { it("should fetch from local cache first", async () => { diff --git a/packages/cache/tests/backfillWrapper.test.ts b/packages/cache/tests/backfillWrapper.test.ts index 24a26c1c7..4cafdd806 100644 --- a/packages/cache/tests/backfillWrapper.test.ts +++ b/packages/cache/tests/backfillWrapper.test.ts @@ -1,6 +1,6 @@ -import { AzureBlobCacheStorageConfig } from "backfill-config"; +import type { AzureBlobCacheStorageConfig, AzureBlobCacheStorageConnectionStringOptions } from "backfill-config"; import path from "path"; -import { createBackfillLogger, createBackfillCacheConfig } from "../src/backfillWrapper"; +import { createBackfillLogger, createBackfillCacheConfig } from "../src/backfillWrapper.js"; describe("backfill-config", () => { it("should read values from environment variables", () => { @@ -14,8 +14,9 @@ describe("backfill-config", () => { expect(config.cacheStorageConfig.provider).toBe("azure-blob"); const cacheStorageConfig = config.cacheStorageConfig as AzureBlobCacheStorageConfig; - expect(cacheStorageConfig.options.connectionString).toBe("somestring"); - expect(cacheStorageConfig.options.container).toBe("somecontainer"); + const cacheOptions = cacheStorageConfig.options as AzureBlobCacheStorageConnectionStringOptions; + expect(cacheOptions.connectionString).toBe("somestring"); + expect(cacheOptions.container).toBe("somecontainer"); delete process.env.BACKFILL_CACHE_PROVIDER; delete process.env.BACKFILL_CACHE_PROVIDER_OPTIONS; diff --git a/packages/cache/tests/chunkPromise.test.ts b/packages/cache/tests/chunkPromise.test.ts index fbb290aeb..f343ea1f0 100644 --- a/packages/cache/tests/chunkPromise.test.ts +++ b/packages/cache/tests/chunkPromise.test.ts @@ -1,4 +1,4 @@ -import { chunkPromise } from "../src/chunkPromise"; +import { chunkPromise } from "../src/chunkPromise.js"; describe("chunking promises", () => { it("should chunk promises", async () => { diff --git a/packages/cli/src/commands/info/action.ts b/packages/cli/src/commands/info/action.ts index d91b8c46c..9ac29b938 100644 --- a/packages/cli/src/commands/info/action.ts +++ b/packages/cli/src/commands/info/action.ts @@ -36,7 +36,7 @@ export interface InfoActionOptions extends ReporterInitOptions { optimizeGraph: boolean; } -interface PackageTask { +export interface PackageTask { id: string; command: string[]; dependencies: string[]; diff --git a/packages/cli/tests/createTargetGraph.test.ts b/packages/cli/tests/createTargetGraph.test.ts index d353f73c1..09eff2314 100644 --- a/packages/cli/tests/createTargetGraph.test.ts +++ b/packages/cli/tests/createTargetGraph.test.ts @@ -1,10 +1,9 @@ -import { getConfig, PipelineDefinition } from "@lage-run/config"; +import { getConfig, type PipelineDefinition } from "@lage-run/config"; import createLogger from "@lage-run/logger"; +import type { PackageInfo, PackageInfos } from "workspace-tools"; +import { generatePackageTask, type InfoActionOptions, type PackageTask } from "../src/commands/info/action.js"; import { initializeReporters } from "../src/commands/initializeReporters.js"; -import { generatePackageTask, type InfoActionOptions } from "../src/commands/info/action.js"; -import { PackageInfo, PackageInfos } from "workspace-tools"; import { createTargetGraph } from "../src/commands/run/createTargetGraph.js"; -import { getFilteredPackages } from "../src/filter/getFilteredPackages.js"; import { getBinPaths } from "../src/getBinPaths.js"; describe("createTargetGraph", () => { @@ -141,17 +140,18 @@ async function createPackageTasks(tasks: string[], packageInfos: PackageInfos, p priorities: config.priorities, }); - const scope = getFilteredPackages({ - root, - packageInfos, - logger, - includeDependencies: options.dependencies, - includeDependents: options.dependents && !options.to, // --to is a short hand for --scope + --no-dependents - since: options.since, - scope: (options.scope ?? []).concat(options.to ?? []), // --to is a short hand for --scope + --no-dependents - repoWideChanges: config.repoWideChanges, - sinceIgnoreGlobs: options.ignore.concat(config.ignore), - }); + // unused? + // const scope = getFilteredPackages({ + // root, + // packageInfos, + // logger, + // includeDependencies: options.dependencies, + // includeDependents: options.dependents && !options.to, // --to is a short hand for --scope + --no-dependents + // since: options.since, + // scope: (options.scope ?? []).concat(options.to ?? []), // --to is a short hand for --scope + --no-dependents + // repoWideChanges: config.repoWideChanges, + // sinceIgnoreGlobs: options.ignore.concat(config.ignore), + // }); const binPaths = getBinPaths(); const targets = [...targetGraph.targets.values()]; diff --git a/packages/cli/tests/filterPackages.test.ts b/packages/cli/tests/filterPackages.test.ts index 380c4f199..48c79c548 100644 --- a/packages/cli/tests/filterPackages.test.ts +++ b/packages/cli/tests/filterPackages.test.ts @@ -1,6 +1,6 @@ -import { filterPackages } from "../src/filter/getFilteredPackages"; -import { PackageInfos, PackageInfo } from "workspace-tools"; import { Logger } from "@lage-run/logger"; +import type { PackageInfo, PackageInfos } from "workspace-tools"; +import { filterPackages } from "../src/filter/getFilteredPackages.js"; describe("filterPackages", () => { const logger = new Logger(); diff --git a/packages/cli/tests/getFilteredPackages.test.ts b/packages/cli/tests/getFilteredPackages.test.ts index ead7b067a..156d2fd55 100644 --- a/packages/cli/tests/getFilteredPackages.test.ts +++ b/packages/cli/tests/getFilteredPackages.test.ts @@ -1,7 +1,7 @@ import createLogger from "@lage-run/logger"; import { Monorepo } from "@lage-run/monorepo-fixture"; import { getPackageInfosAsync } from "workspace-tools"; -import { getFilteredPackages } from "../src/filter/getFilteredPackages"; +import { getFilteredPackages } from "../src/filter/getFilteredPackages.js"; describe("getFilteredPackages", () => { it("should respect the ignore flag when since flag is used", async () => { diff --git a/packages/cli/tests/initializeReporters.test.ts b/packages/cli/tests/initializeReporters.test.ts index 4df811781..52b282062 100644 --- a/packages/cli/tests/initializeReporters.test.ts +++ b/packages/cli/tests/initializeReporters.test.ts @@ -1,10 +1,10 @@ +import { Logger, type Reporter } from "@lage-run/logger"; +import { AdoReporter, BasicReporter, ChromeTraceEventsReporter, LogReporter } from "@lage-run/reporters"; import fs from "fs"; -import path from "path"; +import isInteractive from "is-interactive"; import os from "os"; -import { Logger, Reporter } from "@lage-run/logger"; -import { AdoReporter, BasicReporter, ChromeTraceEventsReporter, LogReporter } from "@lage-run/reporters"; +import path from "path"; import { initializeReporters } from "../src/commands/initializeReporters.js"; -import isInteractive from "is-interactive"; jest.mock("is-interactive", () => jest.fn(() => true)); diff --git a/packages/cli/tests/jsonReporter.test.ts b/packages/cli/tests/jsonReporter.test.ts index 677633eac..ec25d619c 100644 --- a/packages/cli/tests/jsonReporter.test.ts +++ b/packages/cli/tests/jsonReporter.test.ts @@ -35,7 +35,12 @@ describe("json reporter", () => { logger.info("test Json", testObject); expect(logSpy).toHaveBeenCalledWith( - '{"timestamp":0,"level":30,"msg":"test Json","data":{"x":"field x","number":1,"array":[1,2,3],"object":{"a":1,"b":2}}}' + JSON.stringify({ + timestamp: 0, + level: 30, + msg: "test Json", + data: testObject, + }) ); jest.clearAllMocks(); }); @@ -57,24 +62,16 @@ describe("json reporter", () => { logger.info("test Json", testObject); expect(logSpy).toHaveBeenCalledWith( - `{ - \"timestamp\": 0, - \"level\": 30, - \"msg\": \"test Json\", - \"data\": { - \"x\": \"field x\", - \"number\": 1, - \"array\": [ - 1, - 2, - 3 - ], - \"object\": { - \"a\": 1, - \"b\": 2 - } - } -}` + JSON.stringify( + { + timestamp: 0, + level: 30, + msg: "test Json", + data: testObject, + }, + null, + 2 + ) ); jest.clearAllMocks(); }); diff --git a/packages/cli/tests/simulateFileAccess.test.ts b/packages/cli/tests/simulateFileAccess.test.ts index bd6804c77..ca6f31420 100644 --- a/packages/cli/tests/simulateFileAccess.test.ts +++ b/packages/cli/tests/simulateFileAccess.test.ts @@ -1,20 +1,22 @@ -import { simulateFileAccess } from "../src/commands/exec/simulateFileAccess"; -import fs from "fs"; -import path from "path"; +import { Logger } from "@lage-run/logger"; +import fs, { type Stats } from "fs"; import os from "os"; +import path from "path"; +import { simulateFileAccess } from "../src/commands/exec/simulateFileAccess.js"; jest.mock("fs"); // Mock the logger const mockSilly = jest.fn(); -const mockLogger = { - silly: mockSilly, - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), - verbose: jest.fn(), - debug: jest.fn(), -}; +class MockLogger extends Logger { + override silly = mockSilly; + // do nothing + override log() {} + override stream() { + return () => {}; + } +} +const mockLogger = new MockLogger(); describe("simulateFileAccess", () => { let mockRoot: string; @@ -23,7 +25,6 @@ describe("simulateFileAccess", () => { let mockCloseSync: jest.SpyInstance; let mockReaddirSync: jest.SpyInstance; let mockUtimesSync: jest.SpyInstance; - let mockLstatSync: jest.SpyInstance; beforeEach(() => { mockRoot = path.join(os.tmpdir(), "lage-test-root"); @@ -33,11 +34,11 @@ describe("simulateFileAccess", () => { mockCloseSync = jest.spyOn(fs, "closeSync").mockImplementation(() => {}); mockReaddirSync = jest.spyOn(fs, "readdirSync").mockImplementation(() => []); mockUtimesSync = jest.spyOn(fs, "utimesSync").mockImplementation(() => {}); - mockLstatSync = jest.spyOn(fs, "lstatSync").mockImplementation((inputPath: any) => { + jest.spyOn(fs, "lstatSync").mockImplementation((inputPath: any) => { const strPath = Buffer.isBuffer(inputPath) ? inputPath.toString() : String(inputPath); return { isDirectory: () => strPath.endsWith(path.sep), - }; + } as Stats; }); }); @@ -134,7 +135,7 @@ describe("simulateFileAccess", () => { // Set up a mock that fails for a specific file path const failingPath = path.join(mockRoot, "src/components/Missing.tsx"); - jest.spyOn(fs, "openSync").mockImplementation((filePath, mode) => { + jest.spyOn(fs, "openSync").mockImplementation((filePath) => { if (filePath === failingPath) { throw new Error("ENOENT: File not found"); } diff --git a/packages/config/tests/getConfig.test.ts b/packages/config/tests/getConfig.test.ts index 0927ce013..e8d9de4c5 100644 --- a/packages/config/tests/getConfig.test.ts +++ b/packages/config/tests/getConfig.test.ts @@ -1,5 +1,5 @@ -import { getConfig } from "../src/getConfig"; import path from "path"; +import { getConfig } from "../src/getConfig.js"; describe("getConfig", () => { it("should read from an asynchronous config file", async () => { diff --git a/packages/config/tests/getMaxWorkersPerTask.test.ts b/packages/config/tests/getMaxWorkersPerTask.test.ts index 62d460a50..ee099bc81 100644 --- a/packages/config/tests/getMaxWorkersPerTask.test.ts +++ b/packages/config/tests/getMaxWorkersPerTask.test.ts @@ -1,4 +1,4 @@ -import { getMaxWorkersPerTask } from "../src/getMaxWorkersPerTask"; +import { getMaxWorkersPerTask } from "../src/getMaxWorkersPerTask.js"; describe("getMaxWorkersPerTask", () => { it("parses the pipeline config for maxWorkers", () => { diff --git a/packages/format-hrtime/tests/formatDuration.test.ts b/packages/format-hrtime/tests/formatDuration.test.ts index cbd64e8ee..310b38776 100644 --- a/packages/format-hrtime/tests/formatDuration.test.ts +++ b/packages/format-hrtime/tests/formatDuration.test.ts @@ -1,4 +1,4 @@ -import { hrtimeDiff, hrToSeconds } from "../src/formatDuration"; +import { hrtimeDiff, hrToSeconds } from "../src/formatDuration.js"; describe("hrtimeDiff", () => { it("should calulate diffs between two hrtime", () => { diff --git a/packages/hasher/src/__tests__/PackageTree.test.ts b/packages/hasher/src/__tests__/PackageTree.test.ts index ce6d3cfc6..c679c8aed 100644 --- a/packages/hasher/src/__tests__/PackageTree.test.ts +++ b/packages/hasher/src/__tests__/PackageTree.test.ts @@ -1,8 +1,7 @@ -import path from "path"; - -import { PackageTree } from "../index"; import { Monorepo } from "@lage-run/monorepo-fixture"; +import path from "path"; import { getPackageInfos } from "workspace-tools"; +import { PackageTree } from "../index.js"; const fixturesPath = path.join(__dirname, "..", "__fixtures__"); diff --git a/packages/hasher/src/__tests__/TargetHasher.test.ts b/packages/hasher/src/__tests__/TargetHasher.test.ts index f8411792d..7851eecca 100644 --- a/packages/hasher/src/__tests__/TargetHasher.test.ts +++ b/packages/hasher/src/__tests__/TargetHasher.test.ts @@ -1,15 +1,25 @@ +import { Monorepo } from "@lage-run/monorepo-fixture"; +import type { Target } from "@lage-run/target-graph"; +import fs from "fs"; import path from "path"; +import { TargetHasher } from "../index.js"; -import { TargetHasher } from "../index"; -import fs from "fs"; -import { Monorepo } from "@lage-run/monorepo-fixture"; -import { Target } from "@lage-run/target-graph"; -const fixturesPath = path.join(__dirname, "..", "__fixtures__"); +const fixturesPath = path.resolve(__dirname, "../__fixtures__"); describe("The main Hasher class", () => { + let monorepos: Monorepo[] = []; + + afterEach(async () => { + for (const monorepo of monorepos) { + await monorepo.cleanup(); + } + monorepos = []; + }); + async function setupFixture(fixture = "monorepo") { const monorepo = new Monorepo("fixture"); await monorepo.init(path.join(fixturesPath, fixture)); + monorepos.push(monorepo); return monorepo; } @@ -46,8 +56,6 @@ describe("The main Hasher class", () => { const hash2 = await getHash(hasher2, target2); expect(hash).not.toEqual(hash2); - - monorepo1.cleanup(); }); it("creates different hashes given different fixtures", async () => { @@ -61,9 +69,6 @@ describe("The main Hasher class", () => { const hasher2 = new TargetHasher({ root: monorepo2.root, environmentGlob: [] }); const hash2 = await getHash(hasher2, target2); expect(hash).not.toEqual(hash2); - - monorepo1.cleanup(); - monorepo2.cleanup(); }); it("creates the same hash given the same fixture, with different target hasher instances", async () => { @@ -78,9 +83,6 @@ describe("The main Hasher class", () => { const hash2 = await getHash(hasher2, target2); expect(hash).toEqual(hash2); - - monorepo1.cleanup(); - monorepo2.cleanup(); }); it("creates different hashes when a src file has changed", async () => { @@ -98,9 +100,6 @@ describe("The main Hasher class", () => { const hash2 = await getHash(hasher2, target2); expect(hash).not.toEqual(hash2); - - monorepo1.cleanup(); - monorepo2.cleanup(); }); it("creates different hashes when a src file has changed for a dependency", async () => { @@ -121,9 +120,6 @@ describe("The main Hasher class", () => { const hash2 = await getHash(hasher2, target2); expect(hash).not.toEqual(hash2); - - monorepo1.cleanup(); - monorepo2.cleanup(); }); it("creates different hashes when the target has a different env glob", async () => { @@ -142,8 +138,6 @@ describe("The main Hasher class", () => { const hash2 = await getHash(hasher, target2); expect(hash).not.toEqual(hash2); - - monorepo1.cleanup(); }); it("creates different hashes when the target has a different env glob for different task types", async () => { @@ -169,7 +163,5 @@ describe("The main Hasher class", () => { expect(hash).not.toEqual(hash2); expect(hash2).not.toEqual(hash3); - - monorepo1.cleanup(); }); }); diff --git a/packages/hasher/src/__tests__/getPackageDeps.test.ts b/packages/hasher/src/__tests__/getPackageDeps.test.ts index 1651056ef..b4bbd8f89 100644 --- a/packages/hasher/src/__tests__/getPackageDeps.test.ts +++ b/packages/hasher/src/__tests__/getPackageDeps.test.ts @@ -1,8 +1,7 @@ -import * as path from "path"; -import * as fs from "fs"; - -import { getPackageDeps, parseGitLsTree, parseGitFilename } from "../getPackageDeps"; import { Monorepo } from "@lage-run/monorepo-fixture"; +import fs from "fs"; +import path from "path"; +import { getPackageDeps, parseGitFilename, parseGitLsTree } from "../getPackageDeps.js"; const SOURCE_PATH: string = path.join(__dirname, "..", "__fixtures__"); @@ -29,10 +28,10 @@ describe(parseGitFilename.name, () => { describe(parseGitLsTree.name, () => { it("can handle a blob", () => { - const filename: string = "src/typings/tsd.d.ts"; - const hash: string = "3451bccdc831cb43d7a70ed8e628dcf9c7f888c8"; + const filename = "src/typings/tsd.d.ts"; + const hash = "3451bccdc831cb43d7a70ed8e628dcf9c7f888c8"; - const output: string = `100644 blob ${hash}\t${filename}`; + const output = `100644 blob ${hash}\t${filename}`; const changes: Map = parseGitLsTree(output); expect(changes.size).toEqual(1); // Expect there to be exactly 1 change @@ -40,10 +39,10 @@ describe(parseGitLsTree.name, () => { }); it("can handle a submodule", () => { - const filename: string = "rushstack"; - const hash: string = "c5880bf5b0c6c1f2e2c43c95beeb8f0a808e8bac"; + const filename = "rushstack"; + const hash = "c5880bf5b0c6c1f2e2c43c95beeb8f0a808e8bac"; - const output: string = `160000 commit ${hash}\t${filename}`; + const output = `160000 commit ${hash}\t${filename}`; const changes: Map = parseGitLsTree(output); expect(changes.size).toEqual(1); // Expect there to be exactly 1 change @@ -51,13 +50,13 @@ describe(parseGitLsTree.name, () => { }); it("can handle multiple lines", () => { - const filename1: string = "src/typings/tsd.d.ts"; - const hash1: string = "3451bccdc831cb43d7a70ed8e628dcf9c7f888c8"; + const filename1 = "src/typings/tsd.d.ts"; + const hash1 = "3451bccdc831cb43d7a70ed8e628dcf9c7f888c8"; - const filename2: string = "src/foo bar/tsd.d.ts"; - const hash2: string = "0123456789abcdef1234567890abcdef01234567"; + const filename2 = "src/foo bar/tsd.d.ts"; + const hash2 = "0123456789abcdef1234567890abcdef01234567"; - const output: string = `100644 blob ${hash1}\t${filename1}\n100666 blob ${hash2}\t${filename2}`; + const output = `100644 blob ${hash1}\t${filename1}\n100666 blob ${hash2}\t${filename2}`; const changes: Map = parseGitLsTree(output); expect(changes.size).toEqual(2); // Expect there to be exactly 2 changes diff --git a/packages/hasher/src/__tests__/resolveExternalDependencies.test.ts b/packages/hasher/src/__tests__/resolveExternalDependencies.test.ts index 606f37736..76d15dadb 100644 --- a/packages/hasher/src/__tests__/resolveExternalDependencies.test.ts +++ b/packages/hasher/src/__tests__/resolveExternalDependencies.test.ts @@ -5,11 +5,11 @@ import { _addToQueue, type DependencySpec, type DependencyQueue, -} from "../resolveExternalDependencies"; +} from "../resolveExternalDependencies.js"; import path from "path"; import { Monorepo } from "@lage-run/monorepo-fixture"; -const fixturesPath = path.join(__dirname, "..", "__fixtures__"); +const fixturesPath = path.join(__dirname, "../__fixtures__"); describe("_filterExternalDependencies", () => { let monorepo: Monorepo | undefined; diff --git a/packages/logger/tests/logger.test.ts b/packages/logger/tests/logger.test.ts index 299b18660..39decec79 100644 --- a/packages/logger/tests/logger.test.ts +++ b/packages/logger/tests/logger.test.ts @@ -1,16 +1,16 @@ import { PassThrough } from "stream"; -import createLogger, { LogEntry, LogLevel, LogStructuredData, Reporter } from "../src/index"; +import createLogger, { type LogEntry, LogLevel, type LogStructuredData, type Reporter } from "../src/index.js"; describe("logger", () => { class TestReporter implements Reporter { logLevel = LogLevel.warn; entries: LogEntry[] = []; - log(entry) { + log(entry: LogEntry) { this.entries.push(entry); } - summarize(_context: TContext): void {} + summarize(): void {} } it("should create a logger that reports to a single reporter", () => { diff --git a/packages/reporters/tests/AdoReporter.test.ts b/packages/reporters/tests/AdoReporter.test.ts index fbbd35fa7..1d2b02451 100644 --- a/packages/reporters/tests/AdoReporter.test.ts +++ b/packages/reporters/tests/AdoReporter.test.ts @@ -1,7 +1,9 @@ import { LogLevel } from "@lage-run/logger"; -import { AdoReporter } from "../src/AdoReporter"; +import type { TargetRun } from "@lage-run/scheduler-types"; import streams from "memory-streams"; -import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry"; +import { AdoReporter } from "../src/AdoReporter.js"; +import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry.js"; +import { writerToString } from "./writerToString.js"; function createTarget(packageName: string, task: string) { return { @@ -37,8 +39,8 @@ describe("AdoReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` - "VERB: a task ➔ start + expect(writerToString(writer)).toMatchInlineSnapshot(` + "VERB: a task ➔ start " `); }); @@ -61,7 +63,7 @@ describe("AdoReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "VERB: a task | test message " `); @@ -103,7 +105,7 @@ describe("AdoReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "##[group] a test success, took 10.00s VERB: ➔ start a test VERB: | test message for a#test @@ -162,10 +164,10 @@ describe("AdoReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` - "VERB: a build ➔ start - VERB: a test ➔ start - VERB: b build ➔ start + expect(writerToString(writer)).toMatchInlineSnapshot(` + "VERB: a build ➔ start + VERB: a test ➔ start + VERB: b build ➔ start VERB: a build | test message for a#build VERB: a test | test message for a#test VERB: a build | test message for a#build again @@ -174,7 +176,7 @@ describe("AdoReporter", () => { VERB: b build | test message for b#build again VERB: a test ✓ done - 10.00s VERB: b build ✓ done - 30.00s - VERB: a build ✖ fail + VERB: a build ✖ fail " `); }); @@ -215,13 +217,13 @@ describe("AdoReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` - "INFO: a build ➔ start - INFO: a test ➔ start - INFO: b build ➔ start + expect(writerToString(writer)).toMatchInlineSnapshot(` + "INFO: a build ➔ start + INFO: a test ➔ start + INFO: b build ➔ start INFO: a test ✓ done - 10.00s INFO: b build ✓ done - 30.00s - INFO: a build ✖ fail + INFO: a build ✖ fail " `); }); @@ -273,10 +275,13 @@ describe("AdoReporter", () => { skipped: [], queued: [], }, - targetRuns: new Map([ - [aBuildTarget.id, { target: aBuildTarget, status: "failed", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0] }], - [aTestTarget.id, { target: aTestTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0] }], - [bBuildTarget.id, { target: bBuildTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0] }], + targetRuns: new Map>([ + [aBuildTarget.id, { target: aBuildTarget, status: "failed", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0], threadId: 0 }], + [aTestTarget.id, { target: aTestTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0], threadId: 0 }], + [ + bBuildTarget.id, + { target: bBuildTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0], threadId: 0 }, + ], ]), maxWorkerMemoryUsage: 0, workerRestarts: 0, @@ -284,7 +289,7 @@ describe("AdoReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "##[group] a test success, took 10.00s INFO: ➔ start a test VERB: | test message for a#test @@ -309,10 +314,10 @@ describe("AdoReporter", () => { INFO: b build success, took 60.00s [Tasks Count] success: 2, skipped: 0, pending: 0, aborted: 0 ##[error] [a build] ERROR DETECTED - ##[error] + ##[error] ##[error] test message for a#build ##[error] test message for a#build again, but look there is an error! - ##[error] + ##[error] ##vso[task.logissue type=error]Your build failed on the following packages => [a build], find the error logs above with the prefix '##[error]!' INFO: Took a total of 1m 40.00s to complete " diff --git a/packages/reporters/tests/ChromeTraceEventsReporter.test.ts b/packages/reporters/tests/ChromeTraceEventsReporter.test.ts index e580e7ba5..591b4ab90 100644 --- a/packages/reporters/tests/ChromeTraceEventsReporter.test.ts +++ b/packages/reporters/tests/ChromeTraceEventsReporter.test.ts @@ -1,8 +1,9 @@ import fs from "fs"; +import streams from "memory-streams"; import os from "os"; import path from "path"; -import { ChromeTraceEventsReporter } from "../src/ChromeTraceEventsReporter"; -import streams from "memory-streams"; +import { ChromeTraceEventsReporter } from "../src/ChromeTraceEventsReporter.js"; +import { writerToString } from "./writerToString.js"; function createTarget(packageName: string, task: string) { return { @@ -102,7 +103,7 @@ describe("ChromeTraceEventsReporter", () => { "displayTimeUnit": "ms" }" `); - expect(consoleWriter.toString()).toMatchInlineSnapshot(` + expect(writerToString(consoleWriter)).toMatchInlineSnapshot(` " Profiler output written to ${outputFile}, open it with chrome://tracing or edge://tracing " diff --git a/packages/reporters/tests/JsonReporter.test.ts b/packages/reporters/tests/JsonReporter.test.ts index 352166a78..8ed6113d7 100644 --- a/packages/reporters/tests/JsonReporter.test.ts +++ b/packages/reporters/tests/JsonReporter.test.ts @@ -1,6 +1,7 @@ import { LogLevel } from "@lage-run/logger"; -import { JsonReporter } from "../src/JsonReporter"; -import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry"; +import type { TargetRun } from "@lage-run/scheduler-types"; +import { JsonReporter } from "../src/JsonReporter.js"; +import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry.js"; function createTarget(packageName: string, task: string) { return { @@ -17,7 +18,7 @@ function createTarget(packageName: string, task: string) { describe("JsonReporter", () => { it("logs both status and message entries", () => { - let rawLogs: string[] = []; + const rawLogs: string[] = []; jest.spyOn(console, "log").mockImplementation((message: string) => { rawLogs.push(JSON.parse(message)); }); @@ -347,7 +348,7 @@ describe("JsonReporter", () => { }); it("creates a summary entry", () => { - let rawLogs: string[] = []; + const rawLogs: string[] = []; jest.spyOn(console, "log").mockImplementation((message: string) => { rawLogs.push(JSON.parse(message)); }); @@ -398,10 +399,13 @@ describe("JsonReporter", () => { skipped: [], queued: [], }, - targetRuns: new Map([ - [aBuildTarget.id, { target: aBuildTarget, status: "failed", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0] }], - [aTestTarget.id, { target: aTestTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0] }], - [bBuildTarget.id, { target: bBuildTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0] }], + targetRuns: new Map>([ + [aBuildTarget.id, { target: aBuildTarget, status: "failed", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0], threadId: 0 }], + [aTestTarget.id, { target: aTestTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0], threadId: 0 }], + [ + bBuildTarget.id, + { target: bBuildTarget, status: "success", duration: [60, 0], startTime: [1, 0], queueTime: [0, 0], threadId: 0 }, + ], ]), maxWorkerMemoryUsage: 0, workerRestarts: 0, diff --git a/packages/reporters/tests/LogReporter.test.ts b/packages/reporters/tests/LogReporter.test.ts index b8b5097f8..b28759602 100644 --- a/packages/reporters/tests/LogReporter.test.ts +++ b/packages/reporters/tests/LogReporter.test.ts @@ -1,8 +1,9 @@ import { LogLevel } from "@lage-run/logger"; -import { LogReporter } from "../src/LogReporter"; +import type { TargetRun } from "@lage-run/scheduler-types"; import streams from "memory-streams"; -import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry"; -import { TargetRun } from "@lage-run/scheduler-types"; +import { LogReporter } from "../src/LogReporter.js"; +import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry.js"; +import { writerToString } from "./writerToString.js"; function createTarget(packageName: string, task: string) { return { @@ -38,7 +39,7 @@ describe("LogReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "a task ➔ start " `); @@ -62,7 +63,7 @@ describe("LogReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "a task : test message " `); @@ -104,7 +105,7 @@ describe("LogReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "a test ➔ start a test : test message for a#test a test : test message for a#test again @@ -160,7 +161,7 @@ describe("LogReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "a build ➔ start a test ➔ start b build ➔ start @@ -213,7 +214,7 @@ describe("LogReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "a build ➔ start a test ➔ start b build ➔ start @@ -300,7 +301,7 @@ describe("LogReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "a test ➔ start a test : test message for a#test a test : test message for a#test again @@ -331,7 +332,7 @@ describe("LogReporter", () => { test message for a#build again, but look there is an error! ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ - Took a total of 1m 40.00s to complete. + Took a total of 1m 40.00s to complete. " `); }); diff --git a/packages/reporters/tests/VerboseFileLogReporter.test.ts b/packages/reporters/tests/VerboseFileLogReporter.test.ts index 5e276fa4e..dad1d9768 100644 --- a/packages/reporters/tests/VerboseFileLogReporter.test.ts +++ b/packages/reporters/tests/VerboseFileLogReporter.test.ts @@ -1,7 +1,8 @@ -import { LogEntry, LogLevel } from "@lage-run/logger"; -import { VerboseFileLogReporter } from "../src/VerboseFileLogReporter"; +import { LogLevel, type LogEntry } from "@lage-run/logger"; import streams from "memory-streams"; -import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry"; +import { VerboseFileLogReporter } from "../src/VerboseFileLogReporter.js"; +import type { TargetMessageEntry, TargetStatusEntry } from "../src/types/TargetLogEntry.js"; +import { writerToString } from "./writerToString.js"; function createTarget(packageName: string, task: string) { return { @@ -36,7 +37,7 @@ describe("VerboseFileLogReporter", () => { reporter.log(entry); writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "[:${entry.data.target.id}:] @madeUp/avettLyrics generateLyrics ➔ start " `); @@ -59,7 +60,7 @@ describe("VerboseFileLogReporter", () => { reporter.log(entry); writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "[:${entry.data.target.id}:] @madeUp/avettLyrics generateLyrics : Be loud. Let your colors show! " `); @@ -83,7 +84,7 @@ describe("VerboseFileLogReporter", () => { reporter.log(entry); writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "[:I love the Avett Brothers!:] @madeUp/avettLyrics generateLyrics : I've got something to say, but it's all vanity. " `); @@ -102,7 +103,7 @@ describe("VerboseFileLogReporter", () => { reporter.log(entry); writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "For every year of knowledge gained, there's a negative year I've earned. " `); @@ -143,7 +144,7 @@ describe("VerboseFileLogReporter", () => { writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "[:${aBuildTarget.id}:] a build ➔ start [:${aTestTarget.id}:] a test ➔ start [:${bBuildTarget.id}:] b build ➔ start @@ -191,7 +192,7 @@ describe("VerboseFileLogReporter", () => { reporter.log(entry4); writer.end(); - expect(writer.toString()).toMatchInlineSnapshot(` + expect(writerToString(writer)).toMatchInlineSnapshot(` "Well my speed meter don't work, so I'm gonna guess 95. Well maybe I'll fix it, and maybe I won't; it depend on my being alive. Well my '63 Ford is a bull, she's 4000 lbs at least. diff --git a/packages/reporters/tests/writerToString.ts b/packages/reporters/tests/writerToString.ts new file mode 100644 index 000000000..86831b2a5 --- /dev/null +++ b/packages/reporters/tests/writerToString.ts @@ -0,0 +1,14 @@ +import type streams from "memory-streams"; + +/** + * Convert a stream to a string and remove trailing whitespace from lines (does not remove empty lines). + * This ensures the output is stable between snapshots and file editing. + */ +export function writerToString(writer: streams.WritableStream): string { + writer.end(); + return writer + .toString() + .split(/\r?\n/g) + .map((line) => line.trimEnd()) + .join("\n"); +} diff --git a/packages/scheduler/src/workers/targetWorker.ts b/packages/scheduler/src/workers/targetWorker.ts index 3d38f211f..97ebc44fb 100644 --- a/packages/scheduler/src/workers/targetWorker.ts +++ b/packages/scheduler/src/workers/targetWorker.ts @@ -49,7 +49,6 @@ async function setup(options: TargetWorkerDataOptions) { void (async () => { const { cacheProvider, runnerPicker, options } = await setup(workerData); - // eslint-disable-next-line @typescript-eslint/no-unused-vars let hashPromiseResolve = (_hash: string) => {}; // main thread sends hash to worker because it keeps a global memory cache of the hashes diff --git a/packages/scheduler/tests/NpmScriptRunner.test.ts b/packages/scheduler/tests/NpmScriptRunner.test.ts index 6f36b04dc..70e309b2e 100644 --- a/packages/scheduler/tests/NpmScriptRunner.test.ts +++ b/packages/scheduler/tests/NpmScriptRunner.test.ts @@ -1,12 +1,11 @@ -import "child_process"; -import { ChildProcess } from "child_process"; -import { getTargetId, Target } from "@lage-run/target-graph"; import { NpmScriptRunner } from "@lage-run/runners"; -import { waitFor } from "./waitFor"; +import { getTargetId, type Target } from "@lage-run/target-graph"; +import type { ChildProcess } from "child_process"; import os from "os"; import path from "path"; +import { waitFor } from "./waitFor.js"; -let childProcesses: Map = new Map(); +const childProcesses: Map = new Map(); function getChildProcessKey(packageName: string, task: string) { const testName = expect.getState().currentTestName!.replace(/ /g, "_"); @@ -151,7 +150,7 @@ describe("NpmScriptRunner", () => { fakeExceptionSpies[packageName] = jest.fn(); } - let runPromises = fakePackages.map((packageName) => + const runPromises = fakePackages.map((packageName) => runner .run({ target: createTarget(packageName), diff --git a/packages/scheduler/tests/SimpleScheduler.test.ts b/packages/scheduler/tests/SimpleScheduler.test.ts index 33424423b..267862c5d 100644 --- a/packages/scheduler/tests/SimpleScheduler.test.ts +++ b/packages/scheduler/tests/SimpleScheduler.test.ts @@ -1,12 +1,13 @@ -import { Logger } from "@lage-run/logger"; import { TargetHasher } from "@lage-run/hasher"; -import { SimpleScheduler } from "../src/SimpleScheduler"; -import { getStartTargetId, Target, TargetGraph } from "@lage-run/target-graph"; -import { InProcPool, SingleSchedulePool } from "./fixtures/pools"; - +import { Logger } from "@lage-run/logger"; +import { NoOpRunner } from "@lage-run/runners"; +import { getStartTargetId, type Target, type TargetGraph } from "@lage-run/target-graph"; import fs from "fs"; -import path from "path"; import os from "os"; +import path from "path"; +import { SimpleScheduler } from "../src/SimpleScheduler.js"; +import { FailOnPackageRunner } from "./fixtures/FailOnPackageRunner.js"; +import { InProcPool, SingleSchedulePool } from "./fixtures/pools.js"; /** * Purely manually managed target graph. @@ -21,8 +22,8 @@ class TestTargetGraph implements TargetGraph { id: getStartTargetId(), cwd: "", label: "Start", - }, - ] as [string, Target], + } as Target, + ], ]); dependencies: [string, string][] = []; @@ -67,7 +68,7 @@ describe("SimpleScheduler", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "no-target-deps")); const logger = new Logger(); - const runner = new (require("./fixtures/NoOpRunner").NoOpRunner)(); + const runner = new NoOpRunner(); const scheduler = new SimpleScheduler({ logger, @@ -117,7 +118,7 @@ describe("SimpleScheduler", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "early-throw")); const logger = new Logger(); - const runner = new (require("./fixtures/FailOnPackageRunner").FailOnPackageRunner)("d"); + const runner = new FailOnPackageRunner("d"); const scheduler = new SimpleScheduler({ logger, @@ -163,7 +164,7 @@ describe("SimpleScheduler", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "continue-on-error")); const logger = new Logger(); - const runner = new (require("./fixtures/FailOnPackageRunner").FailOnPackageRunner)("d"); + const runner = new FailOnPackageRunner("d"); const scheduler = new SimpleScheduler({ logger, @@ -210,7 +211,7 @@ describe("SimpleScheduler", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "abort")); const logger = new Logger(); - const runner = new (require("./fixtures/FailOnPackageRunner").FailOnPackageRunner)("d"); + const runner = new FailOnPackageRunner("d"); const scheduler = new SimpleScheduler({ logger, diff --git a/packages/scheduler/tests/SimpleScheduler.watchmode.test.ts b/packages/scheduler/tests/SimpleScheduler.watchmode.test.ts index 2ab9286a4..9048295f7 100644 --- a/packages/scheduler/tests/SimpleScheduler.watchmode.test.ts +++ b/packages/scheduler/tests/SimpleScheduler.watchmode.test.ts @@ -1,13 +1,12 @@ import { TargetHasher } from "@lage-run/hasher"; import { Logger } from "@lage-run/logger"; -import { SimpleScheduler } from "../src/SimpleScheduler"; -import { InProcPool } from "./fixtures/pools"; -import { getTargetId, Target, TargetGraphBuilder } from "@lage-run/target-graph"; -import { TargetRunner } from "@lage-run/runners"; - +import type { TargetRunner } from "@lage-run/runners"; +import { TargetGraphBuilder, getTargetId, type Target } from "@lage-run/target-graph"; import fs from "fs"; -import path from "path"; import os from "os"; +import path from "path"; +import { SimpleScheduler } from "../src/SimpleScheduler.js"; +import { InProcPool } from "./fixtures/pools.js"; function createTarget(packageName: string, task: string): Target { const id = getTargetId(packageName, task); diff --git a/packages/scheduler/tests/WrappedTarget.test.ts b/packages/scheduler/tests/WrappedTarget.test.ts index 4eeca965d..126bc9776 100644 --- a/packages/scheduler/tests/WrappedTarget.test.ts +++ b/packages/scheduler/tests/WrappedTarget.test.ts @@ -1,11 +1,12 @@ -import { Target } from "@lage-run/target-graph"; -import { WrappedTarget } from "../src/WrappedTarget"; - -import path from "path"; -import { CacheProvider, TargetHasher } from "@lage-run/cache"; +import { TargetHasher } from "@lage-run/hasher"; import { Logger } from "@lage-run/logger"; -import { TargetRunner } from "@lage-run/scheduler-types"; -import { Pool } from "@lage-run/worker-threads-pool"; +import type { TargetRunner } from "@lage-run/runners"; +import type { Target } from "@lage-run/target-graph"; +import type { Pool } from "@lage-run/worker-threads-pool"; +import fs from "fs"; +import os from "os"; +import path from "path"; +import { WrappedTarget } from "../src/WrappedTarget.js"; function createTarget(packageName: string): Target { return { @@ -22,8 +23,8 @@ function createTarget(packageName: string): Target { class InProcPool implements Pool { constructor(private runner: TargetRunner) {} - exec({ target }: { target: Target; weight: number }, weight, _setup, _teardown, abortSignal?: AbortSignal) { - return this.runner.run({ target, weight, abortSignal }); + exec(data: { target: Target; weight: number }, _weight: number, _setup: any, _teardown: any, abortSignal?: AbortSignal) { + return this.runner.run({ target: data.target, weight: data.weight, abortSignal }); } stats() { return { @@ -38,8 +39,14 @@ class InProcPool implements Pool { class SkippyInProcPool implements Pool { constructor(private runner: TargetRunner) {} - exec({ target }: { target: Target; weight: number }, weight, _setup, _teardown, abortSignal?: AbortSignal): Promise { - this.runner.run({ target, weight, abortSignal }); + async exec( + data: { target: Target; weight: number }, + _weight: number, + _setup: any, + _teardown: any, + abortSignal?: AbortSignal + ): Promise { + await this.runner.run({ target: data.target, weight: data.weight, abortSignal }); return Promise.resolve({ skipped: true, hash: "1234", @@ -57,6 +64,12 @@ class SkippyInProcPool implements Pool { } describe("WrappedTarget", () => { + let root = ""; + + beforeEach(() => { + root = fs.mkdtempSync(path.join(os.tmpdir(), "lage-wrapped-target-")); + }); + it("should be able to run a target to completion", async () => { const logger = new Logger(); @@ -73,10 +86,11 @@ describe("WrappedTarget", () => { abortController: new AbortController(), continueOnError: false, logger, - root: process.cwd(), + root, shouldCache: true, target: createTarget("a"), pool: new InProcPool(runner), + hasher: new TargetHasher({ root, environmentGlob: [] }), }); expect(wrappedTarget.status).toBe("pending"); @@ -106,10 +120,11 @@ describe("WrappedTarget", () => { abortController: new AbortController(), continueOnError: false, logger, - root: process.cwd(), + root, shouldCache: true, target: createTarget(packageName), pool: new InProcPool(runner), + hasher: new TargetHasher({ root, environmentGlob: [] }), }); wrappedTargets.push(wrappedTarget); @@ -146,10 +161,11 @@ describe("WrappedTarget", () => { abortController: new AbortController(), continueOnError, logger, - root: process.cwd(), + root, shouldCache: true, target: createTarget(packageName), pool: new InProcPool(runner), + hasher: new TargetHasher({ root, environmentGlob: [] }), }); wrappedTargets.push(wrappedTarget); @@ -200,10 +216,11 @@ describe("WrappedTarget", () => { abortController, continueOnError, logger, - root: process.cwd(), + root, shouldCache: true, target: createTarget(packageName), pool: new InProcPool(runner), + hasher: new TargetHasher({ root, environmentGlob: [] }), }); wrappedTargets.push(wrappedTarget); @@ -232,10 +249,11 @@ describe("WrappedTarget", () => { abortController: new AbortController(), continueOnError: false, logger, - root: process.cwd(), + root, shouldCache: true, target: { ...createTarget("a"), cache: true }, pool: new SkippyInProcPool(runner), + hasher: new TargetHasher({ root, environmentGlob: [] }), }); expect(wrappedTarget.status).toBe("pending"); diff --git a/packages/scheduler/tests/fixtures/AbortEarlyRunner.js b/packages/scheduler/tests/fixtures/AbortEarlyRunner.js deleted file mode 100644 index 36102289a..000000000 --- a/packages/scheduler/tests/fixtures/AbortEarlyRunner.js +++ /dev/null @@ -1,28 +0,0 @@ -class AbortEarlyRunner { - constructor(packageName) { - this.failPackage = packageName; - } - - async shouldRun() { - return true; - } - - run(target, abortSignal) { - return new Promise((resolve, reject) => { - if (target.packageName === this.failPackage) { - reject(new Error("oops")); - } - - const timeout = setTimeout(() => { - resolve(); - }, 50000); - - abortSignal?.addEventListener("abort", () => { - timeout?.unref(); - reject(new Error("aborted")); - }); - }); - } -} - -module.exports.AbortEarlyRunner = AbortEarlyRunner; diff --git a/packages/scheduler/tests/fixtures/FailOnPackageRunner.js b/packages/scheduler/tests/fixtures/FailOnPackageRunner.js index ad58a2f49..9df04d82d 100644 --- a/packages/scheduler/tests/fixtures/FailOnPackageRunner.js +++ b/packages/scheduler/tests/fixtures/FailOnPackageRunner.js @@ -1,5 +1,8 @@ +/** @import { TargetRunner, TargetRunnerOptions } from "@lage-run/runners" */ + +/** @implements {TargetRunner} */ class FailOnPackageRunner { - constructor(packageName) { + constructor(/** @type {string} */ packageName) { this.failPackage = packageName; } @@ -7,7 +10,8 @@ class FailOnPackageRunner { return true; } - run(target, abortSignal) { + /** @returns {Promise} */ + run(/** @type {TargetRunnerOptions} */ { target, abortSignal }) { return new Promise((resolve, reject) => { if (target.packageName === this.failPackage) { reject(new Error("oops")); diff --git a/packages/scheduler/tests/fixtures/NoOpRunner.js b/packages/scheduler/tests/fixtures/NoOpRunner.js deleted file mode 100644 index 9e6df7522..000000000 --- a/packages/scheduler/tests/fixtures/NoOpRunner.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports.NoOpRunner = class NoOpRunner { - async run() { - // pass - } -}; diff --git a/packages/scheduler/tests/fixtures/fakeNpm.js b/packages/scheduler/tests/fixtures/fakeNpm.js index 3bdbbe7a6..d226bcfb9 100644 --- a/packages/scheduler/tests/fixtures/fakeNpm.js +++ b/packages/scheduler/tests/fixtures/fakeNpm.js @@ -1,10 +1,10 @@ -let sleep = parseInt( +const sleep = parseInt( process.argv .find((arg) => arg.includes("--sleep=")) - .trim() + ?.trim() .replace("--sleep=", "") ?? "100" ); -let fail = !!process.argv.find((arg) => arg.includes("--fail")); +const fail = process.argv.some((arg) => arg.includes("--fail")); if (fail) { throw new Error("Fake npm failed"); @@ -13,3 +13,5 @@ if (fail) { setTimeout(() => { /* do NOTHING */ }, sleep); + +module.exports = {}; // remove from global scope diff --git a/packages/scheduler/tests/fixtures/pools.ts b/packages/scheduler/tests/fixtures/pools.ts index b12de9909..61eb48136 100644 --- a/packages/scheduler/tests/fixtures/pools.ts +++ b/packages/scheduler/tests/fixtures/pools.ts @@ -1,7 +1,6 @@ -import { TargetRunner } from "@lage-run/runners"; -import { Target } from "@lage-run/target-graph"; -import { Pool } from "@lage-run/worker-threads-pool"; -import { PoolStats } from "@lage-run/worker-threads-pool"; +import type { TargetRunner } from "@lage-run/runners"; +import type { Target } from "@lage-run/target-graph"; +import type { Pool, PoolStats } from "@lage-run/worker-threads-pool"; export class InProcPool implements Pool { constructor(private runner: TargetRunner) {} diff --git a/packages/scheduler/tests/fixtures/worker.js b/packages/scheduler/tests/fixtures/worker.js deleted file mode 100644 index 56d50ca1f..000000000 --- a/packages/scheduler/tests/fixtures/worker.js +++ /dev/null @@ -1,6 +0,0 @@ -// Fixture uses the `workerpool` -const { threadId } = require("worker_threads"); - -module.exports = function run({ target }) { - console.log(`Thread: ${threadId}, Target: ${target.id}`); -}; diff --git a/packages/scheduler/tests/waitFor.ts b/packages/scheduler/tests/waitFor.ts index df31b2716..e12c9fd0f 100644 --- a/packages/scheduler/tests/waitFor.ts +++ b/packages/scheduler/tests/waitFor.ts @@ -1,7 +1,7 @@ -export function waitFor(condition: () => boolean, maxWait: number = 5000): Promise { +export function waitFor(condition: () => boolean, maxWait = 5000): Promise { let retries = 0; - let timeout = 100; - let maxRetries = maxWait / timeout; + const timeout = 100; + const maxRetries = maxWait / timeout; return new Promise((resolve, reject) => { const loop = (timer: NodeJS.Timeout) => { @@ -18,6 +18,6 @@ export function waitFor(condition: () => boolean, maxWait: number = 5000): Promi } }; - const timer: NodeJS.Timeout = setTimeout(() => loop(timer), timeout); + const initialTimer: NodeJS.Timeout = setTimeout(() => loop(initialTimer), timeout); }); } diff --git a/packages/target-graph/tests/TargetFactory.test.ts b/packages/target-graph/tests/TargetFactory.test.ts index 95588f9aa..8049d0220 100644 --- a/packages/target-graph/tests/TargetFactory.test.ts +++ b/packages/target-graph/tests/TargetFactory.test.ts @@ -1,5 +1,5 @@ import path from "path"; -import { TargetFactory } from "../src/TargetFactory"; +import { TargetFactory } from "../src/TargetFactory.js"; describe("TargetFactory", () => { it("should give a type of 'npmScript' if one of the packages contain that script", () => { diff --git a/packages/target-graph/tests/TargetGraphBuilder.test.ts b/packages/target-graph/tests/TargetGraphBuilder.test.ts index 6eb22bb4c..c2b18c1e5 100644 --- a/packages/target-graph/tests/TargetGraphBuilder.test.ts +++ b/packages/target-graph/tests/TargetGraphBuilder.test.ts @@ -1,5 +1,5 @@ -import { TargetGraphBuilder } from "../src/TargetGraphBuilder"; -import { Target } from "../src/types/Target"; +import { TargetGraphBuilder } from "../src/TargetGraphBuilder.js"; +import type { Target } from "../src/types/Target.js"; describe("Target Graph Builder", () => { it("should build a full graph", () => { diff --git a/packages/target-graph/tests/WorkspaceTargetGraphBuilder.test.ts b/packages/target-graph/tests/WorkspaceTargetGraphBuilder.test.ts index a9806dc7d..adad9ed7b 100644 --- a/packages/target-graph/tests/WorkspaceTargetGraphBuilder.test.ts +++ b/packages/target-graph/tests/WorkspaceTargetGraphBuilder.test.ts @@ -38,8 +38,8 @@ describe("workspace target graph builder", () => { b: [], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); - builder.addTargetConfig("build", { + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); + await builder.addTargetConfig("build", { dependsOn: ["^build"], }); @@ -80,9 +80,9 @@ describe("workspace target graph builder", () => { b: [], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); - builder.addTargetConfig("test"); - builder.addTargetConfig("lint"); + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); + await builder.addTargetConfig("test"); + await builder.addTargetConfig("lint"); const targetGraph = await builder.build(["test", "lint"]); @@ -119,13 +119,13 @@ describe("workspace target graph builder", () => { c: ["b"], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); - builder.addTargetConfig("build", { + await builder.addTargetConfig("build", { dependsOn: ["^build"], }); - builder.addTargetConfig("a#build", { + await builder.addTargetConfig("a#build", { dependsOn: [], }); @@ -161,13 +161,13 @@ describe("workspace target graph builder", () => { c: ["b"], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); - builder.addTargetConfig("build", { + await builder.addTargetConfig("build", { dependsOn: ["^build"], }); - builder.addTargetConfig("a#build", { + await builder.addTargetConfig("a#build", { dependsOn: [], }); @@ -195,13 +195,13 @@ describe("workspace target graph builder", () => { c: [], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); - builder.addTargetConfig("bundle", { + await builder.addTargetConfig("bundle", { dependsOn: ["^^transpile"], }); - builder.addTargetConfig("transpile"); + await builder.addTargetConfig("transpile"); const targetGraph = await builder.build(["bundle"], ["a"]); expect(getGraphFromTargets(targetGraph)).toMatchInlineSnapshot(` @@ -240,14 +240,14 @@ describe("workspace target graph builder", () => { common: [], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); - builder.addTargetConfig("build", { + await builder.addTargetConfig("build", { dependsOn: ["common#copy", "^build"], }); - builder.addTargetConfig("common#copy"); - builder.addTargetConfig("common#build"); + await builder.addTargetConfig("common#copy"); + await builder.addTargetConfig("common#build"); const targetGraph = await builder.build(["build"]); expect(getGraphFromTargets(targetGraph)).toMatchInlineSnapshot(` @@ -296,12 +296,12 @@ describe("workspace target graph builder", () => { b: [], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); - builder.addTargetConfig("build", { + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); + await builder.addTargetConfig("build", { dependsOn: ["^build", "#global:task"], }); - builder.addTargetConfig("#global:task", { + await builder.addTargetConfig("#global:task", { dependsOn: [], }); @@ -345,12 +345,12 @@ describe("workspace target graph builder", () => { b: [], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); - builder.addTargetConfig("build", { + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); + await builder.addTargetConfig("build", { dependsOn: ["^build", "#global:task"], }); - builder.addTargetConfig("#global:task", { + await builder.addTargetConfig("#global:task", { dependsOn: [], }); @@ -374,12 +374,12 @@ describe("workspace target graph builder", () => { b: [], }); - const builder = new WorkspaceTargetGraphBuilder(root, packageInfos); - builder.addTargetConfig("build", { + const builder = new WorkspaceTargetGraphBuilder(root, packageInfos, false); + await builder.addTargetConfig("build", { dependsOn: ["^build"], }); - builder.addTargetConfig("#global:task", { + await builder.addTargetConfig("#global:task", { dependsOn: [], }); diff --git a/packages/target-graph/tests/detectCycles.test.ts b/packages/target-graph/tests/detectCycles.test.ts index bb7062397..6064ecddb 100644 --- a/packages/target-graph/tests/detectCycles.test.ts +++ b/packages/target-graph/tests/detectCycles.test.ts @@ -1,6 +1,6 @@ -import type { Target } from "../src/types/Target"; -import { detectCycles } from "../src/detectCycles"; -import { getPackageAndTask } from "../src/targetId"; +import { detectCycles } from "../src/detectCycles.js"; +import { getPackageAndTask } from "../src/targetId.js"; +import type { Target } from "../src/types/Target.js"; function createTarget({ packageName, diff --git a/packages/target-graph/tests/prioritize.test.ts b/packages/target-graph/tests/prioritize.test.ts index d84809d08..0d106b213 100644 --- a/packages/target-graph/tests/prioritize.test.ts +++ b/packages/target-graph/tests/prioritize.test.ts @@ -1,6 +1,6 @@ -import { getPackageAndTask } from "../src/targetId"; -import { Target } from "../src/types/Target"; -import { prioritize } from "../src/prioritize"; +import { prioritize } from "../src/prioritize.js"; +import { getPackageAndTask } from "../src/targetId.js"; +import type { Target } from "../src/types/Target.js"; function createTarget({ packageName, diff --git a/packages/target-graph/tests/targetId.test.ts b/packages/target-graph/tests/targetId.test.ts index 9e43eb85a..d0ce2a073 100644 --- a/packages/target-graph/tests/targetId.test.ts +++ b/packages/target-graph/tests/targetId.test.ts @@ -1,4 +1,4 @@ -import { getPackageAndTask, getTargetId } from "../src/targetId"; +import { getPackageAndTask, getTargetId } from "../src/targetId.js"; describe("getTargetId", () => { it("should return a string representing an id of a target given task and package", () => { diff --git a/packages/target-graph/tests/transitiveReduction.test.ts b/packages/target-graph/tests/transitiveReduction.test.ts index 27e9365c8..05a9c6ecc 100644 --- a/packages/target-graph/tests/transitiveReduction.test.ts +++ b/packages/target-graph/tests/transitiveReduction.test.ts @@ -1,6 +1,6 @@ -import { TargetGraphBuilder } from "../src/TargetGraphBuilder"; -import { Target } from "../src/types/Target"; -import { transitiveReduction } from "../src/transitiveReduction"; +import { TargetGraphBuilder } from "../src/TargetGraphBuilder.js"; +import type { Target } from "../src/types/Target.js"; +import { transitiveReduction } from "../src/transitiveReduction.js"; import { diff } from "jest-diff"; describe("transitiveReduction", () => { diff --git a/packages/worker-threads-pool/tests/AggregatedPool.test.ts b/packages/worker-threads-pool/tests/AggregatedPool.test.ts index 631e10b7e..e83edfaa8 100644 --- a/packages/worker-threads-pool/tests/AggregatedPool.test.ts +++ b/packages/worker-threads-pool/tests/AggregatedPool.test.ts @@ -1,6 +1,6 @@ import { Logger } from "@lage-run/logger"; import path from "path"; -import { AggregatedPool } from "../src/AggregatedPool"; +import { AggregatedPool } from "../src/AggregatedPool.js"; describe("AggregatedPool", () => { it("should create multiple workerpools for defined groups", async () => { diff --git a/packages/worker-threads-pool/tests/WorkerPool.test.ts b/packages/worker-threads-pool/tests/WorkerPool.test.ts index 5bcef4f79..f37844703 100644 --- a/packages/worker-threads-pool/tests/WorkerPool.test.ts +++ b/packages/worker-threads-pool/tests/WorkerPool.test.ts @@ -1,6 +1,6 @@ -import { WorkerPool } from "../src/WorkerPool"; import path from "path"; import { Readable } from "stream"; +import { WorkerPool } from "../src/WorkerPool.js"; describe("WorkerPool", () => { it("should be able to process multiple tasks in parallel", async () => { @@ -13,7 +13,7 @@ describe("WorkerPool", () => { const numTasks = 100; - const setup = (data) => { + const setup = (data: any) => { running.push(data); }; @@ -40,7 +40,7 @@ describe("WorkerPool", () => { const numTasks = 100; - const setup = (data) => { + const setup = (data: any) => { running.push(data); }; @@ -53,7 +53,7 @@ describe("WorkerPool", () => { try { results = await Promise.all(range.map((i) => pool.exec({ id: i }, 1, setup).catch(() => {}))); } finally { - pool.close(); + await pool.close(); } expect(pool.workers.length).toBe(5); diff --git a/packages/worker-threads-pool/tests/fixtures/my-5mb-worker.js b/packages/worker-threads-pool/tests/fixtures/my-5mb-worker.js index a7435db9e..f2d606559 100644 --- a/packages/worker-threads-pool/tests/fixtures/my-5mb-worker.js +++ b/packages/worker-threads-pool/tests/fixtures/my-5mb-worker.js @@ -1,6 +1,7 @@ const { registerWorker } = require("./registerWorker.fixture.js"); const fiveMb = (5 * 1024 * 1024) /* bytes */ / 8; /* bytes per item in empty array */ +/** @type {any[]} */ let buffer = []; function fn() { diff --git a/packages/worker-threads-pool/tests/fixtures/registerWorker.fixture.js b/packages/worker-threads-pool/tests/fixtures/registerWorker.fixture.js index b12e8aea6..aa3f71bdc 100644 --- a/packages/worker-threads-pool/tests/fixtures/registerWorker.fixture.js +++ b/packages/worker-threads-pool/tests/fixtures/registerWorker.fixture.js @@ -3,8 +3,9 @@ const { parentPort } = require("worker_threads"); const START_WORKER_STREAM_MARKER = "## WORKER:START:"; const END_WORKER_STREAM_MARKER = "## WORKER:END:"; -module.exports.registerWorker = function (fn) { +module.exports.registerWorker = function (/** @type {Function} */ fn) { parentPort?.on("message", async (message) => { + /** @type {AbortController | undefined} */ let abortController; switch (message.type) { @@ -21,7 +22,8 @@ module.exports.registerWorker = function (fn) { } }); - async function start(task, abortSignal, id) { + // TODO: this should use proper lage worker types once available + async function start(/** @type {*} */ task, /** @type {AbortSignal} */ abortSignal, /** @type {string} */ id) { try { process.stdout.write(`${START_WORKER_STREAM_MARKER}${id}\n`); process.stderr.write(`${START_WORKER_STREAM_MARKER}${id}\n`); diff --git a/packages/worker-threads-pool/tests/pickTaskFromQueue.test.ts b/packages/worker-threads-pool/tests/pickTaskFromQueue.test.ts index 760fd3dcd..82daa34e2 100644 --- a/packages/worker-threads-pool/tests/pickTaskFromQueue.test.ts +++ b/packages/worker-threads-pool/tests/pickTaskFromQueue.test.ts @@ -1,5 +1,5 @@ -import { pickTaskFromQueue } from "../src/pickTaskFromQueue"; -import type { QueueItem } from "../src/types/WorkerQueue"; +import { pickTaskFromQueue } from "../src/pickTaskFromQueue.js"; +import type { QueueItem } from "../src/types/WorkerQueue.js"; function createMockQueueItem(partialProps: Partial): QueueItem { return { task: {}, weight: 1, resolve: jest.fn(), reject: jest.fn(), ...partialProps };