@flemist/test-variants 1.0.7 → 2.0.0-alpha
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 +270 -228
- package/dist/lib/index.cjs +6 -2
- package/dist/lib/index.d.ts +5 -2
- package/dist/lib/index.mjs +6 -2
- package/dist/lib/test-variants/argsToString.cjs +17 -0
- package/dist/lib/test-variants/argsToString.d.ts +2 -0
- package/dist/lib/test-variants/argsToString.mjs +13 -0
- package/dist/lib/test-variants/createTestVariants.cjs +68 -188
- package/dist/lib/test-variants/createTestVariants.d.ts +8 -30
- package/dist/lib/test-variants/createTestVariants.mjs +68 -188
- package/dist/lib/test-variants/createTestVariants.perf.cjs +29 -20
- package/dist/lib/test-variants/createTestVariants.perf.mjs +29 -20
- package/dist/lib/test-variants/prime.cjs +65 -0
- package/dist/lib/test-variants/prime.d.ts +3 -0
- package/dist/lib/test-variants/prime.mjs +59 -0
- package/dist/lib/test-variants/prime.perf.cjs +30 -0
- package/dist/lib/test-variants/prime.perf.d.ts +1 -0
- package/dist/lib/test-variants/prime.perf.mjs +28 -0
- package/dist/lib/test-variants/testVariantsCreateTestRun.cjs +80 -0
- package/dist/lib/test-variants/testVariantsCreateTestRun.d.ts +22 -0
- package/dist/lib/test-variants/testVariantsCreateTestRun.mjs +76 -0
- package/dist/lib/test-variants/testVariantsIterable.cjs +67 -0
- package/dist/lib/test-variants/testVariantsIterable.d.ts +12 -0
- package/dist/lib/test-variants/testVariantsIterable.mjs +63 -0
- package/dist/lib/test-variants/testVariantsRun.cjs +187 -0
- package/dist/lib/test-variants/testVariantsRun.d.ts +31 -0
- package/dist/lib/test-variants/testVariantsRun.mjs +183 -0
- package/dist/lib/test-variants/types.cjs +2 -0
- package/dist/lib/test-variants/types.d.ts +1 -0
- package/dist/lib/test-variants/types.mjs +1 -0
- package/package.json +6 -6
|
@@ -1,32 +1,41 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var tslib = require('tslib');
|
|
4
|
+
var node = require('rdtsc/node');
|
|
4
5
|
var testVariants_createTestVariants = require('./createTestVariants.cjs');
|
|
5
|
-
require('
|
|
6
|
-
require('
|
|
6
|
+
require('./testVariantsIterable.cjs');
|
|
7
|
+
require('./testVariantsCreateTestRun.cjs');
|
|
8
|
+
require('@flemist/async-utils');
|
|
9
|
+
require('./argsToString.cjs');
|
|
10
|
+
require('./testVariantsRun.cjs');
|
|
7
11
|
require('@flemist/abort-controller-fast');
|
|
8
12
|
require('@flemist/time-limits');
|
|
9
|
-
require('
|
|
13
|
+
require('../garbage-collect/garbageCollect.cjs');
|
|
10
14
|
|
|
11
15
|
describe('test > testVariants perf', function () {
|
|
12
16
|
this.timeout(300000);
|
|
13
17
|
it('sync', function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
const testVariantsSync = testVariants_createTestVariants.createTestVariants(({ a, b, c }) => {
|
|
20
|
+
});
|
|
21
|
+
const args = {
|
|
22
|
+
a: [1, 2],
|
|
23
|
+
b: ['3', '4'],
|
|
24
|
+
c: [true, false],
|
|
25
|
+
};
|
|
26
|
+
const perfResult = node.calcPerformance({
|
|
27
|
+
time: 10000,
|
|
28
|
+
funcs: [
|
|
29
|
+
() => {
|
|
30
|
+
},
|
|
31
|
+
() => {
|
|
32
|
+
testVariantsSync(args)();
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
const result = yield testVariantsSync(args)();
|
|
37
|
+
perfResult.absoluteDiff = perfResult.absoluteDiff.map(o => o / result.iterations);
|
|
38
|
+
console.log('testVariants perf:', result);
|
|
27
39
|
});
|
|
28
|
-
const count = testVariantsSync(args)();
|
|
29
|
-
result.absoluteDiff = result.absoluteDiff.map(o => o / count);
|
|
30
|
-
console.log('testVariants perf:', result);
|
|
31
40
|
});
|
|
32
41
|
});
|
|
@@ -1,30 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __awaiter } from 'tslib';
|
|
2
|
+
import { calcPerformance } from 'rdtsc/node';
|
|
2
3
|
import { createTestVariants } from './createTestVariants.mjs';
|
|
3
|
-
import '
|
|
4
|
-
import '
|
|
4
|
+
import './testVariantsIterable.mjs';
|
|
5
|
+
import './testVariantsCreateTestRun.mjs';
|
|
6
|
+
import '@flemist/async-utils';
|
|
7
|
+
import './argsToString.mjs';
|
|
8
|
+
import './testVariantsRun.mjs';
|
|
5
9
|
import '@flemist/abort-controller-fast';
|
|
6
10
|
import '@flemist/time-limits';
|
|
7
|
-
import '
|
|
11
|
+
import '../garbage-collect/garbageCollect.mjs';
|
|
8
12
|
|
|
9
13
|
describe('test > testVariants perf', function () {
|
|
10
14
|
this.timeout(300000);
|
|
11
15
|
it('sync', function () {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const testVariantsSync = createTestVariants(({ a, b, c }) => {
|
|
18
|
+
});
|
|
19
|
+
const args = {
|
|
20
|
+
a: [1, 2],
|
|
21
|
+
b: ['3', '4'],
|
|
22
|
+
c: [true, false],
|
|
23
|
+
};
|
|
24
|
+
const perfResult = calcPerformance({
|
|
25
|
+
time: 10000,
|
|
26
|
+
funcs: [
|
|
27
|
+
() => {
|
|
28
|
+
},
|
|
29
|
+
() => {
|
|
30
|
+
testVariantsSync(args)();
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
const result = yield testVariantsSync(args)();
|
|
35
|
+
perfResult.absoluteDiff = perfResult.absoluteDiff.map(o => o / result.iterations);
|
|
36
|
+
console.log('testVariants perf:', result);
|
|
25
37
|
});
|
|
26
|
-
const count = testVariantsSync(args)();
|
|
27
|
-
result.absoluteDiff = result.absoluteDiff.map(o => o / count);
|
|
28
|
-
console.log('testVariants perf:', result);
|
|
29
38
|
});
|
|
30
39
|
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const MAX_NUMBER = (Math.pow(2, 31) - 1) | 0;
|
|
6
|
+
const MAX_NUMBER_PRIME = 2147483647;
|
|
7
|
+
function isPrime(n) {
|
|
8
|
+
if (n > MAX_NUMBER) {
|
|
9
|
+
throw new Error(`Number is too large: ${n}, max is ${MAX_NUMBER}`);
|
|
10
|
+
}
|
|
11
|
+
// convert number to 32-bit integer for performance
|
|
12
|
+
n = n | 0;
|
|
13
|
+
if (n <= 1) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (n <= 3) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (n % 2 === 0 || n % 3 === 0) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
for (let i = 5; i * i <= n; i += 6) {
|
|
23
|
+
if (n % i === 0 || n % (i + 2) === 0) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
function nextPrime(n) {
|
|
30
|
+
if (n >= MAX_NUMBER_PRIME) {
|
|
31
|
+
throw new Error(`Number is too large: ${n}, max is ${MAX_NUMBER_PRIME - 1}`);
|
|
32
|
+
}
|
|
33
|
+
// convert number to 32-bit integer for performance
|
|
34
|
+
n = n | 0;
|
|
35
|
+
if (n < 2) {
|
|
36
|
+
return 2;
|
|
37
|
+
}
|
|
38
|
+
let candidate = n + (n % 2 === 0 ? 1 : 2);
|
|
39
|
+
while (!isPrime(candidate)) {
|
|
40
|
+
candidate += 2;
|
|
41
|
+
}
|
|
42
|
+
return candidate;
|
|
43
|
+
}
|
|
44
|
+
function prevPrime(n) {
|
|
45
|
+
if (n > MAX_NUMBER) {
|
|
46
|
+
throw new Error(`Number is too large: ${n}, max is ${MAX_NUMBER}`);
|
|
47
|
+
}
|
|
48
|
+
// convert number to 32-bit integer for performance
|
|
49
|
+
n = n | 0;
|
|
50
|
+
if (n <= 2) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
let candidate = n - (n % 2 === 0 ? 1 : 2);
|
|
54
|
+
while (candidate > 2 && !isPrime(candidate)) {
|
|
55
|
+
candidate -= 2;
|
|
56
|
+
}
|
|
57
|
+
if (candidate > 2) {
|
|
58
|
+
return candidate;
|
|
59
|
+
}
|
|
60
|
+
return 2;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
exports.isPrime = isPrime;
|
|
64
|
+
exports.nextPrime = nextPrime;
|
|
65
|
+
exports.prevPrime = prevPrime;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const MAX_NUMBER = (Math.pow(2, 31) - 1) | 0;
|
|
2
|
+
const MAX_NUMBER_PRIME = 2147483647;
|
|
3
|
+
function isPrime(n) {
|
|
4
|
+
if (n > MAX_NUMBER) {
|
|
5
|
+
throw new Error(`Number is too large: ${n}, max is ${MAX_NUMBER}`);
|
|
6
|
+
}
|
|
7
|
+
// convert number to 32-bit integer for performance
|
|
8
|
+
n = n | 0;
|
|
9
|
+
if (n <= 1) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
if (n <= 3) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (n % 2 === 0 || n % 3 === 0) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
for (let i = 5; i * i <= n; i += 6) {
|
|
19
|
+
if (n % i === 0 || n % (i + 2) === 0) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
function nextPrime(n) {
|
|
26
|
+
if (n >= MAX_NUMBER_PRIME) {
|
|
27
|
+
throw new Error(`Number is too large: ${n}, max is ${MAX_NUMBER_PRIME - 1}`);
|
|
28
|
+
}
|
|
29
|
+
// convert number to 32-bit integer for performance
|
|
30
|
+
n = n | 0;
|
|
31
|
+
if (n < 2) {
|
|
32
|
+
return 2;
|
|
33
|
+
}
|
|
34
|
+
let candidate = n + (n % 2 === 0 ? 1 : 2);
|
|
35
|
+
while (!isPrime(candidate)) {
|
|
36
|
+
candidate += 2;
|
|
37
|
+
}
|
|
38
|
+
return candidate;
|
|
39
|
+
}
|
|
40
|
+
function prevPrime(n) {
|
|
41
|
+
if (n > MAX_NUMBER) {
|
|
42
|
+
throw new Error(`Number is too large: ${n}, max is ${MAX_NUMBER}`);
|
|
43
|
+
}
|
|
44
|
+
// convert number to 32-bit integer for performance
|
|
45
|
+
n = n | 0;
|
|
46
|
+
if (n <= 2) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
let candidate = n - (n % 2 === 0 ? 1 : 2);
|
|
50
|
+
while (candidate > 2 && !isPrime(candidate)) {
|
|
51
|
+
candidate -= 2;
|
|
52
|
+
}
|
|
53
|
+
if (candidate > 2) {
|
|
54
|
+
return candidate;
|
|
55
|
+
}
|
|
56
|
+
return 2;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { isPrime, nextPrime, prevPrime };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var node = require('rdtsc/node');
|
|
4
|
+
var testVariants_prime = require('./prime.cjs');
|
|
5
|
+
|
|
6
|
+
describe('test-variants > prime perf', function () {
|
|
7
|
+
this.timeout(300000);
|
|
8
|
+
it('isPrime', function () {
|
|
9
|
+
let number1 = testVariants_prime.nextPrime(Math.pow(2, 30));
|
|
10
|
+
let number2 = testVariants_prime.prevPrime(Math.pow(2, 31) - 1);
|
|
11
|
+
console.log('number:', number1);
|
|
12
|
+
console.log('number:', number2);
|
|
13
|
+
const result = node.calcPerformance({
|
|
14
|
+
time: 10000,
|
|
15
|
+
funcs: [
|
|
16
|
+
() => {
|
|
17
|
+
},
|
|
18
|
+
() => {
|
|
19
|
+
number1 = testVariants_prime.nextPrime(number1);
|
|
20
|
+
},
|
|
21
|
+
() => {
|
|
22
|
+
number2 = testVariants_prime.prevPrime(number2);
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
console.log('number1:', number1);
|
|
27
|
+
console.log('number2:', number2);
|
|
28
|
+
console.log('perf:', result);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { calcPerformance } from 'rdtsc/node';
|
|
2
|
+
import { nextPrime, prevPrime } from './prime.mjs';
|
|
3
|
+
|
|
4
|
+
describe('test-variants > prime perf', function () {
|
|
5
|
+
this.timeout(300000);
|
|
6
|
+
it('isPrime', function () {
|
|
7
|
+
let number1 = nextPrime(Math.pow(2, 30));
|
|
8
|
+
let number2 = prevPrime(Math.pow(2, 31) - 1);
|
|
9
|
+
console.log('number:', number1);
|
|
10
|
+
console.log('number:', number2);
|
|
11
|
+
const result = calcPerformance({
|
|
12
|
+
time: 10000,
|
|
13
|
+
funcs: [
|
|
14
|
+
() => {
|
|
15
|
+
},
|
|
16
|
+
() => {
|
|
17
|
+
number1 = nextPrime(number1);
|
|
18
|
+
},
|
|
19
|
+
() => {
|
|
20
|
+
number2 = prevPrime(number2);
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
console.log('number1:', number1);
|
|
25
|
+
console.log('number2:', number2);
|
|
26
|
+
console.log('perf:', result);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
var asyncUtils = require('@flemist/async-utils');
|
|
7
|
+
var testVariants_argsToString = require('./argsToString.cjs');
|
|
8
|
+
|
|
9
|
+
function testVariantsCreateTestRun(test, options) {
|
|
10
|
+
let debugIteration = 0;
|
|
11
|
+
let errorEvent = null;
|
|
12
|
+
function onError(error, args, index) {
|
|
13
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
errorEvent = {
|
|
15
|
+
error,
|
|
16
|
+
args,
|
|
17
|
+
index: index,
|
|
18
|
+
};
|
|
19
|
+
console.error(`[test-variants] error variant: ${index}\n${testVariants_argsToString.argsToString(args)}`);
|
|
20
|
+
console.error(error);
|
|
21
|
+
// Rerun failed variant 5 times for debug
|
|
22
|
+
const time0 = Date.now();
|
|
23
|
+
// Will stop execution right before next error iteration for step-by-step debugging
|
|
24
|
+
// eslint-disable-next-line no-debugger
|
|
25
|
+
debugger;
|
|
26
|
+
if (Date.now() - time0 > 50 && debugIteration < 5) {
|
|
27
|
+
console.log('[test-variants] DEBUG ITERATION: ' + debugIteration);
|
|
28
|
+
debugIteration++;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (options.onError) {
|
|
32
|
+
yield options.onError(errorEvent);
|
|
33
|
+
}
|
|
34
|
+
throw errorEvent.error;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return function testRun(args, index, abortSignal) {
|
|
38
|
+
try {
|
|
39
|
+
const promiseOrIterations = test(args, abortSignal);
|
|
40
|
+
if (asyncUtils.isPromiseLike(promiseOrIterations)) {
|
|
41
|
+
return promiseOrIterations.then(value => {
|
|
42
|
+
if (typeof value === 'number') {
|
|
43
|
+
return {
|
|
44
|
+
iterationsAsync: value,
|
|
45
|
+
iterationsSync: 0,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (value !== null && typeof value === 'object') {
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
iterationsAsync: 1,
|
|
53
|
+
iterationsSync: 0,
|
|
54
|
+
};
|
|
55
|
+
}, err => {
|
|
56
|
+
return onError(err, args, index);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const value = promiseOrIterations;
|
|
60
|
+
if (typeof value === 'number') {
|
|
61
|
+
return {
|
|
62
|
+
iterationsAsync: 0,
|
|
63
|
+
iterationsSync: value,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (value !== null && typeof value === 'object') {
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
iterationsAsync: 0,
|
|
71
|
+
iterationsSync: 1,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
return onError(err, args, index);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
exports.testVariantsCreateTestRun = testVariantsCreateTestRun;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type IAbortSignalFast } from '@flemist/abort-controller-fast';
|
|
2
|
+
import { type PromiseOrValue } from '@flemist/async-utils';
|
|
3
|
+
import { Obj } from "./types";
|
|
4
|
+
export declare type ErrorEvent<Args extends Obj> = {
|
|
5
|
+
error: any;
|
|
6
|
+
args: Args;
|
|
7
|
+
index: number;
|
|
8
|
+
};
|
|
9
|
+
export declare type OnErrorCallback<Args extends Obj> = (event: ErrorEvent<Args>) => PromiseOrValue<void>;
|
|
10
|
+
export declare type TestVariantsCreateTestRunOptions<Args extends Obj> = {
|
|
11
|
+
onError?: null | OnErrorCallback<Args>;
|
|
12
|
+
};
|
|
13
|
+
export declare type TestVariantsTestRunResult = void | {
|
|
14
|
+
iterationsAsync: number;
|
|
15
|
+
iterationsSync: number;
|
|
16
|
+
};
|
|
17
|
+
export declare type TestVariantsTestRun<Args extends Obj> = (args: Args, index: number, abortSignal: IAbortSignalFast) => PromiseOrValue<TestVariantsTestRunResult>;
|
|
18
|
+
export declare type TestVariantsTestResult = number | void | TestVariantsTestRunResult;
|
|
19
|
+
export declare type TestVariantsTest<Args extends Obj> = (args: Args & {
|
|
20
|
+
seed?: null | number;
|
|
21
|
+
}, abortSignal: IAbortSignalFast) => PromiseOrValue<TestVariantsTestResult>;
|
|
22
|
+
export declare function testVariantsCreateTestRun<Args extends Obj>(test: TestVariantsTest<Args>, options?: null | TestVariantsCreateTestRunOptions<Args>): TestVariantsTestRun<Args>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { __awaiter } from 'tslib';
|
|
2
|
+
import { isPromiseLike } from '@flemist/async-utils';
|
|
3
|
+
import { argsToString } from './argsToString.mjs';
|
|
4
|
+
|
|
5
|
+
function testVariantsCreateTestRun(test, options) {
|
|
6
|
+
let debugIteration = 0;
|
|
7
|
+
let errorEvent = null;
|
|
8
|
+
function onError(error, args, index) {
|
|
9
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10
|
+
errorEvent = {
|
|
11
|
+
error,
|
|
12
|
+
args,
|
|
13
|
+
index: index,
|
|
14
|
+
};
|
|
15
|
+
console.error(`[test-variants] error variant: ${index}\n${argsToString(args)}`);
|
|
16
|
+
console.error(error);
|
|
17
|
+
// Rerun failed variant 5 times for debug
|
|
18
|
+
const time0 = Date.now();
|
|
19
|
+
// Will stop execution right before next error iteration for step-by-step debugging
|
|
20
|
+
// eslint-disable-next-line no-debugger
|
|
21
|
+
debugger;
|
|
22
|
+
if (Date.now() - time0 > 50 && debugIteration < 5) {
|
|
23
|
+
console.log('[test-variants] DEBUG ITERATION: ' + debugIteration);
|
|
24
|
+
debugIteration++;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (options.onError) {
|
|
28
|
+
yield options.onError(errorEvent);
|
|
29
|
+
}
|
|
30
|
+
throw errorEvent.error;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return function testRun(args, index, abortSignal) {
|
|
34
|
+
try {
|
|
35
|
+
const promiseOrIterations = test(args, abortSignal);
|
|
36
|
+
if (isPromiseLike(promiseOrIterations)) {
|
|
37
|
+
return promiseOrIterations.then(value => {
|
|
38
|
+
if (typeof value === 'number') {
|
|
39
|
+
return {
|
|
40
|
+
iterationsAsync: value,
|
|
41
|
+
iterationsSync: 0,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (value !== null && typeof value === 'object') {
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
iterationsAsync: 1,
|
|
49
|
+
iterationsSync: 0,
|
|
50
|
+
};
|
|
51
|
+
}, err => {
|
|
52
|
+
return onError(err, args, index);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const value = promiseOrIterations;
|
|
56
|
+
if (typeof value === 'number') {
|
|
57
|
+
return {
|
|
58
|
+
iterationsAsync: 0,
|
|
59
|
+
iterationsSync: value,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (value !== null && typeof value === 'object') {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
iterationsAsync: 0,
|
|
67
|
+
iterationsSync: 1,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return onError(err, args, index);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { testVariantsCreateTestRun };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
function testVariantsIterable({ argsTemplates, }) {
|
|
6
|
+
return {
|
|
7
|
+
[Symbol.iterator]() {
|
|
8
|
+
const keys = Object.keys(argsTemplates);
|
|
9
|
+
const templates = Object.values(argsTemplates);
|
|
10
|
+
const keysCount = keys.length;
|
|
11
|
+
const args = {};
|
|
12
|
+
function calcVariants(keyIndex) {
|
|
13
|
+
let template = templates[keyIndex];
|
|
14
|
+
if (typeof template === 'function') {
|
|
15
|
+
template = template(args);
|
|
16
|
+
}
|
|
17
|
+
return template;
|
|
18
|
+
}
|
|
19
|
+
const indexes = [];
|
|
20
|
+
const variants = [];
|
|
21
|
+
for (let nArg = 0; nArg < keysCount; nArg++) {
|
|
22
|
+
indexes[nArg] = -1;
|
|
23
|
+
variants[nArg] = [];
|
|
24
|
+
}
|
|
25
|
+
variants[0] = calcVariants(0);
|
|
26
|
+
function nextVariant() {
|
|
27
|
+
for (let keyIndex = keysCount - 1; keyIndex >= 0; keyIndex--) {
|
|
28
|
+
const valueIndex = indexes[keyIndex] + 1;
|
|
29
|
+
if (valueIndex < variants[keyIndex].length) {
|
|
30
|
+
const key = keys[keyIndex];
|
|
31
|
+
const value = variants[keyIndex][valueIndex];
|
|
32
|
+
indexes[keyIndex] = valueIndex;
|
|
33
|
+
args[key] = value;
|
|
34
|
+
for (keyIndex++; keyIndex < keysCount; keyIndex++) {
|
|
35
|
+
const keyVariants = calcVariants(keyIndex);
|
|
36
|
+
if (keyVariants.length === 0) {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
indexes[keyIndex] = 0;
|
|
40
|
+
variants[keyIndex] = keyVariants;
|
|
41
|
+
const key = keys[keyIndex];
|
|
42
|
+
const value = keyVariants[0];
|
|
43
|
+
args[key] = value;
|
|
44
|
+
}
|
|
45
|
+
if (keyIndex >= keysCount) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
next() {
|
|
54
|
+
if (nextVariant()) {
|
|
55
|
+
return {
|
|
56
|
+
done: false,
|
|
57
|
+
value: Object.assign({}, args),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return { done: true, value: null };
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
exports.testVariantsIterable = testVariantsIterable;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Obj } from "./types";
|
|
2
|
+
export declare type TestVariantsTemplate<Args extends Obj, Value> = Value[] | ((args: Args) => Value[]);
|
|
3
|
+
export declare type TestVariantsTemplates<Args extends Obj> = {
|
|
4
|
+
[key in keyof Args]: TestVariantsTemplate<Args, Args[key]>;
|
|
5
|
+
};
|
|
6
|
+
export declare type TestVariantsTemplatesExt<Args extends Obj, ArgsExtra extends Obj> = TestVariantsTemplates<{
|
|
7
|
+
[key in (keyof ArgsExtra | keyof Args)]: key extends keyof Args ? Args[key] : key extends keyof ArgsExtra ? ArgsExtra[key] : never;
|
|
8
|
+
}>;
|
|
9
|
+
export declare type TestVariantsIterableOptions<Args extends Obj, ArgsExtra extends Obj> = {
|
|
10
|
+
argsTemplates: TestVariantsTemplatesExt<Args, ArgsExtra>;
|
|
11
|
+
};
|
|
12
|
+
export declare function testVariantsIterable<Args extends Obj, ArgsExtra extends Obj>({ argsTemplates, }: TestVariantsIterableOptions<Args, ArgsExtra>): Iterable<Args>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
function testVariantsIterable({ argsTemplates, }) {
|
|
2
|
+
return {
|
|
3
|
+
[Symbol.iterator]() {
|
|
4
|
+
const keys = Object.keys(argsTemplates);
|
|
5
|
+
const templates = Object.values(argsTemplates);
|
|
6
|
+
const keysCount = keys.length;
|
|
7
|
+
const args = {};
|
|
8
|
+
function calcVariants(keyIndex) {
|
|
9
|
+
let template = templates[keyIndex];
|
|
10
|
+
if (typeof template === 'function') {
|
|
11
|
+
template = template(args);
|
|
12
|
+
}
|
|
13
|
+
return template;
|
|
14
|
+
}
|
|
15
|
+
const indexes = [];
|
|
16
|
+
const variants = [];
|
|
17
|
+
for (let nArg = 0; nArg < keysCount; nArg++) {
|
|
18
|
+
indexes[nArg] = -1;
|
|
19
|
+
variants[nArg] = [];
|
|
20
|
+
}
|
|
21
|
+
variants[0] = calcVariants(0);
|
|
22
|
+
function nextVariant() {
|
|
23
|
+
for (let keyIndex = keysCount - 1; keyIndex >= 0; keyIndex--) {
|
|
24
|
+
const valueIndex = indexes[keyIndex] + 1;
|
|
25
|
+
if (valueIndex < variants[keyIndex].length) {
|
|
26
|
+
const key = keys[keyIndex];
|
|
27
|
+
const value = variants[keyIndex][valueIndex];
|
|
28
|
+
indexes[keyIndex] = valueIndex;
|
|
29
|
+
args[key] = value;
|
|
30
|
+
for (keyIndex++; keyIndex < keysCount; keyIndex++) {
|
|
31
|
+
const keyVariants = calcVariants(keyIndex);
|
|
32
|
+
if (keyVariants.length === 0) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
indexes[keyIndex] = 0;
|
|
36
|
+
variants[keyIndex] = keyVariants;
|
|
37
|
+
const key = keys[keyIndex];
|
|
38
|
+
const value = keyVariants[0];
|
|
39
|
+
args[key] = value;
|
|
40
|
+
}
|
|
41
|
+
if (keyIndex >= keysCount) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
next() {
|
|
50
|
+
if (nextVariant()) {
|
|
51
|
+
return {
|
|
52
|
+
done: false,
|
|
53
|
+
value: Object.assign({}, args),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return { done: true, value: null };
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { testVariantsIterable };
|