@flemist/test-variants 5.0.12 → 5.0.13

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 CHANGED
@@ -275,6 +275,11 @@ const result = await testVariants({
275
275
  // Used inside testVariants instead of direct setTimeout, Date.now calls, etc
276
276
  // Intended only for testing and debugging the test-variants library itself
277
277
  timeController: ITimeController, // default: null - use timeControllerDefault
278
+
279
+ // Maximum duration for a single test run (milliseconds)
280
+ // Throws TimeoutError if exceeded
281
+ // Function form returns timeout per variant; null/undefined disables for that variant
282
+ timeout: number | ((args: Args) => number | null | undefined), // default: null - no timeout
278
283
  })
279
284
 
280
285
  // Result:
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../createTestVariants-DlP_jc3m.js");exports.createTestVariants=e.createTestVariants;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../createTestVariants-B34VFl9m.js");exports.TimeoutError=e.TimeoutError;exports.createTestVariants=e.createTestVariants;
@@ -1,4 +1,5 @@
1
- import { c as r } from "../createTestVariants-DxolnPmm.mjs";
1
+ import { T as e, c as t } from "../createTestVariants-Bbto3Xye.mjs";
2
2
  export {
3
- r as createTestVariants
3
+ e as TimeoutError,
4
+ t as createTestVariants
4
5
  };
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../createTestVariants-DlP_jc3m.js");exports.createTestVariants=e.createTestVariants;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../createTestVariants-B34VFl9m.js");exports.TimeoutError=e.TimeoutError;exports.createTestVariants=e.createTestVariants;
@@ -1,4 +1,5 @@
1
- import { c as r } from "../createTestVariants-DxolnPmm.mjs";
1
+ import { T as e, c as t } from "../createTestVariants-Bbto3Xye.mjs";
2
2
  export {
3
- r as createTestVariants
3
+ e as TimeoutError,
4
+ t as createTestVariants
4
5
  };
@@ -0,0 +1,13 @@
1
+ import { IObservable } from '@flemist/simple-utils';
2
+ import { ITimeController } from '@flemist/time-controller';
3
+ export declare class NowObservable implements IObservable<number> {
4
+ private readonly _timeController;
5
+ private readonly _subject;
6
+ private _interval;
7
+ private _timer;
8
+ constructor(interval: number, timeController?: null | ITimeController);
9
+ private update;
10
+ get interval(): number;
11
+ set interval(value: number);
12
+ subscribe(callback: (value: number) => void): () => void;
13
+ }
@@ -56,6 +56,8 @@ export type TestVariantsCreateTestRunOptions<Args extends Obj> = {
56
56
  log: RequiredNonNullable<TestVariantsLogOptions>;
57
57
  /** Pause debugger on error */
58
58
  pauseDebuggerOnError?: null | boolean;
59
+ /** Throws TimeoutError if single test run exceeds this timeout. Minimum is 100ms */
60
+ timeout?: null | number | ((args: Args) => number | null | undefined);
59
61
  };
60
62
  export type TestVariantsCall<Args extends Obj> = <SavedArgs = Args>(options?: null | TestVariantsRunOptionsInternal<Args, SavedArgs>) => PromiseOrValue<TestVariantsResult<Args>>;
61
63
  export type TestVariantsSetArgs<Args extends Obj> = <ArgsExtra extends Obj>(args: TestVariantsTemplatesExt<Omit<Args, 'seed'>, ArgsExtra>) => TestVariantsCall<Args>;
@@ -213,4 +213,8 @@ export type TestVariantsRunOptions<Args extends Obj = Obj, SavedArgs = Args> = {
213
213
  limitTime?: null | number;
214
214
  /** Time controller for testable time-dependent operations; null uses timeControllerDefault */
215
215
  timeController?: null | ITimeController;
216
+ /** Throws TimeoutError if single test run exceeds this timeout. Minimum is 100ms */
217
+ timeout?: null | number | ((args: Args) => number | null | undefined);
216
218
  };
