velocious 1.0.667 → 1.0.669

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 (112) hide show
  1. package/README.md +34 -9
  2. package/build/configuration.js +23 -1
  3. package/build/environment-handlers/node/cli/commands/test/timing-manifest/merge.js +2 -48
  4. package/build/environment-handlers/node/cli/commands/test.js +17 -69
  5. package/build/frontend-models/websocket-channel.js +18 -0
  6. package/build/http-server/client/websocket-session.js +41 -4
  7. package/build/http-server/websocket-channel.js +14 -0
  8. package/build/http-server/websocket-event-log-store.js +85 -12
  9. package/build/http-server/websocket-events-host.js +14 -6
  10. package/build/src/configuration.d.ts +18 -1
  11. package/build/src/configuration.d.ts.map +1 -1
  12. package/build/src/configuration.js +22 -2
  13. package/build/src/environment-handlers/node/cli/commands/test/timing-manifest/merge.d.ts.map +1 -1
  14. package/build/src/environment-handlers/node/cli/commands/test/timing-manifest/merge.js +3 -47
  15. package/build/src/environment-handlers/node/cli/commands/test.d.ts +2 -28
  16. package/build/src/environment-handlers/node/cli/commands/test.d.ts.map +1 -1
  17. package/build/src/environment-handlers/node/cli/commands/test.js +10 -61
  18. package/build/src/frontend-models/websocket-channel.d.ts +9 -0
  19. package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
  20. package/build/src/frontend-models/websocket-channel.js +16 -1
  21. package/build/src/http-server/client/websocket-session.d.ts +25 -2
  22. package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
  23. package/build/src/http-server/client/websocket-session.js +40 -5
  24. package/build/src/http-server/websocket-channel.d.ts +11 -0
  25. package/build/src/http-server/websocket-channel.d.ts.map +1 -1
  26. package/build/src/http-server/websocket-channel.js +14 -1
  27. package/build/src/http-server/websocket-event-log-store.d.ts +60 -41
  28. package/build/src/http-server/websocket-event-log-store.d.ts.map +1 -1
  29. package/build/src/http-server/websocket-event-log-store.js +79 -12
  30. package/build/src/http-server/websocket-events-host.d.ts +10 -3
  31. package/build/src/http-server/websocket-events-host.d.ts.map +1 -1
  32. package/build/src/http-server/websocket-events-host.js +14 -7
  33. package/build/src/testing/expect-utils.d.ts +1 -51
  34. package/build/src/testing/expect-utils.d.ts.map +1 -1
  35. package/build/src/testing/expect-utils.js +2 -205
  36. package/build/src/testing/expect.d.ts +1 -171
  37. package/build/src/testing/expect.d.ts.map +1 -1
  38. package/build/src/testing/expect.js +2 -667
  39. package/build/src/testing/test-files-finder.d.ts +13 -116
  40. package/build/src/testing/test-files-finder.d.ts.map +1 -1
  41. package/build/src/testing/test-files-finder.js +26 -296
  42. package/build/src/testing/test-filter-parser.d.ts +32 -22
  43. package/build/src/testing/test-filter-parser.d.ts.map +1 -1
  44. package/build/src/testing/test-filter-parser.js +25 -217
  45. package/build/src/testing/test-profile-activity.d.ts +1 -6
  46. package/build/src/testing/test-profile-activity.d.ts.map +1 -1
  47. package/build/src/testing/test-profile-activity.js +2 -12
  48. package/build/src/testing/test-profile-output.d.ts +1 -40
  49. package/build/src/testing/test-profile-output.d.ts.map +1 -1
  50. package/build/src/testing/test-profile-output.js +2 -217
  51. package/build/src/testing/test-profiler.d.ts +15 -659
  52. package/build/src/testing/test-profiler.d.ts.map +1 -1
  53. package/build/src/testing/test-profiler.js +35 -833
  54. package/build/src/testing/test-runner.d.ts +10 -1
  55. package/build/src/testing/test-runner.d.ts.map +1 -1
  56. package/build/src/testing/test-runner.js +26 -4
  57. package/build/src/testing/test-suite-splitter.d.ts +1 -128
  58. package/build/src/testing/test-suite-splitter.d.ts.map +1 -1
  59. package/build/src/testing/test-suite-splitter.js +2 -259
  60. package/build/src/testing/test.d.ts +1 -13
  61. package/build/src/testing/test.d.ts.map +1 -1
  62. package/build/src/testing/test.js +2 -14
  63. package/build/src/testing/timing-manifest.d.ts +5 -93
  64. package/build/src/testing/timing-manifest.d.ts.map +1 -1
  65. package/build/src/testing/timing-manifest.js +4 -283
  66. package/build/src/testing/velocious-attempt-executor.d.ts.map +1 -1
  67. package/build/src/testing/velocious-attempt-executor.js +8 -2
  68. package/build/testing/expect-utils.js +1 -242
  69. package/build/testing/expect.js +1 -760
  70. package/build/testing/test-files-finder.js +29 -345
  71. package/build/testing/test-filter-parser.js +29 -248
  72. package/build/testing/test-profile-activity.js +1 -12
  73. package/build/testing/test-profile-output.js +8 -253
  74. package/build/testing/test-profiler.js +38 -895
  75. package/build/testing/test-runner.js +33 -9
  76. package/build/testing/test-suite-splitter.js +1 -301
  77. package/build/testing/test.js +3 -14
  78. package/build/testing/timing-manifest.js +10 -344
  79. package/build/testing/velocious-attempt-executor.js +7 -1
  80. package/package.json +3 -4
  81. package/scripts/test-browser.js +29 -6
  82. package/scripts/verify-docker-dev-environment.js +13 -1
  83. package/src/configuration.js +23 -1
  84. package/src/environment-handlers/node/cli/commands/test/timing-manifest/merge.js +2 -48
  85. package/src/environment-handlers/node/cli/commands/test.js +17 -69
  86. package/src/frontend-models/websocket-channel.js +18 -0
  87. package/src/http-server/client/websocket-session.js +41 -4
  88. package/src/http-server/websocket-channel.js +14 -0
  89. package/src/http-server/websocket-event-log-store.js +85 -12
  90. package/src/http-server/websocket-events-host.js +14 -6
  91. package/src/testing/expect-utils.js +1 -242
  92. package/src/testing/expect.js +1 -760
  93. package/src/testing/test-files-finder.js +29 -345
  94. package/src/testing/test-filter-parser.js +29 -248
  95. package/src/testing/test-profile-activity.js +1 -12
  96. package/src/testing/test-profile-output.js +8 -253
  97. package/src/testing/test-profiler.js +38 -895
  98. package/src/testing/test-runner.js +33 -9
  99. package/src/testing/test-suite-splitter.js +1 -301
  100. package/src/testing/test.js +3 -14
  101. package/src/testing/timing-manifest.js +10 -344
  102. package/src/testing/velocious-attempt-executor.js +7 -1
  103. package/build/src/testing/base-expect.d.ts +0 -15
  104. package/build/src/testing/base-expect.d.ts.map +0 -1
  105. package/build/src/testing/base-expect.js +0 -16
  106. package/build/src/testing/expect-to-change.d.ts +0 -32
  107. package/build/src/testing/expect-to-change.d.ts.map +0 -1
  108. package/build/src/testing/expect-to-change.js +0 -46
  109. package/build/testing/base-expect.js +0 -17
  110. package/build/testing/expect-to-change.js +0 -55
  111. package/src/testing/base-expect.js +0 -17
  112. package/src/testing/expect-to-change.js +0 -55
