@geekmidas/testkit 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Factory-z2m01hMj.mjs → Factory-BFVnMMCC.mjs} +2 -2
- package/dist/Factory-BFVnMMCC.mjs.map +1 -0
- package/dist/{Factory-Cmr3s3-s.d.mts → Factory-BcGJjLc8.d.mts} +23 -9
- package/dist/{Factory-WMhTNZ9S.cjs → Factory-BhjUOBWN.cjs} +2 -2
- package/dist/Factory-BhjUOBWN.cjs.map +1 -0
- package/dist/{Factory-D7oHtI2D.d.cts → Factory-IdfEkOeT.d.cts} +24 -10
- package/dist/Factory.cjs +1 -1
- package/dist/Factory.d.cts +3 -3
- package/dist/Factory.d.mts +2 -2
- package/dist/Factory.mjs +1 -1
- package/dist/{KyselyFactory-DaaCykWP.cjs → KyselyFactory-BFqVIn_0.cjs} +21 -4
- package/dist/KyselyFactory-BFqVIn_0.cjs.map +1 -0
- package/dist/{KyselyFactory-BTdygZ-i.d.mts → KyselyFactory-Cj-EultY.d.mts} +17 -4
- package/dist/{KyselyFactory-CXY5gJk2.mjs → KyselyFactory-DMswpwji.mjs} +21 -4
- package/dist/KyselyFactory-DMswpwji.mjs.map +1 -0
- package/dist/{KyselyFactory-dYdviox2.d.cts → KyselyFactory-Dxhi_ZkA.d.cts} +18 -5
- package/dist/KyselyFactory.cjs +2 -2
- package/dist/KyselyFactory.d.cts +3 -3
- package/dist/KyselyFactory.d.mts +2 -2
- package/dist/KyselyFactory.mjs +2 -2
- package/dist/{ObjectionFactory-0gUdx8bB.d.cts → ObjectionFactory-BRAkAByP.d.cts} +18 -5
- package/dist/{ObjectionFactory-Eb04AOnv.cjs → ObjectionFactory-BeFBYcan.cjs} +21 -4
- package/dist/ObjectionFactory-BeFBYcan.cjs.map +1 -0
- package/dist/{ObjectionFactory-BagGjikT.d.mts → ObjectionFactory-DL4qkuF1.d.mts} +17 -4
- package/dist/{ObjectionFactory-zf2fLKrL.mjs → ObjectionFactory-QCJ7u0Ql.mjs} +21 -4
- package/dist/ObjectionFactory-QCJ7u0Ql.mjs.map +1 -0
- package/dist/ObjectionFactory.cjs +2 -2
- package/dist/ObjectionFactory.d.cts +3 -3
- package/dist/ObjectionFactory.d.mts +2 -2
- package/dist/ObjectionFactory.mjs +2 -2
- package/dist/benchmark.cjs +49 -0
- package/dist/benchmark.cjs.map +1 -0
- package/dist/benchmark.d.cts +35 -0
- package/dist/benchmark.d.mts +35 -0
- package/dist/benchmark.mjs +45 -0
- package/dist/benchmark.mjs.map +1 -0
- package/dist/better-auth.d.cts +2 -2
- package/dist/{directory-BUcnztHI.d.cts → directory-Mi7tdOuD.d.cts} +3 -3
- package/dist/{faker-Dg3trU4a.d.cts → faker-CbYiF-8_.d.cts} +3 -3
- package/dist/faker.d.cts +1 -1
- package/dist/kysely.cjs +2 -2
- package/dist/kysely.cjs.map +1 -1
- package/dist/kysely.d.cts +4 -4
- package/dist/kysely.d.mts +3 -3
- package/dist/kysely.mjs +2 -2
- package/dist/kysely.mjs.map +1 -1
- package/dist/objection.cjs +2 -2
- package/dist/objection.cjs.map +1 -1
- package/dist/objection.d.cts +4 -4
- package/dist/objection.d.mts +3 -3
- package/dist/objection.mjs +2 -2
- package/dist/objection.mjs.map +1 -1
- package/dist/os/directory.d.cts +1 -1
- package/dist/os/index.d.cts +1 -1
- package/package.json +6 -1
- package/src/Factory.ts +25 -11
- package/src/KyselyFactory.ts +21 -4
- package/src/ObjectionFactory.ts +21 -4
- package/src/__tests__/Factory.spec.ts +16 -10
- package/src/__tests__/KyselyFactory.spec.ts +12 -6
- package/src/__tests__/ObjectionFactory.spec.ts +57 -48
- package/src/__tests__/integration.spec.ts +16 -8
- package/src/benchmark.ts +48 -0
- package/src/kysely.ts +1 -0
- package/src/objection.ts +1 -0
- package/dist/Factory-WMhTNZ9S.cjs.map +0 -1
- package/dist/Factory-z2m01hMj.mjs.map +0 -1
- package/dist/KyselyFactory-CXY5gJk2.mjs.map +0 -1
- package/dist/KyselyFactory-DaaCykWP.cjs.map +0 -1
- package/dist/ObjectionFactory-Eb04AOnv.cjs.map +0 -1
- package/dist/ObjectionFactory-zf2fLKrL.mjs.map +0 -1
package/dist/objection.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objection.cjs","names":["api: TestAPI","options: ObjectionTransactionOptions<Extended>","VitestObjectionTransactionIsolator","extendWithFixtures","wrappedTest: T","fixtures: FixtureCreators<Knex.Transaction, Extended>"],"sources":["../src/objection.ts"],"sourcesContent":["import type { Knex } from 'knex';\nimport type { TestAPI } from 'vitest';\nimport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nimport {\n type DatabaseConnection,\n type FixtureCreators,\n type IsolationLevel,\n extendWithFixtures as baseExtendWithFixtures,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific exports for test utilities.\n * Provides factory implementation for creating test data with Objection.js ORM\n * and transaction isolation for test suites.\n */\n\nexport { ObjectionFactory } from './ObjectionFactory';\nexport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nexport { IsolationLevel } from './VitestTransactionIsolator';\nexport { PostgresObjectionMigrator } from './PostgresObjectionMigrator';\nexport type {\n DatabaseFixtures,\n ExtendedDatabaseFixtures,\n FixtureCreators,\n TestWithExtendedFixtures,\n TransactionWrapperOptions,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific options for transaction wrapping.\n */\nexport interface ObjectionTransactionOptions<\n Extended extends Record<string, unknown> = {},\n> {\n /** Function that creates or returns a Knex database connection */\n connection: DatabaseConnection<Knex>;\n /** Optional setup function to run within the transaction before each test */\n setup?: (trx: Knex.Transaction) => Promise<void>;\n /** Transaction isolation level (defaults to REPEATABLE_READ) */\n isolationLevel?: IsolationLevel;\n /** Additional fixtures that depend on the transaction */\n fixtures?: FixtureCreators<Knex.Transaction, Extended>;\n}\n\n// Re-export faker and FakerFactory for type portability in declaration files\nexport { faker, type FakerFactory } from './faker';\n\n/**\n * Creates a wrapped Vitest test API with automatic transaction rollback for Objection.js.\n * Each test runs in an isolated database transaction that is rolled back after completion.\n * This ensures tests don't affect each other's data and run faster than truncating tables.\n *\n * @template Extended - Additional fixtures to provide\n * @param api - The Vitest test API (usually `test` from vitest)\n * @param options - Configuration options for transaction wrapping\n * @returns A wrapped test API that provides transaction isolation\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction } from '@geekmidas/testkit/objection';\n * import { knex } from './database';\n * import { User } from './models';\n *\n * // Create isolated test with automatic rollback\n * const isolatedTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * });\n *\n * // Use in tests - each test gets its own transaction\n * isolatedTest('should create user', async ({ trx }) => {\n * const user = await User.query(trx)\n * .insert({ name: 'Test User', email: 'test@example.com' });\n *\n * expect(user).toBeDefined();\n * });\n *\n * // With fixtures for factories\n * const it = wrapVitestObjectionTransaction<{ factory: Factory }>(test, {\n * connection: knex,\n * fixtures: {\n * factory: (trx) => new Factory(trx),\n * },\n * });\n *\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test' });\n * expect(user.id).toBeDefined();\n * });\n * ```\n */\nexport function wrapVitestObjectionTransaction<\n Extended extends Record<string, unknown> = {},\n>(api: TestAPI, options: ObjectionTransactionOptions<Extended>) {\n const wrapper = new VitestObjectionTransactionIsolator(api);\n\n return wrapper.wrapVitestWithTransaction(options);\n}\n\n/**\n * Extends an Objection.js transaction-wrapped test with additional fixtures.\n * Each fixture receives the transaction and can create dependencies like factories or repositories.\n *\n * @template Extended - The type of additional fixtures to provide\n * @param wrappedTest - The base wrapped test from wrapVitestObjectionTransaction\n * @param fixtures - Object mapping fixture names to creator functions\n * @returns An extended test API with both trx and the additional fixtures\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction, extendWithFixtures, ObjectionFactory } from '@geekmidas/testkit/objection';\n * import { User } from './models';\n *\n * // Define your builders\n * const builders = {\n * user: ObjectionFactory.createBuilder(User, ({ faker }) => ({\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * })),\n * };\n *\n * // Create base wrapped test\n * const baseTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * setup: createTestTables,\n * });\n *\n * // Extend with fixtures - each fixture receives the transaction\n * const it = extendWithFixtures<{ factory: ObjectionFactory<typeof builders, {}> }>(\n * baseTest,\n * {\n * factory: (trx) => new ObjectionFactory(builders, {}, trx),\n * }\n * );\n *\n * // Use in tests - both trx and factory are available\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test User' });\n * expect(user.id).toBeDefined();\n *\n * // Verify in database\n * const found = await User.query(trx).findById(user.id);\n * expect(found?.name).toBe('Test User');\n * });\n * ```\n */\nexport function extendWithFixtures<\n Extended extends Record<string, unknown>,\n T extends ReturnType<TestAPI['extend']> = ReturnType<TestAPI['extend']>,\n>(wrappedTest: T, fixtures: FixtureCreators<Knex.Transaction, Extended>) {\n return baseExtendWithFixtures<Knex.Transaction, Extended, T>(\n wrappedTest,\n fixtures,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"objection.cjs","names":["api: TestAPI","options: ObjectionTransactionOptions<Extended>","VitestObjectionTransactionIsolator","extendWithFixtures","wrappedTest: T","fixtures: FixtureCreators<Knex.Transaction, Extended>"],"sources":["../src/objection.ts"],"sourcesContent":["import type { Knex } from 'knex';\nimport type { TestAPI } from 'vitest';\nimport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nimport {\n type DatabaseConnection,\n type FixtureCreators,\n type IsolationLevel,\n extendWithFixtures as baseExtendWithFixtures,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific exports for test utilities.\n * Provides factory implementation for creating test data with Objection.js ORM\n * and transaction isolation for test suites.\n */\n\nexport { ObjectionFactory } from './ObjectionFactory';\nexport type { ExtractSeedAttrs, FactorySeed } from './Factory';\nexport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nexport { IsolationLevel } from './VitestTransactionIsolator';\nexport { PostgresObjectionMigrator } from './PostgresObjectionMigrator';\nexport type {\n DatabaseFixtures,\n ExtendedDatabaseFixtures,\n FixtureCreators,\n TestWithExtendedFixtures,\n TransactionWrapperOptions,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific options for transaction wrapping.\n */\nexport interface ObjectionTransactionOptions<\n Extended extends Record<string, unknown> = {},\n> {\n /** Function that creates or returns a Knex database connection */\n connection: DatabaseConnection<Knex>;\n /** Optional setup function to run within the transaction before each test */\n setup?: (trx: Knex.Transaction) => Promise<void>;\n /** Transaction isolation level (defaults to REPEATABLE_READ) */\n isolationLevel?: IsolationLevel;\n /** Additional fixtures that depend on the transaction */\n fixtures?: FixtureCreators<Knex.Transaction, Extended>;\n}\n\n// Re-export faker and FakerFactory for type portability in declaration files\nexport { faker, type FakerFactory } from './faker';\n\n/**\n * Creates a wrapped Vitest test API with automatic transaction rollback for Objection.js.\n * Each test runs in an isolated database transaction that is rolled back after completion.\n * This ensures tests don't affect each other's data and run faster than truncating tables.\n *\n * @template Extended - Additional fixtures to provide\n * @param api - The Vitest test API (usually `test` from vitest)\n * @param options - Configuration options for transaction wrapping\n * @returns A wrapped test API that provides transaction isolation\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction } from '@geekmidas/testkit/objection';\n * import { knex } from './database';\n * import { User } from './models';\n *\n * // Create isolated test with automatic rollback\n * const isolatedTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * });\n *\n * // Use in tests - each test gets its own transaction\n * isolatedTest('should create user', async ({ trx }) => {\n * const user = await User.query(trx)\n * .insert({ name: 'Test User', email: 'test@example.com' });\n *\n * expect(user).toBeDefined();\n * });\n *\n * // With fixtures for factories\n * const it = wrapVitestObjectionTransaction<{ factory: Factory }>(test, {\n * connection: knex,\n * fixtures: {\n * factory: (trx) => new Factory(trx),\n * },\n * });\n *\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test' });\n * expect(user.id).toBeDefined();\n * });\n * ```\n */\nexport function wrapVitestObjectionTransaction<\n Extended extends Record<string, unknown> = {},\n>(api: TestAPI, options: ObjectionTransactionOptions<Extended>) {\n const wrapper = new VitestObjectionTransactionIsolator(api);\n\n return wrapper.wrapVitestWithTransaction(options);\n}\n\n/**\n * Extends an Objection.js transaction-wrapped test with additional fixtures.\n * Each fixture receives the transaction and can create dependencies like factories or repositories.\n *\n * @template Extended - The type of additional fixtures to provide\n * @param wrappedTest - The base wrapped test from wrapVitestObjectionTransaction\n * @param fixtures - Object mapping fixture names to creator functions\n * @returns An extended test API with both trx and the additional fixtures\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction, extendWithFixtures, ObjectionFactory } from '@geekmidas/testkit/objection';\n * import { User } from './models';\n *\n * // Define your builders\n * const builders = {\n * user: ObjectionFactory.createBuilder(User, ({ faker }) => ({\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * })),\n * };\n *\n * // Create base wrapped test\n * const baseTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * setup: createTestTables,\n * });\n *\n * // Extend with fixtures - each fixture receives the transaction\n * const it = extendWithFixtures<{ factory: ObjectionFactory<typeof builders, {}> }>(\n * baseTest,\n * {\n * factory: (trx) => new ObjectionFactory(builders, {}, trx),\n * }\n * );\n *\n * // Use in tests - both trx and factory are available\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test User' });\n * expect(user.id).toBeDefined();\n *\n * // Verify in database\n * const found = await User.query(trx).findById(user.id);\n * expect(found?.name).toBe('Test User');\n * });\n * ```\n */\nexport function extendWithFixtures<\n Extended extends Record<string, unknown>,\n T extends ReturnType<TestAPI['extend']> = ReturnType<TestAPI['extend']>,\n>(wrappedTest: T, fixtures: FixtureCreators<Knex.Transaction, Extended>) {\n return baseExtendWithFixtures<Knex.Transaction, Extended, T>(\n wrappedTest,\n fixtures,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4FA,SAAgB,+BAEdA,KAAcC,SAAgD;CAC9D,MAAM,UAAU,IAAIC,8EAAmC;AAEvD,QAAO,QAAQ,0BAA0B,QAAQ;AAClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDD,SAAgBC,qBAGdC,aAAgBC,UAAuD;AACvE,QAAO,qDACL,aACA,SACD;AACF"}
|
package/dist/objection.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FakerFactory, faker } from "./faker-
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { ObjectionFactory } from "./ObjectionFactory-
|
|
1
|
+
import { FakerFactory, faker } from "./faker-CbYiF-8_.cjs";
|
|
2
|
+
import { ExtractSeedAttrs, FactorySeed } from "./Factory-IdfEkOeT.cjs";
|
|
3
|
+
import { ObjectionFactory } from "./ObjectionFactory-BRAkAByP.cjs";
|
|
4
4
|
import "./PostgresMigrator-D5UkK1_K.cjs";
|
|
5
5
|
import { PostgresObjectionMigrator } from "./PostgresObjectionMigrator-CZHHcCOv.cjs";
|
|
6
6
|
import { DatabaseConnection, DatabaseFixtures, ExtendedDatabaseFixtures, FixtureCreators, IsolationLevel, TestWithExtendedFixtures, TransactionWrapperOptions } from "./VitestTransactionIsolator-CwQaxZLP.cjs";
|
|
@@ -118,5 +118,5 @@ declare function wrapVitestObjectionTransaction<Extended extends Record<string,
|
|
|
118
118
|
*/
|
|
119
119
|
declare function extendWithFixtures<Extended extends Record<string, unknown>, T extends ReturnType<TestAPI['extend']> = ReturnType<TestAPI['extend']>>(wrappedTest: T, fixtures: FixtureCreators<Knex.Transaction, Extended>): TestWithExtendedFixtures<Knex.Transaction<any, any[]>, Extended, T>;
|
|
120
120
|
//#endregion
|
|
121
|
-
export { DatabaseFixtures, ExtendedDatabaseFixtures, FakerFactory, FixtureCreators, IsolationLevel, ObjectionFactory, ObjectionTransactionOptions, PostgresObjectionMigrator, TestWithExtendedFixtures, TransactionWrapperOptions, VitestObjectionTransactionIsolator, extendWithFixtures, faker, wrapVitestObjectionTransaction };
|
|
121
|
+
export { DatabaseFixtures, ExtendedDatabaseFixtures, ExtractSeedAttrs, FactorySeed, FakerFactory, FixtureCreators, IsolationLevel, ObjectionFactory, ObjectionTransactionOptions, PostgresObjectionMigrator, TestWithExtendedFixtures, TransactionWrapperOptions, VitestObjectionTransactionIsolator, extendWithFixtures, faker, wrapVitestObjectionTransaction };
|
|
122
122
|
//# sourceMappingURL=objection.d.cts.map
|
package/dist/objection.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FakerFactory, faker } from "./faker-DHh7xs4u.mjs";
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { ObjectionFactory } from "./ObjectionFactory-
|
|
2
|
+
import { ExtractSeedAttrs, FactorySeed } from "./Factory-BcGJjLc8.mjs";
|
|
3
|
+
import { ObjectionFactory } from "./ObjectionFactory-DL4qkuF1.mjs";
|
|
4
4
|
import "./PostgresMigrator-DQaRxoaY.mjs";
|
|
5
5
|
import { PostgresObjectionMigrator } from "./PostgresObjectionMigrator-D_hCcrQu.mjs";
|
|
6
6
|
import { DatabaseConnection, DatabaseFixtures, ExtendedDatabaseFixtures, FixtureCreators, IsolationLevel, TestWithExtendedFixtures, TransactionWrapperOptions } from "./VitestTransactionIsolator-BvR19bYn.mjs";
|
|
@@ -118,5 +118,5 @@ declare function wrapVitestObjectionTransaction<Extended extends Record<string,
|
|
|
118
118
|
*/
|
|
119
119
|
declare function extendWithFixtures<Extended extends Record<string, unknown>, T extends ReturnType<TestAPI['extend']> = ReturnType<TestAPI['extend']>>(wrappedTest: T, fixtures: FixtureCreators<Knex.Transaction, Extended>): TestWithExtendedFixtures<Knex.Transaction<any, any[]>, Extended, T>;
|
|
120
120
|
//#endregion
|
|
121
|
-
export { DatabaseFixtures, ExtendedDatabaseFixtures, FakerFactory, FixtureCreators, IsolationLevel, ObjectionFactory, ObjectionTransactionOptions, PostgresObjectionMigrator, TestWithExtendedFixtures, TransactionWrapperOptions, VitestObjectionTransactionIsolator, extendWithFixtures, faker, wrapVitestObjectionTransaction };
|
|
121
|
+
export { DatabaseFixtures, ExtendedDatabaseFixtures, ExtractSeedAttrs, FactorySeed, FakerFactory, FixtureCreators, IsolationLevel, ObjectionFactory, ObjectionTransactionOptions, PostgresObjectionMigrator, TestWithExtendedFixtures, TransactionWrapperOptions, VitestObjectionTransactionIsolator, extendWithFixtures, faker, wrapVitestObjectionTransaction };
|
|
122
122
|
//# sourceMappingURL=objection.d.mts.map
|
package/dist/objection.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./Factory-
|
|
1
|
+
import "./Factory-BFVnMMCC.mjs";
|
|
2
2
|
import { faker } from "./faker-BGKYFoCT.mjs";
|
|
3
|
-
import { ObjectionFactory } from "./ObjectionFactory-
|
|
3
|
+
import { ObjectionFactory } from "./ObjectionFactory-QCJ7u0Ql.mjs";
|
|
4
4
|
import "./PostgresMigrator-DbuJGAVy.mjs";
|
|
5
5
|
import { PostgresObjectionMigrator } from "./PostgresObjectionMigrator-DPj2pOpX.mjs";
|
|
6
6
|
import { IsolationLevel, extendWithFixtures } from "./VitestTransactionIsolator-DQ7tLqgV.mjs";
|
package/dist/objection.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objection.mjs","names":["api: TestAPI","options: ObjectionTransactionOptions<Extended>","extendWithFixtures","wrappedTest: T","fixtures: FixtureCreators<Knex.Transaction, Extended>"],"sources":["../src/objection.ts"],"sourcesContent":["import type { Knex } from 'knex';\nimport type { TestAPI } from 'vitest';\nimport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nimport {\n type DatabaseConnection,\n type FixtureCreators,\n type IsolationLevel,\n extendWithFixtures as baseExtendWithFixtures,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific exports for test utilities.\n * Provides factory implementation for creating test data with Objection.js ORM\n * and transaction isolation for test suites.\n */\n\nexport { ObjectionFactory } from './ObjectionFactory';\nexport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nexport { IsolationLevel } from './VitestTransactionIsolator';\nexport { PostgresObjectionMigrator } from './PostgresObjectionMigrator';\nexport type {\n DatabaseFixtures,\n ExtendedDatabaseFixtures,\n FixtureCreators,\n TestWithExtendedFixtures,\n TransactionWrapperOptions,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific options for transaction wrapping.\n */\nexport interface ObjectionTransactionOptions<\n Extended extends Record<string, unknown> = {},\n> {\n /** Function that creates or returns a Knex database connection */\n connection: DatabaseConnection<Knex>;\n /** Optional setup function to run within the transaction before each test */\n setup?: (trx: Knex.Transaction) => Promise<void>;\n /** Transaction isolation level (defaults to REPEATABLE_READ) */\n isolationLevel?: IsolationLevel;\n /** Additional fixtures that depend on the transaction */\n fixtures?: FixtureCreators<Knex.Transaction, Extended>;\n}\n\n// Re-export faker and FakerFactory for type portability in declaration files\nexport { faker, type FakerFactory } from './faker';\n\n/**\n * Creates a wrapped Vitest test API with automatic transaction rollback for Objection.js.\n * Each test runs in an isolated database transaction that is rolled back after completion.\n * This ensures tests don't affect each other's data and run faster than truncating tables.\n *\n * @template Extended - Additional fixtures to provide\n * @param api - The Vitest test API (usually `test` from vitest)\n * @param options - Configuration options for transaction wrapping\n * @returns A wrapped test API that provides transaction isolation\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction } from '@geekmidas/testkit/objection';\n * import { knex } from './database';\n * import { User } from './models';\n *\n * // Create isolated test with automatic rollback\n * const isolatedTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * });\n *\n * // Use in tests - each test gets its own transaction\n * isolatedTest('should create user', async ({ trx }) => {\n * const user = await User.query(trx)\n * .insert({ name: 'Test User', email: 'test@example.com' });\n *\n * expect(user).toBeDefined();\n * });\n *\n * // With fixtures for factories\n * const it = wrapVitestObjectionTransaction<{ factory: Factory }>(test, {\n * connection: knex,\n * fixtures: {\n * factory: (trx) => new Factory(trx),\n * },\n * });\n *\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test' });\n * expect(user.id).toBeDefined();\n * });\n * ```\n */\nexport function wrapVitestObjectionTransaction<\n Extended extends Record<string, unknown> = {},\n>(api: TestAPI, options: ObjectionTransactionOptions<Extended>) {\n const wrapper = new VitestObjectionTransactionIsolator(api);\n\n return wrapper.wrapVitestWithTransaction(options);\n}\n\n/**\n * Extends an Objection.js transaction-wrapped test with additional fixtures.\n * Each fixture receives the transaction and can create dependencies like factories or repositories.\n *\n * @template Extended - The type of additional fixtures to provide\n * @param wrappedTest - The base wrapped test from wrapVitestObjectionTransaction\n * @param fixtures - Object mapping fixture names to creator functions\n * @returns An extended test API with both trx and the additional fixtures\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction, extendWithFixtures, ObjectionFactory } from '@geekmidas/testkit/objection';\n * import { User } from './models';\n *\n * // Define your builders\n * const builders = {\n * user: ObjectionFactory.createBuilder(User, ({ faker }) => ({\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * })),\n * };\n *\n * // Create base wrapped test\n * const baseTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * setup: createTestTables,\n * });\n *\n * // Extend with fixtures - each fixture receives the transaction\n * const it = extendWithFixtures<{ factory: ObjectionFactory<typeof builders, {}> }>(\n * baseTest,\n * {\n * factory: (trx) => new ObjectionFactory(builders, {}, trx),\n * }\n * );\n *\n * // Use in tests - both trx and factory are available\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test User' });\n * expect(user.id).toBeDefined();\n *\n * // Verify in database\n * const found = await User.query(trx).findById(user.id);\n * expect(found?.name).toBe('Test User');\n * });\n * ```\n */\nexport function extendWithFixtures<\n Extended extends Record<string, unknown>,\n T extends ReturnType<TestAPI['extend']> = ReturnType<TestAPI['extend']>,\n>(wrappedTest: T, fixtures: FixtureCreators<Knex.Transaction, Extended>) {\n return baseExtendWithFixtures<Knex.Transaction, Extended, T>(\n wrappedTest,\n fixtures,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"objection.mjs","names":["api: TestAPI","options: ObjectionTransactionOptions<Extended>","extendWithFixtures","wrappedTest: T","fixtures: FixtureCreators<Knex.Transaction, Extended>"],"sources":["../src/objection.ts"],"sourcesContent":["import type { Knex } from 'knex';\nimport type { TestAPI } from 'vitest';\nimport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nimport {\n type DatabaseConnection,\n type FixtureCreators,\n type IsolationLevel,\n extendWithFixtures as baseExtendWithFixtures,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific exports for test utilities.\n * Provides factory implementation for creating test data with Objection.js ORM\n * and transaction isolation for test suites.\n */\n\nexport { ObjectionFactory } from './ObjectionFactory';\nexport type { ExtractSeedAttrs, FactorySeed } from './Factory';\nexport { VitestObjectionTransactionIsolator } from './VitestObjectionTransactionIsolator';\nexport { IsolationLevel } from './VitestTransactionIsolator';\nexport { PostgresObjectionMigrator } from './PostgresObjectionMigrator';\nexport type {\n DatabaseFixtures,\n ExtendedDatabaseFixtures,\n FixtureCreators,\n TestWithExtendedFixtures,\n TransactionWrapperOptions,\n} from './VitestTransactionIsolator';\n\n/**\n * Objection.js-specific options for transaction wrapping.\n */\nexport interface ObjectionTransactionOptions<\n Extended extends Record<string, unknown> = {},\n> {\n /** Function that creates or returns a Knex database connection */\n connection: DatabaseConnection<Knex>;\n /** Optional setup function to run within the transaction before each test */\n setup?: (trx: Knex.Transaction) => Promise<void>;\n /** Transaction isolation level (defaults to REPEATABLE_READ) */\n isolationLevel?: IsolationLevel;\n /** Additional fixtures that depend on the transaction */\n fixtures?: FixtureCreators<Knex.Transaction, Extended>;\n}\n\n// Re-export faker and FakerFactory for type portability in declaration files\nexport { faker, type FakerFactory } from './faker';\n\n/**\n * Creates a wrapped Vitest test API with automatic transaction rollback for Objection.js.\n * Each test runs in an isolated database transaction that is rolled back after completion.\n * This ensures tests don't affect each other's data and run faster than truncating tables.\n *\n * @template Extended - Additional fixtures to provide\n * @param api - The Vitest test API (usually `test` from vitest)\n * @param options - Configuration options for transaction wrapping\n * @returns A wrapped test API that provides transaction isolation\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction } from '@geekmidas/testkit/objection';\n * import { knex } from './database';\n * import { User } from './models';\n *\n * // Create isolated test with automatic rollback\n * const isolatedTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * });\n *\n * // Use in tests - each test gets its own transaction\n * isolatedTest('should create user', async ({ trx }) => {\n * const user = await User.query(trx)\n * .insert({ name: 'Test User', email: 'test@example.com' });\n *\n * expect(user).toBeDefined();\n * });\n *\n * // With fixtures for factories\n * const it = wrapVitestObjectionTransaction<{ factory: Factory }>(test, {\n * connection: knex,\n * fixtures: {\n * factory: (trx) => new Factory(trx),\n * },\n * });\n *\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test' });\n * expect(user.id).toBeDefined();\n * });\n * ```\n */\nexport function wrapVitestObjectionTransaction<\n Extended extends Record<string, unknown> = {},\n>(api: TestAPI, options: ObjectionTransactionOptions<Extended>) {\n const wrapper = new VitestObjectionTransactionIsolator(api);\n\n return wrapper.wrapVitestWithTransaction(options);\n}\n\n/**\n * Extends an Objection.js transaction-wrapped test with additional fixtures.\n * Each fixture receives the transaction and can create dependencies like factories or repositories.\n *\n * @template Extended - The type of additional fixtures to provide\n * @param wrappedTest - The base wrapped test from wrapVitestObjectionTransaction\n * @param fixtures - Object mapping fixture names to creator functions\n * @returns An extended test API with both trx and the additional fixtures\n *\n * @example\n * ```typescript\n * import { test } from 'vitest';\n * import { wrapVitestObjectionTransaction, extendWithFixtures, ObjectionFactory } from '@geekmidas/testkit/objection';\n * import { User } from './models';\n *\n * // Define your builders\n * const builders = {\n * user: ObjectionFactory.createBuilder(User, ({ faker }) => ({\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * })),\n * };\n *\n * // Create base wrapped test\n * const baseTest = wrapVitestObjectionTransaction(test, {\n * connection: knex,\n * setup: createTestTables,\n * });\n *\n * // Extend with fixtures - each fixture receives the transaction\n * const it = extendWithFixtures<{ factory: ObjectionFactory<typeof builders, {}> }>(\n * baseTest,\n * {\n * factory: (trx) => new ObjectionFactory(builders, {}, trx),\n * }\n * );\n *\n * // Use in tests - both trx and factory are available\n * it('should create user with factory', async ({ trx, factory }) => {\n * const user = await factory.insert('user', { name: 'Test User' });\n * expect(user.id).toBeDefined();\n *\n * // Verify in database\n * const found = await User.query(trx).findById(user.id);\n * expect(found?.name).toBe('Test User');\n * });\n * ```\n */\nexport function extendWithFixtures<\n Extended extends Record<string, unknown>,\n T extends ReturnType<TestAPI['extend']> = ReturnType<TestAPI['extend']>,\n>(wrappedTest: T, fixtures: FixtureCreators<Knex.Transaction, Extended>) {\n return baseExtendWithFixtures<Knex.Transaction, Extended, T>(\n wrappedTest,\n fixtures,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4FA,SAAgB,+BAEdA,KAAcC,SAAgD;CAC9D,MAAM,UAAU,IAAI,mCAAmC;AAEvD,QAAO,QAAQ,0BAA0B,QAAQ;AAClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDD,SAAgBC,qBAGdC,aAAgBC,UAAuD;AACvE,QAAO,mBACL,aACA,SACD;AACF"}
|
package/dist/os/directory.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DirectoryFixtures, itWithDir } from "../directory-
|
|
1
|
+
import { DirectoryFixtures, itWithDir } from "../directory-Mi7tdOuD.cjs";
|
|
2
2
|
export { DirectoryFixtures, itWithDir };
|
package/dist/os/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { itWithDir } from "../directory-
|
|
1
|
+
import { itWithDir } from "../directory-Mi7tdOuD.cjs";
|
|
2
2
|
export { itWithDir };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/testkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
"types": "./dist/better-auth.d.ts",
|
|
44
44
|
"import": "./dist/better-auth.mjs",
|
|
45
45
|
"require": "./dist/better-auth.cjs"
|
|
46
|
+
},
|
|
47
|
+
"./benchmark": {
|
|
48
|
+
"types": "./dist/benchmark.d.ts",
|
|
49
|
+
"import": "./dist/benchmark.mjs",
|
|
50
|
+
"require": "./dist/benchmark.cjs"
|
|
46
51
|
}
|
|
47
52
|
},
|
|
48
53
|
"dependencies": {
|
package/src/Factory.ts
CHANGED
|
@@ -39,7 +39,7 @@ export abstract class Factory<
|
|
|
39
39
|
*
|
|
40
40
|
* @example
|
|
41
41
|
* ```typescript
|
|
42
|
-
* const userWithPostsSeed = Factory.createSeed(async (attrs, factory, db) => {
|
|
42
|
+
* const userWithPostsSeed = Factory.createSeed(async ({ attrs, factory, db }) => {
|
|
43
43
|
* const user = await factory.insert('user', attrs);
|
|
44
44
|
* return user;
|
|
45
45
|
* });
|
|
@@ -86,7 +86,7 @@ export abstract class Factory<
|
|
|
86
86
|
*/
|
|
87
87
|
abstract seed<K extends keyof Seeds>(
|
|
88
88
|
seedName: K,
|
|
89
|
-
attrs?:
|
|
89
|
+
attrs?: ExtractSeedAttrs<Seeds[K]>,
|
|
90
90
|
): ReturnType<Seeds[K]>;
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -133,15 +133,16 @@ export type MixedFactoryBuilder<
|
|
|
133
133
|
* @template Result - The type of object returned by the seed
|
|
134
134
|
* @template DB - The database connection type (Kysely, Knex, etc.)
|
|
135
135
|
*
|
|
136
|
-
* @param
|
|
137
|
-
* @param
|
|
138
|
-
* @param
|
|
136
|
+
* @param context - Object containing attrs, factory, and db
|
|
137
|
+
* @param context.attrs - Configuration attributes for the seed
|
|
138
|
+
* @param context.factory - The factory instance for creating records
|
|
139
|
+
* @param context.db - The database connection
|
|
139
140
|
* @returns A promise resolving to the seed result
|
|
140
141
|
*
|
|
141
142
|
* @example
|
|
142
143
|
* ```typescript
|
|
143
144
|
* const userWithPostsSeed: FactorySeed<{ postCount?: number }, Factory, User, DB> =
|
|
144
|
-
* async (attrs, factory, db) => {
|
|
145
|
+
* async ({ attrs, factory, db }) => {
|
|
145
146
|
* const user = await factory.insert('user', attrs);
|
|
146
147
|
* const postCount = attrs.postCount || 3;
|
|
147
148
|
*
|
|
@@ -153,8 +154,21 @@ export type MixedFactoryBuilder<
|
|
|
153
154
|
* };
|
|
154
155
|
* ```
|
|
155
156
|
*/
|
|
156
|
-
export type FactorySeed<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
export type FactorySeed<
|
|
158
|
+
Attrs = any,
|
|
159
|
+
Factory = any,
|
|
160
|
+
Result = any,
|
|
161
|
+
DB = any,
|
|
162
|
+
> = (context: { attrs: Attrs; factory: Factory; db: DB }) => Promise<Result>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Helper type to extract the Attrs type from a FactorySeed function.
|
|
166
|
+
* Used internally by Factory implementations to correctly type the seed method parameters.
|
|
167
|
+
*/
|
|
168
|
+
export type ExtractSeedAttrs<T> = T extends (context: {
|
|
169
|
+
attrs: infer A;
|
|
170
|
+
factory: any;
|
|
171
|
+
db: any;
|
|
172
|
+
}) => any
|
|
173
|
+
? A
|
|
174
|
+
: never;
|
package/src/KyselyFactory.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
Kysely,
|
|
5
5
|
Selectable,
|
|
6
6
|
} from 'kysely';
|
|
7
|
-
import { Factory, type FactorySeed } from './Factory.ts';
|
|
7
|
+
import { type ExtractSeedAttrs, Factory, type FactorySeed } from './Factory.ts';
|
|
8
8
|
import { type FakerFactory, faker } from './faker.ts';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -55,8 +55,21 @@ export class KyselyFactory<
|
|
|
55
55
|
* Inherits from the base Factory class implementation.
|
|
56
56
|
*
|
|
57
57
|
* @template Seed - The seed function type
|
|
58
|
-
* @param seedFn - The seed function to wrap
|
|
58
|
+
* @param seedFn - The seed function to wrap (receives { attrs, factory, db } object)
|
|
59
59
|
* @returns The same seed function with proper typing
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const seeds = {
|
|
64
|
+
* userWithPosts: KyselyFactory.createSeed(
|
|
65
|
+
* async ({ attrs, factory }) => {
|
|
66
|
+
* const user = await factory.insert('user', attrs);
|
|
67
|
+
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
68
|
+
* return user;
|
|
69
|
+
* },
|
|
70
|
+
* ),
|
|
71
|
+
* };
|
|
72
|
+
* ```
|
|
60
73
|
*/
|
|
61
74
|
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed {
|
|
62
75
|
return Factory.createSeed(seedFn);
|
|
@@ -359,7 +372,7 @@ export class KyselyFactory<
|
|
|
359
372
|
*/
|
|
360
373
|
seed<K extends keyof Seeds>(
|
|
361
374
|
seedName: K,
|
|
362
|
-
attrs?:
|
|
375
|
+
attrs?: ExtractSeedAttrs<Seeds[K]>,
|
|
363
376
|
): ReturnType<Seeds[K]> {
|
|
364
377
|
if (!(seedName in this.seeds)) {
|
|
365
378
|
throw new Error(
|
|
@@ -369,6 +382,10 @@ export class KyselyFactory<
|
|
|
369
382
|
);
|
|
370
383
|
}
|
|
371
384
|
|
|
372
|
-
return this.seeds[seedName](
|
|
385
|
+
return this.seeds[seedName]({
|
|
386
|
+
attrs: attrs || {},
|
|
387
|
+
factory: this,
|
|
388
|
+
db: this.db,
|
|
389
|
+
});
|
|
373
390
|
}
|
|
374
391
|
}
|
package/src/ObjectionFactory.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Knex } from 'knex';
|
|
2
2
|
import type { Model } from 'objection';
|
|
3
|
-
import { Factory, type FactorySeed } from './Factory.ts';
|
|
3
|
+
import { type ExtractSeedAttrs, Factory, type FactorySeed } from './Factory.ts';
|
|
4
4
|
import { type FakerFactory, faker } from './faker.ts';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -48,8 +48,21 @@ export class ObjectionFactory<
|
|
|
48
48
|
* Inherits from the base Factory class implementation.
|
|
49
49
|
*
|
|
50
50
|
* @template Seed - The seed function type
|
|
51
|
-
* @param seedFn - The seed function to wrap
|
|
51
|
+
* @param seedFn - The seed function to wrap (receives { attrs, factory, db } object)
|
|
52
52
|
* @returns The same seed function with proper typing
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const seeds = {
|
|
57
|
+
* userWithPosts: ObjectionFactory.createSeed(
|
|
58
|
+
* async ({ attrs, factory }) => {
|
|
59
|
+
* const user = await factory.insert('user', attrs);
|
|
60
|
+
* await factory.insertMany(3, 'post', { userId: user.id });
|
|
61
|
+
* return user;
|
|
62
|
+
* },
|
|
63
|
+
* ),
|
|
64
|
+
* };
|
|
65
|
+
* ```
|
|
53
66
|
*/
|
|
54
67
|
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed {
|
|
55
68
|
return Factory.createSeed(seedFn);
|
|
@@ -381,7 +394,7 @@ export class ObjectionFactory<
|
|
|
381
394
|
*/
|
|
382
395
|
seed<K extends keyof Seeds>(
|
|
383
396
|
seedName: K,
|
|
384
|
-
attrs?:
|
|
397
|
+
attrs?: ExtractSeedAttrs<Seeds[K]>,
|
|
385
398
|
): ReturnType<Seeds[K]> {
|
|
386
399
|
if (!(seedName in this.seeds)) {
|
|
387
400
|
throw new Error(
|
|
@@ -391,6 +404,10 @@ export class ObjectionFactory<
|
|
|
391
404
|
);
|
|
392
405
|
}
|
|
393
406
|
|
|
394
|
-
return this.seeds[seedName](
|
|
407
|
+
return this.seeds[seedName]({
|
|
408
|
+
attrs: attrs || {},
|
|
409
|
+
factory: this,
|
|
410
|
+
db: this.db,
|
|
411
|
+
});
|
|
395
412
|
}
|
|
396
413
|
}
|
|
@@ -46,7 +46,11 @@ describe('Factory', () => {
|
|
|
46
46
|
|
|
47
47
|
describe('createSeed static method', () => {
|
|
48
48
|
it('should return the seed function unchanged', () => {
|
|
49
|
-
const seedFn = async (
|
|
49
|
+
const seedFn = async ({
|
|
50
|
+
attrs,
|
|
51
|
+
factory,
|
|
52
|
+
db,
|
|
53
|
+
}: { attrs: any; factory: any; db: any }) => {
|
|
50
54
|
return { id: 1, name: 'test' };
|
|
51
55
|
};
|
|
52
56
|
|
|
@@ -57,12 +61,14 @@ describe('Factory', () => {
|
|
|
57
61
|
});
|
|
58
62
|
|
|
59
63
|
it('should work with different seed function signatures', () => {
|
|
60
|
-
const simpleSeed = () =>
|
|
61
|
-
const complexSeed = async (
|
|
62
|
-
attrs
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
const simpleSeed = async () => ({ simple: true });
|
|
65
|
+
const complexSeed = async ({
|
|
66
|
+
attrs,
|
|
67
|
+
}: {
|
|
68
|
+
attrs: { name: string };
|
|
69
|
+
factory: any;
|
|
70
|
+
db: any;
|
|
71
|
+
}) => {
|
|
66
72
|
return { name: attrs.name, created: true };
|
|
67
73
|
};
|
|
68
74
|
|
|
@@ -124,8 +130,8 @@ describe('Factory', () => {
|
|
|
124
130
|
});
|
|
125
131
|
|
|
126
132
|
it('should properly type FactorySeed', () => {
|
|
127
|
-
// Test that FactorySeed requires async return
|
|
128
|
-
const seed: FactorySeed = async (attrs, factory, db) => ({
|
|
133
|
+
// Test that FactorySeed requires async return with object parameter
|
|
134
|
+
const seed: FactorySeed = async ({ attrs, factory, db }) => ({
|
|
129
135
|
seeded: true,
|
|
130
136
|
});
|
|
131
137
|
|
|
@@ -155,7 +161,7 @@ describe('Factory types', () => {
|
|
|
155
161
|
TestFactory,
|
|
156
162
|
{ created: number },
|
|
157
163
|
any
|
|
158
|
-
> = async (attrs
|
|
164
|
+
> = async ({ attrs }) => {
|
|
159
165
|
return { created: attrs.count };
|
|
160
166
|
};
|
|
161
167
|
|
|
@@ -279,7 +279,10 @@ describe('KyselyFactory', () => {
|
|
|
279
279
|
|
|
280
280
|
const seeds = {
|
|
281
281
|
createAdminUser: KyselyFactory.createSeed(
|
|
282
|
-
async (
|
|
282
|
+
async ({
|
|
283
|
+
attrs,
|
|
284
|
+
factory,
|
|
285
|
+
}: { attrs: { name?: string }; factory: any; db: any }) => {
|
|
283
286
|
return await factory.insert('user', {
|
|
284
287
|
name: attrs.name || 'Admin User',
|
|
285
288
|
email: 'admin@example.com',
|
|
@@ -319,11 +322,14 @@ describe('KyselyFactory', () => {
|
|
|
319
322
|
|
|
320
323
|
const seeds = {
|
|
321
324
|
createCustomUser: KyselyFactory.createSeed(
|
|
322
|
-
async (
|
|
323
|
-
attrs
|
|
324
|
-
factory
|
|
325
|
-
|
|
326
|
-
|
|
325
|
+
async ({
|
|
326
|
+
attrs,
|
|
327
|
+
factory,
|
|
328
|
+
}: {
|
|
329
|
+
attrs: { name: string; email: string };
|
|
330
|
+
factory: any;
|
|
331
|
+
db: any;
|
|
332
|
+
}) => {
|
|
327
333
|
return await factory.insert('user', attrs);
|
|
328
334
|
},
|
|
329
335
|
),
|
|
@@ -216,20 +216,22 @@ describe('ObjectionFactory', () => {
|
|
|
216
216
|
|
|
217
217
|
const builders = { user: userBuilder };
|
|
218
218
|
|
|
219
|
-
const createAdminSeed = async (attrs: any, factory: any, db: Knex) => {
|
|
220
|
-
return await factory.insert('user', {
|
|
221
|
-
name: attrs.name || 'Admin User',
|
|
222
|
-
});
|
|
223
|
-
};
|
|
224
|
-
|
|
225
219
|
const seeds = {
|
|
226
|
-
createAdmin:
|
|
220
|
+
createAdmin: ObjectionFactory.createSeed(
|
|
221
|
+
async ({
|
|
222
|
+
attrs,
|
|
223
|
+
factory,
|
|
224
|
+
}: { attrs: { name?: string }; factory: any; db: Knex }) => {
|
|
225
|
+
return await factory.insert('user', {
|
|
226
|
+
name: attrs.name || 'Admin User',
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
),
|
|
227
230
|
};
|
|
228
231
|
|
|
229
232
|
const factory = new ObjectionFactory(builders, seeds, trx);
|
|
230
233
|
|
|
231
|
-
const
|
|
232
|
-
const result = await factory.seed('createAdmin', attrs);
|
|
234
|
+
const result = await factory.seed('createAdmin', { name: 'Super Admin' });
|
|
233
235
|
|
|
234
236
|
expect(result).toBeInstanceOf(User);
|
|
235
237
|
expect(result.name).toBe('Super Admin');
|
|
@@ -247,15 +249,15 @@ describe('ObjectionFactory', () => {
|
|
|
247
249
|
|
|
248
250
|
const builders = { user: userBuilder };
|
|
249
251
|
|
|
250
|
-
const createAdminSeed = async (attrs: any, factory: any, db: Knex) => {
|
|
251
|
-
return await factory.insert('user', {
|
|
252
|
-
name: 'Default Admin',
|
|
253
|
-
role: 'admin',
|
|
254
|
-
});
|
|
255
|
-
};
|
|
256
|
-
|
|
257
252
|
const seeds = {
|
|
258
|
-
createAdmin:
|
|
253
|
+
createAdmin: ObjectionFactory.createSeed(
|
|
254
|
+
async ({ factory }: { attrs: any; factory: any; db: Knex }) => {
|
|
255
|
+
return await factory.insert('user', {
|
|
256
|
+
name: 'Default Admin',
|
|
257
|
+
role: 'admin',
|
|
258
|
+
});
|
|
259
|
+
},
|
|
260
|
+
),
|
|
259
261
|
};
|
|
260
262
|
|
|
261
263
|
const factory = new ObjectionFactory(builders, seeds, trx);
|
|
@@ -283,25 +285,28 @@ describe('ObjectionFactory', () => {
|
|
|
283
285
|
|
|
284
286
|
const builders = { user: userBuilder };
|
|
285
287
|
|
|
286
|
-
|
|
287
|
-
attrs: any,
|
|
288
|
-
passedFactory: any,
|
|
289
|
-
passedDb: Knex,
|
|
290
|
-
) => {
|
|
291
|
-
// Verify that factory and db are passed correctly
|
|
292
|
-
expect(passedFactory).toBe(factory);
|
|
293
|
-
expect(passedDb).toBe(trx);
|
|
294
|
-
|
|
295
|
-
return await passedFactory.insert('user', {
|
|
296
|
-
name: `Complex ${attrs.data}`,
|
|
297
|
-
});
|
|
298
|
-
};
|
|
288
|
+
let factoryRef: any;
|
|
299
289
|
|
|
300
290
|
const seeds = {
|
|
301
|
-
complexSeed
|
|
291
|
+
complexSeed: ObjectionFactory.createSeed(
|
|
292
|
+
async ({
|
|
293
|
+
attrs,
|
|
294
|
+
factory: passedFactory,
|
|
295
|
+
db: passedDb,
|
|
296
|
+
}: { attrs: { data: string }; factory: any; db: Knex }) => {
|
|
297
|
+
// Verify that factory and db are passed correctly
|
|
298
|
+
expect(passedFactory).toBe(factoryRef);
|
|
299
|
+
expect(passedDb).toBe(trx);
|
|
300
|
+
|
|
301
|
+
return await passedFactory.insert('user', {
|
|
302
|
+
name: `Complex ${attrs.data}`,
|
|
303
|
+
});
|
|
304
|
+
},
|
|
305
|
+
),
|
|
302
306
|
};
|
|
303
307
|
|
|
304
308
|
const factory = new ObjectionFactory(builders, seeds, trx);
|
|
309
|
+
factoryRef = factory;
|
|
305
310
|
|
|
306
311
|
const result = await factory.seed('complexSeed', { data: 'test' });
|
|
307
312
|
|
|
@@ -310,7 +315,7 @@ describe('ObjectionFactory', () => {
|
|
|
310
315
|
});
|
|
311
316
|
|
|
312
317
|
it('should return the seed function unchanged', () => {
|
|
313
|
-
const seedFn = async (attrs: any
|
|
318
|
+
const seedFn = async ({ attrs }: { attrs: any; factory: any; db: any }) => {
|
|
314
319
|
return { id: 1, name: 'test' };
|
|
315
320
|
};
|
|
316
321
|
|
|
@@ -481,12 +486,12 @@ describe('ObjectionFactory', () => {
|
|
|
481
486
|
});
|
|
482
487
|
|
|
483
488
|
it('should handle seed function errors gracefully', async ({ trx }) => {
|
|
484
|
-
const failingSeed = async (attrs: any, factory: any, db: Knex) => {
|
|
485
|
-
throw new Error('Seed failed');
|
|
486
|
-
};
|
|
487
|
-
|
|
488
489
|
const seeds = {
|
|
489
|
-
failingSeed
|
|
490
|
+
failingSeed: ObjectionFactory.createSeed(
|
|
491
|
+
async ({}: { attrs: any; factory: any; db: Knex }) => {
|
|
492
|
+
throw new Error('Seed failed');
|
|
493
|
+
},
|
|
494
|
+
),
|
|
490
495
|
};
|
|
491
496
|
|
|
492
497
|
const factory = new ObjectionFactory({}, seeds, trx);
|
|
@@ -508,18 +513,22 @@ describe('ObjectionFactory', () => {
|
|
|
508
513
|
});
|
|
509
514
|
};
|
|
510
515
|
|
|
511
|
-
const adminSeed = async (
|
|
512
|
-
attrs: { isSuper?: boolean },
|
|
513
|
-
factory: any,
|
|
514
|
-
db: Knex,
|
|
515
|
-
) => {
|
|
516
|
-
return factory.insert('user', {
|
|
517
|
-
name: 'Admin',
|
|
518
|
-
});
|
|
519
|
-
};
|
|
520
|
-
|
|
521
516
|
const builders = { user: userBuilder };
|
|
522
|
-
const seeds = {
|
|
517
|
+
const seeds = {
|
|
518
|
+
admin: ObjectionFactory.createSeed(
|
|
519
|
+
async ({
|
|
520
|
+
factory,
|
|
521
|
+
}: {
|
|
522
|
+
attrs: { isSuper?: boolean };
|
|
523
|
+
factory: any;
|
|
524
|
+
db: Knex;
|
|
525
|
+
}) => {
|
|
526
|
+
return factory.insert('user', {
|
|
527
|
+
name: 'Admin',
|
|
528
|
+
});
|
|
529
|
+
},
|
|
530
|
+
),
|
|
531
|
+
};
|
|
523
532
|
|
|
524
533
|
// This should compile without type errors
|
|
525
534
|
const factory = new ObjectionFactory(builders, seeds, trx);
|
|
@@ -192,10 +192,14 @@ describe('Testkit Integration Tests', () => {
|
|
|
192
192
|
// Create complex seeds
|
|
193
193
|
const seeds = {
|
|
194
194
|
blogWithAdminAndPosts: KyselyFactory.createSeed(
|
|
195
|
-
async (
|
|
196
|
-
attrs
|
|
197
|
-
factory
|
|
198
|
-
|
|
195
|
+
async ({
|
|
196
|
+
attrs,
|
|
197
|
+
factory,
|
|
198
|
+
}: {
|
|
199
|
+
attrs: { postCount?: number };
|
|
200
|
+
factory: KyselyFactory<TestDatabase, typeof builders, {}>;
|
|
201
|
+
db: any;
|
|
202
|
+
}) => {
|
|
199
203
|
// Create admin user
|
|
200
204
|
const admin = await factory.insert('user', {
|
|
201
205
|
name: 'Blog Admin',
|
|
@@ -229,10 +233,14 @@ describe('Testkit Integration Tests', () => {
|
|
|
229
233
|
),
|
|
230
234
|
|
|
231
235
|
usersWithPosts: KyselyFactory.createSeed(
|
|
232
|
-
async (
|
|
233
|
-
attrs
|
|
234
|
-
factory
|
|
235
|
-
|
|
236
|
+
async ({
|
|
237
|
+
attrs,
|
|
238
|
+
factory,
|
|
239
|
+
}: {
|
|
240
|
+
attrs: { userCount?: number; postsPerUser?: number };
|
|
241
|
+
factory: KyselyFactory<TestDatabase, typeof builders, {}>;
|
|
242
|
+
db: any;
|
|
243
|
+
}) => {
|
|
236
244
|
const userCount = attrs.userCount || 2;
|
|
237
245
|
const postsPerUser = attrs.postsPerUser || 2;
|
|
238
246
|
|
package/src/benchmark.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates an array of test records for benchmark data sets.
|
|
3
|
+
*
|
|
4
|
+
* @param count - Number of records to generate
|
|
5
|
+
* @returns Array of test data objects
|
|
6
|
+
*/
|
|
7
|
+
export function generateTestData(
|
|
8
|
+
count: number,
|
|
9
|
+
): Array<{ id: string; name: string; value: number }> {
|
|
10
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
11
|
+
id: `id-${i}`,
|
|
12
|
+
name: `Item ${i}`,
|
|
13
|
+
value: Math.random() * 1000,
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generates unique keys for cache benchmarks to avoid collisions.
|
|
19
|
+
*
|
|
20
|
+
* @param prefix - Key prefix
|
|
21
|
+
* @param count - Number of keys to generate
|
|
22
|
+
* @returns Array of unique cache keys
|
|
23
|
+
*/
|
|
24
|
+
export function generateCacheKeys(prefix: string, count: number): string[] {
|
|
25
|
+
return Array.from({ length: count }, (_, i) => `${prefix}:${i}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generates IP addresses for rate limit benchmarks.
|
|
30
|
+
*
|
|
31
|
+
* @param count - Number of IPs to generate
|
|
32
|
+
* @param subnet - Subnet prefix (default: '192.168.1')
|
|
33
|
+
* @returns Array of IP addresses
|
|
34
|
+
*/
|
|
35
|
+
export function generateIpAddresses(
|
|
36
|
+
count: number,
|
|
37
|
+
subnet: string = '192.168.1',
|
|
38
|
+
): string[] {
|
|
39
|
+
return Array.from({ length: count }, (_, i) => `${subnet}.${i % 256}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a random IP address for rate limit benchmarks.
|
|
44
|
+
*/
|
|
45
|
+
export function randomIpAddress(): string {
|
|
46
|
+
const octet = () => Math.floor(Math.random() * 256);
|
|
47
|
+
return `${octet()}.${octet()}.${octet()}.${octet()}`;
|
|
48
|
+
}
|
package/src/kysely.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
export { KyselyFactory } from './KyselyFactory';
|
|
17
|
+
export type { ExtractSeedAttrs, FactorySeed } from './Factory';
|
|
17
18
|
export { PostgresKyselyMigrator } from './PostgresKyselyMigrator';
|
|
18
19
|
export { VitestKyselyTransactionIsolator } from './VitestKyselyTransactionIsolator';
|
|
19
20
|
export { IsolationLevel } from './VitestTransactionIsolator';
|