Skip to content

Commit 1b2617d

Browse files
authored
Update vitest monorepo to v4.1.0 (#547)
no ref Updated to vitest v4.1.0.
1 parent 8303573 commit 1b2617d

19 files changed

Lines changed: 767 additions & 600 deletions

File tree

nx.json

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
{
2-
"$schema": "./node_modules/nx/schemas/nx-schema.json",
3-
"targetDefaults": {
4-
"build": {
5-
"dependsOn": ["^build"],
6-
"cache": true
7-
},
8-
"lint": {
9-
"cache": true
10-
},
11-
"test": {
12-
"dependsOn": ["^build"],
13-
"cache": true
14-
}
2+
"$schema": "./node_modules/nx/schemas/nx-schema.json",
3+
"targetDefaults": {
4+
"build": {
5+
"dependsOn": [
6+
"^build"
7+
],
8+
"cache": true
159
},
16-
"release": {
17-
"projects": ["packages/*"],
18-
"projectsRelationship": "independent",
19-
"version": {
20-
"preserveMatchingDependencyRanges": false,
21-
"git": {
22-
"commit": true,
23-
"tag": true,
24-
"commitMessage": "Published new versions"
25-
}
26-
},
27-
"changelog": {
28-
"workspaceChangelog": false
29-
},
30-
"publish": {
31-
"registry": "https://registry.npmjs.org"
32-
}
10+
"lint": {
11+
"cache": true
12+
},
13+
"test": {
14+
"dependsOn": [
15+
"^build"
16+
],
17+
"cache": true
18+
}
19+
},
20+
"release": {
21+
"projects": [
22+
"packages/*"
23+
],
24+
"projectsRelationship": "independent",
25+
"version": {
26+
"preserveMatchingDependencyRanges": false,
27+
"git": {
28+
"commit": true,
29+
"tag": true,
30+
"commitMessage": "Published new versions"
31+
}
32+
},
33+
"changelog": {
34+
"workspaceChangelog": false
35+
},
36+
"publish": {
37+
"registry": "https://registry.npmjs.org"
3338
}
34-
}
39+
},
40+
"analytics": false
41+
}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"presetup": "yarn",
1616
"setup": "yarn",
1717
"test": "nx run-many -t test --parallel=10 --outputStyle=dynamic-legacy",
18-
"test:ci": "nx run-many -t test --outputStyle=dynamic",
18+
"test:ci": "nx run-many -t test --outputStyle=static",
1919
"lint": "nx run-many -t lint --outputStyle=dynamic",
2020
"format": "oxfmt -c .oxfmtrc.json \"packages/**/*.{js,ts,json,md}\"",
2121
"format:check": "oxfmt -c .oxfmtrc.json --check \"packages/**/*.{js,ts,json,md}\"",
@@ -28,13 +28,13 @@
2828
},
2929
"devDependencies": {
3030
"@nx/js": "22.6.5",
31-
"@vitest/coverage-v8": "3.2.4",
31+
"@vitest/coverage-v8": "4.1.0",
3232
"nx": "22.6.5",
3333
"oxfmt": "0.45.0",
3434
"oxlint": "1.60.0",
3535
"sinon": "21.1.2",
3636
"ts-node": "10.9.2",
37-
"vitest": "3.2.4"
37+
"vitest": "4.1.0"
3838
},
3939
"resolutions": {
4040
"node-loggly-bulk": "^4.0.2"

packages/bookshelf-pagination/test/pagination.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,58 @@ describe('@tryghost/bookshelf-pagination', function () {
294294
assert.equal(modelState.rawCalls[0], 'count(distinct posts.id) as aggregate');
295295
});
296296

297+
it('useSmartCount supports SQL fragments returned as an array', async function () {
298+
const {bookshelf, modelState} = createBookshelf({countRows: [{aggregate: 1}]});
299+
const model = new bookshelf.Model();
300+
301+
const originalQuery = model.query;
302+
model.query = function () {
303+
const qb = originalQuery.apply(this, arguments);
304+
if (arguments.length === 0) {
305+
qb.toSQL = () => [
306+
{sql: 'select *'},
307+
{},
308+
{sql: 'from `posts`, `tags` where `posts`.`id` = `tags`.`post_id`'}
309+
];
310+
}
311+
return qb;
312+
};
313+
314+
await model.fetchPage({page: 1, limit: 10, useSmartCount: true});
315+
316+
assert.equal(modelState.rawCalls[0], 'count(distinct posts.id) as aggregate');
317+
});
318+
319+
it('useSmartCount falls back safely when compiled SQL is missing', async function () {
320+
const {bookshelf, modelState} = createBookshelf({countRows: [{aggregate: 1}]});
321+
const model = new bookshelf.Model();
322+
323+
const originalQuery = model.query;
324+
model.query = function () {
325+
const qb = originalQuery.apply(this, arguments);
326+
if (arguments.length === 0) {
327+
qb.toSQL = () => ({});
328+
}
329+
return qb;
330+
};
331+
332+
await model.fetchPage({page: 1, limit: 10, useSmartCount: true});
333+
334+
assert.equal(modelState.rawCalls[0], 'count(*) as aggregate');
335+
});
336+
337+
it('handleRelation does not duplicate entries and ignores same-table properties', function () {
338+
const {bookshelf} = createBookshelf();
339+
const model = new bookshelf.Model();
340+
model.eagerLoad = ['authors'];
341+
342+
paginationPlugin.paginationUtils.handleRelation(model, 'posts.id');
343+
paginationPlugin.paginationUtils.handleRelation(model, 'title');
344+
paginationPlugin.paginationUtils.handleRelation(model, 'authors.name');
345+
346+
assert.deepEqual(model.eagerLoad, ['authors']);
347+
});
348+
297349
it('falls back to zero total when aggregate row is missing', async function () {
298350
const { bookshelf } = createBookshelf({ countRows: [] });
299351
const model = new bookshelf.Model();

packages/config/lib/config.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
const getConfig = require('./get-config');
22

3-
let config;
3+
const config = getConfig();
44
function initConfig() {
5-
if (!config) {
6-
config = getConfig();
7-
}
8-
95
return config;
106
}
117

packages/config/test/config.test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ describe('Config', function () {
7575
assert.equal(config.get('env'), 'development');
7676
});
7777

78+
it('handles missing process root gracefully', function () {
79+
const config = withEnv('testing', () => withRoot('', () => loadFreshGetConfig()()));
80+
assert.equal(config.get('env'), 'testing');
81+
});
82+
7883
it('index exports lib/config and only initializes config once', function () {
7984
const originalGetConfig = require(getConfigPath);
8085
const fakeConfig = { name: 'fake-config' };

packages/domain-events/lib/DomainEvents.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class DomainEvents {
3838
}
3939
if (this.#trackingEnabled) {
4040
this.#onProcessed();
41+
} else {
42+
// Tracking is disabled outside tests.
4143
}
4244
});
4345
}
@@ -61,6 +63,8 @@ class DomainEvents {
6163
static dispatchRaw(name, data) {
6264
if (this.#trackingEnabled) {
6365
this.#dispatchCount += DomainEvents.ee.listenerCount(name);
66+
} else {
67+
// Tracking is disabled outside tests.
6468
}
6569
DomainEvents.ee.emit(name, data);
6670
}
@@ -80,8 +84,9 @@ class DomainEvents {
8084
// Resolve immediately if there are no events in the queue
8185
resolve();
8286
return;
87+
} else {
88+
this.#awaitQueue.push({ resolve });
8389
}
84-
this.#awaitQueue.push({ resolve });
8590
});
8691
}
8792

@@ -92,8 +97,27 @@ class DomainEvents {
9297
item.resolve();
9398
}
9499
this.#awaitQueue = [];
100+
} else {
101+
// Wait for the remaining tracked listeners.
95102
}
96103
}
104+
105+
/**
106+
* Enable or disable dispatch/processed tracking. Test-only.
107+
* @param {boolean} enabled
108+
*/
109+
static setTrackingEnabledForTest(enabled) {
110+
this.#trackingEnabled = enabled;
111+
}
112+
113+
/**
114+
* Clear the await queue and reset dispatch/processed counts. Test-only.
115+
*/
116+
static resetTrackingStateForTest() {
117+
this.#awaitQueue = [];
118+
this.#dispatchCount = 0;
119+
this.#processedCount = 0;
120+
}
97121
}
98122