219
+ export declare class TimeoutError extends Error {
220
+ }
@@ -0,0 +1,4 @@
1
+ "use strict";const W=require("@flemist/time-controller"),z=require("@flemist/simple-utils"),E=require("@flemist/async-utils"),B=require("@flemist/abort-controller-fast"),K=require("@flemist/time-limits");class ge extends Error{}function ne(){if(typeof process<"u"&&process.memoryUsage)try{return process.memoryUsage.rss()}catch{}if(typeof performance<"u"){const e=performance.memory;if(e)try{return e.usedJSHeapSize}catch{}}return null}const Je=1e3,U=[];function Xe(e){return z.formatAny(e,{pretty:!0,maxDepth:5,maxItems:50})}function Ze(...e){const r=e.map(t=>typeof t=="string"?t:Xe(t)).join(" ");U.push(r),U.length>Je&&U.shift(),console.log(r)}function Ke(){return U.join(`
2
+ `)}globalThis.__getStressTestLogLast=Ke;const pe=(e,r)=>{Ze(r)},he=e=>z.formatAny(e,{pretty:!0,maxDepth:20,maxItems:100,maxStringLength:5e3,dontExpandClassInstances:!0,dontExpandFunctions:!0}),C={start:!0,progress:5e3,completed:!0,error:!0,modeChange:!0,debug:!1,func:pe,format:he},Qe={start:!1,progress:!1,completed:!1,error:!1,modeChange:!1,debug:!1,func:pe,format:he};function be(e){return e===!1?Qe:e===!0||!e?C:{start:e.start??C.start,progress:e.progress??C.progress,completed:e.completed??C.completed,error:e.error??C.error,modeChange:e.modeChange??C.modeChange,debug:e.debug??C.debug,func:e.func??C.func,format:e.format??C.format}}function Ye(e,r){const t=e.now();return{startTime:t,startMemory:r,debugMode:!1,tests:0,iterations:0,iterationsAsync:0,prevLogTime:t,prevLogMemory:r,pendingModeChange:null,prevGcTime:t,prevGcIterations:0,prevGcIterationsAsync:0}}class V extends B.AbortError{}class et{_timeController;_subject;_interval;_timer;constructor(r,t){this._interval=r,this._timeController=t??W.timeControllerDefault,this._subject=new z.Subject({startStopNotifier:()=>(this.update(),()=>{this._timeController.clearTimeout(this._timer)})})}update(){this._subject.emit(this._timeController.now()),this._timer=this._timeController.setTimeout(()=>this.update(),this._interval)}get interval(){return this._interval}set interval(r){this._interval=r,this._timer&&(this._timeController.clearTimeout(this._timer),this.update())}subscribe(r){return this._subject.subscribe(r)}}const tt=50,rt=5;function nt(e,r){return e==null?null:typeof e=="number"?e:e(r)??null}function ue(e,r){return typeof e=="number"?{iterationsAsync:0,iterationsSync:e}:e!=null&&typeof e=="object"?e:r?{iterationsAsync:1,iterationsSync:0}:{iterationsAsync:0,iterationsSync:1}}function it(e,r){const t=r.log,o=r.pauseDebuggerOnError??!0,i=r.onStart,s=r.onEnd;let n=null,a=0;function c(m,h,y){n==null&&(n={error:m,args:h,tests:y},t.error&&t.func("error",`[test-variants] error variant: ${t.format(h)}
3
+ tests: ${y}
4
+ ${t.format(m)}`));const d=Date.now();if(o)debugger;if(Date.now()-d>tt&&a<rt){t.func("debug",`[test-variants] debug iteration: ${a}`),a++;return}const v=n;throw n=null,r.onError&&r.onError(v),v.error}const g=new et(100);return function(h,y,d){i&&i({args:h,tests:y});const b=nt(r.timeout,h);let v=null,M=d,f=null;b&&(v=Date.now(),f=new B.AbortControllerFast,M={abortSignal:E.combineAbortSignals(d.abortSignal,f.signal),timeController:d.timeController});function w(){f.abort(new ge(`[test-variants] test timeout ${b}ms exceeded`))}try{let S=e(h,M);if(E.isPromiseLike(S)){let T=null;return f&&(T=g.subscribe(()=>{Date.now()-v>=b&&(w(),T())}),S=Promise.race([S,E.abortSignalToPromise(f.signal)])),S.then(O=>{T?.();const G=ue(O,!0);return s&&s({args:h,tests:y,result:G}),G},O=>(T?.(),s&&!(O instanceof V)&&s({args:h,tests:y,error:O}),c(O,h,y)))}v!=null&&Date.now()-v>=b&&(w(),f.signal.throwIfAborted());const A=ue(S,!1);return s&&s({args:h,tests:y,result:A}),A}catch(S){return S instanceof V?void 0:(s&&s({args:h,tests:y,error:S}),c(S,h,y))}}}function R(e,r,t){for(let o=0,i=e.length;o<i;o++)if(t?t(e[o],r):e[o]===r)return o;return-1}function ce(e,r,t,o){const i=Object.keys(e.templates),s={},n=[],a=[],c=[],g=i.length;for(let m=0;m<g;m++){const h=i[m];s[h]=void 0,n.push(-1),a.push(void 0),c.push(null)}return{args:s,argsNames:i,indexes:n,argValues:a,argLimits:c,attempts:0,templates:e,limitArgOnError:t,equals:r,includeErrorVariant:o??!1}}function N(e,r){const t=e.templates.templates[r],o=e.templates.extra[r];let i;if(typeof t=="function"?i=t(e.args):i=t,o==null)return i;let s=null;const n=o.length;for(let a=0;a<n;a++){const c=o[a];R(i,c,e.equals)<0&&(s==null?s=[...i,c]:s.push(c))}return s??i}function I(e,r,t){const o=e.argValues[r].length;if(o===0)return-1;const i=e.argLimits[r];if(i==null)return o-1;let s=e.limitArgOnError;if(typeof s=="function"){const n=e.argsNames[r];s=s({name:n,values:e.argValues[r],maxValueIndex:i})}return!t||s?Math.min(i,o-1):o-1}function L(e){const r=e.indexes.length;for(let t=0;t<r;t++){const o=e.argLimits[t];if(o==null)return!1;const i=e.indexes[t];if(i>o)return!0;if(i<o)return!1}return!e.includeErrorVariant}function _(e){const r=e.indexes.length;for(let t=0;t<r;t++)e.indexes[t]=-1,e.argValues[t]=void 0,e.args[e.argsNames[t]]=void 0}function ye(e){let r=!1,t=!0;const o=e.indexes.length;let i=o,s=!1,n=0;for(;n<o;n++){const a=e.argValues[n]==null;(a||s)&&(a&&(r=!0),e.argValues[n]=N(e,e.argsNames[n]));const c=I(e,n,n>i);if(c<0){t=!1,e.indexes[n]=-1;break}a&&(e.indexes[n]=0,e.args[e.argsNames[n]]=e.argValues[n][0]),(s||e.indexes[n]>c)&&(e.indexes[n]=c,e.args[e.argsNames[n]]=e.argValues[n][c],s=!0),i===o&&e.indexes[n]<c&&(i=n)}if(L(e))return _(e),!1;if(r&&t)return!0;for(n--;n>=0;n--){if(e.argValues[n]==null)continue;let a=n>i;const c=I(e,n,a),g=e.indexes[n]+1;if(g<=c){e.indexes[n]=g,e.args[e.argsNames[n]]=e.argValues[n][g],g<c&&(a=!0);for(let m=n+1;m<o;m++)e.args[e.argsNames[m]]=void 0;for(n++;n<o;n++){e.argValues[n]=N(e,e.argsNames[n]);const m=I(e,n,a);if(m<0)break;e.indexes[n]=0,e.args[e.argsNames[n]]=e.argValues[n][0],m>0&&(a=!0)}if(n>=o)return L(e)?(_(e),!1):!0}}return _(e),!1}function Q(e){L(e)&&_(e);let r=!1,t=!0;const o=e.indexes.length;let i=o,s=!1,n=0;for(;n<o;n++){const a=e.argValues[n]==null;(a||s)&&(a&&(r=!0),e.argValues[n]=N(e,e.argsNames[n]));const c=I(e,n,n>i);if(c<0){t=!1,e.indexes[n]=-1;break}a&&(e.indexes[n]=c,e.args[e.argsNames[n]]=e.argValues[n][c]),(s||e.indexes[n]>c)&&(e.indexes[n]=c,e.args[e.argsNames[n]]=e.argValues[n][c],s=!0),i===o&&e.indexes[n]<c&&(i=n)}if((r||s)&&t&&!L(e))return!0;for(n--;n>=0;n--){if(e.argValues[n]==null)continue;let a=n>i;const c=I(e,n,a);let g=e.indexes[n]-1;if(g>c&&(g=c),g>=0){e.indexes[n]=g,e.args[e.argsNames[n]]=e.argValues[n][g],g<c&&(a=!0);for(let m=n+1;m<o;m++)e.args[e.argsNames[m]]=void 0;for(n++;n<o;n++){e.argValues[n]=N(e,e.argsNames[n]);const m=I(e,n,a);if(m<0)break;e.indexes[n]=m,e.args[e.argsNames[n]]=e.argValues[n][m],m>0&&(a=!0)}if(n>=o)return!0}}return _(e),!1}function ot(e,r){_(e);const t=e.argsNames,o=t.length;let i=!1;for(let s=0;s<o;s++){const n=t[s],a=r[n];if(a===void 0)return null;e.argValues[s]=N(e,n);const c=I(e,s,i);if(c<0)return null;const g=R(e.argValues[s],a,e.equals);if(g<0||g>c)return null;e.indexes[s]=g,e.args[e.argsNames[s]]=e.argValues[s][g],e.indexes[s]<c&&(i=!0)}return L(e)?null:e.indexes.slice()}function st(e){const r=e.indexes.length;if(r===0)return!1;let t=!1;for(let o=0;o<r;o++){e.argValues[o]=N(e,e.argsNames[o]);const i=I(e,o,t);if(i<0)return Math.random()<.5?ye(e):Q(e);e.indexes[o]=Math.floor(Math.random()*(i+1)),e.args[e.argsNames[o]]=e.argValues[o][e.indexes[o]],e.indexes[o]<i&&(t=!0)}return L(e)?Q(e):!0}function k(e){return e.mode==="forward"||e.mode==="backward"}function lt(e,r,t,o){const i=r[t],s=e.templates[t];if(typeof s!="function"){if(R(s,i,o)>=0)return;s.push(i);return}const n=e.extra[t];if(n==null){e.extra[t]=[i];return}R(n,i,o)>=0||n.push(i)}function at(e,r,t){for(const o in r)if(Object.prototype.hasOwnProperty.call(r,o)){if(o==="seed")continue;lt(e,r,o,t)}}function fe(e,r){for(const t in r)if(Object.prototype.hasOwnProperty.call(r,t)){if(t==="seed")continue;if(!e[t])return!1}return!0}const ut=[{mode:"forward"}];function ct(e){const{argsTemplates:r,equals:t,limitArgOnError:o,includeErrorVariant:i,getSeed:s,iterationModes:n,onModeChange:a,limitCompletionCount:c,limitTests:g,limitTime:m}=e,h=e.timeController??W.timeControllerDefault,y={templates:z.deepCloneJsonLike(r),extra:{}},d=n==null||n.length===0?ut:n,b=[];let v=null,M=null,f=0,w=0,S=!1,A=0;function T(){S||(S=!0,A=h.now(),O(),f=0,se(),xe())}function O(){for(let l=0,u=d.length;l<u;l++)b.push(G())}function G(){return{navigationState:ce(y,t??null,o??null,i??null),cycleCount:0,completedCount:0,testsInLastTurn:0,tryNextVariantAttempts:0,startTime:null}}function xe(){v=ce(y,t??null,!1,!1)}function se(){a?.({mode:d[f],modeIndex:f,tests:w})}function Te(l){T(),fe(y.templates,l)&&at(y,l,t)}function le(l,u){return T(),fe(y.templates,l)?(v.limitArgOnError=u?.limitArg??o??null,v.includeErrorVariant=u?.includeLimit??i??!1,ot(v,l)):null}function Ce(l){const u=l?.args;if(u==null)return;T();const p=le(u);if(p!=null){M={args:u,error:l?.error,tests:l?.tests??w},v.argLimits=p;for(let x=0,q=b.length;x<q;x++){const X=b[x].navigationState;X.argLimits=p}}}function Me(){return T(),Ie()}function Ie(){for(;;){if(!Ve())return null;for(;;){const l=qe();if(l!=null)return b[f].testsInLastTurn++,w++,l;if(Ne()){if(!$e())return null;De();break}}}}function Ve(){return!(Ae()||Oe()||D()&&(Le()||!Pe())||!_e())}function Ae(){return g!=null&&w>=g}function Oe(){return m!=null&&h.now()-A>=m}function Le(){if(!D())throw new Error("Unexpected behavior");return c!=null&&c<=0}function Pe(){if(!D())throw new Error("Unexpected behavior");for(let l=0,u=d.length;l<u;l++)if(P(d[l])&&H(l))return!0;return!1}function _e(){for(let l=0,u=d.length;l<u;l++)if(H(l))return!0;return!1}function Ne(){f++;const l=f>=d.length;return l&&(f=0),se(),l}function $e(){if(D()){const l=Ge();if(c!=null&&l>=c)return!1}return!0}function D(){for(let l=0,u=d.length;l<u;l++)if(k(d[l]))return!0;return!1}function Ge(){let l=!1,u=1/0;for(let p=0,x=b.length;p<x;p++){const q=b[p],X=d[p];k(X)&&(l=!0,H(p)&&q.completedCount<u&&(u=q.completedCount))}if(!l)throw new Error("Unexpected behavior");return u}function H(l){const u=d[l],p=b[l];return u.limitTests!=null&&u.limitTests<=0||P(u)&&(u.cycles!=null&&u.cycles<=0||u.attemptsPerVariant!=null&&u.attemptsPerVariant<=0)?!1:p.tryNextVariantAttempts<2}function De(){f=0;for(let l=0,u=b.length;l<u;l++){const p=b[l];p.testsInLastTurn=0,p.startTime=null}}function qe(){let l=0;for(;l<2;){if(!ke())return null;const u=je();if(u!=null)return u;if(P(d[f])&&Fe())return null;l++}return null}function ke(){const l=d[f];return!(Ue()||Be()||P(l)&&!Re(f))}function Ue(){const l=d[f],u=b[f];return l.limitTests!=null&&u.testsInLastTurn>=l.limitTests}function Be(){const l=d[f],u=b[f];return l.limitTime!=null&&u.startTime!=null&&h.now()-u.startTime>=l.limitTime}function P(l){return k(l)}function Re(l){const u=d[l],p=b[l];if(!P(u))throw new Error("Unexpected behavior");return p.cycleCount<(u.cycles??1)}function Fe(){const l=d[f],u=b[f];if(!P(l))throw new Error("Unexpected behavior");return u.cycleCount++,u.cycleCount>=(l.cycles??1)?(u.cycleCount=0,u.completedCount++,!0):!1}function je(){const l=d[f],u=b[f],p=u.navigationState;if($(l)){if(J())return null;const x=We();if(x!=null)return u.startTime==null&&(u.startTime=h.now()),x}return He()?(u.tryNextVariantAttempts=0,$(l)&&ze(),u.startTime==null&&(u.startTime=h.now()),ae(p.args)):(u.tryNextVariantAttempts++,null)}function We(){const l=d[f],p=b[f].navigationState;if(!$(l))throw new Error("Unexpected behavior");if(J())throw new Error("Unexpected behavior");const x=l.attemptsPerVariant??1;return p.attempts>0&&p.attempts<x?L(p)?null:(p.attempts++,ae(p.args)):null}function ze(){const l=d[f],p=b[f].navigationState;if(!$(l))throw new Error("Unexpected behavior");if(J())throw new Error("Unexpected behavior");p.attempts=1}function $(l){return k(l)}function J(){const l=d[f];if(!$(l))throw new Error("Unexpected behavior");return(l.attemptsPerVariant??1)<=0}function He(){const l=d[f],p=b[f].navigationState;switch(l.mode){case"forward":return ye(p);case"backward":return Q(p);case"random":return st(p);default:throw new Error(`Unknown mode: ${l.mode}`)}}function ae(l){const u={...l};return s!=null&&(u.seed=s({tests:w})),u}return{get limit(){return M},get modeIndex(){return f},get modeConfigs(){return d},get modeStates(){return b},get tests(){return w},calcIndexes:le,extendTemplates:Te,addLimit:Ce,next:Me}}function ie(e){if(e==null||e<=0)throw new Error(`Iterations = ${e}`);e--;const r=E.waitMicrotasks().then(()=>e);return e<=0?r:r.then(ie)}function ft(e,r,t){const o=r.limit?{error:r.limit.error,args:r.limit.args,tests:r.limit.tests}:null;if(o&&!t)throw o.error;return{iterations:e.iterations,bestError:o}}const me=2**31;function mt(e){if(e==null)return{parallel:1,sequentialOnError:!1};if(typeof e=="boolean")return{parallel:e?me:1,sequentialOnError:!1};if(typeof e=="number")return{parallel:e>0?e:1,sequentialOnError:!1};const r=e.count;let t=1;return r===!0?t=me:typeof r=="number"&&r>0&&(t=r),{parallel:t,sequentialOnError:e.sequentialOnError??!1}}function dt(e){const r=e?.saveErrorVariants,t=r&&e.createSaveErrorVariantsStore?e.createSaveErrorVariantsStore(r):null,o=e?.findBestError,{parallel:i,sequentialOnError:s}=mt(e?.parallel);return{store:t,GC_Iterations:e?.GC_Iterations??1e6,GC_IterationsAsync:e?.GC_IterationsAsync??1e4,GC_Interval:e?.GC_Interval??1e3,logOptions:be(e?.log),abortSignalExternal:e?.abortSignal,findBestError:o,dontThrowIfError:o?.dontThrowIfError,timeController:e?.timeController??W.timeControllerDefault,parallel:i,sequentialOnError:s}}function F(e,r,t){const{options:o,variantsIterator:i}=e,s=i.limit?.args??r;if(!o.store)return;const n=o.store.save(s);if(t)return n}function gt(e,r,t,o){const{abortControllerParallel:i,state:s,options:n}=e,{logOptions:a}=n;if(e.options.findBestError)e.variantsIterator.addLimit({args:r,error:t,tests:o}),s.debugMode=!1,F(e,r,!1),n.sequentialOnError&&!i.signal.aborted?(a.debug&&a.func("debug","[test-variants] sequentialOnError: aborting parallel, switching to sequential"),i.abort(new V)):a.debug&&a.func("debug","[test-variants] parallel error in findBestError mode, continuing with new limits");else{if(i.signal.aborted)return;F(e,r,!1),i.abort(t)}}function de(e,r,t,o){const{state:i}=e;if(e.options.findBestError){e.variantsIterator.addLimit({args:r,error:t,tests:o});const n=F(e,r,!0);if(n)return n.then(()=>{i.debugMode=!1});i.debugMode=!1;return}const s=F(e,r,!0);if(s)return s.then(()=>{throw t});throw t}function pt(e,r){const{GC_Iterations:t,GC_IterationsAsync:o,GC_Interval:i}=e.options;return t>0&&e.state.iterations-e.state.prevGcIterations>=t||o>0&&e.state.iterationsAsync-e.state.prevGcIterationsAsync>=o||i>0&&r-e.state.prevGcTime>=i}async function ht(e,r){e.prevGcIterations=e.iterations,e.prevGcIterationsAsync=e.iterationsAsync,e.prevGcTime=r,await ie(1)}function oe(e){const r=e/1e3;if(r<60)return`${r.toFixed(1)}s`;const t=r/60;return t<60?`${t.toFixed(1)}m`:`${(t/60).toFixed(1)}h`}function Y(e){const r=e/1073741824;if(r>=1)return r>=10?`${Math.round(r)}GB`:`${r.toFixed(1)}GB`;const t=e/(1024*1024);return t>=10?`${Math.round(t)}MB`:`${t.toFixed(1)}MB`}function bt(e,r){if(!e)return`mode[${r}]: null`;let t=`mode[${r}]: ${e.mode}`;return(e.mode==="forward"||e.mode==="backward")&&(e.cycles!=null&&(t+=`, cycles=${e.cycles}`),e.attemptsPerVariant!=null&&(t+=`, attempts=${e.attemptsPerVariant}`)),e.limitTime!=null&&(t+=`, limitTime=${oe(e.limitTime)}`),e.limitTests!=null&&(t+=`, limitTests=${e.limitTests}`),t}function ve(e,r){const t=e-r,o=t>=0?"+":"";return`${Y(e)} (${o}${Y(t)})`}function yt(e,r){if(!e.start)return;let t="[test-variants] start";r!=null&&(t+=`, memory: ${Y(r)}`),e.func("start",t)}function vt(e){const{options:r,state:t}=e,{logOptions:o,timeController:i}=r;if(!o.completed)return;const s=i.now()-t.startTime;let n=`[test-variants] end, tests: ${t.tests} (${oe(s)}), async: ${t.iterationsAsync}`;if(t.startMemory!=null){const a=ne();a!=null&&(n+=`, memory: ${ve(a,t.startMemory)}`)}o.func("completed",n)}function Se(e){const{options:r,state:t}=e,{logOptions:o}=r,i=t.pendingModeChange;!o.modeChange||i==null||(o.func("modeChange",`[test-variants] ${bt(i.mode,i.modeIndex)}`),t.pendingModeChange=null)}function St(e){const{options:r,state:t}=e,{logOptions:o,timeController:i}=r,s=i.now();if(!o.progress||s-t.prevLogTime<o.progress)return!1;Se(e);const n=s-t.startTime;let a=`[test-variants] tests: ${t.tests} (${oe(n)}), async: ${t.iterationsAsync}`;if(t.prevLogMemory!=null){const c=ne();c!=null&&(a+=`, memory: ${ve(c,t.prevLogMemory)}`,t.prevLogMemory=c)}return o.func("progress",a),t.prevLogTime=s,!0}function ee(e,r){e.debugMode=!1,r&&(e.iterationsAsync+=r.iterationsAsync,e.iterations+=r.iterationsSync+r.iterationsAsync)}function te(e){e.state.debugMode=!0,e.abortControllerParallel.abort(new V)}function Ee(e,r){const{testRun:t,testOptions:o,state:i}=e,s=i.tests;i.tests++;try{const n=t(r,s,o);if(E.isPromiseLike(n))return n.then(a=>{if(!a){te(e);return}ee(i,a)},a=>de(e,r,a,s));if(!n){te(e);return}ee(i,n)}catch(n){return n instanceof V?void 0:de(e,r,n,s)}}function Et(e,r){const{pool:t,abortSignal:o,testRun:i,testOptionsParallel:s,state:n}=e;if(!t)return;const a=n.tests;n.tests++,(async()=>{try{if(o.aborted)return;let c=i(r,a,s);if(E.isPromiseLike(c)&&(c=await c),!c){te(e);return}ee(n,c)}catch(c){if(c instanceof V)return;gt(e,r,c,a)}finally{t.release(1)}})()}function we(e){const{options:r,state:t}=e,{logOptions:o,timeController:i,GC_Interval:s}=r;if(!o.progress&&!s)return;St(e);const n=i.now();if(pt(e,n))return ht(t,n)}function j(e){return e.options.abortSignalExternal?.aborted??!1}function re(e){return e.abortSignal.aborted}async function Z(e,r){const{pool:t,state:o,options:i}=e,{parallel:s,logOptions:n}=i;let a=null;for(;!j(e);){const c=t&&!re(e);let g=!1;c&&(t.hold(1)||await K.poolWait({pool:t,count:1,hold:!0}),g=!0);try{if(r!=null?(a=r,r=null):e.state.debugMode||(a=e.variantsIterator.next()),a==null)break;const m=we(e);if(E.isPromiseLike(m)&&await m,j(e))continue;if(c)Et(e,a),g=!1;else{n.debug&&t&&re(e)&&n.func("debug",`[test-variants] parallel aborted, running sequential: tests=${o.tests}`);const h=Ee(e,a);E.isPromiseLike(h)&&await h}}finally{g&&t.release(1)}}t&&(await K.poolWait({pool:t,count:s,hold:!0}),t.release(s))}function wt(e){const{pool:r,state:t,options:o}=e,{logOptions:i}=o;if(r)return Z(e);let s=null;for(;!j(e)&&(e.state.debugMode||(s=e.variantsIterator.next()),s!=null);){const n=we(e);if(E.isPromiseLike(n))return n.then(()=>Z(e,s));if(j(e))continue;i.debug&&re(e)&&i.func("debug",`[test-variants] parallel aborted, running sequential: tests=${t.tests}`);const a=Ee(e,s);if(E.isPromiseLike(a))return a.then(()=>Z(e))}}async function xt(e,r,t,o){const i=dt(o),{store:s,logOptions:n,abortSignalExternal:a,findBestError:c,dontThrowIfError:g,timeController:m,parallel:h}=i,y=new B.AbortControllerFast,d=new B.AbortControllerFast,b=E.combineAbortSignals(a,y.signal),v=E.combineAbortSignals(b,d.signal),M={abortSignal:b,timeController:m},f={abortSignal:v,timeController:m};s&&await s.replay({testRun:e,variantsIterator:r,testOptions:M,findBestErrorEnabled:!!c});const w=h<=1?null:new K.Pool(h);yt(n,t.startMemory);const S={options:i,testRun:e,variantsIterator:r,testOptions:M,testOptionsParallel:f,abortControllerGlobal:y,abortControllerParallel:d,abortSignal:v,pool:w,state:t};Se(S);try{await wt(S),v.throwIfAborted()}catch(A){throw y.abort(new V),A}return b.throwIfAborted(),y.abort(new V),vt(S),await ie(1),ft(t,r,g)}function Tt(e){return function(t){return async function(i){const s=be(i?.log),n=it(e,{onStart:i?.onStart,onEnd:i?.onEnd,onError:i?.onError,log:s,pauseDebuggerOnError:i?.pauseDebuggerOnError,timeout:i?.timeout}),a=i?.timeController??W.timeControllerDefault,c=ne(),g=Ye(a,c),m=i?.onModeChange;function h(d){g.pendingModeChange=d,m?.(d)}const y=ct({argsTemplates:t,getSeed:i?.getSeed,iterationModes:i?.iterationModes,equals:i?.findBestError?.equals,limitArgOnError:i?.findBestError?.limitArgOnError,includeErrorVariant:i?.findBestError?.includeErrorVariant,timeController:a,onModeChange:h,limitCompletionCount:i?.cycles??1,limitTests:i?.limitTests,limitTime:i?.limitTime});return xt(n,y,g,i)}}}exports.TimeoutError=ge;exports.createTestVariants=Tt;