From d8dcac740c102bd0aeccf8ea78e7dc34ad070131 Mon Sep 17 00:00:00 2001 From: Chris Manson Date: Fri, 5 Jan 2024 14:05:48 +0000 Subject: [PATCH 1/7] remove yarn from package.json --- package.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c5fff59..dc2f155 100644 --- a/package.json +++ b/package.json @@ -31,13 +31,13 @@ "dist/" ], "scripts": { - "build": "yarn tsup cli.ts index.ts list.ts output.ts --tsconfig tsconfig.esm.json --dts --format esm,cjs", + "build": "pnpm tsup cli.ts index.ts list.ts output.ts --tsconfig tsconfig.esm.json --dts --format esm,cjs", "docs": "typedoc --tsconfig tsconfig.esm.json index.ts --out typedoc/", - "docs:dev": "concurrently \"yarn docs:watch\" \"yarn docs:serve\"", + "docs:dev": "concurrently \"pnpm docs:watch\" \"pnpm docs:serve\"", "docs:serve": "browser-sync start --server \"typedoc/\" --files \"**/*.html\"", - "docs:watch": "yarn docs -- --watch", + "docs:watch": "pnpm docs -- --watch", "lint": "eslint '*.ts'", - "prepare": "yarn build", + "prepare": "pnpm build", "start": "tsc --watch", "test": "concurrently --no-color \"npm:test:*\" --names \"test:\"", "test:cjs": "qunit tests/test.cjs", @@ -79,8 +79,7 @@ "typescript": "^5.1.6" }, "volta": { - "node": "18.17.0", - "yarn": "1.22.18" + "node": "18.17.0" }, "publishConfig": { "registry": "https://registry.npmjs.org" From 2c3819b201f77cf96f018190e395339b870526b4 Mon Sep 17 00:00:00 2001 From: Chris Manson Date: Fri, 5 Jan 2024 14:05:56 +0000 Subject: [PATCH 2/7] fix TS errors --- list.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/list.ts b/list.ts index 3422f31..2383004 100644 --- a/list.ts +++ b/list.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ import { Scenario } from './index.js'; import glob from 'glob'; import { resolve } from 'path'; @@ -15,8 +16,11 @@ export interface ListParams { export async function list(params: ListParams): Promise { if (params.require) { for (let r of params.require) { + // @ts-ignore this doesn't actually fail since we're checking before using it if(import.meta.url) { + // @ts-ignore const require = createRequire(import.meta.url); + // @ts-ignore this will only happen if we have import.meta.url await import(require.resolve(r, { paths: [process.cwd()]})); } else { require(require.resolve(r, { paths: [process.cwd()]})); @@ -25,7 +29,9 @@ export async function list(params: ListParams): Promise { } for (let pattern of params.files) { for (let file of globSync(pattern)) { + // @ts-ignore if(import.meta.url) { + // @ts-ignore await import(resolve(file)); } else { require(resolve(file)); From d05671305d4c4cae5bedf3720a56fea9fad05811 Mon Sep 17 00:00:00 2001 From: Chris Manson Date: Fri, 5 Jan 2024 14:33:59 +0000 Subject: [PATCH 3/7] call skip multiple times with same name is a no-op --- index.ts | 19 ++++++++++++------- tests/test.cjs | 12 +++++++++++- tests/test.mjs | 10 +++++++++- tests/test.ts | 10 +++++++++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/index.ts b/index.ts index 0068dad..18e1c19 100644 --- a/index.ts +++ b/index.ts @@ -32,6 +32,8 @@ export type CallbackMutateProject = (project: Project) => void | Promise; */ export type CallbackDefineTests = (scenario: Scenario) => void; +type SkippableVariant = { status: 'active' | 'skipped', project: CallbackMutateProject[]}; + export { Project }; type State = @@ -42,7 +44,7 @@ type State = | { type: 'derived'; parent: Scenarios; - variants: Record; + variants: Record; }; /** @@ -167,7 +169,7 @@ export class Scenarios { type: 'derived', parent: this, variants: Object.fromEntries( - Object.entries(variants).map(([variantName, mutator]) => [variantName, [mutator]]) + Object.entries(variants).map(([variantName, mutator]) => [variantName, { status: 'active', project: [mutator]}]) ), }); } @@ -189,7 +191,7 @@ export class Scenarios { ); } let variants = Object.assign({}, this.state.variants); - delete variants[variantName]; + variants[variantName].status = 'skipped'; return new Scenarios({ type: 'derived', parent: this.state.parent, @@ -255,7 +257,7 @@ export class Scenarios { type: 'derived', parent: this, variants: { - [name]: [callbackMutateProject], + [name]: { status: 'active', project: [callbackMutateProject]}, }, }); } else { @@ -265,7 +267,7 @@ export class Scenarios { variants: Object.fromEntries( Object.entries(this.state.variants).map(([variantName, mutators]) => [ `${variantName}-${name}`, - [...mutators, callbackMutateProject], + { status: 'active', project: [...mutators.project, callbackMutateProject]}, ]) ), }); @@ -284,12 +286,15 @@ export class Scenarios { } else { let state = this.state; this.state.parent.iterate((parent) => { - for (let [variantName, mutators] of Object.entries(state.variants)) { + for (let [variantName, variant] of Object.entries(state.variants)) { + if(variant.status === 'skipped') { + continue; + } let combinedName = parent.name ? `${parent.name}-${variantName}` : variantName; fn({ name: combinedName, callbackCreateProject: parent.callbackCreateProject, - mutators: [...parent.mutators, ...mutators], + mutators: [...parent.mutators, ...variant.project], }); } }); diff --git a/tests/test.cjs b/tests/test.cjs index b3e5c69..b255f8e 100644 --- a/tests/test.cjs +++ b/tests/test.cjs @@ -17,11 +17,21 @@ function hello2(project) { resolveName: 'hello', }); } + +function skipMe(project) { + // do nothing +} + const scenarios = Scenarios.fromDir('./tests/fixtures/app').expand({ hello1, hello2, + skipMe, }); -scenarios.forEachScenario((scenario) => { + +scenarios + .skip('skipMe') + .skip('skipMe') // show that skipping twice doesn't crash + .forEachScenario((scenario) => { qunit.module(scenario.name, (hooks) => { hooks.before(async function () { this.app = await scenario.prepare(); diff --git a/tests/test.mjs b/tests/test.mjs index c88c28b..6a99f3b 100644 --- a/tests/test.mjs +++ b/tests/test.mjs @@ -16,13 +16,21 @@ function hello2(project) { }); } +function skipMe(project) { + // do nothing +} + const scenarios = Scenarios.fromDir('./tests/fixtures/app').expand({ hello1, hello2, + skipMe, }); -scenarios.forEachScenario((scenario) => { +scenarios + .skip('skipMe') + .skip('skipMe') // show that skipping twice doesn't crash + .forEachScenario((scenario) => { Qunit.module(scenario.name, (hooks) => { hooks.before(async function () { this.app = await scenario.prepare(); diff --git a/tests/test.ts b/tests/test.ts index 38b18cd..858077f 100644 --- a/tests/test.ts +++ b/tests/test.ts @@ -18,14 +18,22 @@ function hello2(project: Project) { }); } +function skipMe(/* project: Project */) { + // do nothing +} + const scenarios = Scenarios.fromDir('./tests/fixtures/app').expand({ hello1, hello2, + skipMe, }); type TestContext = { app: PreparedApp }; -scenarios.forEachScenario((scenario) => { +scenarios + .skip('skipMe') + .skip('skipMe') // show that skipping twice doesn't crash + .forEachScenario((scenario) => { Qunit.module(scenario.name, (hooks) => { hooks.before(async function (this: TestContext) { this.app = await scenario.prepare(); From a63649c75e2dda36470a473937c3d68a7d923f1f Mon Sep 17 00:00:00 2001 From: Chris Manson Date: Fri, 5 Jan 2024 16:24:48 +0000 Subject: [PATCH 4/7] keep variant status when you call .map() --- index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.ts b/index.ts index 18e1c19..8762ab3 100644 --- a/index.ts +++ b/index.ts @@ -265,9 +265,9 @@ export class Scenarios { type: 'derived', parent: this.state.parent, variants: Object.fromEntries( - Object.entries(this.state.variants).map(([variantName, mutators]) => [ + Object.entries(this.state.variants).map(([variantName, variant]) => [ `${variantName}-${name}`, - { status: 'active', project: [...mutators.project, callbackMutateProject]}, + { status: variant.status, project: [...variant.project, callbackMutateProject]}, ]) ), }); From 230d2512d44760f7615e146f6f16457a5c6bc439 Mon Sep 17 00:00:00 2001 From: Chris Manson Date: Sat, 6 Jan 2024 23:48:27 +0000 Subject: [PATCH 5/7] stop calling yarn test --- tests/test.cjs | 4 ++-- tests/test.mjs | 4 ++-- tests/test.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test.cjs b/tests/test.cjs index b255f8e..ea02299 100644 --- a/tests/test.cjs +++ b/tests/test.cjs @@ -36,8 +36,8 @@ scenarios hooks.before(async function () { this.app = await scenario.prepare(); }); - qunit.test('yarn test', async function (assert) { - const result = await this.app.execute('yarn --silent test'); + qunit.test('pnpm test', async function (assert) { + const result = await this.app.execute('pnpm --silent test'); assert.equal(result.stdout, `TAP version 13 ok 1 project > createHello 1..1 diff --git a/tests/test.mjs b/tests/test.mjs index 6a99f3b..69e22a8 100644 --- a/tests/test.mjs +++ b/tests/test.mjs @@ -37,9 +37,9 @@ scenarios }); Qunit.test( - 'yarn test', + 'pnpm test', async function (assert) { - const result = await this.app.execute('yarn --silent test'); + const result = await this.app.execute('pnpm --silent test'); assert.equal( result.stdout, `TAP version 13 diff --git a/tests/test.ts b/tests/test.ts index 858077f..89198e3 100644 --- a/tests/test.ts +++ b/tests/test.ts @@ -40,9 +40,9 @@ scenarios }); Qunit.test( - 'yarn test', + 'pnpm test', async function (this: TestContext, assert) { - const result = await this.app.execute('yarn --silent test'); + const result = await this.app.execute('pnpm --silent test'); assert.equal( result.stdout, `TAP version 13 From 44f0dd98a936f3358d736e7f7605b8aeb4f3e24b Mon Sep 17 00:00:00 2001 From: Chris Manson Date: Sat, 6 Jan 2024 23:48:59 +0000 Subject: [PATCH 6/7] delete bin location test this kind of test is not relevant in a pnpm world --- tests/test.cjs | 7 ------- tests/test.mjs | 10 ---------- tests/test.ts | 11 ----------- 3 files changed, 28 deletions(-) diff --git a/tests/test.cjs b/tests/test.cjs index ea02299..61ed724 100644 --- a/tests/test.cjs +++ b/tests/test.cjs @@ -47,13 +47,6 @@ ok 1 project > createHello # fail 0 `); }); - qunit.test('yarn bin inside app', async function (assert) { - let result = await this.app.execute('yarn --silent bin'); - const yarnBin = result.stdout.trimRight(); - assert.ok(yarnBin.startsWith(this.app.dir)); - result = await this.app.execute('yarn --silent exec which qunit'); - assert.ok(result.stdout.startsWith(yarnBin)); - }); qunit.test('check scenario', async function (assert) { let result = await this.app.execute(`node -p 'require("./index").polyfilled'`); assert.equal(result.stdout.trim(), ('hello1' === scenario.name).toString()); diff --git a/tests/test.mjs b/tests/test.mjs index 69e22a8..6b99b20 100644 --- a/tests/test.mjs +++ b/tests/test.mjs @@ -54,16 +54,6 @@ ok 1 project > createHello } ); - Qunit.test( - 'yarn bin inside app', - async function (assert) { - let result = await this.app.execute('yarn --silent bin'); - const yarnBin = result.stdout.trimRight(); - assert.ok(yarnBin.startsWith(this.app.dir)); - result = await this.app.execute('yarn --silent exec which qunit'); - assert.ok(result.stdout.startsWith(yarnBin)); - } - ); Qunit.test( 'check scenario', diff --git a/tests/test.ts b/tests/test.ts index 89198e3..ec29a9e 100644 --- a/tests/test.ts +++ b/tests/test.ts @@ -57,17 +57,6 @@ ok 1 project > createHello } ); - Qunit.test( - 'yarn bin inside app', - async function (this: TestContext, assert) { - let result = await this.app.execute('yarn --silent bin'); - const yarnBin = result.stdout.trimRight(); - assert.ok(yarnBin.startsWith(this.app.dir)); - result = await this.app.execute('yarn --silent exec which qunit'); - assert.ok(result.stdout.startsWith(yarnBin)); - } - ); - Qunit.test( 'check scenario', async function (this: TestContext, assert) { From 00cdb086dfa4ec07accf3caf78e3825c88cd0090 Mon Sep 17 00:00:00 2001 From: Chris Manson Date: Sat, 6 Jan 2024 23:49:13 +0000 Subject: [PATCH 7/7] delete unused test file --- test-modules.mjs | 89 ------------------------------------------------ 1 file changed, 89 deletions(-) delete mode 100644 test-modules.mjs diff --git a/test-modules.mjs b/test-modules.mjs deleted file mode 100644 index 1257fd6..0000000 --- a/test-modules.mjs +++ /dev/null @@ -1,89 +0,0 @@ -import { Project } from 'fixturify-project'; -import { Scenarios } from './index.js'; -import Qunit from 'qunit'; -import child_process from 'child_process'; - -function hello1(project) { - project.linkDependency('hello', { - baseDir: './fixtures', - resolveName: 'hello1', - }); -} - -function hello2(project) { - project.linkDependency('hello', { - baseDir: './fixtures', - resolveName: 'hello', - }); -} - -const scenarios = Scenarios.fromDir('./fixtures/app').expand({ - hello1, - hello2, -}); - -scenarios.forEachScenario((scenario) => { - Qunit.module(scenario.name, (hooks) => { - hooks.before(async function ({ app }) { - this.app = await scenario.prepare(); - }); - - Qunit.test( - 'yarn test', - async function (assert) { - const result = await this.app.execute('yarn --silent test'); - assert.equal( - result.stdout, - `TAP version 13 -ok 1 project > createHello -1..1 -# pass 1 -# skip 0 -# todo 0 -# fail 0 -` - ); - } - ); - - Qunit.test( - 'yarn bin inside app', - async function (assert) { - let result = await this.app.execute('yarn --silent bin'); - const yarnBin = result.stdout.trimRight(); - assert.ok(yarnBin.startsWith(this.app.dir)); - result = await this.app.execute('yarn --silent exec which qunit'); - assert.ok(result.stdout.startsWith(yarnBin)); - } - ); - - Qunit.test( - 'check scenario', - async function (assert) { - let result = await this.app.execute( - `node -p 'require("./index").polyfilled'` - ); - assert.equal( - result.stdout.trim(), - ('hello1' === scenario.name).toString() - ); - } - ); - }); -}); - -Qunit.module('cli', () => { - Qunit.test('list', (assert) => { - assert.deepEqual( - child_process - .execFileSync( - process.execPath, - ['cli.js', 'list', '--files', 'test-modules.mjs', '--matrix'], - { encoding: 'utf8' } - ) - .trimRight() - .split('\n'), - ['hello1', 'hello2'] - ); - }); -});