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 +1 @@
1
- {"version":3,"file":"expect-utils.d.ts","sourceRoot":"","sources":["../../../src/testing/expect-utils.js"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,KAAK,EAHpB,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGR,GAFlB;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAA;CAAC,CAW9E;AAED;;;;GAIG;AACH,iBAAS,eAAe,CAAC,KAAK,EAHnB,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGT,GAFjB;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAA;CAAC,CAW9E;AAWD;;;;GAIG;AACH,iBAAS,iBAAiB,CAAC,KAAK,EAHrB,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGP,GAFnB,OAAO,CAInB;AAED;;;;GAIG;AACH,iBAAS,kBAAkB,CAAC,KAAK,EAHtB,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGN,GAFpB,OAAO,CAInB;AAmGD;;;;;GAKG;AACH,iBAAS,WAAW,CAAC,MAAM,EAJhB,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAIZ,EAAE,QAAQ,EAH1B,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAGzD,GAFxB;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;CAAC,CAcjG;AAED;;;;;GAKG;AACH,iBAAS,oBAAoB,CAAC,MAAM,EAJzB,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAIH,EAAE,QAAQ,EAHnC,KAAK,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAGA,GAFjC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;CAAC,CAyDjG;AAED,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EACjB,CAAA"}
1
+ {"version":3,"file":"expect-utils.d.ts","sourceRoot":"","sources":["../../../src/testing/expect-utils.js"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EACjB,MAAM,oBAAoB,CAAA"}
@@ -1,206 +1,3 @@
1
1
  // @ts-check
2
- import { anythingDifferent } from "set-state-compare/build/diff-utils.js";
3
- /**
4
- * Runs object containing.
5
- * @param {ReturnType<typeof JSON.parse>} value - Value.
6
- * @returns {{__velociousMatcher: string, value: ReturnType<typeof JSON.parse>}} - Matcher wrapper.
7
- */
8
- function objectContaining(value) {
9
- if (value === null || typeof value !== "object") {
10
- throw new Error(`Expected object but got ${typeof value}`);
11
- }
12
- return {
13
- __velociousMatcher: "objectContaining",
14
- value
15
- };
16
- }
17
- /**
18
- * Runs array containing.
19
- * @param {ReturnType<typeof JSON.parse>} value - Value.
20
- * @returns {{__velociousMatcher: string, value: ReturnType<typeof JSON.parse>}} - Matcher wrapper.
21
- */
22
- function arrayContaining(value) {
23
- if (!Array.isArray(value)) {
24
- throw new Error(`Expected array but got ${typeof value}`);
25
- }
26
- return {
27
- __velociousMatcher: "arrayContaining",
28
- value
29
- };
30
- }
31
- /**
32
- * Runs is object like.
33
- * @param {ReturnType<typeof JSON.parse>} value - Value.
34
- * @returns {boolean} - Whether object-like.
35
- */
36
- function isObjectLike(value) {
37
- return value !== null && typeof value === "object";
38
- }
39
- /**
40
- * Runs is array containing.
41
- * @param {ReturnType<typeof JSON.parse>} value - Value.
42
- * @returns {boolean} - Whether arrayContaining matcher.
43
- */
44
- function isArrayContaining(value) {
45
- return !!value && typeof value === "object" && /** @type {ReturnType<typeof JSON.parse>} */ (value).__velociousMatcher === "arrayContaining";
46
- }
47
- /**
48
- * Runs is object containing.
49
- * @param {ReturnType<typeof JSON.parse>} value - Value.
50
- * @returns {boolean} - Whether objectContaining matcher.
51
- */
52
- function isObjectContaining(value) {
53
- return !!value && typeof value === "object" && /** @type {ReturnType<typeof JSON.parse>} */ (value).__velociousMatcher === "objectContaining";
54
- }
55
- /**
56
- * Runs is plain object.
57
- * @param {ReturnType<typeof JSON.parse>} value - Value.
58
- * @returns {boolean} - Whether plain object.
59
- */
60
- function isPlainObject(value) {
61
- if (!value || typeof value !== "object")
62
- return false;
63
- const prototype = Object.getPrototypeOf(value);
64
- return prototype === Object.prototype || prototype === null;
65
- }
66
- /**
67
- * Runs values equal.
68
- * @param {ReturnType<typeof JSON.parse>} actual - Actual value.
69
- * @param {ReturnType<typeof JSON.parse>} expected - Expected value.
70
- * @returns {boolean} - Whether values are equal.
71
- */
72
- function valuesEqual(actual, expected) {
73
- if (actual instanceof Date && expected instanceof Date) {
74
- return actual.getTime() === expected.getTime();
75
- }
76
- if (actual instanceof RegExp && expected instanceof RegExp) {
77
- return actual.source === expected.source && actual.flags === expected.flags;
78
- }
79
- return Object.is(actual, expected);
80
- }
81
- /**
82
- * Runs collect match differences.
83
- * @param {ReturnType<typeof JSON.parse>} actual - Actual value.
84
- * @param {ReturnType<typeof JSON.parse>} expected - Expected value.
85
- * @param {string} path - Path.
86
- * @param {Record<string, Array<ReturnType<typeof JSON.parse>>>} differences - Differences.
87
- * @returns {void} - No return value.
88
- */
89
- function collectMatchDifferences(actual, expected, path, differences) {
90
- if (isObjectContaining(expected)) {
91
- collectMatchDifferences(actual, /** @type {ReturnType<typeof JSON.parse>} */ (expected).value, path, differences);
92
- return;
93
- }
94
- if (isArrayContaining(expected)) {
95
- const { matches } = matchArrayContaining(actual, /** @type {Array<ReturnType<typeof JSON.parse>>} */ ( /** @type {ReturnType<typeof JSON.parse>} */(expected).value));
96
- if (!matches) {
97
- differences[path || "$"] = [expected, actual];
98
- }
99
- return;
100
- }
101
- if (Array.isArray(expected)) {
102
- if (!Array.isArray(actual)) {
103
- differences[path || "$"] = [expected, actual];
104
- return;
105
- }
106
- for (let i = 0; i < expected.length; i++) {
107
- const nextPath = `${path}[${i}]`;
108
- collectMatchDifferences(actual[i], expected[i], nextPath, differences);
109
- }
110
- return;
111
- }
112
- if (isPlainObject(expected)) {
113
- if (!isObjectLike(actual)) {
114
- differences[path || "$"] = [expected, actual];
115
- return;
116
- }
117
- const expectedObject = /** @type {Record<string, ReturnType<typeof JSON.parse>>} */ (expected);
118
- const actualObject = /** @type {Record<string, ReturnType<typeof JSON.parse>>} */ (actual);
119
- for (const key of Object.keys(expectedObject)) {
120
- const nextPath = path ? `${path}.${key}` : key;
121
- if (!Object.prototype.hasOwnProperty.call(actualObject, key)) {
122
- differences[nextPath] = [expectedObject[key], undefined];
123
- continue;
124
- }
125
- collectMatchDifferences(actualObject[key], expectedObject[key], nextPath, differences);
126
- }
127
- return;
128
- }
129
- if (!valuesEqual(actual, expected)) {
130
- differences[path || "$"] = [expected, actual];
131
- }
132
- }
133
- /**
134
- * Runs match object.
135
- * @param {ReturnType<typeof JSON.parse>} actual - Actual value.
136
- * @param {Record<string, ReturnType<typeof JSON.parse>> | Array<ReturnType<typeof JSON.parse>>} expected - Expected value.
137
- * @returns {{matches: boolean, differences: Record<string, Array<ReturnType<typeof JSON.parse>>>}} - Match result.
138
- */
139
- function matchObject(actual, expected) {
140
- /**
141
- * Differences.
142
- * @type {Record<string, Array<ReturnType<typeof JSON.parse>>>} */
143
- const differences = {};
144
- collectMatchDifferences(actual, expected, "", differences);
145
- return {
146
- matches: Object.keys(differences).length === 0,
147
- differences
148
- };
149
- }
150
- /**
151
- * Runs match array containing.
152
- * @param {ReturnType<typeof JSON.parse>} actual - Actual value.
153
- * @param {Array<ReturnType<typeof JSON.parse>>} expected - Expected values.
154
- * @returns {{matches: boolean, differences: Record<string, Array<ReturnType<typeof JSON.parse>>>}} - Match result.
155
- */
156
- function matchArrayContaining(actual, expected) {
157
- /**
158
- * Differences.
159
- * @type {Record<string, Array<ReturnType<typeof JSON.parse>>>} */
160
- const differences = {};
161
- if (!Array.isArray(actual)) {
162
- differences["$"] = [expected, actual];
163
- return { matches: false, differences };
164
- }
165
- const usedIndexes = new Set();
166
- for (const expectedItem of expected) {
167
- let matchedIndex = -1;
168
- for (let i = 0; i < actual.length; i++) {
169
- if (usedIndexes.has(i))
170
- continue;
171
- if (isObjectContaining(expectedItem)) {
172
- const { matches } = matchObject(actual[i], /** @type {ReturnType<typeof JSON.parse>} */ (expectedItem).value);
173
- if (matches) {
174
- matchedIndex = i;
175
- break;
176
- }
177
- continue;
178
- }
179
- if (isArrayContaining(expectedItem)) {
180
- const { matches } = matchArrayContaining(actual[i], /** @type {ReturnType<typeof JSON.parse>} */ (expectedItem).value);
181
- if (matches) {
182
- matchedIndex = i;
183
- break;
184
- }
185
- continue;
186
- }
187
- if (!anythingDifferent(actual[i], expectedItem)) {
188
- matchedIndex = i;
189
- break;
190
- }
191
- }
192
- if (matchedIndex >= 0) {
193
- usedIndexes.add(matchedIndex);
194
- }
195
- else {
196
- differences["$"] = [expected, actual];
197
- break;
198
- }
199
- }
200
- return {
201
- matches: Object.keys(differences).length === 0,
202
- differences
203
- };
204
- }
205
- export { arrayContaining, isArrayContaining, isObjectContaining, matchArrayContaining, matchObject, objectContaining };
206
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwZWN0LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Rlc3RpbmcvZXhwZWN0LXV0aWxzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSx1Q0FBdUMsQ0FBQTtBQUV2RTs7OztHQUlHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFLO0lBQzdCLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNoRCxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixPQUFPLEtBQUssRUFBRSxDQUFDLENBQUE7SUFDNUQsQ0FBQztJQUVELE9BQU87UUFDTCxrQkFBa0IsRUFBRSxrQkFBa0I7UUFDdEMsS0FBSztLQUNOLENBQUE7QUFDSCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsZUFBZSxDQUFDLEtBQUs7SUFDNUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixPQUFPLEtBQUssRUFBRSxDQUFDLENBQUE7SUFDM0QsQ0FBQztJQUVELE9BQU87UUFDTCxrQkFBa0IsRUFBRSxpQkFBaUI7UUFDckMsS0FBSztLQUNOLENBQUE7QUFDSCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsWUFBWSxDQUFDLEtBQUs7SUFDekIsT0FBTyxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQTtBQUNwRCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsaUJBQWlCLENBQUMsS0FBSztJQUM5QixPQUFPLENBQUMsQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFLLDRDQUE0QyxDQUFDLENBQUMsS0FBSyxDQUFFLENBQUMsa0JBQWtCLEtBQUssaUJBQWlCLENB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Q0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge2FueXRoaW5nRGlmZmVyZW50fSBmcm9tIFwic2V0LXN0YXRlLWNvbXBhcmUvYnVpbGQvZGlmZi11dGlscy5qc1wiXG5cbi8qKlxuICogUnVucyBvYmplY3QgY29udGFpbmluZy5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHZhbHVlIC0gVmFsdWUuXG4gKiBAcmV0dXJucyB7e19fdmVsb2Npb3VzTWF0Y2hlcjogc3RyaW5nLCB2YWx1ZTogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59fSAtIE1hdGNoZXIgd3JhcHBlci5cbiAqL1xuZnVuY3Rpb24gb2JqZWN0Q29udGFpbmluZyh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBvYmplY3QgYnV0IGdvdCAke3R5cGVvZiB2YWx1ZX1gKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBfX3ZlbG9jaW91c01hdGNoZXI6IFwib2JqZWN0Q29udGFpbmluZ1wiLFxuICAgIHZhbHVlXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIGFycmF5IGNvbnRhaW5pbmcuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSB2YWx1ZSAtIFZhbHVlLlxuICogQHJldHVybnMge3tfX3ZlbG9jaW91c01hdGNoZXI6IHN0cmluZywgdmFsdWU6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fX0gLSBNYXRjaGVyIHdyYXBwZXIuXG4gKi9cbmZ1bmN0aW9uIGFycmF5Q29udGFpbmluZyh2YWx1ZSkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhcnJheSBidXQgZ290ICR7dHlwZW9mIHZhbHVlfWApXG4gIH1cblxuICByZXR1cm4ge1xuICAgIF9fdmVsb2Npb3VzTWF0Y2hlcjogXCJhcnJheUNvbnRhaW5pbmdcIixcbiAgICB2YWx1ZVxuICB9XG59XG5cbi8qKlxuICogUnVucyBpcyBvYmplY3QgbGlrZS5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHZhbHVlIC0gVmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIG9iamVjdC1saWtlLlxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIlxufVxuXG4vKipcbiAqIFJ1bnMgaXMgYXJyYXkgY29udGFpbmluZy5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHZhbHVlIC0gVmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFycmF5Q29udGFpbmluZyBtYXRjaGVyLlxuICovXG5mdW5jdGlvbiBpc0FycmF5Q29udGFpbmluZyh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgKC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59ICovICh2YWx1ZSkpLl9fdmVsb2Npb3VzTWF0Y2hlciA9PT0gXCJhcnJheUNvbnRhaW5pbmdcIlxufVxuXG4vKipcbiAqIFJ1bnMgaXMgb2JqZWN0IGNvbnRhaW5pbmcuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSB2YWx1ZSAtIFZhbHVlLlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBvYmplY3RDb250YWluaW5nIG1hdGNoZXIuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0Q29udGFpbmluZyh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgKC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59ICovICh2YWx1ZSkpLl9fdmVsb2Npb3VzTWF0Y2hlciA9PT0gXCJvYmplY3RDb250YWluaW5nXCJcbn1cblxuLyoqXG4gKiBSdW5zIGlzIHBsYWluIG9iamVjdC5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHZhbHVlIC0gVmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHBsYWluIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIikgcmV0dXJuIGZhbHNlXG5cbiAgY29uc3QgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlKVxuXG4gIHJldHVybiBwcm90b3R5cGUgPT09IE9iamVjdC5wcm90b3R5cGUgfHwgcHJvdG90eXBlID09PSBudWxsXG59XG5cbi8qKlxuICogUnVucyB2YWx1ZXMgZXF1YWwuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhY3R1YWwgLSBBY3R1YWwgdmFsdWUuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBleHBlY3RlZCAtIEV4cGVjdGVkIHZhbHVlLlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB2YWx1ZXMgYXJlIGVxdWFsLlxuICovXG5mdW5jdGlvbiB2YWx1ZXNFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIGlmIChhY3R1YWwgaW5zdGFuY2VvZiBEYXRlICYmIGV4cGVjdGVkIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiBhY3R1YWwuZ2V0VGltZSgpID09PSBleHBlY3RlZC5nZXRUaW1lKClcbiAgfVxuXG4gIGlmIChhY3R1YWwgaW5zdGFuY2VvZiBSZWdFeHAgJiYgZXhwZWN0ZWQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICByZXR1cm4gYWN0dWFsLnNvdXJjZSA9PT0gZXhwZWN0ZWQuc291cmNlICYmIGFjdHVhbC5mbGFncyA9PT0gZXhwZWN0ZWQuZmxhZ3NcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuaXMoYWN0dWFsLCBleHBlY3RlZClcbn1cblxuLyoqXG4gKiBSdW5zIGNvbGxlY3QgbWF0Y2ggZGlmZmVyZW5jZXMuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhY3R1YWwgLSBBY3R1YWwgdmFsdWUuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBleHBlY3RlZCAtIEV4cGVjdGVkIHZhbHVlLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBQYXRoLlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBBcnJheTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj4+fSBkaWZmZXJlbmNlcyAtIERpZmZlcmVuY2VzLlxuICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICovXG5mdW5jdGlvbiBjb2xsZWN0TWF0Y2hEaWZmZXJlbmNlcyhhY3R1YWwsIGV4cGVjdGVkLCBwYXRoLCBkaWZmZXJlbmNlcykge1xuICBpZiAoaXNPYmplY3RDb250YWluaW5nKGV4cGVjdGVkKSkge1xuICAgIGNvbGxlY3RNYXRjaERpZmZlcmVuY2VzKGFjdHVhbCwgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gKi8gKGV4cGVjdGVkKS52YWx1ZSwgcGF0aCwgZGlmZmVyZW5jZXMpXG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAoaXNBcnJheUNvbnRhaW5pbmcoZXhwZWN0ZWQpKSB7XG4gICAgY29uc3Qge21hdGNoZXN9ID0gbWF0Y2hBcnJheUNvbnRhaW5pbmcoYWN0dWFsLCAvKiogQHR5cGUge0FycmF5PFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gKi8gKC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59ICovIChleHBlY3RlZCkudmFsdWUpKVxuXG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICBkaWZmZXJlbmNlc1twYXRoIHx8IFwiJFwiXSA9IFtleHBlY3RlZCwgYWN0dWFsXVxuICAgIH1cblxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGFjdHVhbCkpIHtcbiAgICAgIGRpZmZlcmVuY2VzW3BhdGggfHwgXCIkXCJdID0gW2V4cGVjdGVkLCBhY3R1YWxdXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBuZXh0UGF0aCA9IGAke3BhdGh9WyR7aX1dYFxuICAgICAgY29sbGVjdE1hdGNoRGlmZmVyZW5jZXMoYWN0dWFsW2ldLCBleHBlY3RlZFtpXSwgbmV4dFBhdGgsIGRpZmZlcmVuY2VzKVxuICAgIH1cblxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKGlzUGxhaW5PYmplY3QoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKCFpc09iamVjdExpa2UoYWN0dWFsKSkge1xuICAgICAgZGlmZmVyZW5jZXNbcGF0aCB8fCBcIiRcIl0gPSBbZXhwZWN0ZWQsIGFjdHVhbF1cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGV4cGVjdGVkT2JqZWN0ID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovIChleHBlY3RlZClcbiAgICBjb25zdCBhY3R1YWxPYmplY3QgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gKi8gKGFjdHVhbClcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGV4cGVjdGVkT2JqZWN0KSkge1xuICAgICAgY29uc3QgbmV4dFBhdGggPSBwYXRoID8gYCR7cGF0aH0uJHtrZXl9YCA6IGtleVxuXG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhY3R1YWxPYmplY3QsIGtleSkpIHtcbiAgICAgICAgZGlmZmVyZW5jZXNbbmV4dFBhdGhdID0gW2V4cGVjdGVkT2JqZWN0W2tleV0sIHVuZGVmaW5lZF1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29sbGVjdE1hdGNoRGlmZmVyZW5jZXMoYWN0dWFsT2JqZWN0W2tleV0sIGV4cGVjdGVkT2JqZWN0W2tleV0sIG5leHRQYXRoLCBkaWZmZXJlbmNlcylcbiAgICB9XG5cbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmICghdmFsdWVzRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBkaWZmZXJlbmNlc1twYXRoIHx8IFwiJFwiXSA9IFtleHBlY3RlZCwgYWN0dWFsXVxuICB9XG59XG5cbi8qKlxuICogUnVucyBtYXRjaCBvYmplY3QuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhY3R1YWwgLSBBY3R1YWwgdmFsdWUuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+PiB8IEFycmF5PFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gZXhwZWN0ZWQgLSBFeHBlY3RlZCB2YWx1ZS5cbiAqIEByZXR1cm5zIHt7bWF0Y2hlczogYm9vbGVhbiwgZGlmZmVyZW5jZXM6IFJlY29yZDxzdHJpbmcsIEFycmF5PFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pj59fSAtIE1hdGNoIHJlc3VsdC5cbiAqL1xuZnVuY3Rpb24gbWF0Y2hPYmplY3QoYWN0dWFsLCBleHBlY3RlZCkge1xuICAvKipcbiAgICogRGlmZmVyZW5jZXMuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBBcnJheTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj4+fSAqL1xuICBjb25zdCBkaWZmZXJlbmNlcyA9IHt9XG5cbiAgY29sbGVjdE1hdGNoRGlmZmVyZW5jZXMoYWN0dWFsLCBleHBlY3RlZCwgXCJcIiwgZGlmZmVyZW5jZXMpXG5cbiAgcmV0dXJuIHtcbiAgICBtYXRjaGVzOiBPYmplY3Qua2V5cyhkaWZmZXJlbmNlcykubGVuZ3RoID09PSAwLFxuICAgIGRpZmZlcmVuY2VzXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIG1hdGNoIGFycmF5IGNvbnRhaW5pbmcuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhY3R1YWwgLSBBY3R1YWwgdmFsdWUuXG4gKiBAcGFyYW0ge0FycmF5PFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gZXhwZWN0ZWQgLSBFeHBlY3RlZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7e21hdGNoZXM6IGJvb2xlYW4sIGRpZmZlcmVuY2VzOiBSZWNvcmQ8c3RyaW5nLCBBcnJheTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj4+fX0gLSBNYXRjaCByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIG1hdGNoQXJyYXlDb250YWluaW5nKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgLyoqXG4gICAqIERpZmZlcmVuY2VzLlxuICAgKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgQXJyYXk8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+Pn0gKi9cbiAgY29uc3QgZGlmZmVyZW5jZXMgPSB7fVxuXG4gIGlmICghQXJyYXkuaXNBcnJheShhY3R1YWwpKSB7XG4gICAgZGlmZmVyZW5jZXNbXCIkXCJdID0gW2V4cGVjdGVkLCBhY3R1YWxdXG4gICAgcmV0dXJuIHttYXRjaGVzOiBmYWxzZSwgZGlmZmVyZW5jZXN9XG4gIH1cblxuICBjb25zdCB1c2VkSW5kZXhlcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3QgZXhwZWN0ZWRJdGVtIG9mIGV4cGVjdGVkKSB7XG4gICAgbGV0IG1hdGNoZWRJbmRleCA9IC0xXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFjdHVhbC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHVzZWRJbmRleGVzLmhhcyhpKSkgY29udGludWVcblxuICAgICAgaWYgKGlzT2JqZWN0Q29udGFpbmluZyhleHBlY3RlZEl0ZW0pKSB7XG4gICAgICAgIGNvbnN0IHttYXRjaGVzfSA9IG1hdGNoT2JqZWN0KGFjdHVhbFtpXSwgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gKi8gKGV4cGVjdGVkSXRlbSkudmFsdWUpXG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgbWF0Y2hlZEluZGV4ID0gaVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXlDb250YWluaW5nKGV4cGVjdGVkSXRlbSkpIHtcbiAgICAgICAgY29uc3Qge21hdGNoZXN9ID0gbWF0Y2hBcnJheUNvbnRhaW5pbmcoYWN0dWFsW2ldLCAvKiogQHR5cGUge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSAqLyAoZXhwZWN0ZWRJdGVtKS52YWx1ZSlcbiAgICAgICAgaWYgKG1hdGNoZXMpIHtcbiAgICAgICAgICBtYXRjaGVkSW5kZXggPSBpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoIWFueXRoaW5nRGlmZmVyZW50KGFjdHVhbFtpXSwgZXhwZWN0ZWRJdGVtKSkge1xuICAgICAgICBtYXRjaGVkSW5kZXggPSBpXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoZWRJbmRleCA+PSAwKSB7XG4gICAgICB1c2VkSW5kZXhlcy5hZGQobWF0Y2hlZEluZGV4KVxuICAgIH0gZWxzZSB7XG4gICAgICBkaWZmZXJlbmNlc1tcIiRcIl0gPSBbZXhwZWN0ZWQsIGFjdHVhbF1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtYXRjaGVzOiBPYmplY3Qua2V5cyhkaWZmZXJlbmNlcykubGVuZ3RoID09PSAwLFxuICAgIGRpZmZlcmVuY2VzXG4gIH1cbn1cblxuZXhwb3J0IHtcbiAgYXJyYXlDb250YWluaW5nLFxuICBpc0FycmF5Q29udGFpbmluZyxcbiAgaXNPYmplY3RDb250YWluaW5nLFxuICBtYXRjaEFycmF5Q29udGFpbmluZyxcbiAgbWF0Y2hPYmplY3QsXG4gIG9iamVjdENvbnRhaW5pbmdcbn1cbiJdfQ==
2
+ export { arrayContaining, isArrayContaining, isObjectContaining, matchArrayContaining, matchObject, objectContaining } from "@velocious/testing";
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwZWN0LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Rlc3RpbmcvZXhwZWN0LXV0aWxzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQ0wsZUFBZSxFQUNmLGlCQUFpQixFQUNqQixrQkFBa0IsRUFDbEIsb0JBQW9CLEVBQ3BCLFdBQVcsRUFDWCxnQkFBZ0IsRUFDakIsTUFBTSxvQkFBb0IsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5leHBvcnQge1xuICBhcnJheUNvbnRhaW5pbmcsXG4gIGlzQXJyYXlDb250YWluaW5nLFxuICBpc09iamVjdENvbnRhaW5pbmcsXG4gIG1hdGNoQXJyYXlDb250YWluaW5nLFxuICBtYXRjaE9iamVjdCxcbiAgb2JqZWN0Q29udGFpbmluZ1xufSBmcm9tIFwiQHZlbG9jaW91cy90ZXN0aW5nXCJcbiJdfQ==
@@ -1,172 +1,2 @@
1
- import BaseExpect from "./base-expect.js";
2
- import ExpectToChange from "./expect-to-change.js";
3
- export default class Expect extends BaseExpect {
4
- _object: any;
5
- /**
6
- * Narrows the runtime value to the documented type.
7
- * @type {Array<Expect | ExpectToChange>} */
8
- expectations: Array<Expect | ExpectToChange>;
9
- _not: boolean | undefined;
10
- /**
11
- * Runs constructor.
12
- * @param {ReturnType<typeof JSON.parse>} object - Object.
13
- */
14
- constructor(object: ReturnType<typeof JSON.parse>);
15
- /**
16
- * Runs and change.
17
- * @param {() => Promise<number>} changeCallback - Change callback.
18
- * @returns {ExpectToChange} - The and change.
19
- */
20
- andChange(changeCallback: () => Promise<number>): ExpectToChange;
21
- /**
22
- * Returns not.
23
- * @returns {this} - A value.
24
- */
25
- get not(): this;
26
- /**
27
- * Runs to be.
28
- * @param {ReturnType<typeof JSON.parse>} result - Result.
29
- * @returns {void} - No return value.
30
- */
31
- toBe(result: ReturnType<typeof JSON.parse>): void;
32
- /**
33
- * Runs to be less than.
34
- * @param {number} result - Result.
35
- * @returns {void} - No return value.
36
- */
37
- toBeLessThan(result: number): void;
38
- /**
39
- * Runs to be less than or equal.
40
- * @param {number} result - Result.
41
- * @returns {void} - No return value.
42
- */
43
- toBeLessThanOrEqual(result: number): void;
44
- /**
45
- * Runs to be greater than.
46
- * @param {number} result - Result.
47
- * @returns {void} - No return value.
48
- */
49
- toBeGreaterThan(result: number): void;
50
- /**
51
- * Runs to be greater than or equal.
52
- * @param {number} result - Result.
53
- * @returns {void} - No return value.
54
- */
55
- toBeGreaterThanOrEqual(result: number): void;
56
- /**
57
- * Runs to be close to.
58
- * @param {number} result - Result.
59
- * @param {number} [precision] - Decimal precision.
60
- * @returns {void} - No return value.
61
- */
62
- toBeCloseTo(result: number, precision?: number): void;
63
- /**
64
- * Runs to have length.
65
- * @param {number} result - Expected length.
66
- * @returns {void} - No return value.
67
- */
68
- toHaveLength(result: number): void;
69
- /**
70
- * Runs to be defined.
71
- * @returns {void} - No return value.
72
- */
73
- toBeDefined(): void;
74
- /**
75
- * Runs to be instance of.
76
- * @param {new (...args: Array<ReturnType<typeof JSON.parse>>) => ReturnType<typeof JSON.parse>} klass - Class constructor to check against (e.g. a built-in like Error).
77
- * @returns {void} - No return value.
78
- */
79
- toBeInstanceOf(klass: new (...args: Array<ReturnType<typeof JSON.parse>>) => ReturnType<typeof JSON.parse>): void;
80
- /**
81
- * Runs to be false.
82
- * @returns {void} - No return value.
83
- */
84
- toBeFalse(): void;
85
- /**
86
- * Runs to be null.
87
- * @returns {void} - No return value.
88
- */
89
- toBeNull(): void;
90
- /**
91
- * Runs to be undefined.
92
- * @returns {void} - No return value.
93
- */
94
- toBeUndefined(): void;
95
- /**
96
- * Runs to be true.
97
- * @returns {void} - No return value.
98
- */
99
- toBeTrue(): void;
100
- /**
101
- * Runs to be truthy.
102
- * @returns {void} - No return value.
103
- */
104
- toBeTruthy(): void;
105
- /**
106
- * Runs to change.
107
- * @param {() => Promise<number>} changeCallback - Change callback.
108
- * @returns {ExpectToChange} - The change.
109
- */
110
- toChange(changeCallback: () => Promise<number>): ExpectToChange;
111
- /**
112
- * Runs to contain.
113
- * @param {ReturnType<typeof JSON.parse>} valueToContain - Value to contain.
114
- * @returns {void} - No return value.
115
- */
116
- toContain(valueToContain: ReturnType<typeof JSON.parse>): void;
117
- /**
118
- * Runs to contain equal.
119
- * @param {ReturnType<typeof JSON.parse>} valueToContain - Value to contain.
120
- * @returns {void} - No return value.
121
- */
122
- toContainEqual(valueToContain: ReturnType<typeof JSON.parse>): void;
123
- /**
124
- * Runs to include.
125
- * @param {ReturnType<typeof JSON.parse>} valueToInclude - Value to include.
126
- * @returns {void} - No return value.
127
- */
128
- toInclude(valueToInclude: ReturnType<typeof JSON.parse>): void;
129
- /**
130
- * Runs to equal.
131
- * @param {ReturnType<typeof JSON.parse>} result - Result.
132
- * @returns {void} - No return value.
133
- */
134
- toEqual(result: ReturnType<typeof JSON.parse>): void;
135
- /**
136
- * Runs to match.
137
- * @param {RegExp} regex - Regex.
138
- * @returns {void} - No return value.
139
- */
140
- toMatch(regex: RegExp): void;
141
- /**
142
- * Runs to match object.
143
- * @param {Record<string, ReturnType<typeof JSON.parse>> | Array<ReturnType<typeof JSON.parse>>} expected - Expected partial object.
144
- * @returns {void} - No return value.
145
- */
146
- toMatchObject(expected: Record<string, ReturnType<typeof JSON.parse>> | Array<ReturnType<typeof JSON.parse>>): void;
147
- /**
148
- * Runs to throw error.
149
- * @template T extends Error
150
- * @param {string|T} expectedError - Expected error.
151
- * @returns {Promise<void>} - Resolves when complete.
152
- */
153
- toThrowError<T>(expectedError: string | T): Promise<void>;
154
- /**
155
- * Runs to throw.
156
- * @param {string|RegExp|Error|((new (...args: Array<ReturnType<typeof JSON.parse>>) => Error))} [expected] - Expected error.
157
- * @returns {Promise<void>} - Resolves when complete.
158
- */
159
- toThrow(expected?: string | RegExp | Error | ((new (...args: Array<ReturnType<typeof JSON.parse>>) => Error))): Promise<void>;
160
- /**
161
- * Runs execute.
162
- * @returns {Promise<ReturnType<typeof JSON.parse>>} - Resolves with the execute.
163
- */
164
- execute(): Promise<ReturnType<typeof JSON.parse>>;
165
- /**
166
- * Runs to have attributes.
167
- * @param {Record<string, ReturnType<typeof JSON.parse>>} result - Result.
168
- * @returns {void} - No return value.
169
- */
170
- toHaveAttributes(result: Record<string, ReturnType<typeof JSON.parse>>): void;
171
- }
1
+ export { Expect as default } from "@velocious/testing";
172
2
  //# sourceMappingURL=expect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../../src/testing/expect.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../../src/testing/expect.js"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,IAAI,OAAO,EAAC,MAAM,oBAAoB,CAAA"}