summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md14
-rw-r--r--packages/upgrade/package.json4
-rw-r--r--packages/upgrade/test/context.test.js13
-rw-r--r--packages/upgrade/test/install.test.js57
-rw-r--r--packages/upgrade/test/utils.js1
-rw-r--r--packages/upgrade/test/verify.test.js23
-rw-r--r--pnpm-lock.yaml6
-rw-r--r--scripts/cmd/test.js51
-rwxr-xr-xscripts/index.js5
9 files changed, 119 insertions, 55 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 05a07e125..73f4cc2ae 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -88,13 +88,25 @@ DEBUG=vite:[name] astro dev # debug specific process, e.g. "vite:deps" or "vit
# run this in the top-level project root to run all tests
pnpm run test
# run only a few tests in the `astro` package, great for working on a single feature
-# (example - `pnpm run test:match "cli"` runs `cli.test.js`)
+# (example - `pnpm run test:match "cli"` runs tests with "cli" in the name)
pnpm run test:match "$STRING_MATCH"
# run tests on another package
# (example - `pnpm --filter @astrojs/rss run test` runs `packages/astro-rss/test/rss.test.js`)
pnpm --filter $STRING_MATCH run test
```
+Most tests use [`mocha`](https://mochajs.org) as the test runner. We're slowly migrating to use [`node:test`](https://nodejs.org/api/test.html) instead through the custom [`astro-scripts test`](./scripts/cmd/test.js) command. For packages that use `node:test`, you can run these commands in their directories:
+
+```shell
+# run all of the package's tests
+pnpm run test
+# run only a few tests in the package
+# (example - `pnpm run test -m "cli"` runs tests with "cli" in the name)
+pnpm run test -m "$STRING_MATCH"
+# run a single test file, you can use `node --test` directly
+node --test ./test/foo.test.js
+```
+
#### E2E tests
Certain features, like HMR and client hydration, need end-to-end tests to verify functionality in the dev server. [Playwright](https://playwright.dev/) is used to test against the dev server.
diff --git a/packages/upgrade/package.json b/packages/upgrade/package.json
index 802b18015..a15c90616 100644
--- a/packages/upgrade/package.json
+++ b/packages/upgrade/package.json
@@ -20,7 +20,7 @@
"build": "astro-scripts build \"src/index.ts\" --bundle && tsc",
"build:ci": "astro-scripts build \"src/index.ts\" --bundle",
"dev": "astro-scripts dev \"src/**/*.ts\"",
- "test": "mocha --exit --timeout 20000 --parallel"
+ "test": "astro-scripts test \"test/**/*.test.js\""
},
"files": [
"dist",
@@ -39,8 +39,6 @@
"@types/which-pm-runs": "^1.0.0",
"arg": "^5.0.2",
"astro-scripts": "workspace:*",
- "chai": "^4.3.7",
- "mocha": "^10.2.0",
"strip-ansi": "^7.1.0"
},
"engines": {
diff --git a/packages/upgrade/test/context.test.js b/packages/upgrade/test/context.test.js
index 5b6b8c6b2..714a7b64a 100644
--- a/packages/upgrade/test/context.test.js
+++ b/packages/upgrade/test/context.test.js
@@ -1,19 +1,20 @@
-import { expect } from 'chai';
+import { describe, it } from 'node:test';
+import * as assert from 'node:assert/strict';
import { getContext } from '../dist/index.js';
describe('context', () => {
it('no arguments', async () => {
const ctx = await getContext([]);
- expect(ctx.version).to.eq('latest');
- expect(ctx.dryRun).to.be.undefined;
+ assert.equal(ctx.version, 'latest');
+ assert.equal(ctx.dryRun, undefined);
});
it('tag', async () => {
const ctx = await getContext(['beta']);
- expect(ctx.version).to.eq('beta');
- expect(ctx.dryRun).to.be.undefined;
+ assert.equal(ctx.version, 'beta');
+ assert.equal(ctx.dryRun, undefined);
});
it('dry run', async () => {
const ctx = await getContext(['--dry-run']);
- expect(ctx.dryRun).to.eq(true);
+ assert.equal(ctx.dryRun, true);
});
});
diff --git a/packages/upgrade/test/install.test.js b/packages/upgrade/test/install.test.js
index 05c46cdce..b4158d264 100644
--- a/packages/upgrade/test/install.test.js
+++ b/packages/upgrade/test/install.test.js
@@ -1,4 +1,5 @@
-import { expect } from 'chai';
+import { describe, it } from 'node:test';
+import * as assert from 'node:assert/strict';
import { setup } from './utils.js';
import { install } from '../dist/index.js';
@@ -23,7 +24,7 @@ describe('install', () => {
],
};
await install(context);
- expect(fixture.hasMessage('◼ astro is up to date on v1.0.0')).to.be.true;
+ assert.equal(fixture.hasMessage('◼ astro is up to date on v1.0.0'), true);
});
it('patch', async () => {
@@ -38,7 +39,7 @@ describe('install', () => {
],
};
await install(context);
- expect(fixture.hasMessage('● astro can be updated to v1.0.1')).to.be.true;
+ assert.equal(fixture.hasMessage('● astro can be updated to v1.0.1'), true);
});
it('minor', async () => {
@@ -53,7 +54,7 @@ describe('install', () => {
],
};
await install(context);
- expect(fixture.hasMessage('● astro can be updated to v1.2.0')).to.be.true;
+ assert.equal(fixture.hasMessage('● astro can be updated to v1.2.0'), true);
});
it('major (reject)', async () => {
@@ -80,10 +81,10 @@ describe('install', () => {
],
};
await install(context);
- expect(fixture.hasMessage('▲ astro can be updated to v2.0.0')).to.be.true;
- expect(prompted).to.be.true;
- expect(exitCode).to.eq(0);
- expect(fixture.hasMessage('check Be sure to follow the CHANGELOG.')).to.be.false;
+ assert.equal(fixture.hasMessage('▲ astro can be updated to v2.0.0'), true);
+ assert.equal(prompted, true);
+ assert.equal(exitCode, 0);
+ assert.equal(fixture.hasMessage('check Be sure to follow the CHANGELOG.'), false);
});
it('major (accept)', async () => {
@@ -110,10 +111,10 @@ describe('install', () => {
],
};
await install(context);
- expect(fixture.hasMessage('▲ astro can be updated to v2.0.0')).to.be.true;
- expect(prompted).to.be.true;
- expect(exitCode).to.be.undefined;
- expect(fixture.hasMessage('check Be sure to follow the CHANGELOG.')).to.be.true;
+ assert.equal(fixture.hasMessage('▲ astro can be updated to v2.0.0'), true);
+ assert.equal(prompted, true);
+ assert.equal(exitCode, undefined);
+ assert.equal(fixture.hasMessage('check Be sure to follow the CHANGELOG.'), true);
});
it('multiple major', async () => {
@@ -148,14 +149,14 @@ describe('install', () => {
],
};
await install(context);
- expect(fixture.hasMessage('▲ a can be updated to v2.0.0')).to.be.true;
- expect(fixture.hasMessage('▲ b can be updated to v7.0.0')).to.be.true;
- expect(prompted).to.be.true;
- expect(exitCode).to.be.undefined;
+ assert.equal(fixture.hasMessage('▲ a can be updated to v2.0.0'), true);
+ assert.equal(fixture.hasMessage('▲ b can be updated to v7.0.0'), true);
+ assert.equal(prompted, true);
+ assert.equal(exitCode, undefined);
const [changelog, a, b] = fixture.messages().slice(-5);
- expect(changelog).to.match(/^check/);
- expect(a).to.match(/^a/);
- expect(b).to.match(/^b/);
+ assert.match(changelog, /^check/);
+ assert.match(a, /^a/);
+ assert.match(b, /^b/);
});
it('current patch minor major', async () => {
@@ -197,15 +198,15 @@ describe('install', () => {
],
};
await install(context);
- expect(fixture.hasMessage('◼ current is up to date on v1.0.0')).to.be.true;
- expect(fixture.hasMessage('● patch can be updated to v1.0.1')).to.be.true;
- expect(fixture.hasMessage('● minor can be updated to v1.2.0')).to.be.true;
- expect(fixture.hasMessage('▲ major can be updated to v3.0.0')).to.be.true;
- expect(prompted).to.be.true;
- expect(exitCode).to.be.undefined;
- expect(fixture.hasMessage('check Be sure to follow the CHANGELOG.')).to.be.true;
+ assert.equal(fixture.hasMessage('◼ current is up to date on v1.0.0'), true);
+ assert.equal(fixture.hasMessage('● patch can be updated to v1.0.1'), true);
+ assert.equal(fixture.hasMessage('● minor can be updated to v1.2.0'), true);
+ assert.equal(fixture.hasMessage('▲ major can be updated to v3.0.0'), true);
+ assert.equal(prompted, true);
+ assert.equal(exitCode, undefined);
+ assert.equal(fixture.hasMessage('check Be sure to follow the CHANGELOG.'), true);
const [changelog, major] = fixture.messages().slice(-4);
- expect(changelog).to.match(/^check/);
- expect(major).to.match(/^major/);
+ assert.match(changelog, /^check/);
+ assert.match(major, /^major/)
});
});
diff --git a/packages/upgrade/test/utils.js b/packages/upgrade/test/utils.js
index ff5d5dd83..691e63d90 100644
--- a/packages/upgrade/test/utils.js
+++ b/packages/upgrade/test/utils.js
@@ -1,3 +1,4 @@
+import { before, beforeEach } from 'node:test';
import { setStdout } from '../dist/index.js';
import stripAnsi from 'strip-ansi';
diff --git a/packages/upgrade/test/verify.test.js b/packages/upgrade/test/verify.test.js
index a54cb6bb5..3b9d4b3bc 100644
--- a/packages/upgrade/test/verify.test.js
+++ b/packages/upgrade/test/verify.test.js
@@ -1,4 +1,5 @@
-import { expect } from 'chai';
+import { describe, it, beforeEach } from 'node:test';
+import * as assert from 'node:assert/strict';
import { collectPackageInfo } from '../dist/index.js';
describe('collectPackageInfo', () => {
@@ -16,61 +17,61 @@ describe('collectPackageInfo', () => {
it('detects astro', async () => {
collectPackageInfo(context, { astro: '1.0.0' }, {});
- expect(context.packages).deep.equal([
+ assert.deepEqual(context.packages, [
{ name: 'astro', currentVersion: '1.0.0', targetVersion: 'latest' },
]);
});
it('detects @astrojs', async () => {
collectPackageInfo(context, { '@astrojs/preact': '1.0.0' }, {});
- expect(context.packages).deep.equal([
+ assert.deepEqual(context.packages, [
{ name: '@astrojs/preact', currentVersion: '1.0.0', targetVersion: 'latest' },
]);
});
it('supports ^ prefixes', async () => {
collectPackageInfo(context, { astro: '^1.0.0' }, {});
- expect(context.packages).deep.equal([
+ assert.deepEqual(context.packages, [
{ name: 'astro', currentVersion: '^1.0.0', targetVersion: 'latest' },
]);
});
it('supports ~ prefixes', async () => {
collectPackageInfo(context, { astro: '~1.0.0' }, {});
- expect(context.packages).deep.equal([
+ assert.deepEqual(context.packages, [
{ name: 'astro', currentVersion: '~1.0.0', targetVersion: 'latest' },
]);
});
it('supports prereleases', async () => {
collectPackageInfo(context, { astro: '1.0.0-beta.0' }, {});
- expect(context.packages).deep.equal([
+ assert.deepEqual(context.packages, [
{ name: 'astro', currentVersion: '1.0.0-beta.0', targetVersion: 'latest' },
]);
});
it('ignores self', async () => {
collectPackageInfo(context, { '@astrojs/upgrade': '0.0.1' }, {});
- expect(context.packages).deep.equal([]);
+ assert.deepEqual(context.packages, []);
});
it('ignores linked packages', async () => {
collectPackageInfo(context, { '@astrojs/preact': 'link:../packages/preact' }, {});
- expect(context.packages).deep.equal([]);
+ assert.deepEqual(context.packages, []);
});
it('ignores workspace packages', async () => {
collectPackageInfo(context, { '@astrojs/preact': 'workspace:*' }, {});
- expect(context.packages).deep.equal([]);
+ assert.deepEqual(context.packages, []);
});
it('ignores github packages', async () => {
collectPackageInfo(context, { '@astrojs/preact': 'github:withastro/astro' }, {});
- expect(context.packages).deep.equal([]);
+ assert.deepEqual(context.packages, []);
});
it('ignores tag', async () => {
collectPackageInfo(context, { '@astrojs/preact': 'beta' }, {});
- expect(context.packages).deep.equal([]);
+ assert.deepEqual(context.packages, []);
});
});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c1a32f444..ab455435e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5148,12 +5148,6 @@ importers:
astro-scripts:
specifier: workspace:*
version: link:../../scripts
- chai:
- specifier: ^4.3.7
- version: 4.3.10
- mocha:
- specifier: ^10.2.0
- version: 10.2.0
strip-ansi:
specifier: ^7.1.0
version: 7.1.0
diff --git a/scripts/cmd/test.js b/scripts/cmd/test.js
index e69de29bb..84f6d9742 100644
--- a/scripts/cmd/test.js
+++ b/scripts/cmd/test.js
@@ -0,0 +1,51 @@
+import { run } from 'node:test';
+import { spec } from 'node:test/reporters';
+import arg from 'arg';
+import glob from 'tiny-glob';
+
+const isCI = !!process.env.CI;
+const defaultTimeout = isCI ? 30000 : 20000;
+
+export default async function test() {
+ const args = arg({
+ '--match': String, // aka --test-name-pattern: https://nodejs.org/api/test.html#filtering-tests-by-name
+ '--only': Boolean, // aka --test-only: https://nodejs.org/api/test.html#only-tests
+ '--parallel': Boolean, // aka --test-concurrency: https://nodejs.org/api/test.html#test-runner-execution-model
+ '--watch': Boolean, // experimental: https://nodejs.org/api/test.html#watch-mode
+ '--timeout': Number, // Test timeout in milliseconds (default: 30000ms)
+ '--setup': String, // Test setup file
+ // Aliases
+ '-m': '--match',
+ '-o': '--only',
+ '-p': '--parallel',
+ '-w': '--watch',
+ '-t': '--timeout',
+ '-s': '--setup',
+ });
+
+ const pattern = args._[1];
+ if (!pattern) throw new Error('Missing test glob pattern');
+
+ const files = await glob(pattern, { filesOnly: true, absolute: true });
+
+ // For some reason, the `only` option does not work and we need to explicitly set the CLI flag instead.
+ // Node.js requires opt-in to run .only tests :(
+ // https://nodejs.org/api/test.html#only-tests
+ if (args['--only']) {
+ process.env.NODE_OPTIONS ??= '';
+ process.env.NODE_OPTIONS += ' --test-only';
+ }
+
+ // https://nodejs.org/api/test.html#runoptions
+ run({
+ files,
+ testNamePatterns: args['--match'],
+ concurrency: args['--parallel'],
+ only: args['--only'],
+ setup: args['--setup'],
+ watch: args['--watch'],
+ timeout: args['--timeout'] ?? defaultTimeout, // Node.js defaults to Infinity, so set better fallback
+ })
+ .pipe(new spec())
+ .pipe(process.stdout);
+}
diff --git a/scripts/index.js b/scripts/index.js
index 249eac53d..381500ac4 100755
--- a/scripts/index.js
+++ b/scripts/index.js
@@ -18,6 +18,11 @@ export default async function run() {
await prebuild(...args);
break;
}
+ case 'test': {
+ const { default: test } = await import('./cmd/test.js');
+ await test(...args);
+ break;
+ }
}
}