@@ -1,346 +1,12 @@
1
1
  // @ts-check
2
2
 
3
- import sha256Hex from "../utils/sha256-hex.js"
4
-
5
- /** @typedef {Record<string, number>} TimingManifest */
6
-
7
- /**
8
- * ValidatedProfileShard type.
9
- * @typedef {object} ValidatedProfileShard
10
- * @property {number} discoveredFileCount - Complete pre-shard file count.
11
- * @property {number} fileCount - Selected post-shard file count.
12
- * @property {number} groupNumber - One-indexed shard number.
13
- * @property {number} groups - Complete shard count.
14
- * @property {string} pathBase - Profiling path-base semantics.
15
- * @property {string} testFileSetHash - Complete canonical file-set identity.
16
- * @property {TimingManifest} timingManifest - Canonical shard timing map.
17
- */
18
-
19
- /**
20
- * TestProfileTimingManifestInput type.
21
- * @typedef {object} TestProfileTimingManifestInput
22
- * @property {ReturnType<typeof JSON.parse>} profile - Parsed rich test profile.
23
- * @property {string} source - Human-readable input source for validation errors.
24
- */
25
-
26
- /**
27
- * Canonicalizes a timing-manifest path relative to its profiling base.
28
- * @param {string} filePath - Candidate relative path.
29
- * @returns {string} - Portable canonical path.
30
- */
31
- export function canonicalTimingManifestPath(filePath) {
32
- if (typeof filePath !== "string" || filePath.length === 0) {
33
- throw new Error("Timing manifest keys must be non-empty relative paths")
34
- }
35
-
36
- const portablePath = filePath.replaceAll("\\", "/")
37
-
38
- if (portablePath.startsWith("/") || /^[A-Za-z]:/.test(portablePath)) {
39
- throw new Error(`Timing manifest key must be a relative path: ${filePath}`)
40
- }
41
-
42
- const segments = []
43
-
44
- for (const segment of portablePath.split("/")) {
45
- if (!segment || segment === ".") continue
46
-
47
- if (segment === "..") {
48
- if (segments.length === 0) {
49
- throw new Error(`Timing manifest key must be a non-escaping relative path: ${filePath}`)
50
- }
51
-
52
- segments.pop()
53
- continue
54
- }
55
-
56
- segments.push(segment)
57
- }
58
-
59
- if (segments.length === 0) {
60
- throw new Error(`Timing manifest key must be a non-empty relative path: ${filePath}`)
61
- }
62
-
63
- return segments.join("/")
64
- }
65
-
66
- /**
67
- * Compares timing-manifest paths by JavaScript code units without locale rules.
68
- * @param {string} filePathA - First path.
69
- * @param {string} filePathB - Second path.
70
- * @returns {number} - Negative, zero, or positive ordering result.
71
- */
72
- export function compareTimingManifestPaths(filePathA, filePathB) {
73
- if (filePathA === filePathB) return 0
74
-
75
- return filePathA < filePathB ? -1 : 1
76
- }
77
-
78
- /**
79
- * Validates and sorts a plain timing manifest.
80
- * @param {ReturnType<typeof JSON.parse>} timingManifest - Parsed timing manifest.
81
- * @param {{source?: string}} [options] - Validation context.
82
- * @returns {TimingManifest} - Canonical sorted timing manifest.
83
- */
84
- export function validateTimingManifest(timingManifest, {source = "timing manifest"} = {}) {
85
- if (!timingManifest || typeof timingManifest !== "object" || Array.isArray(timingManifest)) {
86
- throw new Error(`${source} must be a plain JSON object mapping relative paths to durations`)
87
- }
88
-
89
- /** @type {Map<string, {duration: number, originalPath: string}>} */
90
- const entries = new Map()
91
-
92
- for (const [originalPath, duration] of Object.entries(timingManifest)) {
93
- if (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0) {
94
- throw new Error(`${source} has an invalid duration for ${originalPath}`)
95
- }
96
-
97
- const canonicalPath = canonicalTimingManifestPath(originalPath)
98
- const existing = entries.get(canonicalPath)
99
-
100
- if (existing) {
101
- throw new Error(`${source} has a normalized path collision between ${existing.originalPath} and ${originalPath}`)
102
- }
103
-
104
- entries.set(canonicalPath, {duration, originalPath})
105
- }
106
-
107
- return Object.fromEntries(
108
- [...entries.entries()]
109
- .sort(([filePathA], [filePathB]) => compareTimingManifestPaths(filePathA, filePathB))
110
- .map(([filePath, entry]) => [filePath, entry.duration])
111
- )
112
- }
113
-
114
- /**
115
- * Returns an opaque deterministic identity for a complete canonical test-file set.
116
- * @param {string[]} filePaths - Paths relative to one profiling base.
117
- * @returns {string} - SHA-256 file-set identity.
118
- */
119
- export function timingManifestFileSetHash(filePaths) {
120
- const pathManifest = Object.fromEntries(filePaths.map((filePath) => [filePath, 0]))
121
- const canonicalPaths = Object.keys(validateTimingManifest(pathManifest, {source: "test file set"}))
122
- const identity = `velocious.test-file-set.v1\0${canonicalPaths.join("\0")}`
123
-
124
- return `sha256:${sha256Hex(identity)}`
125
- }
126
-
127
- /**
128
- * Validates that a parsed JSON value is a non-array object.
129
- * @param {ReturnType<typeof JSON.parse>} value - Candidate object.
130
- * @param {string} message - Validation error message.
131
- * @returns {void}
132
- */
133
- function assertJsonObject(value, message) {
134
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(message)
135
- }
136
-
137
- /**
138
- * Requires unfiltered, non-focused profile selection metadata.
139
- * @param {ReturnType<typeof JSON.parse>} selection - Rich profile selection.
140
- * @param {string} source - Input source.
141
- * @returns {void}
142
- */
143
- function assertCompleteSelection(selection, source) {
144
- if (selection.focused !== false) throw new Error(`${source} must not be a focused test profile`)
145
-
146
- const selectionFilters = [
147
- [selection.includeTagCount, 0],
148
- [selection.excludeTagCount, 0],
149
- [selection.hasExampleFilters, false],
150
- [selection.hasLineFilters, false]
151
- ]
152
-
153
- if (selectionFilters.some(([value, expected]) => value !== expected)) {
154
- throw new Error(`${source} must not be a filtered test profile`)
155
- }
156
- }
157
-
158
- /**
159
- * Validates shard numbering metadata.
160
- * @param {ReturnType<typeof JSON.parse>} shard - Candidate shard selection.
161
- * @param {string} source - Input source.
162
- * @returns {{groupNumber: number, groups: number}} - Validated shard numbers.
163
- */
164
- function validatedShardNumbers(shard, source) {
165
- assertJsonObject(shard, `${source} is missing shard metadata`)
166
-
167
- if (!Number.isInteger(shard.groups) || shard.groups < 1) {
168
- throw new Error(`${source} has an invalid shard group count`)
169
- }
170
-
171
- if (!Number.isInteger(shard.groupNumber) || shard.groupNumber < 1 || shard.groupNumber > shard.groups) {
172
- throw new Error(`${source} has an invalid shard number`)
173
- }
174
-
175
- return {groupNumber: shard.groupNumber, groups: shard.groups}
176
- }
177
-
178
- /**
179
- * Validates a non-negative integer selection count.
180
- * @param {ReturnType<typeof JSON.parse>} value - Candidate count.
181
- * @param {string} message - Validation error message.
182
- * @returns {number} - Validated count.
183
- */
184
- function validatedSelectionCount(value, message) {
185
- if (!Number.isInteger(value) || value < 0) throw new Error(message)
186
-
187
- return value
188
- }
189
-
190
- /**
191
- * Validates the selection identity used across shard profiles.
192
- * @param {ReturnType<typeof JSON.parse>} selection - Rich profile selection.
193
- * @param {string} source - Input source.
194
- * @returns {{pathBase: string, testFileSetHash: string}} - Validated identity.
195
- */
196
- function validatedSelectionIdentity(selection, source) {
197
- if (!["configuration-directory", "test-directory"].includes(selection.pathBase)) {
198
- throw new Error(`${source} has an invalid timing manifest path base`)
199
- }
200
-
201
- if (typeof selection.testFileSetHash !== "string" || !/^sha256:[a-f0-9]{64}$/.test(selection.testFileSetHash)) {
202
- throw new Error(`${source} has an invalid test file set identity`)
203
- }
204
-
205
- return {pathBase: selection.pathBase, testFileSetHash: selection.testFileSetHash}
206
- }
207
-
208
- /**
209
- * Validates one rich profile and returns its aggregation contract.
210
- * @param {TestProfileTimingManifestInput} input - Profile input.
211
- * @returns {ValidatedProfileShard} - Validated shard contract.
212
- */
213
- function validatedProfileShard(input) {
214
- const {profile, source} = input
215
-
216
- assertJsonObject(profile, `${source} must be a rich Velocious test profile`)
217
-
218
- if (profile.schema !== "velocious.test-profile" || profile.schemaVersion !== 1) {
219
- throw new Error(`${source} has an incompatible Velocious test profile schema`)
220
- }
221
-
222
- if (profile.status !== "passed") throw new Error(`${source} must have passed status for timing aggregation`)
223
-
224
- const selection = profile.selection
225
-
226
- assertJsonObject(selection, `${source} is missing test profile selection metadata`)
227
- assertCompleteSelection(selection, source)
228
- const {groupNumber, groups} = validatedShardNumbers(selection.shard, source)
229
- const discoveredFileCount = validatedSelectionCount(
230
- selection.discoveredFileCount,
231
- `${source} has an invalid pre-shard discovered file count`
232
- )
233
- const fileCount = validatedSelectionCount(
234
- selection.fileCount,
235
- `${source} has an invalid post-shard file count`
236
- )
237
- const {pathBase, testFileSetHash} = validatedSelectionIdentity(selection, source)
238
-
239
- const timingManifest = validateTimingManifest(profile.timingManifest, {source: `${source} timing manifest`})
240
-
241
- if (Object.keys(timingManifest).length !== fileCount) {
242
- throw new Error(`${source} timing manifest does not match its post-shard file count`)
243
- }
244
-
245
- return {
246
- discoveredFileCount,
247
- fileCount,
248
- groupNumber,
249
- groups,
250
- pathBase,
251
- testFileSetHash,
252
- timingManifest
253
- }
254
- }
255
-
256
- /**
257
- * Requires one shard to describe the same complete selection as the first.
258
- * @param {ValidatedProfileShard} shard - Candidate shard.
259
- * @param {ValidatedProfileShard} expected - First shard contract.
260
- * @param {string} source - Candidate source.
261
- * @returns {void}
262
- */
263
- function assertCompatibleShard(shard, expected, source) {
264
- if (shard.groups !== expected.groups) throw new Error(`${source} has a different shard group count`)
265
- if (shard.pathBase !== expected.pathBase) throw new Error(`${source} has a different timing manifest path base`)
266
- if (shard.discoveredFileCount !== expected.discoveredFileCount) throw new Error(`${source} has a different discovered file count`)
267
- if (shard.testFileSetHash !== expected.testFileSetHash) throw new Error(`${source} has a different test file set identity`)
268
- }
269
-
270
- /**
271
- * Adds one validated shard timing map without allowing duplicate canonical keys.
272
- * @param {object} args - Merge state.
273
- * @param {Map<string, {duration: number, source: string}>} args.mergedEntries - Destination timing entries.
274
- * @param {ValidatedProfileShard} args.shard - Candidate shard.
275
- * @param {string} args.source - Candidate source.
276
- * @returns {void}
277
- */
278
- function mergeShardTimingManifest({mergedEntries, shard, source}) {
279
- for (const [filePath, duration] of Object.entries(shard.timingManifest)) {
280
- const existingEntry = mergedEntries.get(filePath)
281
-
282
- if (existingEntry) {
283
- throw new Error(`Duplicate timing path ${filePath} in ${existingEntry.source} and ${source}`)
284
- }
285
-
286
- mergedEntries.set(filePath, {duration, source})
287
- }
288
- }
289
-
290
- /**
291
- * Merges a complete compatible set of rich Velocious shard profiles.
292
- * @param {TestProfileTimingManifestInput[]} inputs - Parsed profile documents and sources.
293
- * @returns {TimingManifest} - Complete sorted plain timing manifest.
294
- */
295
- export function mergeTestProfileTimingManifests(inputs) {
296
- if (inputs.length === 0) throw new Error("At least one rich test profile is required")
297
-
298
- const shards = inputs.map((input) => validatedProfileShard(input))
299
- const expected = shards[0]
300
- /** @type {Map<number, string>} */
301
- const shardSources = new Map()
302
- /** @type {Map<string, {duration: number, source: string}>} */
303
- const mergedEntries = new Map()
304
- let selectedFileCount = 0
305
-
306
- for (let index = 0; index < shards.length; index++) {
307
- const shard = shards[index]
308
- const source = inputs[index].source
309
-
310
- assertCompatibleShard(shard, expected, source)
311
-
312
- const existingShardSource = shardSources.get(shard.groupNumber)
313
-
314
- if (existingShardSource) {
315
- throw new Error(`Duplicate shard ${shard.groupNumber} in ${existingShardSource} and ${source}`)
316
- }
317
-
318
- shardSources.set(shard.groupNumber, source)
319
- selectedFileCount += shard.fileCount
320
- mergeShardTimingManifest({mergedEntries, shard, source})
321
- }
322
-
323
- const missingShardNumbers = []
324
-
325
- for (let groupNumber = 1; groupNumber <= expected.groups; groupNumber++) {
326
- if (!shardSources.has(groupNumber)) missingShardNumbers.push(groupNumber)
327
- }
328
-
329
- if (missingShardNumbers.length > 0) {
330
- throw new Error(`Missing shard profiles: ${missingShardNumbers.join(", ")}`)
331
- }
332
-
333
- if (selectedFileCount !== expected.discoveredFileCount || mergedEntries.size !== expected.discoveredFileCount) {
334
- throw new Error("Merged timing manifest does not cover the complete file universe")
335
- }
336
-
337
- const merged = Object.fromEntries(
338
- [...mergedEntries].map(([filePath, entry]) => [filePath, entry.duration])
339
- )
340
-
341
- if (timingManifestFileSetHash(Object.keys(merged)) !== expected.testFileSetHash) {
342
- throw new Error("Merged timing manifest does not match the complete file universe")
343
- }
344
-
345
- return validateTimingManifest(merged, {source: "merged timing manifest"})
346
- }
3
+ /** @typedef {import("@velocious/testing/node").TimingManifest} TimingManifest */
4
+ /** @typedef {import("@velocious/testing/node").TestProfileTimingManifestInput} TestProfileTimingManifestInput */
5
+
6
+ export {
7
+ canonicalTimingManifestPath,
8
+ compareTimingManifestPaths,
9
+ mergeTestProfileTimingManifests,
10
+ timingManifestFileSetHash,
11
+ validateTimingManifest
12
+ } from "@velocious/testing/node"
@@ -148,10 +148,16 @@ export default class VelociousAttemptExecutor {
148
148
  await testRunner.registerTransactionalTenant(args, transactionalTenantRegistrations)
149
149
  }
