velocious 1.0.40 → 1.0.41

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.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -1
  3. package/peak_flow.yml +8 -4
  4. package/spec/cli/commands/db/create-spec.js +1 -0
  5. package/spec/cli/commands/db/migrate-spec.js +28 -11
  6. package/spec/cli/commands/test/test-files-finder-spec.js +5 -4
  7. package/spec/database/record/create-spec.js +6 -0
  8. package/spec/database/record/destroy-spec.js +6 -3
  9. package/spec/database/record/find-spec.js +3 -1
  10. package/spec/database/record/query-spec.js +7 -3
  11. package/spec/database/record/translation-fallbacks-spec.js +1 -1
  12. package/spec/database/record/update-spec.js +2 -1
  13. package/spec/database/record/validations-spec.js +10 -6
  14. package/spec/database/transactions-spec.js +7 -5
  15. package/spec/dummy/index.js +18 -29
  16. package/spec/dummy/src/config/configuration.example.js +3 -2
  17. package/spec/dummy/src/config/configuration.peakflow.mariadb.js +3 -7
  18. package/spec/dummy/src/config/configuration.peakflow.mssql.js +3 -2
  19. package/spec/dummy/src/config/configuration.peakflow.pgsql.js +3 -7
  20. package/spec/dummy/src/config/configuration.peakflow.sqlite.js +3 -7
  21. package/spec/dummy/src/config/testing.js +62 -0
  22. package/spec/dummy/src/database/migrations/20250912183605-create-users.js +15 -0
  23. package/spec/dummy/src/database/migrations/20250912183606-create-authentication-tokens.js +15 -0
  24. package/spec/dummy/src/models/authentication-token.js +8 -0
  25. package/spec/dummy/src/models/task.js +2 -2
  26. package/spec/dummy/src/models/user.js +15 -0
  27. package/spec/dummy/src/routes/projects/controller.js +7 -1
  28. package/spec/http-server/client-spec.js +1 -1
  29. package/spec/http-server/get-spec.js +1 -1
  30. package/spec/http-server/post-spec.js +21 -8
  31. package/spec/http-server/root-get-spec.js +1 -1
  32. package/src/cli/commands/db/create.js +11 -8
  33. package/src/cli/commands/db/drop.js +19 -0
  34. package/src/cli/commands/db/migrate.js +1 -1
  35. package/src/cli/commands/db/reset.js +7 -1
  36. package/src/cli/commands/test.js +10 -4
  37. package/src/configuration.js +26 -3
  38. package/src/database/drivers/base-column.js +22 -0
  39. package/src/database/drivers/base-columns-index.js +34 -0
  40. package/src/database/drivers/base-table.js +43 -0
  41. package/src/database/drivers/base.js +12 -16
  42. package/src/database/drivers/mssql/column.js +43 -2
  43. package/src/database/drivers/mssql/columns-index.js +9 -0
  44. package/src/database/drivers/mssql/index.js +26 -14
  45. package/src/database/drivers/mssql/table.js +16 -1
  46. package/src/database/drivers/mysql/column.js +47 -2
  47. package/src/database/drivers/mysql/columns-index.js +10 -0
  48. package/src/database/drivers/mysql/index.js +5 -8
  49. package/src/database/drivers/mysql/table.js +3 -1
  50. package/src/database/drivers/pgsql/column.js +37 -2
  51. package/src/database/drivers/pgsql/columns-index.js +4 -0
  52. package/src/database/drivers/pgsql/index.js +6 -5
  53. package/src/database/drivers/pgsql/table.js +3 -1
  54. package/src/database/drivers/sqlite/base.js +6 -4
  55. package/src/database/drivers/sqlite/column.js +46 -2
  56. package/src/database/drivers/sqlite/columns-index.js +22 -0
  57. package/src/database/drivers/sqlite/connection-sql-js.js +1 -1
  58. package/src/database/drivers/sqlite/table.js +3 -1
  59. package/src/database/migrator.js +27 -7
  60. package/src/database/query/create-index-base.js +10 -1
  61. package/src/database/query/create-table-base.js +56 -2
  62. package/src/database/query/drop-table-base.js +8 -2
  63. package/src/database/table-data/index.js +2 -1
  64. package/src/database/use-database.js +1 -1
  65. package/src/routes/resolver.js +1 -1
  66. package/src/templates/configuration.js +1 -1
  67. package/src/testing/test-runner.js +86 -26
  68. package/src/testing/test.js +155 -7
  69. package/src/utils/with-tracked-stack.js +5 -3
