tests: use describe.each for database test iteration

Refactors all test files that use TestDatabases/TestCaches with
it.each(databases.eachSupportedId()) to instead use describe.each at
the outer level. This ensures that all tests for one database engine
complete before moving to the next, rather than interleaving engines
across individual tests. This reduces the number of concurrent database
connections and should help with test timeout issues in CI.

The TestDatabases.create() call is hoisted to module scope so the
describe.each can iterate over supported IDs at the top level.

40 files changed across packages/backend-defaults,
packages/backend-test-utils, and multiple plugins.

Signed-off-by: Fredrik Adelöw <freben@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2026-05-15 17:15:23 +02:00
parent 18aa6e4d56
commit 8165184fba
40 changed files with 4406 additions and 4992 deletions
@@ -19,12 +19,12 @@ import { StaticAssetsStore } from './StaticAssetsStore';
jest.setTimeout(60_000);
describe('StaticAssetsStore', () => {
const databases = TestDatabases.create();
const databases = TestDatabases.create();
it.each(databases.eachSupportedId())(
'should store and retrieve assets, %p',
async databaseId => {
describe.each(databases.eachSupportedId())(
'StaticAssetsStore, %p',
databaseId => {
it('should store and retrieve assets', async () => {
const knex = await databases.init(databaseId);
const store = await StaticAssetsStore.create({
@@ -61,12 +61,9 @@ describe('StaticAssetsStore', () => {
await expect(
store.getAsset('does-not-exist.txt'),
).resolves.toBeUndefined();
},
);
});
it.each(databases.eachSupportedId())(
'should update assets timestamps, but not contents, %p',
async databaseId => {
it('should update assets timestamps, but not contents', async () => {
const knex = await databases.init(databaseId);
const store = await StaticAssetsStore.create({
@@ -112,12 +109,9 @@ describe('StaticAssetsStore', () => {
const sameBar = await store.getAsset('bar');
expect(oldBar!.lastModifiedAt).toEqual(sameBar!.lastModifiedAt);
},
);
});
it.each(databases.eachSupportedId())(
'should trim old assets, %p',
async databaseId => {
it('should trim old assets', async () => {
const knex = await databases.init(databaseId);
const store = await StaticAssetsStore.create({
@@ -157,12 +151,9 @@ describe('StaticAssetsStore', () => {
await expect(store.getAsset('new')).resolves.toBeDefined();
await expect(store.getAsset('old')).resolves.toBeUndefined();
},
);
});
it.each(databases.eachSupportedId())(
'should isolate assets in namespace, %p',
async databaseId => {
it('should isolate assets in namespace', async () => {
const knex = await databases.init(databaseId);
const store = await StaticAssetsStore.create({
@@ -197,6 +188,6 @@ describe('StaticAssetsStore', () => {
await otherStore.trimAssets({ maxAgeSeconds: 0 });
await expect(otherStore.getAsset('bar')).resolves.not.toBeDefined();
},
);
});
});
},
);
+69 -75
View File
@@ -41,101 +41,95 @@ async function migrateUntilBefore(knex: Knex, target: string): Promise<void> {
jest.setTimeout(60_000);
describe('migrations', () => {
const databases = TestDatabases.create();
const databases = TestDatabases.create();
it.each(databases.eachSupportedId())(
'20211229105307_init.js, %p',
async databaseId => {
const knex = await databases.init(databaseId);
describe.each(databases.eachSupportedId())('migrations, %p', databaseId => {
it('20211229105307_init.js', async () => {
const knex = await databases.init(databaseId);
await migrateUntilBefore(knex, '20211229105307_init.js');
await migrateUpOnce(knex);
await migrateUntilBefore(knex, '20211229105307_init.js');
await migrateUpOnce(knex);
await knex('static_assets_cache').insert({
await knex('static_assets_cache').insert({
path: 'main.js',
content: Buffer.from('some-script'),
last_modified_at: knex.fn.now(),
});
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
last_modified_at: knex.fn.now(),
});
last_modified_at: expect.anything(),
},
]);
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
last_modified_at: expect.anything(),
},
]);
await migrateDownOnce(knex);
await migrateDownOnce(knex);
// This looks odd - you might expect a .toThrow at the end but that
// actually is flaky for some reason specifically on sqlite when
// performing multiple runs in sequence
await expect(knex('static_assets_cache')).rejects.toEqual(
expect.anything(),
);
// This looks odd - you might expect a .toThrow at the end but that
// actually is flaky for some reason specifically on sqlite when
// performing multiple runs in sequence
await expect(knex('static_assets_cache')).rejects.toEqual(
expect.anything(),
);
await knex.destroy();
});
await knex.destroy();
},
);
it('20240113144027_assets-namespace.js', async () => {
const knex = await databases.init(databaseId);
it.each(databases.eachSupportedId())(
'20240113144027_assets-namespace.js, %p',
async databaseId => {
const knex = await databases.init(databaseId);
await migrateUntilBefore(knex, '20240113144027_assets-namespace.js');
await migrateUntilBefore(knex, '20240113144027_assets-namespace.js');
await knex('static_assets_cache').insert({
path: 'main.js',
content: Buffer.from('some-script'),
last_modified_at: knex.fn.now(),
});
await knex('static_assets_cache').insert({
await migrateUpOnce(knex);
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
last_modified_at: knex.fn.now(),
});
namespace: 'default',
last_modified_at: expect.anything(),
},
]);
await migrateUpOnce(knex);
await knex('static_assets_cache').insert({
path: 'main.js',
content: Buffer.from('other-script'),
namespace: 'other',
last_modified_at: knex.fn.now(),
});
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
namespace: 'default',
last_modified_at: expect.anything(),
},
]);
await knex('static_assets_cache').insert({
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
namespace: 'default',
last_modified_at: expect.anything(),
},
{
path: 'main.js',
content: Buffer.from('other-script'),
namespace: 'other',
last_modified_at: knex.fn.now(),
});
last_modified_at: expect.anything(),
},
]);
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
namespace: 'default',
last_modified_at: expect.anything(),
},
{
path: 'main.js',
content: Buffer.from('other-script'),
namespace: 'other',
last_modified_at: expect.anything(),
},
]);
await migrateDownOnce(knex);
await migrateDownOnce(knex);
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
last_modified_at: expect.anything(),
},
]);
await expect(knex('static_assets_cache')).resolves.toEqual([
{
path: 'main.js',
content: Buffer.from('some-script'),
last_modified_at: expect.anything(),
},
]);
await knex.destroy();
},
);
await knex.destroy();
});
});