@stacksjs/testing 0.74.27 → 0.74.28

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.
@@ -0,0 +1,56 @@
1
+ export declare function setupDatabase(): Promise<void>;
2
+ export declare function refreshDatabase(): Promise<void>;
3
+ export declare function truncateMysql(): Promise<void>;
4
+ export declare function truncateSqlite(): Promise<void>;
5
+ /**
6
+ * Snapshot-based SQLite reset. The very first call falls through to the
7
+ * legacy `truncateSqlite()` path (drop, recopy models, migrate) AND
8
+ * captures the resulting empty-but-migrated DB to a `.snapshot` file.
9
+ * Every subsequent call just copies that snapshot back over the live
10
+ * file — orders of magnitude faster than running migrations end to end
11
+ * for each test, and dramatically cheaper than the per-test model file
12
+ * recopy.
13
+ *
14
+ * The snapshot is invalidated automatically when:
15
+ * - any model file is newer than the snapshot
16
+ * - any migration file is newer than the snapshot
17
+ *
18
+ * — re-capturing in those cases keeps schema changes correct without
19
+ * the user remembering to clear it.
20
+ */
21
+ export declare function truncateSqliteFast(): Promise<void>;
22
+ /**
23
+ * Wrap each test in a database transaction that rolls back on completion.
24
+ *
25
+ * The fastest possible test isolation: instead of dropping/recopying
26
+ * the schema between tests, every test runs inside `BEGIN; … ROLLBACK;`
27
+ * so the row state at the end of one test is invisible to the next
28
+ * (and to the `--fresh` snapshot path entirely).
29
+ *
30
+ * Caveats — read these before reaching for this helper:
31
+ * 1. Code under test that issues its own `BEGIN`/`COMMIT` will commit
32
+ * against the outer transaction and the rollback won't undo it
33
+ * (Postgres doesn't support nested transactions natively).
34
+ * 2. Multi-statement tests that test "commit visibility across
35
+ * connections" need the slower `refreshDatabase()` path because
36
+ * the rolled-back transaction never reached the disk.
37
+ * 3. SQLite WAL mode is required for concurrent connections to see
38
+ * each other within the same DB file; the framework configures
39
+ * this by default.
40
+ *
41
+ * Use as a `beforeEach`/`afterEach` pair from your test setup:
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * import { beforeEach, afterEach } from 'bun:test'
46
+ * import { useTransactionalTests } from '@stacksjs/testing/database'
47
+ *
48
+ * const tx = useTransactionalTests()
49
+ * beforeEach(tx.begin)
50
+ * afterEach(tx.rollback)
51
+ * ```
52
+ */
53
+ export declare function useTransactionalTests(): {
54
+ begin: () => Promise<void>
55
+ rollback: () => Promise<void>
56
+ };
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{config as l}from"@stacksjs/config";import{copyModelFiles as w,db as a,deleteFrameworkModels as y,dropSqliteTables as h,fetchSqliteFile as c,fetchTables as T,migrateAuthTables as S,migrateNotificationTables as g,migrateRbacTables as P,migrateTraitTables as E,ensureUtcDatetimeColumns as x,ensureUtcTimestampDefaults as A,runDatabaseMigration as u}from"@stacksjs/database";import{path as o}from"@stacksjs/path";import{fs as i,globSync as f}from"@stacksjs/storage";function m(){return l.database?.default||""}var r=null;function M(){if(r)return r;return r=`${c()}.snapshot`,r}async function d(){let t=[["auth",S],["notification",g],["RBAC",P],["trait",E],["utc-datetime",x],["utc-defaults",A]];for(let[e,n]of t)try{let s=await n();if(!s.success)console.error(`[testing] Failed to migrate ${e} tables: ${s.error}`)}catch(s){console.error(`[testing] Failed to migrate ${e} tables:`,s)}}async function v(){let t=`${l.database?.connections?.mysql?.name??"stacks"}_testing`;if(m()==="mysql")await a.unsafe(`CREATE DATABASE IF NOT EXISTS ${t}`).execute(),await u(),await d()}async function _(){await v();let t=m();if(t==="mysql")await F();if(t==="sqlite")await q()}async function F(){let t=await T();await a.unsafe("SET FOREIGN_KEY_CHECKS = 0").execute();try{for(let e of t)await a.unsafe(`TRUNCATE TABLE ${e}`).execute()}finally{await a.unsafe("SET FOREIGN_KEY_CHECKS = 1").execute()}}async function k(){let t=c();if(!i.existsSync(t))await Bun.$`touch ${t}`;await h(),await y();let e=f([o.userModelsPath("*.ts"),o.storagePath("framework/defaults/app/Models/**/*.ts")],{absolute:!0});for(let n of e)await w(n);await u(),await d()}async function q(){let t=c(),e=M();if((()=>{if(!i.existsSync(e))return!0;let s=i.statSync(e).mtimeMs,p=f([o.userModelsPath("*.ts"),o.storagePath("framework/defaults/app/Models/**/*.ts"),o.userMigrationsPath("*.ts")],{absolute:!0});for(let b of p)try{if(i.statSync(b).mtimeMs>s)return!0}catch{}return!1})()){await k();try{await a.unsafe("PRAGMA wal_checkpoint(TRUNCATE)").execute(),i.copyFileSync(t,e)}catch{}return}i.copyFileSync(e,t)}function D(){let t=null;return{begin:async()=>{let e=`stacks_test_${Date.now()}_${Math.floor(Math.random()*1e6)}`;await a.unsafe(`SAVEPOINT ${e}`).execute(),t={rollback:async()=>{await a.unsafe(`ROLLBACK TO SAVEPOINT ${e}`).execute(),await a.unsafe(`RELEASE SAVEPOINT ${e}`).execute()}}},rollback:async()=>{if(!t)return;try{await t.rollback()}finally{t=null}}}}export{_ as refreshDatabase,v as setupDatabase,F as truncateMysql,k as truncateSqlite,q as truncateSqliteFast,D as useTransactionalTests};
@@ -0,0 +1,3 @@
1
+ export declare function launchServer(): Promise<void>;
2
+ export declare function createStacksTable(): Promise<void>;
3
+ export declare function deleteStacksTable(): Promise<void>;
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import r from"process";import{DynamoDBClient as o}from"@stacksjs/ts-cloud";var i=await import("@stacksjs/cache").then((e)=>e.dynamoDbTool),t=new o("us-east-1");async function y(){if(!r.env.GITHUB_ACTIONS)await i.dynamoDb.launch();await n(5000),await c()}async function n(e){return new Promise((a)=>setTimeout(a,e))}async function c(){try{await t.createTable({TableName:"stacks",KeySchema:[{AttributeName:"key",KeyType:"HASH"}],AttributeDefinitions:[{AttributeName:"key",AttributeType:"S"}],ProvisionedThroughput:{ReadCapacityUnits:5,WriteCapacityUnits:5}})}catch(e){console.error("Error Creating Table",e)}}async function l(){try{await t.deleteTable({TableName:"stacks"})}catch(e){console.error("Error deleting table:",e)}}export{c as createStacksTable,l as deleteStacksTable,y as launchServer};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/testing",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.74.27",
5
+ "version": "0.74.28",
6
6
  "description": "The Stacks way of testing.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -74,14 +74,14 @@
74
74
  "prepublishOnly": "bun run build"
75
75
  },
76
76
  "dependencies": {
77
- "@stacksjs/auth": "0.74.27",
78
- "@stacksjs/cache": "0.74.27",
79
- "@stacksjs/config": "0.74.27",
80
- "@stacksjs/database": "0.74.27",
81
- "@stacksjs/path": "0.74.27",
82
- "@stacksjs/router": "0.74.27",
83
- "@stacksjs/storage": "0.74.27",
84
- "@stacksjs/ts-cloud": "^0.12.10"
77
+ "@stacksjs/auth": "0.74.28",
78
+ "@stacksjs/cache": "0.74.28",
79
+ "@stacksjs/config": "0.74.28",
80
+ "@stacksjs/database": "0.74.28",
81
+ "@stacksjs/path": "0.74.28",
82
+ "@stacksjs/router": "0.74.28",
83
+ "@stacksjs/storage": "0.74.28",
84
+ "@stacksjs/ts-cloud": "^0.12.15"
85
85
  },
86
86
  "devDependencies": {
87
87
  "better-dx": "^0.2.24"