@flemist/test-variants 2.0.4 → 3.0.0
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/dist/bundle/browser.js +599 -517
- package/dist/lib/index.cjs +2 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.mjs +1 -1
- package/dist/lib/test-variants/createTestVariants.cjs +5 -2
- package/dist/lib/test-variants/createTestVariants.mjs +5 -2
- package/dist/lib/test-variants/createTestVariants.perf.cjs +1 -1
- package/dist/lib/test-variants/createTestVariants.perf.mjs +1 -1
- package/dist/lib/test-variants/testVariantsIterable.cjs +3 -0
- package/dist/lib/test-variants/testVariantsIterable.d.ts +3 -0
- package/dist/lib/test-variants/testVariantsIterable.mjs +3 -0
- package/dist/lib/test-variants/testVariantsIterator.cjs +357 -0
- package/dist/lib/test-variants/testVariantsIterator.d.ts +67 -0
- package/dist/lib/test-variants/testVariantsIterator.mjs +353 -0
- package/dist/lib/test-variants/testVariantsRun.cjs +160 -172
- package/dist/lib/test-variants/testVariantsRun.d.ts +6 -16
- package/dist/lib/test-variants/testVariantsRun.mjs +160 -172
- package/dist/lib/test-variants/types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -31,28 +31,28 @@ function _interopNamespace(e) {
|
|
|
31
31
|
|
|
32
32
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
33
33
|
|
|
34
|
+
function formatDuration(ms) {
|
|
35
|
+
const seconds = ms / 1000;
|
|
36
|
+
if (seconds < 60) {
|
|
37
|
+
return `${seconds.toFixed(1)}s`;
|
|
38
|
+
}
|
|
39
|
+
const minutes = seconds / 60;
|
|
40
|
+
if (minutes < 60) {
|
|
41
|
+
return `${minutes.toFixed(1)}m`;
|
|
42
|
+
}
|
|
43
|
+
const hours = minutes / 60;
|
|
44
|
+
return `${hours.toFixed(1)}h`;
|
|
45
|
+
}
|
|
34
46
|
function testVariantsRun(testRun, variants, options = {}) {
|
|
35
47
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
36
48
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
37
49
|
const saveErrorVariants = options.saveErrorVariants;
|
|
38
50
|
const retriesPerVariant = (_a = saveErrorVariants === null || saveErrorVariants === void 0 ? void 0 : saveErrorVariants.retriesPerVariant) !== null && _a !== void 0 ? _a : 1;
|
|
51
|
+
const useToFindBestError = saveErrorVariants === null || saveErrorVariants === void 0 ? void 0 : saveErrorVariants.useToFindBestError;
|
|
39
52
|
const sessionDate = new Date();
|
|
40
53
|
const errorVariantFilePath = saveErrorVariants
|
|
41
54
|
? path__namespace.resolve(saveErrorVariants.dir, (_c = (_b = saveErrorVariants.getFilePath) === null || _b === void 0 ? void 0 : _b.call(saveErrorVariants, { sessionDate })) !== null && _c !== void 0 ? _c : testVariants_saveErrorVariants.generateErrorVariantFilePath({ sessionDate }))
|
|
42
55
|
: null;
|
|
43
|
-
// Replay phase: run previously saved error variants before normal iteration
|
|
44
|
-
if (saveErrorVariants) {
|
|
45
|
-
const files = yield testVariants_saveErrorVariants.readErrorVariantFiles(saveErrorVariants.dir);
|
|
46
|
-
for (const filePath of files) {
|
|
47
|
-
const args = yield testVariants_saveErrorVariants.parseErrorVariantFile(filePath, saveErrorVariants.jsonToArgs);
|
|
48
|
-
for (let retry = 0; retry < retriesPerVariant; retry++) {
|
|
49
|
-
const promiseOrResult = testRun(args, -1, null);
|
|
50
|
-
if (asyncUtils.isPromiseLike(promiseOrResult)) {
|
|
51
|
-
yield promiseOrResult;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
56
|
const GC_Iterations = (_d = options.GC_Iterations) !== null && _d !== void 0 ? _d : 1000000;
|
|
57
57
|
const GC_IterationsAsync = (_e = options.GC_IterationsAsync) !== null && _e !== void 0 ? _e : 10000;
|
|
58
58
|
const GC_Interval = (_f = options.GC_Interval) !== null && _f !== void 0 ? _f : 1000;
|
|
@@ -60,80 +60,47 @@ function testVariantsRun(testRun, variants, options = {}) {
|
|
|
60
60
|
const logCompleted = (_h = options.logCompleted) !== null && _h !== void 0 ? _h : true;
|
|
61
61
|
const abortSignalExternal = options.abortSignal;
|
|
62
62
|
const findBestError = options.findBestError;
|
|
63
|
+
const cycles = (_j = findBestError === null || findBestError === void 0 ? void 0 : findBestError.cycles) !== null && _j !== void 0 ? _j : 1;
|
|
63
64
|
const parallel = options.parallel === true
|
|
64
65
|
? Math.pow(2, 31)
|
|
65
66
|
: !options.parallel || options.parallel <= 0
|
|
66
67
|
? 1
|
|
67
68
|
: options.parallel;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
let repeatIndex = 0;
|
|
72
|
-
let seed = void 0;
|
|
73
|
-
let bestError = null;
|
|
74
|
-
let index = -1;
|
|
75
|
-
let args = {};
|
|
76
|
-
let variantsIterator = variants[Symbol.iterator]();
|
|
77
|
-
function getLimitVariantsCount() {
|
|
78
|
-
if (limitVariantsCount != null && bestError != null) {
|
|
79
|
-
return Math.min(limitVariantsCount, bestError.index);
|
|
80
|
-
}
|
|
81
|
-
if (limitVariantsCount != null) {
|
|
82
|
-
return limitVariantsCount;
|
|
83
|
-
}
|
|
84
|
-
if (bestError != null) {
|
|
85
|
-
return bestError.index;
|
|
86
|
-
}
|
|
87
|
-
return null;
|
|
69
|
+
// Apply initial limits
|
|
70
|
+
if (options.limitVariantsCount != null) {
|
|
71
|
+
variants.addLimit({ index: options.limitVariantsCount });
|
|
88
72
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
});
|
|
101
|
-
return true;
|
|
73
|
+
// Replay phase: run previously saved error variants before normal iteration
|
|
74
|
+
if (saveErrorVariants) {
|
|
75
|
+
const files = yield testVariants_saveErrorVariants.readErrorVariantFiles(saveErrorVariants.dir);
|
|
76
|
+
for (const filePath of files) {
|
|
77
|
+
const args = yield testVariants_saveErrorVariants.parseErrorVariantFile(filePath, saveErrorVariants.jsonToArgs);
|
|
78
|
+
for (let retry = 0; retry < retriesPerVariant; retry++) {
|
|
79
|
+
try {
|
|
80
|
+
const promiseOrResult = testRun(args, -1, null);
|
|
81
|
+
if (asyncUtils.isPromiseLike(promiseOrResult)) {
|
|
82
|
+
yield promiseOrResult;
|
|
83
|
+
}
|
|
102
84
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const result = variantsIterator.next();
|
|
112
|
-
if (!result.done) {
|
|
113
|
-
args = result.value;
|
|
114
|
-
if (findBestError) {
|
|
115
|
-
seed = findBestError.getSeed({
|
|
116
|
-
variantIndex: index,
|
|
117
|
-
cycleIndex,
|
|
118
|
-
repeatIndex,
|
|
119
|
-
totalIndex: cycleIndex * findBestError.repeatsPerVariant + repeatIndex,
|
|
120
|
-
});
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (useToFindBestError && findBestError) {
|
|
87
|
+
// Store as pending limit for findBestError cycle
|
|
88
|
+
variants.addLimit({ args, error });
|
|
89
|
+
break; // Exit retry loop, continue to next file
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
throw error;
|
|
121
93
|
}
|
|
122
|
-
return true;
|
|
123
94
|
}
|
|
124
95
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
prevCycleVariantsCount = index;
|
|
129
|
-
cycleIndex++;
|
|
130
|
-
if (cycleIndex >= findBestError.cycles) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
index = -1;
|
|
134
|
-
variantsIterator = variants[Symbol.iterator]();
|
|
96
|
+
// If no error occurred during replays, the saved variant is no longer reproducible
|
|
97
|
+
// (templates may have changed) - silently skip
|
|
135
98
|
}
|
|
136
99
|
}
|
|
100
|
+
let prevCycleVariantsCount = null;
|
|
101
|
+
let prevCycleDuration = null;
|
|
102
|
+
const startTime = Date.now();
|
|
103
|
+
let cycleStartTime = startTime;
|
|
137
104
|
const abortControllerParallel = new abortControllerFast.AbortControllerFast();
|
|
138
105
|
const abortSignalParallel = asyncUtils.combineAbortSignals(abortSignalExternal, abortControllerParallel.signal);
|
|
139
106
|
const abortSignalAll = abortSignalParallel;
|
|
@@ -149,50 +116,105 @@ function testVariantsRun(testRun, variants, options = {}) {
|
|
|
149
116
|
: new timeLimits.Pool(parallel);
|
|
150
117
|
function onCompleted() {
|
|
151
118
|
if (logCompleted) {
|
|
152
|
-
console.log(`[test-variants] variants: ${index}, iterations: ${iterations}, async: ${iterationsAsync}`);
|
|
119
|
+
console.log(`[test-variants] variants: ${variants.index}, iterations: ${iterations}, async: ${iterationsAsync}`);
|
|
153
120
|
}
|
|
154
121
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
122
|
+
// Main iteration using iterator
|
|
123
|
+
variants.start();
|
|
124
|
+
while (variants.cycleIndex < cycles) {
|
|
125
|
+
let args;
|
|
126
|
+
while (!(abortSignalExternal === null || abortSignalExternal === void 0 ? void 0 : abortSignalExternal.aborted) && (debug || (args = variants.next()) != null)) {
|
|
127
|
+
const _index = variants.index;
|
|
128
|
+
const _args = args;
|
|
129
|
+
const now = (logInterval || GC_Interval) && Date.now();
|
|
130
|
+
if (logInterval && now - prevLogTime >= logInterval) {
|
|
131
|
+
// the log is required to prevent the karma browserNoActivityTimeout
|
|
132
|
+
let log = '';
|
|
133
|
+
const cycleElapsed = now - cycleStartTime;
|
|
134
|
+
const totalElapsed = now - startTime;
|
|
135
|
+
if (findBestError) {
|
|
136
|
+
log += `cycle: ${variants.cycleIndex}, variant: ${variants.index}`;
|
|
137
|
+
let max = variants.count;
|
|
138
|
+
if (max != null) {
|
|
139
|
+
if (prevCycleVariantsCount != null && prevCycleVariantsCount < max) {
|
|
140
|
+
max = prevCycleVariantsCount;
|
|
174
141
|
}
|
|
175
142
|
}
|
|
143
|
+
if (max != null && variants.index > 0) {
|
|
144
|
+
let estimatedCycleTime;
|
|
145
|
+
if (prevCycleDuration != null && prevCycleVariantsCount != null
|
|
146
|
+
&& variants.index < prevCycleVariantsCount && cycleElapsed < prevCycleDuration) {
|
|
147
|
+
const adjustedDuration = prevCycleDuration - cycleElapsed;
|
|
148
|
+
const adjustedCount = prevCycleVariantsCount - variants.index;
|
|
149
|
+
const speedForRemaining = adjustedDuration / adjustedCount;
|
|
150
|
+
const remainingTime = (max - variants.index) * speedForRemaining;
|
|
151
|
+
estimatedCycleTime = cycleElapsed + remainingTime;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
estimatedCycleTime = cycleElapsed * max / variants.index;
|
|
155
|
+
}
|
|
156
|
+
log += `/${max} (${formatDuration(cycleElapsed)}/${formatDuration(estimatedCycleTime)})`;
|
|
157
|
+
}
|
|
176
158
|
else {
|
|
177
|
-
log += `
|
|
159
|
+
log += ` (${formatDuration(cycleElapsed)})`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
log += `variant: ${variants.index} (${formatDuration(cycleElapsed)})`;
|
|
164
|
+
}
|
|
165
|
+
log += `, total: ${iterations} (${formatDuration(totalElapsed)})`;
|
|
166
|
+
console.log(log);
|
|
167
|
+
prevLogTime = now;
|
|
168
|
+
}
|
|
169
|
+
if (GC_Iterations && iterations - prevGC_Iterations >= GC_Iterations
|
|
170
|
+
|| GC_IterationsAsync && iterationsAsync - prevGC_IterationsAsync >= GC_IterationsAsync
|
|
171
|
+
|| GC_Interval && now - prevGC_Time >= GC_Interval) {
|
|
172
|
+
prevGC_Iterations = iterations;
|
|
173
|
+
prevGC_IterationsAsync = iterationsAsync;
|
|
174
|
+
prevGC_Time = now;
|
|
175
|
+
yield garbageCollect_garbageCollect.garbageCollect(1);
|
|
176
|
+
}
|
|
177
|
+
if (abortSignalExternal === null || abortSignalExternal === void 0 ? void 0 : abortSignalExternal.aborted) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (!pool || abortSignalParallel.aborted) {
|
|
181
|
+
try {
|
|
182
|
+
let promiseOrIterations = testRun(_args, _index, abortSignalParallel);
|
|
183
|
+
if (asyncUtils.isPromiseLike(promiseOrIterations)) {
|
|
184
|
+
promiseOrIterations = yield promiseOrIterations;
|
|
185
|
+
}
|
|
186
|
+
if (!promiseOrIterations) {
|
|
187
|
+
debug = true;
|
|
188
|
+
abortControllerParallel.abort();
|
|
189
|
+
continue;
|
|
178
190
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
191
|
+
const { iterationsAsync: _iterationsAsync, iterationsSync: _iterationsSync } = promiseOrIterations;
|
|
192
|
+
iterationsAsync += _iterationsAsync;
|
|
193
|
+
iterations += _iterationsSync + _iterationsAsync;
|
|
182
194
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
195
|
+
catch (err) {
|
|
196
|
+
if (errorVariantFilePath) {
|
|
197
|
+
yield testVariants_saveErrorVariants.saveErrorVariantFile(_args, errorVariantFilePath, saveErrorVariants.argsToJson);
|
|
198
|
+
}
|
|
199
|
+
if (findBestError) {
|
|
200
|
+
variants.addLimit({ error: err });
|
|
201
|
+
debug = false;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
throw err;
|
|
205
|
+
}
|
|
190
206
|
}
|
|
191
|
-
|
|
192
|
-
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
if (!pool.hold(1)) {
|
|
210
|
+
yield pool.holdWait(1);
|
|
193
211
|
}
|
|
194
|
-
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
213
|
+
void (() => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
195
214
|
try {
|
|
215
|
+
if (abortSignalParallel === null || abortSignalParallel === void 0 ? void 0 : abortSignalParallel.aborted) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
196
218
|
let promiseOrIterations = testRun(_args, _index, abortSignalParallel);
|
|
197
219
|
if (asyncUtils.isPromiseLike(promiseOrIterations)) {
|
|
198
220
|
promiseOrIterations = yield promiseOrIterations;
|
|
@@ -200,7 +222,7 @@ function testVariantsRun(testRun, variants, options = {}) {
|
|
|
200
222
|
if (!promiseOrIterations) {
|
|
201
223
|
debug = true;
|
|
202
224
|
abortControllerParallel.abort();
|
|
203
|
-
|
|
225
|
+
return;
|
|
204
226
|
}
|
|
205
227
|
const { iterationsAsync: _iterationsAsync, iterationsSync: _iterationsSync } = promiseOrIterations;
|
|
206
228
|
iterationsAsync += _iterationsAsync;
|
|
@@ -211,78 +233,44 @@ function testVariantsRun(testRun, variants, options = {}) {
|
|
|
211
233
|
yield testVariants_saveErrorVariants.saveErrorVariantFile(_args, errorVariantFilePath, saveErrorVariants.argsToJson);
|
|
212
234
|
}
|
|
213
235
|
if (findBestError) {
|
|
214
|
-
|
|
215
|
-
error: err,
|
|
216
|
-
args: _args,
|
|
217
|
-
index: _index,
|
|
218
|
-
};
|
|
236
|
+
variants.addLimit({ error: err });
|
|
219
237
|
debug = false;
|
|
220
238
|
}
|
|
221
239
|
else {
|
|
222
240
|
throw err;
|
|
223
241
|
}
|
|
224
242
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (!pool.hold(1)) {
|
|
228
|
-
yield pool.holdWait(1);
|
|
243
|
+
finally {
|
|
244
|
+
void pool.release(1);
|
|
229
245
|
}
|
|
230
|
-
|
|
231
|
-
void (() => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
232
|
-
try {
|
|
233
|
-
if (abortSignalParallel === null || abortSignalParallel === void 0 ? void 0 : abortSignalParallel.aborted) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
let promiseOrIterations = testRun(_args, _index, abortSignalParallel);
|
|
237
|
-
if (asyncUtils.isPromiseLike(promiseOrIterations)) {
|
|
238
|
-
promiseOrIterations = yield promiseOrIterations;
|
|
239
|
-
}
|
|
240
|
-
if (!promiseOrIterations) {
|
|
241
|
-
debug = true;
|
|
242
|
-
abortControllerParallel.abort();
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
const { iterationsAsync: _iterationsAsync, iterationsSync: _iterationsSync } = promiseOrIterations;
|
|
246
|
-
iterationsAsync += _iterationsAsync;
|
|
247
|
-
iterations += _iterationsSync + _iterationsAsync;
|
|
248
|
-
}
|
|
249
|
-
catch (err) {
|
|
250
|
-
if (errorVariantFilePath) {
|
|
251
|
-
yield testVariants_saveErrorVariants.saveErrorVariantFile(_args, errorVariantFilePath, saveErrorVariants.argsToJson);
|
|
252
|
-
}
|
|
253
|
-
if (findBestError) {
|
|
254
|
-
bestError = {
|
|
255
|
-
error: err,
|
|
256
|
-
args: _args,
|
|
257
|
-
index: _index,
|
|
258
|
-
};
|
|
259
|
-
debug = false;
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
throw err;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
finally {
|
|
266
|
-
void pool.release(1);
|
|
267
|
-
}
|
|
268
|
-
}))();
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
if (pool) {
|
|
272
|
-
yield pool.holdWait(parallel);
|
|
273
|
-
void pool.release(parallel);
|
|
246
|
+
}))();
|
|
274
247
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
});
|
|
248
|
+
}
|
|
249
|
+
// Track cycle metrics for logging
|
|
250
|
+
prevCycleVariantsCount = variants.count;
|
|
251
|
+
prevCycleDuration = Date.now() - cycleStartTime;
|
|
252
|
+
cycleStartTime = Date.now();
|
|
253
|
+
variants.start();
|
|
282
254
|
}
|
|
283
|
-
|
|
255
|
+
if (pool) {
|
|
256
|
+
yield pool.holdWait(parallel);
|
|
257
|
+
void pool.release(parallel);
|
|
258
|
+
}
|
|
259
|
+
if (abortSignalAll === null || abortSignalAll === void 0 ? void 0 : abortSignalAll.aborted) {
|
|
260
|
+
throw abortSignalAll.reason;
|
|
261
|
+
}
|
|
262
|
+
onCompleted();
|
|
263
|
+
yield garbageCollect_garbageCollect.garbageCollect(1);
|
|
264
|
+
// Construct bestError from iterator state
|
|
265
|
+
const bestError = variants.limit
|
|
266
|
+
? {
|
|
267
|
+
error: variants.limit.error,
|
|
268
|
+
args: variants.limit.args,
|
|
269
|
+
index: variants.count,
|
|
270
|
+
}
|
|
271
|
+
: null;
|
|
284
272
|
return {
|
|
285
|
-
iterations
|
|
273
|
+
iterations,
|
|
286
274
|
bestError,
|
|
287
275
|
};
|
|
288
276
|
});
|
|
@@ -1,25 +1,15 @@
|
|
|
1
1
|
import { TestVariantsTestRun } from './testVariantsCreateTestRun';
|
|
2
2
|
import { type IAbortSignalFast } from '@flemist/abort-controller-fast';
|
|
3
3
|
import { Obj, type SaveErrorVariantsOptions } from "./types";
|
|
4
|
-
|
|
5
|
-
export declare type GetSeedParams = {
|
|
6
|
-
/** Index of current variant/parameter-combination being tested */
|
|
7
|
-
variantIndex: number;
|
|
8
|
-
/** Index of current cycle - full pass through all variants (0..cycles-1) */
|
|
9
|
-
cycleIndex: number;
|
|
10
|
-
/** Index of repeat for current variant within this cycle (0..repeatsPerVariant-1) */
|
|
11
|
-
repeatIndex: number;
|
|
12
|
-
/** Total index across all cycles: cycleIndex × repeatsPerVariant + repeatIndex */
|
|
13
|
-
totalIndex: number;
|
|
14
|
-
};
|
|
4
|
+
import { TestVariantsIterator, type GetSeedParams } from './testVariantsIterator';
|
|
15
5
|
/** Options for finding the earliest failing variant across multiple test runs */
|
|
16
6
|
export declare type TestVariantsFindBestErrorOptions = {
|
|
17
|
-
/** Function to generate seed based on current iteration state */
|
|
18
|
-
getSeed: (params: GetSeedParams) => any;
|
|
19
7
|
/** Number of full passes through all variants */
|
|
20
8
|
cycles: number;
|
|
21
|
-
/**
|
|
22
|
-
|
|
9
|
+
/** Function to generate seed based on current iteration state (passed to iterator) */
|
|
10
|
+
getSeed?: null | ((params: GetSeedParams) => any);
|
|
11
|
+
/** Number of repeat tests per variant within each cycle (passed to iterator) */
|
|
12
|
+
repeatsPerVariant?: null | number;
|
|
23
13
|
};
|
|
24
14
|
export declare type TestVariantsRunOptions<Args extends Obj = Obj, SavedArgs = Args> = {
|
|
25
15
|
/** Wait for garbage collection after iterations */
|
|
@@ -49,4 +39,4 @@ export declare type TestVariantsRunResult<Arg extends Obj> = {
|
|
|
49
39
|
iterations: number;
|
|
50
40
|
bestError: null | TestVariantsBestError<Arg>;
|
|
51
41
|
};
|
|
52
|
-
export declare function testVariantsRun<Args extends Obj, SavedArgs = Args>(testRun: TestVariantsTestRun<Args>, variants:
|
|
42
|
+
export declare function testVariantsRun<Args extends Obj, SavedArgs = Args>(testRun: TestVariantsTestRun<Args>, variants: TestVariantsIterator<Args>, options?: TestVariantsRunOptions<Args, SavedArgs>): Promise<TestVariantsRunResult<Args>>;
|