From afb844e5d6c678032762f5332e6a74dc848542e1 Mon Sep 17 00:00:00 2001 From: Jamie Mason Date: Sat, 14 May 2022 12:33:28 +0100 Subject: [PATCH] test(core): add test for scenario to reproduce #66 --- src/bin-fix-mismatches/fix-mismatches.spec.ts | 54 ++++++++++++++----- .../list-mismatches.spec.ts | 36 +++++++++---- src/bin-list/list.spec.ts | 25 +++++++-- test/scenarios/create-scenario.ts | 10 +++- test/scenarios/index.ts | 26 +++++++-- 5 files changed, 121 insertions(+), 30 deletions(-) diff --git a/src/bin-fix-mismatches/fix-mismatches.spec.ts b/src/bin-fix-mismatches/fix-mismatches.spec.ts index 36460333..ef88fe07 100644 --- a/src/bin-fix-mismatches/fix-mismatches.spec.ts +++ b/src/bin-fix-mismatches/fix-mismatches.spec.ts @@ -1,5 +1,6 @@ import 'expect-more-jest'; import { scenarios } from '../../test/scenarios'; +import type { TestScenario } from '../../test/scenarios/create-scenario'; import { getInput } from '../lib/get-input'; import { fixMismatches } from './fix-mismatches'; @@ -10,18 +11,47 @@ describe('fixMismatches', () => { describe('when dependencies are installed with different versions', () => { describe('when the dependency is a package maintained in this workspace', () => { - it('uses the workspace version', () => { - const scenario = scenarios.dependentDoesNotMatchWorkspaceVersion(); - fixMismatches(getInput(scenario.disk, scenario.config), scenario.disk); - expect(scenario.disk.writeFileSync.mock.calls).toEqual([ - scenario.files['packages/a/package.json'].diskWriteWhenChanged, - scenario.files['packages/b/package.json'].diskWriteWhenChanged, - ]); - expect(scenario.log.mock.calls).toEqual([ - scenario.files['packages/a/package.json'].logEntryWhenChanged, - scenario.files['packages/b/package.json'].logEntryWhenChanged, - scenario.files['packages/c/package.json'].logEntryWhenUnchanged, - ]); + describe('when using a typical workspace', () => { + it('warns about the workspace version', () => { + const scenario = scenarios.dependentDoesNotMatchWorkspaceVersion(); + fixMismatches( + getInput(scenario.disk, scenario.config), + scenario.disk, + ); + expect(scenario.disk.writeFileSync.mock.calls).toEqual([ + scenario.files['packages/a/package.json'].diskWriteWhenChanged, + scenario.files['packages/b/package.json'].diskWriteWhenChanged, + ]); + expect(scenario.log.mock.calls).toEqual([ + scenario.files['packages/a/package.json'].logEntryWhenChanged, + scenario.files['packages/b/package.json'].logEntryWhenChanged, + scenario.files['packages/c/package.json'].logEntryWhenUnchanged, + ]); + }); + }); + describe('when using nested workspaces', () => { + it('warns about the workspace version', () => { + const scenario = + scenarios.dependentDoesNotMatchNestedWorkspaceVersion(); + fixMismatches( + getInput(scenario.disk, scenario.config), + scenario.disk, + ); + expect(scenario.disk.writeFileSync.mock.calls).toEqual([ + scenario.files['workspaces/a/packages/a/package.json'] + .diskWriteWhenChanged, + scenario.files['workspaces/b/packages/b/package.json'] + .diskWriteWhenChanged, + ]); + expect(scenario.log.mock.calls).toEqual([ + scenario.files['workspaces/a/packages/a/package.json'] + .logEntryWhenChanged, + scenario.files['workspaces/b/packages/b/package.json'] + .logEntryWhenChanged, + scenario.files['workspaces/b/packages/c/package.json'] + .logEntryWhenUnchanged, + ]); + }); }); }); diff --git a/src/bin-list-mismatches/list-mismatches.spec.ts b/src/bin-list-mismatches/list-mismatches.spec.ts index a0a030aa..b1247b19 100644 --- a/src/bin-list-mismatches/list-mismatches.spec.ts +++ b/src/bin-list-mismatches/list-mismatches.spec.ts @@ -1,5 +1,6 @@ import 'expect-more-jest'; import { scenarios } from '../../test/scenarios'; +import type { TestScenario } from '../../test/scenarios/create-scenario'; import { getInput } from '../lib/get-input'; import { listMismatches } from './list-mismatches'; @@ -10,15 +11,32 @@ describe('listMismatches', () => { describe('when dependencies are installed with different versions', () => { describe('when the dependency is a package maintained in this workspace', () => { - it('warns ab the workspace version', () => { - const scenario = scenarios.dependentDoesNotMatchWorkspaceVersion(); - listMismatches(getInput(scenario.disk, scenario.config), scenario.disk); - expect(scenario.log.mock.calls).toEqual([ - ['- c 0.0.1'], - [' 0.1.0 in dependencies of a'], - [' 0.2.0 in devDependencies of b'], - ]); - expect(scenario.disk.process.exit).toHaveBeenCalledWith(1); + const variants: [string, () => TestScenario][] = [ + [ + 'when using a typical workspace', + scenarios.dependentDoesNotMatchWorkspaceVersion, + ], + [ + 'when using nested workspaces', + scenarios.dependentDoesNotMatchNestedWorkspaceVersion, + ], + ]; + variants.forEach(([context, getScenario]) => { + describe(context, () => { + it('warns about the workspace version', () => { + const scenario = getScenario(); + listMismatches( + getInput(scenario.disk, scenario.config), + scenario.disk, + ); + expect(scenario.log.mock.calls).toEqual([ + ['- c 0.0.1'], + [' 0.1.0 in dependencies of a'], + [' 0.2.0 in devDependencies of b'], + ]); + expect(scenario.disk.process.exit).toHaveBeenCalledWith(1); + }); + }); }); }); diff --git a/src/bin-list/list.spec.ts b/src/bin-list/list.spec.ts index 12505dab..55010e37 100644 --- a/src/bin-list/list.spec.ts +++ b/src/bin-list/list.spec.ts @@ -1,5 +1,6 @@ import 'expect-more-jest'; import { scenarios } from '../../test/scenarios'; +import type { TestScenario } from '../../test/scenarios/create-scenario'; import { getInput } from '../lib/get-input'; import { list } from './list'; @@ -10,11 +11,25 @@ describe('list', () => { describe('when dependencies are installed with different versions', () => { describe('when the dependency is a package maintained in this workspace', () => { - it('warns ab the workspace version', () => { - const scenario = scenarios.dependentDoesNotMatchWorkspaceVersion(); - list(getInput(scenario.disk, scenario.config), scenario.disk); - expect(scenario.log.mock.calls).toEqual([['✕ c 0.1.0, 0.2.0']]); - expect(scenario.disk.process.exit).toHaveBeenCalledWith(1); + const variants: [string, () => TestScenario][] = [ + [ + 'when using a typical workspace', + scenarios.dependentDoesNotMatchWorkspaceVersion, + ], + [ + 'when using nested workspaces', + scenarios.dependentDoesNotMatchNestedWorkspaceVersion, + ], + ]; + variants.forEach(([context, getScenario]) => { + describe(context, () => { + it('warns about the workspace version', () => { + const scenario = getScenario(); + list(getInput(scenario.disk, scenario.config), scenario.disk); + expect(scenario.log.mock.calls).toEqual([['✕ c 0.1.0, 0.2.0']]); + expect(scenario.disk.process.exit).toHaveBeenCalledWith(1); + }); + }); }); }); diff --git a/test/scenarios/create-scenario.ts b/test/scenarios/create-scenario.ts index a2b5d363..ae8ed0e2 100644 --- a/test/scenarios/create-scenario.ts +++ b/test/scenarios/create-scenario.ts @@ -2,6 +2,7 @@ import minimatch from 'minimatch'; import path from 'path'; import type { SyncpackConfig } from '../../src/constants'; import type { SourceWrapper } from '../../src/lib/get-input/get-wrappers'; +import type { MockDisk } from '../mock-disk'; import { mockDisk } from '../mock-disk'; interface MockedFile { @@ -14,6 +15,13 @@ interface MockedFile { relativePath: string; } +export interface TestScenario { + config: Partial; + disk: MockDisk; + log: jest.SpyInstance; + files: Record; +} + export function createScenario( fileMocks: { path: string; @@ -21,7 +29,7 @@ export function createScenario( after: SourceWrapper; }[], config: Partial, -) { +): TestScenario { const disk = mockDisk(); const log = jest.spyOn(console, 'log').mockImplementation(() => undefined); // resolve all paths diff --git a/test/scenarios/index.ts b/test/scenarios/index.ts index 6a5870a6..b4fbd95d 100644 --- a/test/scenarios/index.ts +++ b/test/scenarios/index.ts @@ -101,8 +101,16 @@ export const scenarios = { ); }, /** - * Variation of the previous scenario in a nested workspace. - * + * Variation of `dependentDoesNotMatchWorkspaceVersion` in a nested workspace. + * + * C is developed in this monorepo, its version is `0.0.1` + * C's version is the single source of truth and should never be changed + * A and B depend on C incorrectly and should be fixed + * A, B, and C are in nested workspaces + * + * @see https://github.com/goldstack/goldstack/pull/170/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R19 + * @see https://github.com/JamieMason/syncpack/pull/74 + * @see https://github.com/JamieMason/syncpack/issues/66 */ dependentDoesNotMatchNestedWorkspaceVersion() { return createScenario( @@ -129,7 +137,19 @@ export const scenarios = { }), }, ], - {}, + { + dev: true, + overrides: false, + peer: false, + prod: true, + resolutions: false, + workspace: true, + source: [ + 'package.json', + 'workspaces/*/package.json', + 'workspaces/*/packages/*/package.json', + ], + }, ); }, /**