99123
module.exports = DomainEvents;

packages/domain-events/test/DomainEvents.test.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ describe('DomainEvents', function () {
2424
afterEach(function () {
2525
sinon.restore();
2626
DomainEvents.ee.removeAllListeners();
27+
DomainEvents.resetTrackingStateForTest();
28+
DomainEvents.setTrackingEnabledForTest(process.env.NODE_ENV?.startsWith('test'));
2729
});
2830

2931
it('Will call multiple subscribers with the event when it is dispatched', async function () {
@@ -78,6 +80,24 @@ describe('DomainEvents', function () {
7880
assert.equal(stub.calledTwice, true);
7981
});
8082

83+
it('works when tracking is disabled', async function () {
84+
let handled = false;
85+
86+
DomainEvents.setTrackingEnabledForTest(false);
87+
88+
DomainEvents.subscribe(TestEvent, () => {
89+
handled = true;
90+
});
91+
92+
DomainEvents.dispatch(new TestEvent('No tracking'));
93+
// Yield once so the async-wrapped handler can run before allSettled()
94+
// resolves immediately with tracking disabled.
95+
await sleep(0);
96+
await DomainEvents.allSettled();
97+
98+
assert.equal(handled, true);
99+
});
100+
81101
describe('allSettled', function () {
82102
it('Resolves when there are no events', async function () {
83103
await DomainEvents.allSettled();
@@ -99,5 +119,39 @@ describe('DomainEvents', function () {
99119
await DomainEvents.allSettled();
100120
assert.equal(counter, 2);
101121
});
122+
123+
it('waits for every tracked listener before resolving', async function () {
124+
let resolveFirst;
125+
let resolveSecond;
126+
127+
DomainEvents.subscribe(TestEvent, () => {
128+
return new Promise((resolve) => {
129+
resolveFirst = resolve;
130+
});
131+
});
132+
DomainEvents.subscribe(TestEvent, () => {
133+
return new Promise((resolve) => {
134+
resolveSecond = resolve;
135+
});
136+
});
137+
138+
DomainEvents.dispatch(new TestEvent('Hello, world!'));
139+
140+
let settled = false;
141+
const allSettled = DomainEvents.allSettled().then(() => {
142+
settled = true;
143+
});
144+
145+
await sleep(0);
146+
assert.equal(settled, false);
147+
148+
resolveFirst();
149+
await sleep(0);
150+
assert.equal(settled, false);
151+
152+
resolveSecond();
153+
await allSettled;
154+
assert.equal(settled, true);
155+
});
102156
});
103157
});

packages/express-test/test/__snapshots__/example-app.test.js.snap renamed to packages/express-test/test/__jest_snapshots__/example-app.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`Example App Set & Expect check body using snapshot matching errors correctly for random data 1: [body] 1`] = `
44
Object {

packages/express-test/test/utils/overrides.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const { snapshotManager } = require('@tryghost/jest-snapshot');
2-
2+
const SNAPSHOT_ROOT = '__jest_snapshots__';
33
beforeAll(() => {
4+
// Keep custom jest-snapshot files out of Vitest's native __snapshots__ discovery.
5+
snapshotManager.defaultSnapshotRoot = SNAPSHOT_ROOT;
46
snapshotManager.resetRegistry();
57
});
68

packages/job-manager/test/job-manager.test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,9 @@ describe('Job Manager', function () {
496496
assert.equal(JobModel.edit.args[1][0].status, 'failed');
497497

498498
// simulate process restart and "fresh" slate to add the job
499-
jobManager.removeJob('failed-oneoff');
499+
await jobManager.removeJob('failed-oneoff').catch((error) => {
500+
assert.match(error.message, /does not exist/i);
501+
});
500502
const completion2 = jobManager.awaitCompletion('failed-oneoff');
501503

502504
await jobManager.addOneOffJob({
@@ -704,6 +706,7 @@ describe('Job Manager', function () {
704706
get: () => status,
705707
}),
706708
add: sinon.stub().resolves(),
709+
edit: sinon.stub().resolves(),
707710
};
708711

709712
jobManager = new JobManager({ JobModel, config: stubConfig });

0 commit comments

Comments
 (0)