package/README.md CHANGED
@@ -82,7 +82,7 @@ Run migrations from anywhere if you want to:
82
82
  const migrationsPath = `/some/dir/migrations`
83
83
  const files = await new FilesFinder({path: migrationsPath}).findFiles()
84
84
 
85
- await this.configuration.withConnections(async () => {
85
+ await this.configuration.ensureConnections(async () => {
86
86
  const migrator = new Migrator({configuration: this.configuration})
87
87
 
88
88
  await migrator.prepare()
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.40",
6
+ "version": "1.0.41",
7
7
  "main": "index.js",
8
8
  "scripts": {
9
9
  "test": "jasmine",
@@ -45,6 +45,7 @@
45
45
  "incorporator": "^1.0.2",
46
46
  "inflection": "^3.0.0",
47
47
  "pure-uuid": "^1.8.1",
48
+ "set-state-compare": "^1.0.58",
48
49
  "sql-escape-string": "^1.1.0",
49
50
  "sql.js": "^1.12.0",
50
51
  "strftime": "^0.10.2"
package/peak_flow.yml CHANGED
@@ -49,7 +49,8 @@ builds:
49
49
  - wait-for-it mariadb:3306
50
50
  - sleep 5
51
51
  - cd spec/dummy && npx velocious db:create
52
- - npm test
52
+ - cd spec/dummy && npx velocious db:migrate
53
+ - cd spec/dummy && npx velocious test
53
54
  build_2:
54
55
  name: MS-SQL
55
56
  script:
@@ -57,7 +58,8 @@ builds:
57
58
  - wait-for-it mssql:1433
58
59
  - sleep 5
59
60
  - cd spec/dummy && npx velocious db:create
60
- - npm test
61
+ - cd spec/dummy && npx velocious db:migrate
62
+ - cd spec/dummy && npx velocious test
61
63
  build_3:
62
64
  name: PG-SQL
63
65
  script:
@@ -66,7 +68,8 @@ builds:
66
68
  - wait-for-it postgres:5432
67
69
  - sleep 5
68
70
  - cd spec/dummy && npx velocious db:create
69
- - npm test
71
+ - cd spec/dummy && npx velocious db:migrate
72
+ - cd spec/dummy && npx velocious test
70
73
  build_4:
71
74
  name: SQLite
72
75
  script:
@@ -74,4 +77,5 @@ builds:
74
77
  - wait-for-it mssql:1433
75
78
  - sleep 5
76
79
  - cd spec/dummy && npx velocious db:create
77
- - npm test
80
+ - cd spec/dummy && npx velocious db:migrate
81
+ - cd spec/dummy && npx velocious test
@@ -8,6 +8,7 @@ describe("Cli - Commands - db:create", () => {
8
8
  processArgs: ["db:create"],
9
9
  testing: true
10
10
  })
11
+
11
12
  const result = await cli.execute()
12
13
 
13
14
  if (cli.getConfiguration().getDatabaseType() == "sqlite") {
@@ -3,7 +3,7 @@ import dummyDirectory from "../../../dummy/dummy-directory.js"
3
3
  import uniqunize from "uniqunize"
4
4
 
5
5
  describe("Cli - Commands - db:migrate", () => {
6
- it("runs migrations", async () => {
6
+ it("runs migrations", {databaseCleaning: {transaction: false}}, async () => {
7
7
  const directory = dummyDirectory()
8
8
  const cli = new Cli({
9
9
  directory,
@@ -15,20 +15,24 @@ describe("Cli - Commands - db:migrate", () => {
15
15
 
16
16
  let defaultDatabaseType, defaultSchemaMigrations = [], projectForeignKey = [], tablesResult = []
17
17
 
18
- await cli.configuration.withConnections(async (dbs) => {
18
+ await cli.configuration.ensureConnections(async (dbs) => {
19
19
  defaultDatabaseType = dbs.default.getType()
20
20
 
21
- const tableNames = ["accounts", "tasks", "project_translations", "projects", "schema_migrations"]
21
+ const tableNames = ["accounts", "authentication_tokens", "tasks", "project_translations", "projects", "schema_migrations", "users"]
22
22
 
23
23
  for (const tableName of tableNames) {
24
- await dbs.default.dropTable(tableName, {ifExists: true})
25
- await dbs.mssql.dropTable(tableName, {ifExists: true})
24
+ await dbs.default.dropTable(tableName, {cascade: true, ifExists: true})
25
+
26
+ if (dbs.default.getType() != "mssql") {
27
+ await dbs.mssql.dropTable(tableName, {cascade: true, ifExists: true})
28
+ }
26
29
  }
27
30
 
28
31
  await cli.execute()
29
32
 
30
- const table = await dbs.default.getTableByName("tasks")
31
- const foreignKeys = await table.getForeignKeys()
33
+ // It creates foreign keys
34
+ const tasksTable = await dbs.default.getTableByName("tasks")
35
+ const foreignKeys = await tasksTable.getForeignKeys()
32
36
 
33
37
  for (const foreignKey of foreignKeys) {
34
38
  if (foreignKey.getColumnName() == "project_id") {
@@ -36,6 +40,15 @@ describe("Cli - Commands - db:migrate", () => {
36
40
  }
37
41
  }
38
42
 
43
+ // It creates unique indexes
44
+ const authenticationTokensTable = await dbs.default.getTableByName("authentication_tokens")
45
+ const tokenColumn = await authenticationTokensTable.getColumnByName("token")
46
+ const tokenIndex = await tokenColumn.getIndexByName("index_on_token")
47
+
48
+ expect(tokenIndex.getName()).toEqual("index_on_token")
49
+ expect(tokenIndex.isPrimaryKey()).toBeFalse()
50
+ expect(tokenIndex.isUnique()).toBeTrue()
51
+
39
52
  for (const db of Object.values(dbs)) {
40
53
  const schemaMigrations = await db.query("SELECT * FROM schema_migrations ORDER BY version")
41
54
 
@@ -62,27 +75,31 @@ describe("Cli - Commands - db:migrate", () => {
62
75
  expect(uniqunize(tablesResult.sort())).toEqual(
63
76
  [
64
77
  "accounts",
78
+ "authentication_tokens",
65
79
  "project_translations",
66
80
  "projects",
67
81
  "schema_migrations",
68
- "tasks"
82
+ "tasks",
83
+ "users"
69
84
  ]
70
85
  )
71
86
 
72
- expect(uniqunize(defaultSchemaMigrations.sort())).toEqual(["20230728075328", "20230728075329", "20250605133926", "20250903112845"])
87
+ expect(uniqunize(defaultSchemaMigrations.sort())).toEqual(["20230728075328", "20230728075329", "20250605133926", "20250903112845", "20250912183605", "20250912183606"])
73
88
  } else {
74
89
  expect(tablesResult.sort()).toEqual(
75
90
  [
76
91
  "accounts",
92
+ "authentication_tokens",
77
93
  "project_translations",
78
94
  "projects",
79
95
  "schema_migrations",
80
96
  "schema_migrations",
81
- "tasks"
97
+ "tasks",
98
+ "users"
82
99
  ]
83
100
  )
84
101
 
85
- expect(defaultSchemaMigrations.sort()).toEqual(["20230728075328", "20230728075329", "20250605133926", "20250903112845"])
102
+ expect(defaultSchemaMigrations.sort()).toEqual(["20230728075328", "20230728075329", "20250605133926", "20250903112845", "20250912183605", "20250912183606"])
86
103
  }
87
104
  })
88
105
  })
@@ -1,12 +1,13 @@
1
+ import fs from "fs/promises"
1
2
  import TestFilesFinder from "../../../../src/testing/test-files-finder.js"
2
3
 
3
4
  describe("Cli - Commands - test - TestFilesFinder", () => {
4
5
  it("finds the correct test files", async () => {
5
- const testFilesFinder = new TestFilesFinder({directory: process.cwd(), processArgs: ["test"]})
6
+ const directory = await fs.realpath(`${process.cwd()}/../..`)
7
+ const testFilesFinder = new TestFilesFinder({directory, processArgs: ["test"]})
6
8
  const testFiles = await testFilesFinder.findTestFiles()
9
+ const sampleTestFilePath = `${directory}/spec/cli/commands/destroy/migration-spec.js`
7
10
 
8
- const sampleTestFilePath = `${process.cwd()}/spec/cli/commands/destroy/migration-spec.js`
9
-
10
- expect(testFiles.includes(sampleTestFilePath)).toBe(true)
11
+ expect(testFiles).toContain(sampleTestFilePath)
11
12
  })
12
13
  })
@@ -44,6 +44,12 @@ describe("Record - create", () => {
44
44
 
45
45
  it("uses transactions and rolls back in case of an error", async () => {
46
46
  await Dummy.run(async () => {
47
+ const beforeProjectsCount = await Project.count()
48
+ const beforeTasksCount = await Task.count()
49
+
50
+ expect(beforeProjectsCount).toEqual(0)
51
+ expect(beforeTasksCount).toEqual(0)
52
+
47
53
  const project = new Project({name: "Test project"})
48
54
 
49
55
  project.tasks().build({name: " ", project})
@@ -1,10 +1,12 @@
1
1
  import Dummy from "../../dummy/index.js"
2
+ import Project from "../../dummy/src/models/project.js"
2
3
  import Task from "../../dummy/src/models/task.js"
3
4
 
4
5
  describe("Record - destroy", () => {
5
6
  it("destroys a record", async () => {
6
7
  await Dummy.run(async () => {
7
- const task = new Task({name: "Test task"})
8
+ const project = await Project.create()
9
+ const task = new Task({name: "Test task", project})
8
10
 
9
11
  await task.save()
10
12
  await task.destroy()
@@ -17,8 +19,9 @@ describe("Record - destroy", () => {
17
19
 
18
20
  it("destroys all records in a collection", async () => {
19
21
  await Dummy.run(async () => {
20
- const task1 = await Task.create({name: "Test task 1"})
21
- const task2 = await Task.create({name: "Test task 2"})
22
+ const project = await Project.create()
23
+ const task1 = await Task.create({name: "Test task 1", project})
24
+ const task2 = await Task.create({name: "Test task 2", project})
22
25
 
23
26
  await Task.where({id: task1.id()}).destroyAll()
24
27
 
@@ -1,10 +1,12 @@
1
1
  import Dummy from "../../dummy/index.js"
2
+ import Project from "../../dummy/src/models/project.js"
2
3
  import Task from "../../dummy/src/models/task.js"
3
4
 
4
5
  describe("Record - find", () => {
5
6
  it("finds an existing record", async () => {
6
7
  await Dummy.run(async () => {
7
- const task = new Task({name: "Test task"})
8
+ const project = await Project.create()
9
+ const task = new Task({name: "Test task", project})
8
10
 
9
11
  await task.save()
10
12
 
@@ -1,4 +1,5 @@
1
1
  import Dummy from "../../dummy/index.js"
2
+ import Project from "../../dummy/src/models/project.js"
2
3
  import Task from "../../dummy/src/models/task.js"
3
4
 
4
5
  describe("Record - query", () => {
@@ -38,9 +39,10 @@ describe("Record - query", () => {
38
39
  it("finds the first record", async () => {
39
40
  await Dummy.run(async () => {
40
41
  const taskIDs = []
42
+ const project = await Project.create()
41
43
 
42
44
  for (let i = 0; i < 5; i++) {
43
- const task = await Task.create({name: `Task ${i}`})
45
+ const task = await Task.create({name: `Task ${i}`, project})
44
46
 
45
47
  taskIDs.push(task.id())
46
48
  }
@@ -54,9 +56,10 @@ describe("Record - query", () => {
54
56
  it("finds the last record", async () => {
55
57
  await Dummy.run(async () => {
56
58
  const taskIDs = []
59
+ const project = await Project.create()
57
60
 
58
61
  for (let i = 0; i < 5; i++) {
59
- const task = await Task.create({name: `Task ${i}`})
62
+ const task = await Task.create({name: `Task ${i}`, project})
60
63
 
61
64
  taskIDs.push(task.id())
62
65
  }
@@ -70,9 +73,10 @@ describe("Record - query", () => {
70
73
  it("counts the records", async () => {
71
74
  await Dummy.run(async () => {
72
75
  const taskIDs = []
76
+ const project = await Project.create()
73
77
 
74
78
  for (let i = 0; i < 5; i++) {
75
- const task = await Task.create({name: `Task ${i}`})
79
+ const task = await Task.create({name: `Task ${i}`, project})
76
80
 
77
81
  taskIDs.push(task.id())
78
82
  }
@@ -1,7 +1,7 @@
1
1
  import Dummy from "../../dummy/index.js"
2
2
  import Task from "../../dummy/src/models/task.js"
3
3
 
4
- describe("Record - create", () => {
4
+ describe("Record - translation fallbacks", () => {
5
5
  it("creates a new simple record with relationships and translations with fallbacks", async () => {
6
6
  await Dummy.run(async () => {
7
7
  const task = new Task({name: "Test task"})
@@ -6,7 +6,8 @@ import wait from "awaitery/src/wait.js"
6
6
  describe("Record - update", () => {
7
7
  it("updates a record", async () => {
8
8
  await Dummy.run(async () => {
9
- const task = new Task({name: "Test task"})
9
+ const project = await Project.create()
10
+ const task = new Task({name: "Test task", project})
10
11
 
11
12
  await task.save()
12
13
  await task.update({name: "Updated name"})
@@ -1,29 +1,33 @@
1
1
  import Dummy from "../../dummy/index.js"
2
2
  import Task from "../../dummy/src/models/task.js"
3
3
  import {ValidationError} from "../../../src/database/record/index.js"
4
+ import Project from "../../dummy/src/models/project.js"
4
5
 
5
6
  describe("Record - validations", () => {
6
7
  it("raises validations if trying to create an invalid record because of a presence validation", async () => {
7
8
  await Dummy.run(async () => {
8
- const task = new Task({name: " "})
9
+ const project = await Project.create()
10
+ const task = new Task({name: " ", project})
9
11
 
10
- await expectAsync(task.save()).toBeRejectedWith(new ValidationError("Name can't be blank"))
12
+ await expect(async () => task.save()).toThrowError(new ValidationError("Name can't be blank"))
11
13
  })
12
14
  })
13
15
 
14
16
  it("raises validations if trying to create an invalid record with a blank value because of a presence validation", async () => {
15
17
  await Dummy.run(async () => {
16
- const task = new Task({name: null})
18
+ const project = await Project.create()
19
+ const task = new Task({name: null, project})
17
20
 
18
- await expectAsync(task.save()).toBeRejectedWith(new ValidationError("Name can't be blank"))
21
+ await expect(async () => task.save()).toThrowError(new ValidationError("Name can't be blank"))
19
22
  })
20
23
  })
21
24
 
22
25
  it("raises validations if trying to create an invalid record because of a uniqueness validation", async () => {
23
26
  await Dummy.run(async () => {
24
- await Task.create({name: "Task 1"})
27
+ const project = await Project.create()
28
+ await Task.create({name: "Task 1", project})
25
29
 
26
- const task2 = await Task.create({name: "Task 2"})
30
+ const task2 = await Task.create({name: "Task 2", project})
27
31
 
28
32
  try {
29
33
  await task2.update({name: "Task 1"})
@@ -1,24 +1,26 @@
1
1
  import Dummy from "../dummy/index.js"
2
2
  import dummyConfiguration from "../dummy/src/config/configuration.js"
3
+ import Project from "../dummy/src/models/project.js"
3
4
  import Task from "../dummy/src/models/task.js"
4
5
  import {ValidationError} from "../../src/database/record/index.js"
5
6
 
6
7
  describe("database - transactions", () => {
7
8
  it("supports transactions and savepoints", async () => {
8
9
  await Dummy.run(async () => {
9
- await dummyConfiguration.withConnections(async (dbs) => {
10
+ await dummyConfiguration.ensureConnections(async (dbs) => {
10
11
  const db = dbs.default
12
+ const project = await Project.create()
11
13
 
12
14
  await db.transaction(async () => {
13
- await Task.create({name: "Task 1"})
15
+ await Task.create({name: "Task 1", project})
14
16
 
15
17
  await db.transaction(async () => {
16
- await Task.create({name: "Task 2"})
18
+ await Task.create({name: "Task 2", project})
17
19
 
18
20
  try {
19
21
  await db.transaction(async () => {
20
- await Task.create({name: "Task 3"})
21
- await Task.create({name: " "})
22
+ await Task.create({name: "Task 3", project})
23
+ await Task.create({name: " ", project})
22
24
 
23
25
  throw new Error("Didn't expect to succeed")
24
26
  })
@@ -1,7 +1,7 @@
1
1
  import Application from "../../src/application.js"
2
- import {digg} from "diggerize"
3
2
  import dummyConfiguration from "./src/config/configuration.js"
4
- import Migration from "../../src/database/migration/index.js"
3
+ import FilesFinder from "../../src/database/migrator/files-finder.js"
4
+ import Migrator from "../../src/database/migrator.js"
5
5
 
6
6
  export default class Dummy {
7
7
  static current() {
@@ -15,31 +15,8 @@ export default class Dummy {
15
15
  static async prepare() {
16
16
  dummyConfiguration.setCurrent()
17
17
 
18
- await dummyConfiguration.withConnections(async (dbs) => {
19
- const db = digg(dbs, "default")
20
-
21
- await db.dropTable("tasks", {ifExists: true})
22
- await db.dropTable("project_translations", {ifExists: true})
23
- await db.dropTable("projects", {ifExists: true})
24
-
25
- const migration = new Migration({configuration: dummyConfiguration, databaseIdentifier: "default", db})
26
-
27
- await migration.createTable("projects", (t) => {
28
- t.timestamps()
29
- })
30
- await migration.createTable("project_translations", (t) => {
31
- t.references("project", {null: false, foreignKey: true})
32
- t.string("locale", {null: false})
33
- t.string("name")
34
- })
35
-
36
- await migration.addIndex("project_translations", ["project_id", "locale"], {unique: true})
37
-
38
- await migration.createTable("tasks", (t) => {
39
- t.references("project")
40
- t.string("name")
41
- t.text("description")
42
- })
18
+ await dummyConfiguration.ensureConnections(async () => {
19
+ await this.runMigrations()
43
20
 
44
21
  if (!dummyConfiguration.isInitialized()) {
45
22
  await dummyConfiguration.initialize()
@@ -47,12 +24,21 @@ export default class Dummy {
47
24
  })
48
25
  }
49
26
 
27
+ static async runMigrations() {
28
+ const migrationsPath = `${import.meta.dirname}/src/database/migrations`
29
+ const files = await new FilesFinder({path: migrationsPath}).findFiles()
30
+ const migrator = new Migrator({configuration: dummyConfiguration})
31
+
32
+ await migrator.prepare()
33
+ await migrator.migrateFiles(files, async (path) => await import(path))
34
+ }
35
+
50
36
  static async run(callback) {
51
37
  await this.current().run(callback)
52
38
  }
53
39
 
54
40
  async run(callback) {
55
- await dummyConfiguration.withConnections(async () => {
41
+ await dummyConfiguration.ensureConnections(async () => {
56
42
  await Dummy.prepare()
57
43
  await this.start()
58
44
 
@@ -78,7 +64,10 @@ export default class Dummy {
78
64
  password: ""
79
65
  }
80
66
  },
81
- httpServer: {port: 3006}
67
+ httpServer: {
68
+ maxWorkers: 1,
69
+ port: 3006
70
+ }
82
71
  })
83
72
 
84
73
  await this.application.initialize()
@@ -49,7 +49,7 @@ export default new Configuration({
49
49
  const requireContextModels = requireContext(modelsPath, true, /^(.+)\.js$/)
50
50
  const initializerFromRequireContext = new InitializerFromRequireContext({requireContext: requireContextModels})
51
51
 
52
- await configuration.withConnections(async () => {
52
+ await configuration.ensureConnections(async () => {
53
53
  await initializerFromRequireContext.initialize({configuration})
54
54
  })
55
55
  },
@@ -58,5 +58,6 @@ export default new Configuration({
58
58
  de: ["de", "en"],
59
59
  en: ["en", "de"]
60
60
  },
61
- locales: ["de", "en"]
61
+ locales: ["de", "en"],
62
+ testing: `${dummyDirectory()}/src/config/testing.js`
62
63
  })
@@ -32,11 +32,6 @@ export default new Configuration({
32
32
  password: "Super-Secret-Password",
33
33
  database: "velocious_test",
34
34
  server: "mssql",
35
- pool: {
36
- max: 10,
37
- min: 0,
38
- idleTimeoutMillis: 30000
39
- },
40
35
  options: {
41
36
  encrypt: true, // for azure
42
37
  trustServerCertificate: true // change to true for local dev / self-signed certs
@@ -51,7 +46,7 @@ export default new Configuration({
51
46
  const requireContextModels = requireContext(modelsPath, true, /^(.+)\.js$/)
52
47
  const initializerFromRequireContext = new InitializerFromRequireContext({requireContext: requireContextModels})
53
48
 
54
- await configuration.withConnections(async () => {
49
+ await configuration.ensureConnections(async () => {
55
50
  await initializerFromRequireContext.initialize({configuration})
56
51
  })
57
52
  },
@@ -60,5 +55,6 @@ export default new Configuration({
60
55
  de: ["de", "en"],
61
56
  en: ["en", "de"]
62
57
  },
63
- locales: ["de", "en"]
58
+ locales: ["de", "en"],
59
+ testing: `${dummyDirectory()}/src/config/testing.js`
64
60
  })
@@ -52,7 +52,7 @@ export default new Configuration({
52
52
  const requireContextModels = requireContext(modelsPath, true, /^(.+)\.js$/)
53
53
  const initializerFromRequireContext = new InitializerFromRequireContext({requireContext: requireContextModels})
54
54
 
55
- await configuration.withConnections(async () => {
55
+ await configuration.ensureConnections(async () => {
56
56
  await initializerFromRequireContext.initialize({configuration})
57
57
  })
58
58
  },
@@ -61,5 +61,6 @@ export default new Configuration({
61
61
  de: ["de", "en"],
62
62
  en: ["en", "de"]
63
63
  },
64
- locales: ["de", "en"]
64
+ locales: ["de", "en"],
65
+ testing: `${dummyDirectory()}/src/config/testing.js`
65
66
  })
@@ -32,11 +32,6 @@ export default new Configuration({
32
32
  password: "Super-Secret-Password",
33
33
  database: "velocious_test",
34
34
  server: "mssql",
35
- pool: {
36
- max: 10,
37
- min: 0,
38
- idleTimeoutMillis: 30000
39
- },
40
35
  options: {
41
36
  encrypt: true, // for azure
42
37
  trustServerCertificate: true // change to true for local dev / self-signed certs
@@ -51,7 +46,7 @@ export default new Configuration({
51
46
  const requireContextModels = requireContext(modelsPath, true, /^(.+)\.js$/)
52
47
  const initializerFromRequireContext = new InitializerFromRequireContext({requireContext: requireContextModels})
53
48
 
54
- await configuration.withConnections(async () => {
49
+ await configuration.ensureConnections(async () => {
55
50
  await initializerFromRequireContext.initialize({configuration})
56
51
  })
57
52
  },
@@ -60,5 +55,6 @@ export default new Configuration({
60
55
  de: ["de", "en"],
61
56
  en: ["en", "de"]
62
57
  },
63
- locales: ["de", "en"]
58
+ locales: ["de", "en"],
59
+ testing: `${dummyDirectory()}/src/config/testing.js`
64
60
  })
@@ -29,11 +29,6 @@ export default new Configuration({
29
29
  password: "Super-Secret-Password",
30
30
  database: "velocious_test",
31
31
  server: "mssql",
32
- pool: {
33
- max: 10,
34
- min: 0,
35
- idleTimeoutMillis: 30000
36
- },
37
32
  options: {
38
33
  encrypt: true, // for azure
39
34
  trustServerCertificate: true // change to true for local dev / self-signed certs
@@ -48,7 +43,7 @@ export default new Configuration({
48
43
  const requireContextModels = requireContext(modelsPath, true, /^(.+)\.js$/)
49
44
  const initializerFromRequireContext = new InitializerFromRequireContext({requireContext: requireContextModels})
50
45
 
51
- await configuration.withConnections(async () => {
46
+ await configuration.ensureConnections(async () => {
52
47
  await initializerFromRequireContext.initialize({configuration})
53
48
  })
54
49
  },
@@ -57,5 +52,6 @@ export default new Configuration({
57
52
  de: ["de", "en"],
58
53
  en: ["en", "de"]
59
54
  },
60
- locales: ["de", "en"]
55
+ locales: ["de", "en"],
56
+ testing: `${dummyDirectory()}/src/config/testing.js`
61
57
  })
@@ -0,0 +1,62 @@
1
+ import dummyConfiguration from "./configuration.js"
2
+
3
+ beforeEach(async ({testArgs}) => {
4
+ const transaction = testArgs.databaseCleaning?.transaction
5
+
6
+ if (transaction === undefined) {
7
+ const dbs = dummyConfiguration.getCurrentConnections()
8
+
9
+ for (const dbIdentifier in dbs) {
10
+ const db = dbs[dbIdentifier]
11
+
12
+ await db.startTransaction()
13
+ }
14
+ }
15
+ })
16
+
17
+ afterEach(async ({testArgs}) => {
18
+ const transaction = testArgs.databaseCleaning?.transaction
19
+ const truncate = testArgs.databaseCleaning?.truncate
20
+
21
+ const dbs = dummyConfiguration.getCurrentConnections()
22
+
23
+ for (const dbIdentifier in dbs) {
24
+ const db = dbs[dbIdentifier]
25
+
26
+ if (transaction === undefined || transaction) {
27
+ await db.rollbackTransaction()
28
+ }
29
+
30
+ if (truncate) {
31
+ await db.withDisabledForeignKeys(async () => {
32
+ let tries = 0
33
+
34
+ while(true) {
35
+ tries++
36
+
37
+ const tables = await db.getTables()
38
+ const truncateErrors = []
39
+
40
+ for (const table of tables) {
41
+ if (table.getName() != "schema_migrations") {
42
+ try {
43
+ await table.truncate({cascade: true})
44
+ } catch (error) {
45
+ console.error(error)
46
+ truncateErrors.push(error)
47
+ }
48
+ }
49
+ }
50
+
51
+ if (truncateErrors.length == 0) {
52
+ break
53
+ } else if (tries <= 5) {
54
+ // Retry
55
+ } else {
56
+ throw truncateErrors[0]
57
+ }
58
+ }
59
+ })
60
+ }
61
+ }
62
+ })
@@ -0,0 +1,15 @@
1
+ import Migration from "../../../../../src/database/migration/index.js"
2
+
3
+ export default class CreateUsers extends Migration {
4
+ async up() {
5
+ await this.createTable("users", (t) => {
6
+ t.string("email", {index: {unique: true}, null: false})
7
+ t.string("encrypted_password", {null: false})
8
+ t.timestamps()
9
+ })
10
+ }
11
+
12
+ async down() {
13
+ await this.dropTable("users")
14
+ }
15
+ }