velocious 1.0.96 → 1.0.98
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/eslint.config.js +1 -0
- package/package.json +2 -1
- package/spec/database/connection/drivers/mysql/query-parser-spec.js +4 -4
- package/spec/http-server/post-spec.js +2 -0
- package/src/application.js +27 -9
- package/src/configuration-resolver.js +29 -10
- package/src/configuration-types.js +44 -0
- package/src/configuration.js +63 -33
- package/src/database/drivers/base-column.js +6 -1
- package/src/database/drivers/base-columns-index.js +11 -1
- package/src/database/drivers/base-foreign-key.js +45 -0
- package/src/database/drivers/base-table.js +24 -2
- package/src/database/drivers/base.js +211 -39
- package/src/database/drivers/mssql/index.js +1 -3
- package/src/database/drivers/sqlite/sql/alter-table.js +4 -2
- package/src/database/handler.js +5 -0
- package/src/database/migration/index.js +77 -19
- package/src/database/migrator/files-finder.js +21 -22
- package/src/database/migrator/types.js +29 -0
- package/src/database/migrator.js +98 -59
- package/src/database/pool/async-tracked-multi-connection.js +42 -7
- package/src/database/pool/base-methods-forward.js +37 -0
- package/src/database/pool/base.js +79 -46
- package/src/database/pool/single-multi-use.js +18 -3
- package/src/database/query/alter-table-base.js +4 -4
- package/src/database/query/base.js +9 -2
- package/src/database/query/create-database-base.js +8 -0
- package/src/database/query/create-index-base.js +20 -5
- package/src/database/query/create-table-base.js +28 -9
- package/src/database/query/from-base.js +17 -0
- package/src/database/query/from-plain.js +8 -3
- package/src/database/query/from-table.js +8 -3
- package/src/database/query/index.js +43 -32
- package/src/database/query/join-base.js +28 -1
- package/src/database/query/join-object.js +67 -0
- package/src/database/query/join-plain.js +6 -1
- package/src/database/query/order-base.js +18 -0
- package/src/database/query/order-plain.js +8 -2
- package/src/database/query/select-base.js +15 -0
- package/src/database/query/select-plain.js +6 -1
- package/src/database/query/select-table-and-column.js +8 -2
- package/src/database/query/where-base.js +23 -1
- package/src/database/query/where-hash.js +15 -0
- package/src/database/query/where-plain.js +6 -0
- package/src/database/query-parser/base-query-parser.js +8 -2
- package/src/database/query-parser/from-parser.js +2 -0
- package/src/database/query-parser/joins-parser.js +10 -45
- package/src/database/query-parser/select-parser.js +2 -0
- package/src/database/record/index.js +1 -1
- package/src/database/table-data/index.js +39 -121
- package/src/database/table-data/table-column.js +54 -25
- package/src/database/table-data/table-foreign-key.js +5 -3
- package/src/database/table-data/table-index.js +12 -6
- package/src/database/table-data/table-reference.js +2 -0
- package/src/database/use-database.js +4 -2
- package/src/environment-handlers/base.js +41 -8
- package/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -0
- package/src/environment-handlers/node/cli/commands/generate/migration.js +3 -0
- package/src/environment-handlers/node/cli/commands/generate/model.js +3 -0
- package/src/environment-handlers/node/cli/commands/init.js +3 -0
- package/src/environment-handlers/node/cli/commands/test.js +17 -3
- package/src/environment-handlers/node.js +59 -28
- package/src/http-client/header.js +6 -0
- package/src/http-client/request.js +31 -5
- package/src/http-client/response.js +31 -7
- package/src/http-server/client/index.js +24 -4
- package/src/http-server/client/request-buffer/form-data-part.js +11 -0
- package/src/http-server/client/request-buffer/header.js +6 -0
- package/src/http-server/client/request-buffer/index.js +91 -13
- package/src/http-server/client/request-parser.js +26 -0
- package/src/http-server/client/request-runner.js +15 -3
- package/src/http-server/client/request.js +17 -0
- package/src/http-server/client/response.js +41 -1
- package/src/http-server/index.js +32 -4
- package/src/http-server/server-client.js +33 -2
- package/src/http-server/worker-handler/index.js +42 -9
- package/src/http-server/worker-handler/worker-script.js +2 -0
- package/src/http-server/worker-handler/worker-thread.js +34 -6
- package/src/logger.js +21 -15
- package/src/routes/app-routes.js +1 -1
- package/src/testing/test-files-finder.js +96 -9
- package/src/testing/test-runner.js +77 -25
- package/src/utils/backtrace-cleaner.js +6 -4
- package/src/utils/ensure-error.js +13 -0
- package/src/utils/file-exists.js +3 -1
- package/src/utils/rest-args-error.js +2 -0
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
2
3
|
import {Logger} from "../../logger.js"
|
|
3
4
|
import {Worker} from "worker_threads"
|
|
5
|
+
import ensureError from "../../utils/ensure-error.js"
|
|
4
6
|
|
|
5
7
|
export default class VelociousHttpServerWorker {
|
|
8
|
+
/**
|
|
9
|
+
* @param {object} args
|
|
10
|
+
* @param {import("../../configuration.js").default} args.configuration
|
|
11
|
+
* @param {number} args.workerCount
|
|
12
|
+
*/
|
|
6
13
|
constructor({configuration, workerCount}) {
|
|
7
14
|
this.configuration = configuration
|
|
15
|
+
|
|
16
|
+
/** @type {Record<number, import("../server-client.js").default>} */
|
|
8
17
|
this.clients = {}
|
|
18
|
+
|
|
9
19
|
this.logger = new Logger(this)
|
|
10
20
|
this.workerCount = workerCount
|
|
11
21
|
}
|
|
@@ -18,7 +28,7 @@ export default class VelociousHttpServerWorker {
|
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
async _spawnWorker() {
|
|
21
|
-
const
|
|
31
|
+
const debug = this.configuration.debug
|
|
22
32
|
const directory = this.configuration.getDirectory()
|
|
23
33
|
const velociousPath = await this.configuration.getEnvironmentHandler().getVelociousPath()
|
|
24
34
|
|
|
@@ -35,25 +45,38 @@ export default class VelociousHttpServerWorker {
|
|
|
35
45
|
this.worker.on("message", this.onWorkerMessage)
|
|
36
46
|
}
|
|
37
47
|
|
|
48
|
+
/**
|
|
49
|
+
* @param {import("../server-client.js").default} client
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
38
52
|
addSocketConnection(client) {
|
|
39
|
-
const clientCount =
|
|
53
|
+
const clientCount = client.clientCount
|
|
40
54
|
|
|
41
55
|
client.socket.on("end", () => {
|
|
42
56
|
this.logger.debug(`Removing ${clientCount} from clients`)
|
|
43
57
|
delete this.clients[clientCount]
|
|
44
58
|
})
|
|
45
59
|
|
|
46
|
-
|
|
60
|
+
if (!this.worker) throw new Error("Worker not initialized")
|
|
61
|
+
|
|
62
|
+
client.setWorker(this.worker)
|
|
47
63
|
client.listen()
|
|
48
64
|
|
|
49
65
|
this.clients[clientCount] = client
|
|
50
66
|
this.worker.postMessage({command: "newClient", clientCount})
|
|
51
67
|
}
|
|
52
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @param {any} error
|
|
71
|
+
*/
|
|
53
72
|
onWorkerError = (error) => {
|
|
54
|
-
throw error // Throws original error with backtrace and everything into the console
|
|
73
|
+
throw ensureError(error) // Throws original error with backtrace and everything into the console
|
|
55
74
|
}
|
|
56
75
|
|
|
76
|
+
/**
|
|
77
|
+
* @param {number} code
|
|
78
|
+
* @returns {void}
|
|
79
|
+
*/
|
|
57
80
|
onWorkerExit = (code) => {
|
|
58
81
|
if (code !== 0) {
|
|
59
82
|
throw new Error(`Client worker stopped with exit code ${code}`)
|
|
@@ -62,22 +85,32 @@ export default class VelociousHttpServerWorker {
|
|
|
62
85
|
}
|
|
63
86
|
}
|
|
64
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @param {object} data
|
|
90
|
+
* @param {string} data.command
|
|
91
|
+
* @param {number} data.clientCount
|
|
92
|
+
* @param {string} data.output
|
|
93
|
+
* @returns {void}
|
|
94
|
+
*/
|
|
65
95
|
onWorkerMessage = (data) => {
|
|
66
96
|
this.logger.debug(`Worker message`, data)
|
|
67
97
|
|
|
68
|
-
const {command} =
|
|
98
|
+
const {command} = data
|
|
69
99
|
|
|
70
100
|
if (command == "started") {
|
|
71
|
-
this.onStartCallback
|
|
101
|
+
if (this.onStartCallback) {
|
|
102
|
+
this.onStartCallback(null)
|
|
103
|
+
}
|
|
104
|
+
|
|
72
105
|
this.onStartCallback = null
|
|
73
106
|
} else if (command == "clientOutput") {
|
|
74
107
|
this.logger.debug("CLIENT OUTPUT", data)
|
|
75
108
|
|
|
76
|
-
const {clientCount, output} =
|
|
109
|
+
const {clientCount, output} = data
|
|
77
110
|
|
|
78
111
|
this.clients[clientCount]?.send(output)
|
|
79
112
|
} else if (command == "clientClose") {
|
|
80
|
-
const {clientCount} =
|
|
113
|
+
const {clientCount} = data
|
|
81
114
|
|
|
82
115
|
this.clients[clientCount]?.end()
|
|
83
116
|
} else {
|
|
@@ -1,14 +1,25 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import Application from "../../application.js"
|
|
2
4
|
import Client from "../client/index.js"
|
|
3
|
-
import {digg
|
|
5
|
+
import {digg} from "diggerize"
|
|
4
6
|
import errorLogger from "../../error-logger.js"
|
|
5
7
|
import {Logger} from "../../logger.js"
|
|
6
8
|
|
|
7
9
|
export default class VelociousHttpServerWorkerHandlerWorkerThread {
|
|
10
|
+
/**
|
|
11
|
+
* @param {object} args
|
|
12
|
+
* @param {import("worker_threads").parentPort} args.parentPort
|
|
13
|
+
* @param {{directory: string, environment: string, workerCount: number}} args.workerData
|
|
14
|
+
*/
|
|
8
15
|
constructor({parentPort, workerData}) {
|
|
9
|
-
|
|
16
|
+
if (!parentPort) throw new Error("parentPort is required")
|
|
17
|
+
|
|
18
|
+
const {workerCount} = workerData
|
|
10
19
|
|
|
20
|
+
/** @type {Record<number, Client>} */
|
|
11
21
|
this.clients = {}
|
|
22
|
+
|
|
12
23
|
this.logger = new Logger(this, {debug: false})
|
|
13
24
|
this.parentPort = parentPort
|
|
14
25
|
this.workerData = workerData
|
|
@@ -17,6 +28,8 @@ export default class VelociousHttpServerWorkerHandlerWorkerThread {
|
|
|
17
28
|
parentPort.on("message", errorLogger(this.onCommand))
|
|
18
29
|
|
|
19
30
|
this.initialize().then(() => {
|
|
31
|
+
if (!this.application) throw new Error("Application not initialized")
|
|
32
|
+
|
|
20
33
|
this.application.initialize().then(() => {
|
|
21
34
|
this.logger.debug(`Worker ${workerCount} started`)
|
|
22
35
|
parentPort.postMessage({command: "started"})
|
|
@@ -24,29 +37,44 @@ export default class VelociousHttpServerWorkerHandlerWorkerThread {
|
|
|
24
37
|
})
|
|
25
38
|
}
|
|
26
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @returns {Promise<void>}
|
|
42
|
+
*/
|
|
27
43
|
async initialize() {
|
|
28
|
-
const {
|
|
44
|
+
const {directory, environment} = this.workerData
|
|
29
45
|
const configurationPath = `${directory}/src/config/configuration.js`
|
|
30
46
|
const configurationImport = await import(configurationPath)
|
|
31
47
|
|
|
48
|
+
/** @type {import("../../configuration.js").default} */
|
|
32
49
|
this.configuration = configurationImport.default
|
|
50
|
+
|
|
51
|
+
if (!this.configuration) throw new Error(`Configuration couldn't be loaded from: ${configurationPath}`)
|
|
52
|
+
|
|
33
53
|
this.configuration.setEnvironment(environment)
|
|
34
54
|
this.configuration.setCurrent()
|
|
35
55
|
|
|
36
|
-
this.application = new Application({configuration: this.configuration,
|
|
56
|
+
this.application = new Application({configuration: this.configuration, type: "worker-handler"})
|
|
37
57
|
|
|
38
58
|
if (this.configuration.isInitialized()) {
|
|
39
59
|
await this.configuration.initialize({type: "worker-handler"})
|
|
40
60
|
}
|
|
41
61
|
}
|
|
42
62
|
|
|
63
|
+
/**
|
|
64
|
+
* @param {object} data
|
|
65
|
+
* @param {string} data.command
|
|
66
|
+
* @param {string} [data.chunk]
|
|
67
|
+
* @param {number} data.clientCount
|
|
68
|
+
*/
|
|
43
69
|
onCommand = async (data) => {
|
|
44
70
|
await this.logger.debug(() => [`Worker ${this.workerCount} received command`, data])
|
|
45
71
|
|
|
46
72
|
const command = data.command
|
|
47
73
|
|
|
48
74
|
if (command == "newClient") {
|
|
49
|
-
|
|
75
|
+
if (!this.configuration) throw new Error("Configuration not initialized")
|
|
76
|
+
|
|
77
|
+
const {clientCount} = data
|
|
50
78
|
const client = new Client({
|
|
51
79
|
clientCount,
|
|
52
80
|
configuration: this.configuration
|
|
@@ -65,7 +93,7 @@ export default class VelociousHttpServerWorkerHandlerWorkerThread {
|
|
|
65
93
|
} else if (command == "clientWrite") {
|
|
66
94
|
await this.logger.debug("Looking up client")
|
|
67
95
|
|
|
68
|
-
const {chunk, clientCount} =
|
|
96
|
+
const {chunk, clientCount} = data
|
|
69
97
|
const client = digg(this.clients, clientCount)
|
|
70
98
|
|
|
71
99
|
await this.logger.debug(`Sending to client ${clientCount}`)
|
package/src/logger.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import Configuration from "./configuration.js"
|
|
2
4
|
import restArgsError from "./utils/rest-args-error.js"
|
|
3
5
|
|
|
@@ -8,9 +10,10 @@ import restArgsError from "./utils/rest-args-error.js"
|
|
|
8
10
|
function consoleLog(message) {
|
|
9
11
|
return new Promise((resolve) => {
|
|
10
12
|
if (process.stdout) {
|
|
11
|
-
process.stdout.write(`${message}\n`, "utf8", resolve)
|
|
13
|
+
process.stdout.write(`${message}\n`, "utf8", () => resolve())
|
|
12
14
|
} else {
|
|
13
15
|
console.log(message)
|
|
16
|
+
resolve()
|
|
14
17
|
}
|
|
15
18
|
})
|
|
16
19
|
}
|
|
@@ -22,9 +25,10 @@ function consoleLog(message) {
|
|
|
22
25
|
function consoleError(message) {
|
|
23
26
|
return new Promise((resolve) => {
|
|
24
27
|
if (process.stderr) {
|
|
25
|
-
process.stderr.write(`${message}\n`, "utf8", resolve)
|
|
28
|
+
process.stderr.write(`${message}\n`, "utf8", () => resolve())
|
|
26
29
|
} else {
|
|
27
30
|
console.error(message)
|
|
31
|
+
resolve()
|
|
28
32
|
}
|
|
29
33
|
})
|
|
30
34
|
}
|
|
@@ -36,17 +40,19 @@ function consoleError(message) {
|
|
|
36
40
|
function consoleWarn(message) {
|
|
37
41
|
return new Promise((resolve) => {
|
|
38
42
|
if (process.stderr) {
|
|
39
|
-
process.stderr.write(`${message}\n`, "utf8", resolve)
|
|
43
|
+
process.stderr.write(`${message}\n`, "utf8", () => resolve())
|
|
40
44
|
} else {
|
|
41
45
|
console.warn(message)
|
|
46
|
+
resolve()
|
|
42
47
|
}
|
|
43
48
|
})
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
/**
|
|
47
|
-
* @param {Array} messages
|
|
52
|
+
* @param {...any|function() : Array<any>} messages
|
|
53
|
+
* @returns {Array<any>} - Either the function result or the messages
|
|
48
54
|
*/
|
|
49
|
-
function functionOrMessages(messages) {
|
|
55
|
+
function functionOrMessages(...messages) {
|
|
50
56
|
if (messages.length === 1 && typeof messages[0] == "function") {
|
|
51
57
|
messages = messages[0]()
|
|
52
58
|
}
|
|
@@ -65,7 +71,7 @@ function messagesToMessage(...messages) {
|
|
|
65
71
|
for (const messagePartIndex in messages) {
|
|
66
72
|
const messagePart = messages[messagePartIndex]
|
|
67
73
|
|
|
68
|
-
if (messagePartIndex > 0) {
|
|
74
|
+
if (typeof messagePartIndex == "number" && messagePartIndex > 0) {
|
|
69
75
|
message += " "
|
|
70
76
|
}
|
|
71
77
|
|
|
@@ -85,7 +91,7 @@ class Logger {
|
|
|
85
91
|
* @param {object} args
|
|
86
92
|
* @param {boolean} args.debug
|
|
87
93
|
*/
|
|
88
|
-
constructor(object, {debug, ...restArgs} = {}) {
|
|
94
|
+
constructor(object, {debug, ...restArgs} = {debug: false}) {
|
|
89
95
|
restArgsError(restArgs)
|
|
90
96
|
|
|
91
97
|
this._debug = debug
|
|
@@ -114,7 +120,7 @@ class Logger {
|
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
/**
|
|
117
|
-
* @
|
|
123
|
+
* @type {(...args: Parameters<typeof functionOrMessages>) => Promise<void>}
|
|
118
124
|
*/
|
|
119
125
|
async debug(...messages) {
|
|
120
126
|
if (this._debug || this.getConfiguration()?.debug) {
|
|
@@ -123,17 +129,17 @@ class Logger {
|
|
|
123
129
|
}
|
|
124
130
|
|
|
125
131
|
/**
|
|
126
|
-
* @
|
|
132
|
+
* @type {(...args: Parameters<typeof functionOrMessages>) => Promise<void>}
|
|
127
133
|
*/
|
|
128
134
|
async log(...messages) {
|
|
129
|
-
await consoleLog(messagesToMessage(this._subject, ...functionOrMessages(messages)))
|
|
135
|
+
await consoleLog(messagesToMessage(this._subject, ...functionOrMessages(...messages)))
|
|
130
136
|
}
|
|
131
137
|
|
|
132
138
|
/**
|
|
133
|
-
* @
|
|
139
|
+
* @type {(...args: Parameters<typeof functionOrMessages>) => Promise<void>}
|
|
134
140
|
*/
|
|
135
141
|
async error(...messages) {
|
|
136
|
-
await consoleError(messagesToMessage(this._subject, ...functionOrMessages(messages)))
|
|
142
|
+
await consoleError(messagesToMessage(this._subject, ...functionOrMessages(...messages)))
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
/**
|
|
@@ -145,10 +151,10 @@ class Logger {
|
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
/**
|
|
148
|
-
* @
|
|
154
|
+
* @type {(...args: Parameters<typeof functionOrMessages>) => Promise<void>}
|
|
149
155
|
*/
|
|
150
156
|
async warn(...messages) {
|
|
151
|
-
await consoleWarn(messagesToMessage(this._subject, ...functionOrMessages(messages)))
|
|
157
|
+
await consoleWarn(messagesToMessage(this._subject, ...functionOrMessages(...messages)))
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
|
|
@@ -163,6 +169,6 @@ export default async function logger(object, ...messages) {
|
|
|
163
169
|
const configuration = object.configuration || Configuration.current()
|
|
164
170
|
|
|
165
171
|
if (configuration.debug) {
|
|
166
|
-
await consoleLog(messagesToMessage(className, ...functionOrMessages(messages)))
|
|
172
|
+
await consoleLog(messagesToMessage(className, ...functionOrMessages(...messages)))
|
|
167
173
|
}
|
|
168
174
|
}
|
package/src/routes/app-routes.js
CHANGED
|
@@ -2,7 +2,7 @@ import {digg} from "diggerize"
|
|
|
2
2
|
|
|
3
3
|
export default class VelociousRoutesAppRoutes {
|
|
4
4
|
/**
|
|
5
|
-
* @param {import("../configuration.js")} configuration
|
|
5
|
+
* @param {import("../configuration.js").default} configuration
|
|
6
6
|
* @returns {import("./index.js").default}
|
|
7
7
|
*/
|
|
8
8
|
static async getRoutes(configuration) {
|
|
@@ -1,21 +1,74 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import fs from "fs/promises"
|
|
2
4
|
|
|
5
|
+
import fileExists from "../utils/file-exists.js"
|
|
6
|
+
import {Logger} from "../logger.js"
|
|
7
|
+
import restArgsError from "../utils/rest-args-error.js"
|
|
8
|
+
|
|
3
9
|
// Incredibly complex class to find files in multiple simultanious running promises to do it as fast as possible.
|
|
4
10
|
export default class TestFilesFinder {
|
|
5
11
|
static IGNORED_NAMES = [".git", "node_modules"]
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @param {object} args
|
|
15
|
+
* @param {string} args.directory
|
|
16
|
+
* @param {string[]} args.directories
|
|
17
|
+
* @param {string[]} args.processArgs
|
|
18
|
+
*/
|
|
19
|
+
constructor({directory, directories, processArgs, ...restArgs}) {
|
|
20
|
+
restArgsError(restArgs)
|
|
21
|
+
|
|
8
22
|
this.directory = directory
|
|
9
|
-
this.
|
|
23
|
+
this.logger = new Logger(this)
|
|
24
|
+
|
|
25
|
+
if (directories) {
|
|
26
|
+
this.directories = directories
|
|
27
|
+
} else {
|
|
28
|
+
this.directories = [
|
|
29
|
+
`${this.directory}/__tests__`,
|
|
30
|
+
`${this.directory}/tests`,
|
|
31
|
+
`${this.directory}/spec`
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
|
|
10
35
|
this.findingCount = 0
|
|
11
|
-
this.findingPromises = {}
|
|
12
36
|
this.processArgs = processArgs
|
|
37
|
+
|
|
38
|
+
/** @type {string[]} */
|
|
39
|
+
this.foundFiles = []
|
|
40
|
+
|
|
41
|
+
/** @type {Record<number, Promise<void>>} */
|
|
42
|
+
this.findingPromises = {}
|
|
43
|
+
|
|
44
|
+
/** @type {string[]} */
|
|
13
45
|
this.testArgs = this.processArgs.filter((processArg, index) => index != 0)
|
|
46
|
+
|
|
47
|
+
/** @type {string[]} */
|
|
48
|
+
this.directoryArgs = []
|
|
49
|
+
|
|
50
|
+
/** @type {string[]} */
|
|
51
|
+
this.fileArgs = []
|
|
52
|
+
|
|
53
|
+
for (const testArg of this.testArgs) {
|
|
54
|
+
if (testArg.endsWith("/")) {
|
|
55
|
+
this.directoryArgs.push(testArg)
|
|
56
|
+
} else {
|
|
57
|
+
this.fileArgs.push(testArg)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
14
60
|
}
|
|
15
61
|
|
|
62
|
+
/**
|
|
63
|
+
* @returns {Promise<string[]>}
|
|
64
|
+
*/
|
|
16
65
|
async findTestFiles() {
|
|
17
66
|
await this.withFindingCount(async () => {
|
|
18
|
-
|
|
67
|
+
for (const directory of this.directories) {
|
|
68
|
+
if (await fileExists(directory)) {
|
|
69
|
+
await this.findTestFilesInDir(directory)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
19
72
|
})
|
|
20
73
|
|
|
21
74
|
await this.waitForFindingPromises()
|
|
@@ -23,6 +76,9 @@ export default class TestFilesFinder {
|
|
|
23
76
|
return this.foundFiles
|
|
24
77
|
}
|
|
25
78
|
|
|
79
|
+
/**
|
|
80
|
+
* @returns {number}
|
|
81
|
+
*/
|
|
26
82
|
findingPromisesLength() { return Object.keys(this.findingPromises).length }
|
|
27
83
|
|
|
28
84
|
async waitForFindingPromises() {
|
|
@@ -31,6 +87,9 @@ export default class TestFilesFinder {
|
|
|
31
87
|
}
|
|
32
88
|
}
|
|
33
89
|
|
|
90
|
+
/**
|
|
91
|
+
* @returns {Promise<void>}
|
|
92
|
+
*/
|
|
34
93
|
async waitForFindingPromisesIteration() {
|
|
35
94
|
const unfinishedPromises = []
|
|
36
95
|
|
|
@@ -43,6 +102,9 @@ export default class TestFilesFinder {
|
|
|
43
102
|
await Promise.all(unfinishedPromises)
|
|
44
103
|
}
|
|
45
104
|
|
|
105
|
+
/**
|
|
106
|
+
* @param {function() : Promise<void>} callback
|
|
107
|
+
*/
|
|
46
108
|
withFindingCount(callback) {
|
|
47
109
|
return new Promise((resolve) => {
|
|
48
110
|
const findingPromise = callback()
|
|
@@ -54,11 +116,15 @@ export default class TestFilesFinder {
|
|
|
54
116
|
findingPromise.finally(() => {
|
|
55
117
|
delete this.findingPromises[findingCount]
|
|
56
118
|
|
|
57
|
-
resolve()
|
|
119
|
+
resolve(undefined)
|
|
58
120
|
})
|
|
59
121
|
})
|
|
60
122
|
}
|
|
61
123
|
|
|
124
|
+
/**
|
|
125
|
+
* @param {string} dir
|
|
126
|
+
* @returns {Promise<void>}
|
|
127
|
+
*/
|
|
62
128
|
async findTestFilesInDir(dir) {
|
|
63
129
|
await this.withFindingCount(async () => {
|
|
64
130
|
const files = await fs.readdir(dir)
|
|
@@ -89,16 +155,37 @@ export default class TestFilesFinder {
|
|
|
89
155
|
* @returns {boolean}
|
|
90
156
|
*/
|
|
91
157
|
isFileMatchingRequirements(file, localPath) {
|
|
92
|
-
if (this.
|
|
93
|
-
for (const
|
|
94
|
-
if (
|
|
158
|
+
if (this.directoryArgs.length > 0) {
|
|
159
|
+
for (const directoryArg of this.directoryArgs) {
|
|
160
|
+
if (localPath.startsWith(directoryArg) && this.looksLikeTestFile(file)) {
|
|
161
|
+
this.logger.debug("Found test file because matching dir and looks like this file:", file)
|
|
162
|
+
return true
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (this.fileArgs.length > 0) {
|
|
168
|
+
for (const fileArg of this.fileArgs) {
|
|
169
|
+
if (fileArg == localPath) {
|
|
170
|
+
this.logger.debug("Found test file because matching file arg:", file)
|
|
95
171
|
return true
|
|
96
172
|
}
|
|
97
173
|
}
|
|
98
|
-
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (this.fileArgs.length == 0 && this.directoryArgs.length == 0 && this.looksLikeTestFile(file)) {
|
|
177
|
+
this.logger.debug("Found test file because looks like this file:", file)
|
|
99
178
|
return true
|
|
100
179
|
}
|
|
101
180
|
|
|
102
181
|
return false
|
|
103
182
|
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {string} file
|
|
186
|
+
* @returns {boolean}
|
|
187
|
+
*/
|
|
188
|
+
looksLikeTestFile(file) {
|
|
189
|
+
return Boolean(file.match(/-(spec|test)\.(m|)js$/))
|
|
190
|
+
}
|
|
104
191
|
}
|