@flemist/test-variants 3.0.2 → 5.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/README.md +283 -49
- package/build/browser/index.cjs +1 -0
- package/build/browser/index.d.ts +1 -0
- package/build/browser/index.mjs +4 -0
- package/build/common/-test/freezeProps.d.ts +2 -0
- package/build/common/garbage-collect/garbageCollect.d.ts +5 -0
- package/build/common/helpers/log.d.ts +5 -0
- package/build/common/index.cjs +1 -0
- package/build/common/index.d.ts +2 -0
- package/build/common/index.mjs +4 -0
- package/build/common/test-variants/-test/caches.d.ts +1 -0
- package/build/common/test-variants/-test/constants.d.ts +8 -0
- package/build/common/test-variants/-test/estimations/estimateCallCount.d.ts +4 -0
- package/build/common/test-variants/-test/estimations/estimateModeChanges.d.ts +4 -0
- package/build/common/test-variants/-test/generators/findBestError.d.ts +4 -0
- package/build/common/test-variants/-test/generators/primitives.d.ts +16 -0
- package/build/common/test-variants/-test/generators/run.d.ts +9 -0
- package/build/common/test-variants/-test/generators/template.d.ts +3 -0
- package/build/common/test-variants/-test/generators/testFunc.d.ts +3 -0
- package/build/common/test-variants/-test/helpers/CallController.d.ts +28 -0
- package/build/common/test-variants/-test/helpers/ErrorVariantController.d.ts +17 -0
- package/build/common/test-variants/-test/helpers/TestError.d.ts +2 -0
- package/build/common/test-variants/-test/helpers/deepEqualJsonLikeWithoutSeed.d.ts +1 -0
- package/build/common/test-variants/-test/helpers/deepFreezeJsonLike.d.ts +1 -0
- package/build/common/test-variants/-test/helpers/forEachVariant.d.ts +4 -0
- package/build/common/test-variants/-test/helpers/getMaxAttemptsPerVariant.d.ts +2 -0
- package/build/common/test-variants/-test/helpers/getParallelLimit.d.ts +7 -0
- package/build/common/test-variants/-test/helpers/getVariantArgs.d.ts +12 -0
- package/build/common/test-variants/-test/helpers/runWithTimeController.d.ts +7 -0
- package/build/common/test-variants/-test/invariants/CallCountInvariant.d.ts +18 -0
- package/build/common/test-variants/-test/invariants/CallOptionsInvariant.d.ts +32 -0
- package/build/common/test-variants/-test/invariants/ErrorBehaviorInvariant.d.ts +32 -0
- package/build/common/test-variants/-test/invariants/FindBestErrorInvariant.d.ts +37 -0
- package/build/common/test-variants/-test/invariants/IterationsInvariant.d.ts +21 -0
- package/build/common/test-variants/-test/invariants/LimitTimeInvariant.d.ts +26 -0
- package/build/common/test-variants/-test/invariants/LogInvariant.d.ts +126 -0
- package/build/common/test-variants/-test/invariants/OnErrorInvariant.d.ts +38 -0
- package/build/common/test-variants/-test/invariants/OnModeChangeInvariant.d.ts +32 -0
- package/build/common/test-variants/-test/invariants/ParallelInvariant.d.ts +25 -0
- package/build/common/test-variants/-test/log.d.ts +3 -0
- package/build/common/test-variants/-test/types.d.ts +34 -0
- package/build/common/test-variants/-test/variants.d.ts +3 -0
- package/build/common/test-variants/createTestRun.d.ts +3 -0
- package/build/common/test-variants/createTestVariants.d.ts +4 -0
- package/build/common/test-variants/iterator/createVariantsIterator.d.ts +4 -0
- package/build/common/test-variants/iterator/helpers/findValueIndex.d.ts +2 -0
- package/build/common/test-variants/iterator/helpers/mode.d.ts +3 -0
- package/build/common/test-variants/iterator/helpers/template.d.ts +7 -0
- package/build/common/test-variants/iterator/types.d.ts +102 -0
- package/build/common/test-variants/iterator/variant-navigation/-test/helpers/caches.d.ts +1 -0
- package/build/common/test-variants/iterator/variant-navigation/-test/helpers/check.d.ts +2 -0
- package/build/common/test-variants/iterator/variant-navigation/-test/helpers/create.d.ts +3 -0
- package/build/common/test-variants/iterator/variant-navigation/-test/helpers/format.d.ts +6 -0
- package/build/common/test-variants/iterator/variant-navigation/-test/helpers/parse.d.ts +8 -0
- package/build/common/test-variants/iterator/variant-navigation/-test/helpers/variants.d.ts +12 -0
- package/build/common/test-variants/iterator/variant-navigation/variantNavigation.d.ts +28 -0
- package/build/common/test-variants/log/format.d.ts +7 -0
- package/build/common/test-variants/log/getMemoryUsage.d.ts +2 -0
- package/build/common/test-variants/log/logOptions.d.ts +8 -0
- package/build/common/test-variants/run/AbortErrorSilent.d.ts +3 -0
- package/build/common/test-variants/run/RunContext.d.ts +21 -0
- package/build/common/test-variants/run/createRunResult.d.ts +6 -0
- package/build/common/test-variants/run/createRunState.d.ts +23 -0
- package/build/common/test-variants/run/errorHandlers.d.ts +20 -0
- package/build/common/test-variants/run/gcManager.d.ts +6 -0
- package/build/common/test-variants/run/resolveRunOptions.d.ts +23 -0
- package/build/common/test-variants/run/runIterationLoop.d.ts +9 -0
- package/build/common/test-variants/run/runLogger.d.ts +9 -0
- package/build/common/test-variants/run/types.d.ts +57 -0
- package/build/common/test-variants/testVariantsRun.d.ts +6 -0
- package/build/common/test-variants/types.d.ts +183 -0
- package/build/createTestVariants-BL9wiuRD.mjs +1014 -0
- package/build/createTestVariants-CpzwjKTs.js +4 -0
- package/build/node/index.cjs +1 -0
- package/build/node/index.d.ts +8 -0
- package/build/node/index.mjs +102 -0
- package/build/node/test-variants/createSaveErrorVariantsStore.d.ts +5 -0
- package/{dist/lib → build/node}/test-variants/saveErrorVariants.d.ts +4 -3
- package/package.json +109 -68
- package/dist/bundle/browser.js +0 -650
- package/dist/lib/garbage-collect/garbageCollect.cjs +0 -30
- package/dist/lib/garbage-collect/garbageCollect.d.ts +0 -2
- package/dist/lib/garbage-collect/garbageCollect.mjs +0 -26
- package/dist/lib/index.cjs +0 -23
- package/dist/lib/index.d.ts +0 -7
- package/dist/lib/index.mjs +0 -13
- package/dist/lib/test-variants/argsToString.cjs +0 -17
- package/dist/lib/test-variants/argsToString.d.ts +0 -2
- package/dist/lib/test-variants/argsToString.mjs +0 -13
- package/dist/lib/test-variants/createTestVariants.cjs +0 -91
- package/dist/lib/test-variants/createTestVariants.d.ts +0 -8
- package/dist/lib/test-variants/createTestVariants.mjs +0 -87
- package/dist/lib/test-variants/createTestVariants.perf.cjs +0 -44
- package/dist/lib/test-variants/createTestVariants.perf.d.ts +0 -1
- package/dist/lib/test-variants/createTestVariants.perf.mjs +0 -42
- package/dist/lib/test-variants/prime.cjs +0 -65
- package/dist/lib/test-variants/prime.d.ts +0 -3
- package/dist/lib/test-variants/prime.mjs +0 -59
- package/dist/lib/test-variants/prime.perf.cjs +0 -30
- package/dist/lib/test-variants/prime.perf.d.ts +0 -1
- package/dist/lib/test-variants/prime.perf.mjs +0 -28
- package/dist/lib/test-variants/saveErrorVariants.cjs +0 -97
- package/dist/lib/test-variants/saveErrorVariants.mjs +0 -69
- package/dist/lib/test-variants/testVariantsCreateTestRun.cjs +0 -80
- package/dist/lib/test-variants/testVariantsCreateTestRun.d.ts +0 -22
- package/dist/lib/test-variants/testVariantsCreateTestRun.mjs +0 -76
- package/dist/lib/test-variants/testVariantsIterable.cjs +0 -70
- package/dist/lib/test-variants/testVariantsIterable.d.ts +0 -15
- package/dist/lib/test-variants/testVariantsIterable.mjs +0 -66
- package/dist/lib/test-variants/testVariantsIterator.cjs +0 -359
- package/dist/lib/test-variants/testVariantsIterator.d.ts +0 -67
- package/dist/lib/test-variants/testVariantsIterator.mjs +0 -355
- package/dist/lib/test-variants/testVariantsRun.cjs +0 -289
- package/dist/lib/test-variants/testVariantsRun.d.ts +0 -50
- package/dist/lib/test-variants/testVariantsRun.mjs +0 -265
- package/dist/lib/test-variants/types.cjs +0 -2
- package/dist/lib/test-variants/types.d.ts +0 -20
- package/dist/lib/test-variants/types.mjs +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { TestVariantsResult, TestVariantsRunOptions } from '../../..';
|
|
2
|
+
import { TestError } from '../helpers/TestError';
|
|
3
|
+
import { StressTestArgs, TestArgs } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Validates error handling behavior
|
|
6
|
+
*
|
|
7
|
+
* ## Applicability
|
|
8
|
+
* Active for all test executions. Validates error propagation based on
|
|
9
|
+
* findBestError and dontThrowIfError options.
|
|
10
|
+
*
|
|
11
|
+
* ## Validated Rules
|
|
12
|
+
* - When error expected and dontThrowIfError=true: no error thrown, bestError populated
|
|
13
|
+
* - When error expected and dontThrowIfError=false: error thrown, matches lastThrownError
|
|
14
|
+
* - When no error expected: no error thrown, bestError is null
|
|
15
|
+
*/
|
|
16
|
+
export declare class ErrorBehaviorInvariant {
|
|
17
|
+
private readonly _options;
|
|
18
|
+
private readonly _runOptions;
|
|
19
|
+
private readonly _variantsCount;
|
|
20
|
+
private readonly _errorVariantIndex;
|
|
21
|
+
private readonly _retriesToError;
|
|
22
|
+
constructor(options: StressTestArgs, runOptions: TestVariantsRunOptions<TestArgs>, variantsCount: number, errorVariantIndex: number | null, retriesToError: number);
|
|
23
|
+
/**
|
|
24
|
+
* Validates error behavior after test execution
|
|
25
|
+
*
|
|
26
|
+
* @param callCount - Number of test function calls
|
|
27
|
+
* @param caughtError - The error that was thrown (or null)
|
|
28
|
+
* @param lastThrownError - The last TestError that occurred (or null)
|
|
29
|
+
* @param result - The test result (may be null if error thrown)
|
|
30
|
+
*/
|
|
31
|
+
validate(callCount: number, caughtError: unknown, lastThrownError: TestError | null, result: TestVariantsResult<TestArgs> | null): void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { TestVariantsResult, TestVariantsRunOptions } from '../../..';
|
|
2
|
+
import { TestError } from '../helpers/TestError';
|
|
3
|
+
import { StressTestArgs, TestArgs } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Validates findBestError behavior
|
|
6
|
+
*
|
|
7
|
+
* ## Applicability
|
|
8
|
+
* Active when findBestError is enabled
|
|
9
|
+
*
|
|
10
|
+
* ## Validated Rules
|
|
11
|
+
* - dontThrowIfError=true + error: caughtError is null, bestError populated
|
|
12
|
+
* - dontThrowIfError=false + error: caughtError is thrown at end
|
|
13
|
+
* - includeErrorVariant=false: error variant never retested after first error
|
|
14
|
+
* - Error at variant 0: testing terminates (no better error possible)
|
|
15
|
+
* - Continues testing variants 0..(errorVariant-1) after error until limits
|
|
16
|
+
*
|
|
17
|
+
* ## Skipped Cases
|
|
18
|
+
* - parallel > 1 without sequentialOnError (race conditions)
|
|
19
|
+
* - attemptsPerVariant > 1 (can't distinguish retry from retest)
|
|
20
|
+
* - dynamic templates (variant indices don't have same meaning)
|
|
21
|
+
*/
|
|
22
|
+
export declare class FindBestErrorInvariant {
|
|
23
|
+
private readonly _options;
|
|
24
|
+
private readonly _runOptions;
|
|
25
|
+
private readonly _errorVariantIndex;
|
|
26
|
+
private readonly _errorVariantArgs;
|
|
27
|
+
private _errorOccurred;
|
|
28
|
+
private _errorVariantRetestedAfterError;
|
|
29
|
+
private _callsAfterError;
|
|
30
|
+
constructor(options: StressTestArgs, runOptions: TestVariantsRunOptions<TestArgs>, errorVariantIndex: number | null, errorVariantArgs: TestArgs | null);
|
|
31
|
+
/** Call inside test func before potential error */
|
|
32
|
+
onCall(args: TestArgs): void;
|
|
33
|
+
/** Call when error occurs */
|
|
34
|
+
onError(): void;
|
|
35
|
+
/** Run after test variants completion */
|
|
36
|
+
validateFinal(caughtError: unknown, lastThrownError: TestError | null, result: TestVariantsResult<TestArgs> | null): void;
|
|
37
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TestVariantsResult } from '../../..';
|
|
2
|
+
import { StressTestArgs, TestArgs } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Validates iteration count in test result
|
|
5
|
+
*
|
|
6
|
+
* ## Applicability
|
|
7
|
+
* Test completion when result is returned
|
|
8
|
+
*
|
|
9
|
+
* ## Invariants
|
|
10
|
+
* - iterations ≥ 0
|
|
11
|
+
* - iterations equals sum of iterations from all completed test calls
|
|
12
|
+
* - Calculation based on completedCount
|
|
13
|
+
* - Mixed mode: call 1 is sync, call 2 is async, call 3 is sync, etc
|
|
14
|
+
*/
|
|
15
|
+
export declare class IterationsInvariant {
|
|
16
|
+
private readonly _options;
|
|
17
|
+
constructor(options: StressTestArgs);
|
|
18
|
+
/** Run after test variants completion */
|
|
19
|
+
validateFinal(completedCount: number, result: TestVariantsResult<TestArgs> | null): void;
|
|
20
|
+
private _calculateExpectedIterations;
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ModeChangeEvent, TestVariantsRunOptions } from '../../..';
|
|
2
|
+
import { TimeControllerMock } from '@flemist/time-controller';
|
|
3
|
+
import { TestArgs } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Validates time limit constraints
|
|
6
|
+
*
|
|
7
|
+
* ## Applicability
|
|
8
|
+
* - Every mode change event
|
|
9
|
+
* - Test completion
|
|
10
|
+
*
|
|
11
|
+
* ## Invariants
|
|
12
|
+
* - Each mode's runtime ≤ its limitTime (if set)
|
|
13
|
+
* - Total runtime ≤ global limitTime (if set)
|
|
14
|
+
*/
|
|
15
|
+
export declare class LimitTimeInvariant {
|
|
16
|
+
private readonly _runOptions;
|
|
17
|
+
private readonly _timeController;
|
|
18
|
+
private readonly _startTime;
|
|
19
|
+
private _modeStartTime;
|
|
20
|
+
private _lastModeIndex;
|
|
21
|
+
constructor(runOptions: TestVariantsRunOptions<TestArgs>, timeController: TimeControllerMock);
|
|
22
|
+
/** Use in onModeChange callback */
|
|
23
|
+
onModeChange(event: ModeChangeEvent): void;
|
|
24
|
+
/** Run after test variants completion */
|
|
25
|
+
validateFinal(): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { TestVariantsLogOptions } from '../../..';
|
|
2
|
+
import { TestVariantsLogType } from '../../types';
|
|
3
|
+
import { RequiredNonNullable } from '@flemist/simple-utils';
|
|
4
|
+
/**
|
|
5
|
+
* Validates log callback behavior
|
|
6
|
+
*
|
|
7
|
+
* ## Applicability
|
|
8
|
+
* Active when log options are provided to runOptions.
|
|
9
|
+
* Validates every log callback invocation during test execution.
|
|
10
|
+
*
|
|
11
|
+
* ## Invariants
|
|
12
|
+
*
|
|
13
|
+
* ### Per-log validation (onLog)
|
|
14
|
+
* - Each log type is called exclusively when its corresponding option is enabled
|
|
15
|
+
* - No logs occur after 'completed'
|
|
16
|
+
* - 'start' log called exactly once, before any other logs
|
|
17
|
+
* - 'completed' log called exactly once, at the end
|
|
18
|
+
* - 'progress' logs occur exclusively after at least one test call (tests > 0)
|
|
19
|
+
* - 'modeChange' and 'debug' logs can occur before test calls
|
|
20
|
+
*
|
|
21
|
+
* ### Content validation (values only, not format)
|
|
22
|
+
* - 'start': no value checks
|
|
23
|
+
* - 'completed': tests value (callCount)
|
|
24
|
+
* - 'modeChange': modeIndex value, mode name value (forward/backward/random)
|
|
25
|
+
* - 'progress': tests value (callCount)
|
|
26
|
+
* - 'error': tests value (callCount - 1, tests completed before error)
|
|
27
|
+
* - 'debug': no value checks
|
|
28
|
+
*
|
|
29
|
+
* ### Log examples
|
|
30
|
+
*
|
|
31
|
+
* start:
|
|
32
|
+
* ```
|
|
33
|
+
* [test-variants] start, memory: 139MB
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* progress:
|
|
37
|
+
* ```
|
|
38
|
+
* [test-variants] tests: 615 (5.0s), async: 12, memory: 148MB (+8.8MB)
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* modeChange:
|
|
42
|
+
* ```
|
|
43
|
+
* [test-variants] mode[0]: forward
|
|
44
|
+
* [test-variants] mode[1]: backward, limitTests=10
|
|
45
|
+
* [test-variants] mode[2]: random, limitTime=10.9m
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* completed:
|
|
49
|
+
* ```
|
|
50
|
+
* [test-variants] end, tests: 815 (7.0s), async: 123, memory: 138MB (-1.0MB)
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* error:
|
|
54
|
+
* ```
|
|
55
|
+
* [test-variants] error variant: {arg1: value1}
|
|
56
|
+
* Error: test error message
|
|
57
|
+
* tests: 5
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* debug:
|
|
61
|
+
* ```
|
|
62
|
+
* [test-variants] debug iteration: 0
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* ## Note on modeChange validation
|
|
66
|
+
*
|
|
67
|
+
* Library calls onModeChange callback BEFORE emitting modeChange log (throttled).
|
|
68
|
+
* LogInvariant stores expected mode info in onModeChange, then validates
|
|
69
|
+
* when modeChange log is received.
|
|
70
|
+
*/
|
|
71
|
+
export declare class LogInvariant {
|
|
72
|
+
private _logStartCount;
|
|
73
|
+
private _logCompletedCount;
|
|
74
|
+
private _logProgressCount;
|
|
75
|
+
private _logModeChangeCount;
|
|
76
|
+
private _logErrorCount;
|
|
77
|
+
private _logDebugCount;
|
|
78
|
+
private _anyLogAfterCompleted;
|
|
79
|
+
/** Stores expected mode info for validation when modeChange log is received */
|
|
80
|
+
private _pendingModeInfo;
|
|
81
|
+
private readonly _logOptions;
|
|
82
|
+
private readonly _parallelLimit;
|
|
83
|
+
constructor(logOptions: RequiredNonNullable<TestVariantsLogOptions>, parallelLimit: number);
|
|
84
|
+
/**
|
|
85
|
+
* Call when mode changes to store expected mode info
|
|
86
|
+
*
|
|
87
|
+
* Library calls onModeChange callback BEFORE logFunc('modeChange', ...),
|
|
88
|
+
* so we store expected info here for validation when log is received
|
|
89
|
+
*/
|
|
90
|
+
onModeChange(modeIndex: number, modeName: string): void;
|
|
91
|
+
/** Call for each log func invocation */
|
|
92
|
+
onLog(type: TestVariantsLogType, message: string, tests: number): void;
|
|
93
|
+
private _validateStartLog;
|
|
94
|
+
private _validateCompletedLog;
|
|
95
|
+
private _onModeChangeLog;
|
|
96
|
+
/**
|
|
97
|
+
* Validates progress log content
|
|
98
|
+
*
|
|
99
|
+
* With parallel execution, tests value in log (library's state.tests) may
|
|
100
|
+
* differ from callCount due to timing differences.
|
|
101
|
+
*/
|
|
102
|
+
private _validateProgressLog;
|
|
103
|
+
/**
|
|
104
|
+
* Validates error log content
|
|
105
|
+
*
|
|
106
|
+
* Note: tests parameter is callCount (calls started), but error log shows
|
|
107
|
+
* tests completed before error, which is callCount - 1.
|
|
108
|
+
* With parallel execution, tests value in log may differ from callCount - 1
|
|
109
|
+
* because more tests may have started between dispatch and error.
|
|
110
|
+
*/
|
|
111
|
+
private _validateErrorLog;
|
|
112
|
+
private _validateDebugLog;
|
|
113
|
+
/**
|
|
114
|
+
* Run after test variants completion
|
|
115
|
+
*
|
|
116
|
+
* @param onErrorCount - number of onError callback calls
|
|
117
|
+
* @param completedSkipped - true if completed log was skipped (error thrown without findBestError)
|
|
118
|
+
*/
|
|
119
|
+
validateFinal(onErrorCount: number, completedSkipped: boolean): void;
|
|
120
|
+
get logStartCount(): number;
|
|
121
|
+
get logCompletedCount(): number;
|
|
122
|
+
get logProgressCount(): number;
|
|
123
|
+
get logModeChangeCount(): number;
|
|
124
|
+
get logErrorCount(): number;
|
|
125
|
+
get logDebugCount(): number;
|
|
126
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { TestVariantsRunOptions } from '../../..';
|
|
2
|
+
import { TestArgs } from '../types';
|
|
3
|
+
import { TestError } from '../helpers/TestError';
|
|
4
|
+
/**
|
|
5
|
+
* Validates onError callback behavior
|
|
6
|
+
*
|
|
7
|
+
* ## Applicability
|
|
8
|
+
* Active when errors occur during test execution.
|
|
9
|
+
* Validates onError callback is called correctly.
|
|
10
|
+
*
|
|
11
|
+
* ## Validated Rules
|
|
12
|
+
* - error parameter is instanceof TestError
|
|
13
|
+
* - error parameter matches lastThrownError (sequential execution)
|
|
14
|
+
* - args parameter matches errorVariantArgs (ignoring seed)
|
|
15
|
+
* - tests parameter is non-negative integer not exceeding callCount
|
|
16
|
+
* - tests parameter does not decrease in findBestError mode
|
|
17
|
+
* - Without findBestError: onError called at most once
|
|
18
|
+
* - With findBestError: onError can be called multiple times
|
|
19
|
+
* - If error occurred, onError was called at least once
|
|
20
|
+
* - If no error occurred, onError was never called
|
|
21
|
+
*
|
|
22
|
+
* ## Skipped Cases
|
|
23
|
+
* - parallel > 1 without sequentialOnError (race conditions)
|
|
24
|
+
*/
|
|
25
|
+
export declare class OnErrorInvariant {
|
|
26
|
+
private _onErrorCount;
|
|
27
|
+
private _lastOnErrorTests;
|
|
28
|
+
private readonly _runOptions;
|
|
29
|
+
private readonly _errorVariantArgs;
|
|
30
|
+
constructor(runOptions: TestVariantsRunOptions<TestArgs>, errorVariantArgs: TestArgs | null);
|
|
31
|
+
onError(event: {
|
|
32
|
+
error: unknown;
|
|
33
|
+
args: TestArgs;
|
|
34
|
+
tests: number;
|
|
35
|
+
}, callCount: number, lastThrownError: TestError | null): void;
|
|
36
|
+
get onErrorCount(): number;
|
|
37
|
+
validateFinal(lastThrownError: TestError | null): void;
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ModeChangeEvent, TestVariantsRunOptions } from '../../..';
|
|
2
|
+
import { NumberRange } from '@flemist/simple-utils';
|
|
3
|
+
import { TestArgs } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Validates onModeChange callback behavior
|
|
6
|
+
*
|
|
7
|
+
* ## Applicability
|
|
8
|
+
* Every mode change event
|
|
9
|
+
*
|
|
10
|
+
* ## Invariants
|
|
11
|
+
* - onModeChange count within estimated range [min, max] (skipped when time limits present)
|
|
12
|
+
* - First modeChange: modeIndex=0, tests=0
|
|
13
|
+
* - modeIndex cycles in order: 0→1→...→N-1→0→...
|
|
14
|
+
* - modeIndex within range [0, modesCount)
|
|
15
|
+
* - mode reference equals iterationModes[modeIndex]
|
|
16
|
+
* - tests ≥ 0
|
|
17
|
+
* - tests increases monotonically
|
|
18
|
+
*/
|
|
19
|
+
export declare class OnModeChangeInvariant {
|
|
20
|
+
private _modeChangeCount;
|
|
21
|
+
private _lastTests;
|
|
22
|
+
private _lastModeIndex;
|
|
23
|
+
private readonly _runOptions;
|
|
24
|
+
private readonly _modeChangesRange;
|
|
25
|
+
private readonly _hasTimeLimits;
|
|
26
|
+
constructor(runOptions: TestVariantsRunOptions<TestArgs>, modeChangesRange: NumberRange);
|
|
27
|
+
private _detectTimeLimits;
|
|
28
|
+
/** Use in onModeChange callback */
|
|
29
|
+
onModeChange(event: ModeChangeEvent): void;
|
|
30
|
+
/** Run after test variants completion */
|
|
31
|
+
validateFinal(): void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TestVariantsRunOptions } from '../../..';
|
|
2
|
+
import { StressTestArgs, TestArgs } from '../types';
|
|
3
|
+
import { CallController } from '../helpers/CallController';
|
|
4
|
+
/**
|
|
5
|
+
* Validates parallel execution behavior
|
|
6
|
+
*
|
|
7
|
+
* ## Applicability
|
|
8
|
+
* Active when parallel execution is configured. Validates concurrency.
|
|
9
|
+
*
|
|
10
|
+
* ## Validated Rules
|
|
11
|
+
* - Concurrent calls never exceed parallelLimit
|
|
12
|
+
* - All calls complete (currentConcurrent === 0) after test execution
|
|
13
|
+
* - Sync-only tests (isAsync=false) have maxConcurrent === 1
|
|
14
|
+
* - With parallelLimit > 1 and enough calls, maxConcurrent === parallelLimit
|
|
15
|
+
*/
|
|
16
|
+
export declare class ParallelInvariant {
|
|
17
|
+
private readonly _options;
|
|
18
|
+
private readonly _runOptions;
|
|
19
|
+
private readonly _callController;
|
|
20
|
+
constructor(options: StressTestArgs, runOptions: TestVariantsRunOptions<TestArgs>, callController: CallController);
|
|
21
|
+
/** Call inside test func after call starts */
|
|
22
|
+
onCall(): void;
|
|
23
|
+
/** Run after test variants completion */
|
|
24
|
+
validateFinal(): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type ObjectValue = {
|
|
2
|
+
value: number;
|
|
3
|
+
};
|
|
4
|
+
export type TemplateValue = number | ObjectValue;
|
|
5
|
+
export type TemplateArray = readonly TemplateValue[];
|
|
6
|
+
export type TestArgs = Record<string, TemplateValue>;
|
|
7
|
+
export type TemplateFunc = (args: TestArgs) => TemplateArray;
|
|
8
|
+
export type Template = Record<string, TemplateArray | TemplateFunc>;
|
|
9
|
+
export type StressTestArgs = {
|
|
10
|
+
argType: 'static' | 'dynamic' | null;
|
|
11
|
+
argValueType: 'primitive' | 'object' | null;
|
|
12
|
+
argsCountMax: number;
|
|
13
|
+
argValuesCountMax: number;
|
|
14
|
+
argValueMax: number;
|
|
15
|
+
errorVariantIndex: 'none' | 0 | 1 | 'last' | 'after-last' | null;
|
|
16
|
+
retriesToErrorMax: number;
|
|
17
|
+
findBestError: boolean | null;
|
|
18
|
+
limitArgOnError: false | true | 'func' | null;
|
|
19
|
+
includeErrorVariant: boolean | null;
|
|
20
|
+
dontThrowIfError: boolean | null;
|
|
21
|
+
withSeed: boolean | null;
|
|
22
|
+
attemptsPerVariantMax: number;
|
|
23
|
+
completionCounts: number;
|
|
24
|
+
modeType: 'forward' | 'backward' | 'random' | null;
|
|
25
|
+
modeCyclesMax: number;
|
|
26
|
+
modeAttemptsMax: number;
|
|
27
|
+
modesCountMax: number;
|
|
28
|
+
withEquals: boolean | null;
|
|
29
|
+
parallel: number | boolean | null;
|
|
30
|
+
async: boolean | null;
|
|
31
|
+
withDelay: boolean | null;
|
|
32
|
+
withLog: boolean | null;
|
|
33
|
+
seed: number;
|
|
34
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Obj } from '@flemist/simple-utils';
|
|
2
|
+
import { TestVariantsCreateTestRunOptions, TestVariantsTest, TestVariantsTestRun } from './run/types';
|
|
3
|
+
export declare function createTestRun<Args extends Obj>(test: TestVariantsTest<Args>, options: TestVariantsCreateTestRunOptions<Args>): TestVariantsTestRun<Args>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Obj } from '@flemist/simple-utils';
|
|
2
|
+
import { VariantsIterator, VariantsIteratorOptions } from './types';
|
|
3
|
+
/** Creates test variants iterator with limiting capabilities */
|
|
4
|
+
export declare function createVariantsIterator<Args extends Obj>(options: VariantsIteratorOptions<Args>): VariantsIterator<Args>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Obj } from '@flemist/simple-utils';
|
|
2
|
+
import { Equals } from '../../types';
|
|
3
|
+
import { TestVariantsTemplates, TestVariantsTemplatesWithExtra } from '../types';
|
|
4
|
+
/** Extend templates with all extra values */
|
|
5
|
+
export declare function extendTemplatesWithExtraArgs<Args extends Obj>(templates: TestVariantsTemplatesWithExtra<Args, any>, args: Args, equals?: null | Equals): void;
|
|
6
|
+
/** Check if all args except `seed` exist in template */
|
|
7
|
+
export declare function isArgsKeysInTemplate<Args extends Obj>(template: TestVariantsTemplates<Args>, args: Args): boolean;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Mutable, Obj } from '@flemist/simple-utils';
|
|
2
|
+
import { ITimeController } from '@flemist/time-controller';
|
|
3
|
+
import { ArgsWithSeed, Equals, GetSeedParams, LimitArgOnError, ModeConfig, OnModeChangeCallback } from '../types';
|
|
4
|
+
/** Limit information with args and optional error */
|
|
5
|
+
export type VariantsIteratorLimit<Args extends Obj> = {
|
|
6
|
+
args: ArgsWithSeed<Args>;
|
|
7
|
+
error?: unknown;
|
|
8
|
+
/** Number of tests run when this limit was applied */
|
|
9
|
+
tests: number;
|
|
10
|
+
};
|
|
11
|
+
/** Options for addLimit method */
|
|
12
|
+
export type AddLimitOptions<Args extends Obj> = {
|
|
13
|
+
args?: null | ArgsWithSeed<Args>;
|
|
14
|
+
error?: unknown;
|
|
15
|
+
/** Number of tests run when this limit is applied */
|
|
16
|
+
tests?: null | number;
|
|
17
|
+
};
|
|
18
|
+
/** Options for creating test variants iterator */
|
|
19
|
+
export type VariantsIteratorOptions<Args extends Obj> = {
|
|
20
|
+
argsTemplates: TestVariantsTemplates<Args>;
|
|
21
|
+
/** Custom equality for comparing arg values */
|
|
22
|
+
equals?: null | Equals;
|
|
23
|
+
/** Limit per-arg indexes on error; boolean enables/disables, function for custom per-arg logic */
|
|
24
|
+
limitArgOnError?: null | boolean | LimitArgOnError;
|
|
25
|
+
/** When true, error variant is included in iteration (for debugging); default false excludes it */
|
|
26
|
+
includeErrorVariant?: null | boolean;
|
|
27
|
+
/** Generates seed for reproducible randomized testing; seed is added to args */
|
|
28
|
+
getSeed?: null | ((params: GetSeedParams) => any);
|
|
29
|
+
/** Iteration modes (variant traversal methods); each mode runs until its limits are reached */
|
|
30
|
+
iterationModes?: null | readonly ModeConfig[];
|
|
31
|
+
/** Time controller for testable time-dependent operations; null uses timeControllerDefault */
|
|
32
|
+
timeController?: null | ITimeController;
|
|
33
|
+
/** Callback invoked when iteration mode changes */
|
|
34
|
+
onModeChange?: null | OnModeChangeCallback;
|
|
35
|
+
/** Global completion count limit; default 1 */
|
|
36
|
+
limitCompletionCount?: null | number;
|
|
37
|
+
/** Global tests limit */
|
|
38
|
+
limitTests?: null | number;
|
|
39
|
+
/** Global time limit in ms */
|
|
40
|
+
limitTime?: null | number;
|
|
41
|
+
};
|
|
42
|
+
/** State for each iteration mode */
|
|
43
|
+
export type ModeState<Args extends Obj> = {
|
|
44
|
+
/** Position and arg state, independent per mode */
|
|
45
|
+
navigationState: VariantNavigationState<Args>;
|
|
46
|
+
/** Full passes through all variants; resets to 0 when completedCount increments */
|
|
47
|
+
cycleCount: number;
|
|
48
|
+
/** Times mode reached its cycles config limit; only grows */
|
|
49
|
+
completedCount: number;
|
|
50
|
+
/** Tests since last switch to this mode; for "did nothing" check */
|
|
51
|
+
testsInLastTurn: number;
|
|
52
|
+
/** Count of attempts to get next variant in current mode */
|
|
53
|
+
tryNextVariantAttempts: number;
|
|
54
|
+
/** Set on first iteration after switching to mode; for per-mode limitTime check */
|
|
55
|
+
startTime: number | null;
|
|
56
|
+
};
|
|
57
|
+
/** Test variants iterator with limiting capabilities */
|
|
58
|
+
export type VariantsIterator<Args extends Obj> = {
|
|
59
|
+
/** Last applied limit's args and error; null if no args-based limit applied */
|
|
60
|
+
readonly limit: VariantsIteratorLimit<Args> | null;
|
|
61
|
+
/** Current mode index in modes array */
|
|
62
|
+
readonly modeIndex: number;
|
|
63
|
+
readonly modeConfigs: readonly ModeConfig[];
|
|
64
|
+
readonly modeStates: ModeState<Args>[];
|
|
65
|
+
/** Total tests count; for external logging, events, etc */
|
|
66
|
+
readonly tests: number;
|
|
67
|
+
/** Add or tighten limit */
|
|
68
|
+
addLimit(options?: null | AddLimitOptions<Args>): void;
|
|
69
|
+
/** Get next variant or null when done */
|
|
70
|
+
next(): ArgsWithSeed<Args> | null;
|
|
71
|
+
};
|
|
72
|
+
export type TestVariantsTemplateValues<Value> = readonly Value[];
|
|
73
|
+
export type TestVariantsTemplateFunc<Args extends Obj, Value> = (args: Args) => readonly Value[];
|
|
74
|
+
export type TestVariantsTemplate<Args extends Obj, Value> = TestVariantsTemplateValues<Value> | TestVariantsTemplateFunc<Args, Value>;
|
|
75
|
+
export type ArgName<Args extends Obj> = Extract<keyof Args, string>;
|
|
76
|
+
export type TestVariantsTemplates<Args extends Obj> = {
|
|
77
|
+
[key in ArgName<Args>]: TestVariantsTemplate<Args, Args[key]>;
|
|
78
|
+
};
|
|
79
|
+
export type TestVariantsTemplatesExtra<Args extends Obj> = {
|
|
80
|
+
[key in ArgName<Args>]?: Mutable<TestVariantsTemplateValues<Args[key]>>;
|
|
81
|
+
};
|
|
82
|
+
export type TestVariantsTemplatesWithExtra<Args extends Obj, Extra extends Obj> = {
|
|
83
|
+
templates: TestVariantsTemplates<Args>;
|
|
84
|
+
extra: TestVariantsTemplatesExtra<Extra>;
|
|
85
|
+
};
|
|
86
|
+
/** State required for variant navigation */
|
|
87
|
+
export type VariantNavigationState<Args extends Obj> = {
|
|
88
|
+
args: Args;
|
|
89
|
+
argsNames: ArgName<Args>[];
|
|
90
|
+
indexes: number[];
|
|
91
|
+
argValues: (readonly any[])[];
|
|
92
|
+
argLimits: (number | null)[];
|
|
93
|
+
attempts: number;
|
|
94
|
+
templates: TestVariantsTemplatesWithExtra<Args, any>;
|
|
95
|
+
limitArgOnError: null | boolean | LimitArgOnError;
|
|
96
|
+
equals: null | Equals;
|
|
97
|
+
includeErrorVariant: boolean;
|
|
98
|
+
};
|
|
99
|
+
/** Extended templates type that allows additional args beyond the base Args type */
|
|
100
|
+
export type TestVariantsTemplatesExt<Args extends Obj, ArgsExtra extends Obj> = TestVariantsTemplates<{
|
|
101
|
+
[key in ArgName<Args | ArgsExtra>]: key extends ArgName<Args> ? Args[key] : key extends ArgName<ArgsExtra> ? ArgsExtra[key] : never;
|
|
102
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getArgName(argIndex: number): string;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TestVariantsTemplates, VariantNavigationState } from '../../../types';
|
|
2
|
+
export declare function createArgs(indexes: number[], templates: TestVariantsTemplates<any>): any;
|
|
3
|
+
export declare function _createVariantNavigationState(argsPattern: string, extraPattern: string, limitPattern: string, valuesAsFuncs?: boolean): VariantNavigationState<any>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Ref } from '@flemist/simple-utils';
|
|
2
|
+
import { VariantNavigationState } from '../../../types';
|
|
3
|
+
export declare function formatIndexes(indexes: number[]): string;
|
|
4
|
+
export declare function formatLimits(limits: (number | null)[]): string;
|
|
5
|
+
export declare function formatTemplatesValues(argValues: (readonly Ref<number>[])[]): string;
|
|
6
|
+
export declare function formatState(state: VariantNavigationState<any>): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Ref } from '@flemist/simple-utils';
|
|
2
|
+
import { TestVariantsTemplates, TestVariantsTemplatesExtra } from '../../../types';
|
|
3
|
+
export declare function parseIndexes(numberPattern: string): number[];
|
|
4
|
+
export declare function parseLimits(numberPattern: string): (number | null)[];
|
|
5
|
+
export declare function parseTemplates(argsPattern: string, valuesAsFuncs: boolean): TestVariantsTemplates<any>;
|
|
6
|
+
export declare function parseTemplatesValues(argsPattern: string): Ref<number>[][];
|
|
7
|
+
export declare function parseTemplatesExtra(extraPattern: string): TestVariantsTemplatesExtra<any>;
|
|
8
|
+
export declare function parseExtraCounts(extraPattern: string, argIndex: number): number[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LimitArgOnError } from '../../../../..';
|
|
2
|
+
import { VariantNavigationState } from '../../../types';
|
|
3
|
+
export type ComplexArgs = {
|
|
4
|
+
a: number;
|
|
5
|
+
b: number;
|
|
6
|
+
c: number;
|
|
7
|
+
d: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function createComplexState(extraPattern: string, limitArgOnError: null | boolean | LimitArgOnError, includeErrorVariant: boolean): VariantNavigationState<ComplexArgs>;
|
|
10
|
+
export declare function collectAllVariants(extraPattern: string): string[];
|
|
11
|
+
export declare const funcTrue: () => boolean;
|
|
12
|
+
export declare const funcFalse: () => boolean;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Obj } from '@flemist/simple-utils';
|
|
2
|
+
import { ArgName, TestVariantsTemplatesWithExtra, VariantNavigationState } from '../types';
|
|
3
|
+
import { LimitArgOnError } from '../../..';
|
|
4
|
+
import { Equals } from '../../types';
|
|
5
|
+
/** Create initial variant navigation state for given templates */
|
|
6
|
+
export declare function createVariantNavigationState<Args extends Obj, Extra extends Obj>(templates: TestVariantsTemplatesWithExtra<Args, Extra>, equals: null | Equals, limitArgOnError: null | boolean | LimitArgOnError, includeErrorVariant: null | boolean): VariantNavigationState<Args>;
|
|
7
|
+
/** Calculate template values for given arg name */
|
|
8
|
+
export declare function calcArgValues<Args extends Obj>(state: VariantNavigationState<Args>, argName: ArgName<Args>): readonly any[];
|
|
9
|
+
/** Get max possible arg value index, considering limits */
|
|
10
|
+
export declare function getArgValueMaxIndex(state: VariantNavigationState<any>, argIndex: number, belowMax: boolean): number;
|
|
11
|
+
/** Reset variant navigation to initial state; variant position will be undefined */
|
|
12
|
+
export declare function resetVariantNavigation<Args extends Obj>(state: VariantNavigationState<Args>): void;
|
|
13
|
+
/** Advance to next variant in cartesian product; returns true if successful */
|
|
14
|
+
export declare function advanceVariantNavigation<Args extends Obj>(state: VariantNavigationState<Args>): boolean;
|
|
15
|
+
/** Retreat to previous variant (decrement with borrow); returns true if successful */
|
|
16
|
+
export declare function retreatVariantNavigation<Args extends Obj>(state: VariantNavigationState<Args>): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Compute indexes for all args
|
|
19
|
+
* @return null if any arg value not found or out of limits
|
|
20
|
+
*/
|
|
21
|
+
export declare function calcArgsIndexes<Args extends Obj>(state: VariantNavigationState<Args>, targetArgs: Args): number[] | null;
|
|
22
|
+
/**
|
|
23
|
+
* Random pick within limits; returns true if successful
|
|
24
|
+
* If the random variant turned out to be invalid,
|
|
25
|
+
* then we try to perform the advance or retreat operation,
|
|
26
|
+
* and they return the final result.
|
|
27
|
+
*/
|
|
28
|
+
export declare function randomVariantNavigation<Args extends Obj>(state: VariantNavigationState<Args>): boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ModeConfig } from '../types';
|
|
2
|
+
/** Format duration in human-readable form */
|
|
3
|
+
export declare function formatDuration(ms: number): string;
|
|
4
|
+
/** Format bytes in human-readable form */
|
|
5
|
+
export declare function formatBytes(bytes: number): string;
|
|
6
|
+
/** Format mode config for logging */
|
|
7
|
+
export declare function formatModeConfig(modeConfig: ModeConfig | null, modeIndex: number): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TestVariantsLogOptions } from '../types';
|
|
2
|
+
import { RequiredNonNullable } from '@flemist/simple-utils';
|
|
3
|
+
/** Default log options when logging is enabled */
|
|
4
|
+
export declare const logOptionsDefault: RequiredNonNullable<TestVariantsLogOptions>;
|
|
5
|
+
/** Log options when logging is disabled */
|
|
6
|
+
export declare const logOptionsDisabled: RequiredNonNullable<TestVariantsLogOptions>;
|
|
7
|
+
/** Resolve log options from various input formats */
|
|
8
|
+
export declare function resolveLogOptions(logRaw: boolean | TestVariantsLogOptions | null | undefined): RequiredNonNullable<TestVariantsLogOptions>;
|