150
150
  const profiler = testRunner._profiler
151
+ const profileTestData = {
152
+ ...test,
153
+ filePath: testData.filePath,
154
+ line: testData.line,
155
+ ownerFilePath: testData.ownerFilePath ?? metadata.ownerFilePath
156
+ }
151
157
  const profileAttempt = profiler?.startAttempt({
152
158
  descriptions,
153
159
  attemptNumber,
154
- testData,
160
+ testData: profileTestData,
155
161
  testDescription
156
162
  })
157
163
 
@@ -1,15 +0,0 @@
1
- export default class BaseExpect {
2
- /**
3
- * Runs run before.
4
- * @abstract
5
- * @returns {Promise<void>} - Resolves when complete.
6
- */
7
- runBefore(): Promise<void>;
8
- /**
9
- * Runs run after.
10
- * @abstract
11
- * @returns {Promise<void>} - Resolves when complete.
12
- */
13
- runAfter(): Promise<void>;
14
- }
15
- //# sourceMappingURL=base-expect.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"base-expect.d.ts","sourceRoot":"","sources":["../../../src/testing/base-expect.js"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAO,UAAU;IAC7B;;;;OAIG;IACG,SAAS,IAFF,OAAO,CAAC,IAAI,CAAC,CAEY;IAEtC;;;;OAIG;IACG,QAAQ,IAFD,OAAO,CAAC,IAAI,CAAC,CAEW;CACtC"}
@@ -1,16 +0,0 @@
1
- // @ts-check
2
- export default class BaseExpect {
3
- /**
4
- * Runs run before.
5
- * @abstract
6
- * @returns {Promise<void>} - Resolves when complete.
7
- */
8
- async runBefore() { }
9
- /**
10
- * Runs run after.
11
- * @abstract
12
- * @returns {Promise<void>} - Resolves when complete.
13
- */
14
- async runAfter() { }
15
- }
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1leHBlY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy9iYXNlLWV4cGVjdC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosTUFBTSxDQUFDLE9BQU8sT0FBTyxVQUFVO0lBQzdCOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsU0FBUyxLQUFzQixDQUFDO0lBRXRDOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsUUFBUSxLQUFzQixDQUFDO0NBQ3RDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2VFeHBlY3Qge1xuICAvKipcbiAgICogUnVucyBydW4gYmVmb3JlLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bkJlZm9yZSgpIHsgLyogZG8gbm90aGluZyAqLyB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIGFmdGVyLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bkFmdGVyKCkgeyAvKiBkbyBub3RoaW5nICovIH1cbn1cbiJdfQ==
@@ -1,32 +0,0 @@
1
- import BaseExpect from "./base-expect.js";
2
- export default class ExpectToChange extends BaseExpect {
3
- expect: import("./expect.js").default;
4
- changeCallback: () => Promise<number>;
5
- count: number | undefined;
6
- oldCount: number | undefined;
7
- newCount: number | undefined;
8
- /**
9
- * Runs constructor.
10
- * @param {object} args - Options object.
11
- * @param {() => Promise<number>} args.changeCallback - Change callback.
12
- * @param {import("./expect.js").default} args.expect - Expect.
13
- */
14
- constructor({ changeCallback, expect, ...restArgs }: {
15
- changeCallback: () => Promise<number>;
16
- expect: import("./expect.js").default;
17
- });
18
- /**
19
- * Runs by.
20
- * @param {number} count - Count value.
21
- * @returns {import("./expect.js").default} - The by.
22
- */
23
- by(count: number): import("./expect.js").default;
24
- runBefore(): Promise<void>;
25
- runAfter(): Promise<void>;
26
- /**
27
- * Runs execute.
28
- * @returns {Promise<void>} - Resolves when complete.
29
- */
30
- execute(): Promise<void>;
31
- }
32
- //# sourceMappingURL=expect-to-change.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"expect-to-change.d.ts","sourceRoot":"","sources":["../../../src/testing/expect-to-change.js"],"names":[],"mappings":"AAEA,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAGzC,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU;IAW7C,MAAM;IACN,cAAc,QARJ,OAAO,CAAC,MAAM,CAAC;IAiBzB,KAAK;IAML,QAAQ;IAIR,QAAQ;IA9Bf;;;;;OAKG;IACH,YAAY,EAAC,cAAc,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAC,EAH9C;QAAoC,cAAc,EAA1C,MAAM,OAAO,CAAC,MAAM,CAAC,CAC7B;QAA4C,MAAM,EAA1C,OAAO,aAAa,EAAE,OAAO,CACvC;KACgD,EAMhD;IAED;;;;OAIG;IACH,EAAE,CAAC,KAAK,EAHG,MAGH,GAFK,OAAO,aAAa,EAAE,OAAO,CAMzC;IAEK,SAAS,kBAEd;IAEK,QAAQ,kBAEb;IAED;;;OAGG;IACG,OAAO,IAFA,OAAO,CAAC,IAAI,CAAC,CAYzB;CACF"}
@@ -1,46 +0,0 @@
1
- // @ts-check
2
- import BaseExpect from "./base-expect.js";
3
- import restArgsError from "../utils/rest-args-error.js";
4
- export default class ExpectToChange extends BaseExpect {
5
- /**
6
- * Runs constructor.
7
- * @param {object} args - Options object.
8
- * @param {() => Promise<number>} args.changeCallback - Change callback.
9
- * @param {import("./expect.js").default} args.expect - Expect.
10
- */
11
- constructor({ changeCallback, expect, ...restArgs }) {
12
- super();
13
- restArgsError(restArgs);
14
- this.expect = expect;
15
- this.changeCallback = changeCallback;
16
- }
17
- /**
18
- * Runs by.
19
- * @param {number} count - Count value.
20
- * @returns {import("./expect.js").default} - The by.
21
- */
22
- by(count) {
23
- this.count = count;
24
- return this.expect;
25
- }
26
- async runBefore() {
27
- this.oldCount = await this.changeCallback();
28
- }
29
- async runAfter() {
30
- this.newCount = await this.changeCallback();
31
- }
32
- /**
33
- * Runs execute.
34
- * @returns {Promise<void>} - Resolves when complete.
35
- */
36
- async execute() {
37
- if (this.newCount === undefined || this.oldCount === undefined) {
38
- throw new Error("ExpectToChange not executed properly");
39
- }
40
- const difference = this.newCount - this.oldCount;
41
- if (difference != this.count) {
42
- throw new Error(`Expected to change by ${this.count} but changed by ${difference}`);
43
- }
44
- }
45
- }
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwZWN0LXRvLWNoYW5nZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL2V4cGVjdC10by1jaGFuZ2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sVUFBVSxNQUFNLGtCQUFrQixDQUFBO0FBQ3pDLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBRXZELE1BQU0sQ0FBQyxPQUFPLE9BQU8sY0FBZSxTQUFRLFVBQVU7SUFDcEQ7Ozs7O09BS0c7SUFDSCxZQUFZLEVBQUMsY0FBYyxFQUFFLE1BQU0sRUFBRSxHQUFHLFFBQVEsRUFBQztRQUMvQyxLQUFLLEVBQUUsQ0FBQTtRQUNQLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUV2QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQTtJQUN0QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEVBQUUsQ0FBQyxLQUFLO1FBQ04sSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUE7UUFFbEIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFBO0lBQ3BCLENBQUM7SUFFRCxLQUFLLENBQUMsU0FBUztRQUNiLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUE7SUFDN0MsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRO1FBQ1osSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQTtJQUM3QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLE9BQU87UUFDWCxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFBO1FBQ3pELENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUE7UUFFaEQsSUFBSSxVQUFVLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLElBQUksQ0FBQyxLQUFLLG1CQUFtQixVQUFVLEVBQUUsQ0FBQyxDQUFBO1FBQ3JGLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IEJhc2VFeHBlY3QgZnJvbSBcIi4vYmFzZS1leHBlY3QuanNcIlxuaW1wb3J0IHJlc3RBcmdzRXJyb3IgZnJvbSBcIi4uL3V0aWxzL3Jlc3QtYXJncy1lcnJvci5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV4cGVjdFRvQ2hhbmdlIGV4dGVuZHMgQmFzZUV4cGVjdCB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8bnVtYmVyPn0gYXJncy5jaGFuZ2VDYWxsYmFjayAtIENoYW5nZSBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4cGVjdC5qc1wiKS5kZWZhdWx0fSBhcmdzLmV4cGVjdCAtIEV4cGVjdC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjaGFuZ2VDYWxsYmFjaywgZXhwZWN0LCAuLi5yZXN0QXJnc30pIHtcbiAgICBzdXBlcigpXG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIHRoaXMuZXhwZWN0ID0gZXhwZWN0XG4gICAgdGhpcy5jaGFuZ2VDYWxsYmFjayA9IGNoYW5nZUNhbGxiYWNrXG4gIH1cblxuICAvKipcbiAgICogUnVucyBieS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gQ291bnQgdmFsdWUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2V4cGVjdC5qc1wiKS5kZWZhdWx0fSAtIFRoZSBieS5cbiAgICovXG4gIGJ5KGNvdW50KSB7XG4gICAgdGhpcy5jb3VudCA9IGNvdW50XG5cbiAgICByZXR1cm4gdGhpcy5leHBlY3RcbiAgfVxuXG4gIGFzeW5jIHJ1bkJlZm9yZSgpIHtcbiAgICB0aGlzLm9sZENvdW50ID0gYXdhaXQgdGhpcy5jaGFuZ2VDYWxsYmFjaygpXG4gIH1cblxuICBhc3luYyBydW5BZnRlcigpIHtcbiAgICB0aGlzLm5ld0NvdW50ID0gYXdhaXQgdGhpcy5jaGFuZ2VDYWxsYmFjaygpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBleGVjdXRlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICBpZiAodGhpcy5uZXdDb3VudCA9PT0gdW5kZWZpbmVkIHx8IHRoaXMub2xkQ291bnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0VG9DaGFuZ2Ugbm90IGV4ZWN1dGVkIHByb3Blcmx5XCIpXG4gICAgfVxuXG4gICAgY29uc3QgZGlmZmVyZW5jZSA9IHRoaXMubmV3Q291bnQgLSB0aGlzLm9sZENvdW50XG5cbiAgICBpZiAoZGlmZmVyZW5jZSAhPSB0aGlzLmNvdW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHRvIGNoYW5nZSBieSAke3RoaXMuY291bnR9IGJ1dCBjaGFuZ2VkIGJ5ICR7ZGlmZmVyZW5jZX1gKVxuICAgIH1cbiAgfVxufVxuIl19
@@ -1,17 +0,0 @@
1
- // @ts-check
2
-
3
- export default class BaseExpect {
4
- /**
5
- * Runs run before.
6
- * @abstract
7
- * @returns {Promise<void>} - Resolves when complete.
8
- */
9
- async runBefore() { /* do nothing */ }
10
-
11
- /**
12
- * Runs run after.
13
- * @abstract
14
- * @returns {Promise<void>} - Resolves when complete.
15
- */
16
- async runAfter() { /* do nothing */ }
17
- }
@@ -1,55 +0,0 @@
1
- // @ts-check
2
-
3
- import BaseExpect from "./base-expect.js"
4
- import restArgsError from "../utils/rest-args-error.js"
5
-
6
- export default class ExpectToChange extends BaseExpect {
7
- /**
8
- * Runs constructor.
9
- * @param {object} args - Options object.
10
- * @param {() => Promise<number>} args.changeCallback - Change callback.
11
- * @param {import("./expect.js").default} args.expect - Expect.
12
- */
13
- constructor({changeCallback, expect, ...restArgs}) {
14
- super()
15
- restArgsError(restArgs)
16
-
17
- this.expect = expect
18
- this.changeCallback = changeCallback
19
- }
20
-
21
- /**
22
- * Runs by.
23
- * @param {number} count - Count value.
24
- * @returns {import("./expect.js").default} - The by.
25
- */
26
- by(count) {
27
- this.count = count
28
-
29
- return this.expect
30
- }
31
-
32
- async runBefore() {
33
- this.oldCount = await this.changeCallback()
34
- }
35
-
36
- async runAfter() {
37
- this.newCount = await this.changeCallback()
38
- }
39
-
40
- /**
41
- * Runs execute.
42
- * @returns {Promise<void>} - Resolves when complete.
43
- */
44
- async execute() {
45
- if (this.newCount === undefined || this.oldCount === undefined) {
46
- throw new Error("ExpectToChange not executed properly")
47
- }
48
-
49
- const difference = this.newCount - this.oldCount
50
-
51
- if (difference != this.count) {
52
- throw new Error(`Expected to change by ${this.count} but changed by ${difference}`)
53
- }
54
- }
55
- }
@@ -1,17 +0,0 @@
1
- // @ts-check
2
-
3
- export default class BaseExpect {
4
- /**
5
- * Runs run before.
6
- * @abstract
7
- * @returns {Promise<void>} - Resolves when complete.
8
- */
9
- async runBefore() { /* do nothing */ }
10
-
11
- /**
12
- * Runs run after.
13
- * @abstract
14
- * @returns {Promise<void>} - Resolves when complete.
15
- */
16
- async runAfter() { /* do nothing */ }
17
- }
@@ -1,55 +0,0 @@
1
- // @ts-check
2
-
3
- import BaseExpect from "./base-expect.js"
4
- import restArgsError from "../utils/rest-args-error.js"
5
-
6
- export default class ExpectToChange extends BaseExpect {
7
- /**
8
- * Runs constructor.
9
- * @param {object} args - Options object.
10
- * @param {() => Promise<number>} args.changeCallback - Change callback.
11
- * @param {import("./expect.js").default} args.expect - Expect.
12
- */
13
- constructor({changeCallback, expect, ...restArgs}) {
14
- super()
15
- restArgsError(restArgs)
16
-
17
- this.expect = expect
18
- this.changeCallback = changeCallback
19
- }
20
-
21
- /**
22
- * Runs by.
23
- * @param {number} count - Count value.
24
- * @returns {import("./expect.js").default} - The by.
25
- */
26
- by(count) {
27
- this.count = count
28
-
29
- return this.expect
30
- }
31
-
32
- async runBefore() {
33
- this.oldCount = await this.changeCallback()
34
- }
35
-
36
- async runAfter() {
37
- this.newCount = await this.changeCallback()
38
- }
39
-
40
- /**
41
- * Runs execute.
42
- * @returns {Promise<void>} - Resolves when complete.
43
- */
44
- async execute() {
45
- if (this.newCount === undefined || this.oldCount === undefined) {
46
- throw new Error("ExpectToChange not executed properly")
47
- }
48
-
49
- const difference = this.newCount - this.oldCount
50
-
51
- if (difference != this.count) {
52
- throw new Error(`Expected to change by ${this.count} but changed by ${difference}`)
53
- }
54
- }
55
- }