@flemist/test-variants 5.0.12 → 5.0.14
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 +5 -0
- package/build/browser/index.cjs +1 -1
- package/build/browser/index.mjs +3 -2
- package/build/common/index.cjs +1 -1
- package/build/common/index.mjs +3 -2
- package/build/common/test-variants/-test/helpers/CallController.d.ts +1 -1
- package/build/common/test-variants/NowObservable.d.ts +13 -0
- package/build/common/test-variants/run/errorHandlers.d.ts +1 -2
- package/build/common/test-variants/run/runIterationLoop.d.ts +1 -2
- package/build/common/test-variants/run/types.d.ts +3 -2
- package/build/common/test-variants/types.d.ts +5 -2
- package/build/createTestVariants-DGrAba6p.mjs +1102 -0
- package/build/createTestVariants-DHZ0gEE2.js +4 -0
- package/build/node/index.cjs +1 -1
- package/build/node/index.mjs +7 -8
- package/package.json +3 -4
- package/build/createTestVariants-DlP_jc3m.js +0 -4
- package/build/createTestVariants-DxolnPmm.mjs +0 -1042
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";const W=require("@flemist/time-controller"),E=require("@flemist/simple-utils"),B=require("@flemist/abort-controller-fast"),Z=require("@flemist/time-limits");class de extends Error{}function re(){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 He=1e3,U=[];function Je(e){return E.formatAny(e,{pretty:!0,maxDepth:5,maxItems:50})}function Xe(...e){const r=e.map(t=>typeof t=="string"?t:Je(t)).join(" ");U.push(r),U.length>He&&U.shift(),console.log(r)}function Ze(){return U.join(`
|
|
2
|
+
`)}globalThis.__getStressTestLogLast=Ze;const ge=(e,r)=>{Xe(r)},pe=e=>E.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:ge,format:pe},Ke={start:!1,progress:!1,completed:!1,error:!1,modeChange:!1,debug:!1,func:ge,format:pe};function he(e){return e===!1?Ke: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 Qe(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 Ye{_timeController;_subject;_interval;_timer;constructor(r,t){this._interval=r,this._timeController=t??W.timeControllerDefault,this._subject=new E.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 et=50,tt=5;function rt(e,r){return e==null?null:typeof e=="number"?e:e(r)??null}function ae(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 nt(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>et&&a<tt){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 Ye(100);return function(h,y,d){i&&i({args:h,tests:y});const b=rt(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 de(`[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=ae(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=ae(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 ue(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 be(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 K(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 it(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 ot(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?be(e):K(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)?K(e):!0}function k(e){return e.mode==="forward"||e.mode==="backward"}function st(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 lt(e,r,t){for(const o in r)if(Object.prototype.hasOwnProperty.call(r,o)){if(o==="seed")continue;st(e,r,o,t)}}function ce(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 at=[{mode:"forward"}];function ut(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:E.deepCloneJsonLike(r),extra:{}},d=n==null||n.length===0?at: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,oe(),we())}function O(){for(let l=0,u=d.length;l<u;l++)b.push(G())}function G(){return{navigationState:ue(y,t??null,o??null,i??null),cycleCount:0,completedCount:0,testsInLastTurn:0,tryNextVariantAttempts:0,startTime:null}}function we(){v=ue(y,t??null,!1,!1)}function oe(){a?.({mode:d[f],modeIndex:f,tests:w})}function xe(l){T(),ce(y.templates,l)&<(y,l,t)}function se(l,u){return T(),ce(y.templates,l)?(v.limitArgOnError=u?.limitArg??o??null,v.includeErrorVariant=u?.includeLimit??i??!1,it(v,l)):null}function Te(l){const u=l?.args;if(u==null)return;T();const p=se(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 J=b[x].navigationState;J.argLimits=p}}}function Ce(){return T(),Me()}function Me(){for(;;){if(!Ie())return null;for(;;){const l=De();if(l!=null)return b[f].testsInLastTurn++,w++,l;if(_e()){if(!Ne())return null;Ge();break}}}}function Ie(){return!(Ve()||Ae()||D()&&(Oe()||!Le())||!Pe())}function Ve(){return g!=null&&w>=g}function Ae(){return m!=null&&h.now()-A>=m}function Oe(){if(!D())throw new Error("Unexpected behavior");return c!=null&&c<=0}function Le(){if(!D())throw new Error("Unexpected behavior");for(let l=0,u=d.length;l<u;l++)if(P(d[l])&&z(l))return!0;return!1}function Pe(){for(let l=0,u=d.length;l<u;l++)if(z(l))return!0;return!1}function _e(){f++;const l=f>=d.length;return l&&(f=0),oe(),l}function Ne(){if(D()){const l=$e();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 $e(){let l=!1,u=1/0;for(let p=0,x=b.length;p<x;p++){const q=b[p],J=d[p];k(J)&&(l=!0,z(p)&&q.completedCount<u&&(u=q.completedCount))}if(!l)throw new Error("Unexpected behavior");return u}function z(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 Ge(){f=0;for(let l=0,u=b.length;l<u;l++){const p=b[l];p.testsInLastTurn=0,p.startTime=null}}function De(){let l=0;for(;l<2;){if(!qe())return null;const u=Fe();if(u!=null)return u;if(P(d[f])&&Re())return null;l++}return null}function qe(){const l=d[f];return!(ke()||Ue()||P(l)&&!Be(f))}function ke(){const l=d[f],u=b[f];return l.limitTests!=null&&u.testsInLastTurn>=l.limitTests}function Ue(){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 Be(l){const u=d[l],p=b[l];if(!P(u))throw new Error("Unexpected behavior");return p.cycleCount<(u.cycles??1)}function Re(){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 Fe(){const l=d[f],u=b[f],p=u.navigationState;if($(l)){if(H())return null;const x=je();if(x!=null)return u.startTime==null&&(u.startTime=h.now()),x}return ze()?(u.tryNextVariantAttempts=0,$(l)&&We(),u.startTime==null&&(u.startTime=h.now()),le(p.args)):(u.tryNextVariantAttempts++,null)}function je(){const l=d[f],p=b[f].navigationState;if(!$(l))throw new Error("Unexpected behavior");if(H())throw new Error("Unexpected behavior");const x=l.attemptsPerVariant??1;return p.attempts>0&&p.attempts<x?L(p)?null:(p.attempts++,le(p.args)):null}function We(){const l=d[f],p=b[f].navigationState;if(!$(l))throw new Error("Unexpected behavior");if(H())throw new Error("Unexpected behavior");p.attempts=1}function $(l){return k(l)}function H(){const l=d[f];if(!$(l))throw new Error("Unexpected behavior");return(l.attemptsPerVariant??1)<=0}function ze(){const l=d[f],p=b[f].navigationState;switch(l.mode){case"forward":return be(p);case"backward":return K(p);case"random":return ot(p);default:throw new Error(`Unknown mode: ${l.mode}`)}}function le(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:se,extendTemplates:xe,addLimit:Te,next:Ce}}function ne(e){if(e==null||e<=0)throw new Error(`Iterations = ${e}`);e--;const r=E.waitMicrotasks().then(()=>e);return e<=0?r:r.then(ne)}function ct(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 fe=2**31;function ft(e){if(e==null)return{parallel:1,sequentialOnError:!1};if(typeof e=="boolean")return{parallel:e?fe: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=fe:typeof r=="number"&&r>0&&(t=r),{parallel:t,sequentialOnError:e.sequentialOnError??!1}}function mt(e){const r=e?.saveErrorVariants,t=r&&e.createSaveErrorVariantsStore?e.createSaveErrorVariantsStore(r):null,o=e?.findBestError,{parallel:i,sequentialOnError:s}=ft(e?.parallel);return{store:t,GC_Iterations:e?.GC_Iterations??1e6,GC_IterationsAsync:e?.GC_IterationsAsync??1e4,GC_Interval:e?.GC_Interval??1e3,logOptions:he(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 dt(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 me(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 gt(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 pt(e,r){e.prevGcIterations=e.iterations,e.prevGcIterationsAsync=e.iterationsAsync,e.prevGcTime=r,await ne(1)}function ie(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 Q(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 ht(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=${ie(e.limitTime)}`),e.limitTests!=null&&(t+=`, limitTests=${e.limitTests}`),t}function ye(e,r){const t=e-r,o=t>=0?"+":"";return`${Q(e)} (${o}${Q(t)})`}function bt(e,r){if(!e.start)return;let t="[test-variants] start";r!=null&&(t+=`, memory: ${Q(r)}`),e.func("start",t)}function yt(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} (${ie(s)}), async: ${t.iterationsAsync}`;if(t.startMemory!=null){const a=re();a!=null&&(n+=`, memory: ${ye(a,t.startMemory)}`)}o.func("completed",n)}function ve(e){const{options:r,state:t}=e,{logOptions:o}=r,i=t.pendingModeChange;!o.modeChange||i==null||(o.func("modeChange",`[test-variants] ${ht(i.mode,i.modeIndex)}`),t.pendingModeChange=null)}function vt(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;ve(e);const n=s-t.startTime;let a=`[test-variants] tests: ${t.tests} (${ie(n)}), async: ${t.iterationsAsync}`;if(t.prevLogMemory!=null){const c=re();c!=null&&(a+=`, memory: ${ye(c,t.prevLogMemory)}`,t.prevLogMemory=c)}return o.func("progress",a),t.prevLogTime=s,!0}function Y(e,r){e.debugMode=!1,r&&(e.iterationsAsync+=r.iterationsAsync,e.iterations+=r.iterationsSync+r.iterationsAsync)}function ee(e){e.state.debugMode=!0,e.abortControllerParallel.abort(new V)}function Se(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){ee(e);return}Y(i,a)},a=>me(e,r,a,s));if(!n){ee(e);return}Y(i,n)}catch(n){return n instanceof V?void 0:me(e,r,n,s)}}function St(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){ee(e);return}Y(n,c)}catch(c){if(c instanceof V)return;dt(e,r,c,a)}finally{t.release(1)}})()}function Ee(e){const{options:r,state:t}=e,{logOptions:o,timeController:i,GC_Interval:s}=r;if(!o.progress&&!s)return;vt(e);const n=i.now();if(gt(e,n))return pt(t,n)}function j(e){return e.options.abortSignalExternal?.aborted??!1}function te(e){return e.abortSignal.aborted}async function X(e,r){const{pool:t,state:o,options:i}=e,{parallel:s,logOptions:n}=i;let a=null;for(;!j(e);){const c=t&&!te(e);let g=!1;c&&(t.hold(1)||await Z.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=Ee(e);if(E.isPromiseLike(m)&&await m,j(e))continue;if(c)St(e,a),g=!1;else{n.debug&&t&&te(e)&&n.func("debug",`[test-variants] parallel aborted, running sequential: tests=${o.tests}`);const h=Se(e,a);E.isPromiseLike(h)&&await h}}finally{g&&t.release(1)}}t&&(await Z.poolWait({pool:t,count:s,hold:!0}),t.release(s))}function Et(e){const{pool:r,state:t,options:o}=e,{logOptions:i}=o;if(r)return X(e);let s=null;for(;!j(e)&&(e.state.debugMode||(s=e.variantsIterator.next()),s!=null);){const n=Ee(e);if(E.isPromiseLike(n))return n.then(()=>X(e,s));if(j(e))continue;i.debug&&te(e)&&i.func("debug",`[test-variants] parallel aborted, running sequential: tests=${t.tests}`);const a=Se(e,s);if(E.isPromiseLike(a))return a.then(()=>X(e))}}async function wt(e,r,t,o){const i=mt(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 Z.Pool(h);bt(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};ve(S);try{await Et(S),v.throwIfAborted()}catch(A){throw y.abort(new V),A}return b.throwIfAborted(),y.abort(new V),yt(S),await ne(1),ct(t,r,g)}function xt(e){return function(t){return async function(i){const s=he(i?.log),n=nt(e,{onStart:i?.onStart,onEnd:i?.onEnd,onError:i?.onError,log:s,pauseDebuggerOnError:i?.pauseDebuggerOnError,timeout:i?.timeout}),a=i?.timeController??W.timeControllerDefault,c=re(),g=Qe(a,c),m=i?.onModeChange;function h(d){g.pendingModeChange=d,m?.(d)}const y=ut({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 wt(n,y,g,i)}}}exports.TimeoutError=de;exports.createTestVariants=xt;
|
package/build/node/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("../createTestVariants-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("../createTestVariants-DHZ0gEE2.js"),F=require("path"),m=require("@flemist/simple-utils"),O=require("@flemist/simple-utils/node"),x=require("fs");function v(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const s in e)if(s!=="default"){const r=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,r.get?r:{enumerable:!0,get:()=>e[s]})}}return t.default=e,Object.freeze(t)}const g=v(F),u=v(x);async function P(e){const t=await u.promises.stat(e).catch(()=>null);if(t==null)return[];if(!t.isDirectory())throw new Error(`[saveErrorVariants] path is not a directory: ${e}`);return(await u.promises.readdir(e)).filter(n=>n.endsWith(".json")).sort((n,a)=>n>a?-1:n<a?1:0).map(n=>g.join(e,n))}async function b(e,t){const s=await u.promises.readFile(e,"utf-8");let r;try{r=JSON.parse(s)}catch{throw new Error(`[saveErrorVariants] invalid JSON in file: ${e}`)}if(t)try{return t(r)}catch{throw new Error(`[saveErrorVariants] jsonToArgs failed for file: ${e}`)}return r}function A(e){const t=Math.random().toString(36).substring(2);return m.formatDateFileName(e.sessionDate,"UTC")+"_"+t+".json"}async function D(e,t,s){let r;if(s){const n=s(e);typeof n=="string"?r=n:r=JSON.stringify(n,null,2)}else r=JSON.stringify(e,null,2);await u.promises.mkdir(g.dirname(t),{recursive:!0}),await u.promises.writeFile(t,r,"utf-8")}function L(e,t){const s=Math.max(e.length,t.length);for(let r=0;r<s;r++){const n=e[r],a=t[r];if(n==null){if(a==null)continue;return 1}if(a==null||n<a)return-1;if(n>a)return 1}return 0}class N{options;filePath;lastSavedArgs=null;constructor(t){this.options=t;const s=new Date;this.filePath=g.resolve(t.dir,t.getFilePath?.({sessionDate:s})??A({sessionDate:s}))}async save(t){m.deepEqualJsonLike(t,this.lastSavedArgs)||(this.lastSavedArgs={...t},await O.fileLock({filePath:this.filePath,func:()=>D(t,this.filePath,this.options.argsToJson)}))}async replay(t){const{testRun:s,variantsIterator:r,testOptions:n,findBestErrorEnabled:a}=t,h=this.options.useToFindBestError,E=this.options.limitArg??!1,V=this.options.extendTemplates??!1,S=this.options.attemptsPerVariant??1,w=new Map;function d(i){let o=w.get(i);return o===void 0&&(o=r.calcIndexes(i,{includeLimit:!1,limitArg:E}),w.set(i,o)),o}const y=await P(this.options.dir),f=[];for(let i=0,o=y.length;i<o;i++){const p=y[i],l=await b(p,this.options.jsonToArgs);V&&r.extendTemplates(l),d(l)!=null&&f.push(l)}function T(i,o){return L(d(i),d(o))}f.sort(T);for(let i=0,o=f.length;i<o;i++){const p=f[i];for(let l=0;l<S;l++)try{const c=s(p,0,n);m.isPromiseLike(c)&&await c}catch(c){if(h&&a){r.addLimit({args:p,error:c});break}throw c}}}}function k(e){return new N(e)}function q(e){const t=j.createTestVariants(e);return function(r){const n=t(r);return function(h){return n({...h,createSaveErrorVariantsStore:k})}}}exports.createTestVariants=q;
|
package/build/node/index.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { c as x } from "../createTestVariants-
|
|
1
|
+
import { c as x } from "../createTestVariants-DGrAba6p.mjs";
|
|
2
2
|
import * as d from "path";
|
|
3
|
-
import {
|
|
4
|
-
import { formatDateFileName as S, deepEqualJsonLike as A } from "@flemist/simple-utils";
|
|
3
|
+
import { formatDateFileName as F, deepEqualJsonLike as S, isPromiseLike as A } from "@flemist/simple-utils";
|
|
5
4
|
import { fileLock as T } from "@flemist/simple-utils/node";
|
|
6
5
|
import * as f from "fs";
|
|
7
6
|
async function P(r) {
|
|
@@ -32,7 +31,7 @@ async function j(r, t) {
|
|
|
32
31
|
}
|
|
33
32
|
function L(r) {
|
|
34
33
|
const t = Math.random().toString(36).substring(2);
|
|
35
|
-
return
|
|
34
|
+
return F(r.sessionDate, "UTC") + "_" + t + ".json";
|
|
36
35
|
}
|
|
37
36
|
async function N(r, t, n) {
|
|
38
37
|
let e;
|
|
@@ -72,7 +71,7 @@ class k {
|
|
|
72
71
|
);
|
|
73
72
|
}
|
|
74
73
|
async save(t) {
|
|
75
|
-
|
|
74
|
+
S(t, this.lastSavedArgs) || (this.lastSavedArgs = { ...t }, await T({
|
|
76
75
|
filePath: this.filePath,
|
|
77
76
|
func: () => N(t, this.filePath, this.options.argsToJson)
|
|
78
77
|
}));
|
|
@@ -103,7 +102,7 @@ class k {
|
|
|
103
102
|
for (let l = 0; l < y; l++)
|
|
104
103
|
try {
|
|
105
104
|
const c = n(h, 0, s);
|
|
106
|
-
|
|
105
|
+
A(c) && await c;
|
|
107
106
|
} catch (c) {
|
|
108
107
|
if (p && o) {
|
|
109
108
|
e.addLimit({
|
|
@@ -120,7 +119,7 @@ class k {
|
|
|
120
119
|
function D(r) {
|
|
121
120
|
return new k(r);
|
|
122
121
|
}
|
|
123
|
-
function
|
|
122
|
+
function B(r) {
|
|
124
123
|
const t = x(r);
|
|
125
124
|
return function(e) {
|
|
126
125
|
const s = t(e);
|
|
@@ -133,5 +132,5 @@ function C(r) {
|
|
|
133
132
|
};
|
|
134
133
|
}
|
|
135
134
|
export {
|
|
136
|
-
|
|
135
|
+
B as createTestVariants
|
|
137
136
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flemist/test-variants",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.14",
|
|
4
4
|
"description": "Runs a test function with all possible combinations of its parameters.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"types": "build/common/index.d.ts",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
},
|
|
80
80
|
"scripts": {
|
|
81
81
|
"========================= install =========================": "",
|
|
82
|
-
"_prepublishOnly": "run-p audit lint build test:all
|
|
82
|
+
"_prepublishOnly": "run-p audit lint build test:all",
|
|
83
83
|
"prepare": "node .husky/install.mjs",
|
|
84
84
|
"install:playwright": "pnpm exec playwright install --with-deps",
|
|
85
85
|
"========================= deploy =========================": "",
|
|
@@ -143,8 +143,7 @@
|
|
|
143
143
|
},
|
|
144
144
|
"dependencies": {
|
|
145
145
|
"@flemist/abort-controller-fast": "^1.0.0",
|
|
146
|
-
"@flemist/
|
|
147
|
-
"@flemist/simple-utils": "^2.1.15",
|
|
146
|
+
"@flemist/simple-utils": "^2.2.2",
|
|
148
147
|
"@flemist/time-controller": "^1.0.4",
|
|
149
148
|
"@flemist/time-limits": "^2.0.4",
|
|
150
149
|
"tslib": ">=2.8.1"
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
"use strict";const Y=require("@flemist/time-controller"),ee=require("@flemist/simple-utils"),S=require("@flemist/async-utils"),z=require("@flemist/abort-controller-fast"),H=require("@flemist/time-limits");function te(){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 He=1e3,_=[];function Je(e){return ee.formatAny(e,{pretty:!0,maxDepth:5,maxItems:50})}function Xe(...e){const n=e.map(t=>typeof t=="string"?t:Je(t)).join(" ");_.push(n),_.length>He&&_.shift(),console.log(n)}function Ze(){return _.join(`
|
|
2
|
-
`)}globalThis.__getStressTestLogLast=Ze;const de=(e,n)=>{Xe(n)},me=e=>ee.formatAny(e,{pretty:!0,maxDepth:20,maxItems:100,maxStringLength:5e3,dontExpandClassInstances:!0,dontExpandFunctions:!0}),x={start:!0,progress:5e3,completed:!0,error:!0,modeChange:!0,debug:!1,func:de,format:me},Ke={start:!1,progress:!1,completed:!1,error:!1,modeChange:!1,debug:!1,func:de,format:me};function ge(e){return e===!1?Ke:e===!0||!e?x:{start:e.start??x.start,progress:e.progress??x.progress,completed:e.completed??x.completed,error:e.error??x.error,modeChange:e.modeChange??x.modeChange,debug:e.debug??x.debug,func:e.func??x.func,format:e.format??x.format}}function Qe(e,n){const t=e.now();return{startTime:t,startMemory:n,debugMode:!1,tests:0,iterations:0,iterationsAsync:0,prevLogTime:t,prevLogMemory:n,pendingModeChange:null,prevGcTime:t,prevGcIterations:0,prevGcIterationsAsync:0}}class T extends z.AbortError{}const Ye=50,et=5;function ae(e,n){return typeof e=="number"?{iterationsAsync:0,iterationsSync:e}:e!=null&&typeof e=="object"?e:n?{iterationsAsync:1,iterationsSync:0}:{iterationsAsync:0,iterationsSync:1}}function tt(e,n){const t=n.log,i=n.pauseDebuggerOnError??!0,o=n.onStart,s=n.onEnd;let r=null,l=0;function c(m,f,b){r==null&&(r={error:m,args:f,tests:b},t.error&&t.func("error",`[test-variants] error variant: ${t.format(f)}
|
|
3
|
-
tests: ${b}
|
|
4
|
-
${t.format(m)}`));const y=Date.now();if(i)debugger;if(Date.now()-y>Ye&&l<et){t.func("debug",`[test-variants] debug iteration: ${l}`),l++;return}const h=r;throw r=null,n.onError&&n.onError(h),h.error}return function(f,b,y){o&&o({args:f,tests:b});try{const d=e(f,y);if(S.isPromiseLike(d))return d.then(v=>{const w=ae(v,!0);return s&&s({args:f,tests:b,result:w}),w},v=>(s&&!(v instanceof T)&&s({args:f,tests:b,error:v}),c(v,f,b)));const h=ae(d,!1);return s&&s({args:f,tests:b,result:h}),h}catch(d){return d instanceof T?void 0:(s&&s({args:f,tests:b,error:d}),c(d,f,b))}}}function k(e,n,t){for(let i=0,o=e.length;i<o;i++)if(t?t(e[i],n):e[i]===n)return i;return-1}function le(e,n,t,i){const o=Object.keys(e.templates),s={},r=[],l=[],c=[],m=o.length;for(let f=0;f<m;f++){const b=o[f];s[b]=void 0,r.push(-1),l.push(void 0),c.push(null)}return{args:s,argsNames:o,indexes:r,argValues:l,argLimits:c,attempts:0,templates:e,limitArgOnError:t,equals:n,includeErrorVariant:i??!1}}function O(e,n){const t=e.templates.templates[n],i=e.templates.extra[n];let o;if(typeof t=="function"?o=t(e.args):o=t,i==null)return o;let s=null;const r=i.length;for(let l=0;l<r;l++){const c=i[l];k(o,c,e.equals)<0&&(s==null?s=[...o,c]:s.push(c))}return s??o}function I(e,n,t){const i=e.argValues[n].length;if(i===0)return-1;const o=e.argLimits[n];if(o==null)return i-1;let s=e.limitArgOnError;if(typeof s=="function"){const r=e.argsNames[n];s=s({name:r,values:e.argValues[n],maxValueIndex:o})}return!t||s?Math.min(o,i-1):i-1}function V(e){const n=e.indexes.length;for(let t=0;t<n;t++){const i=e.argLimits[t];if(i==null)return!1;const o=e.indexes[t];if(o>i)return!0;if(o<i)return!1}return!e.includeErrorVariant}function L(e){const n=e.indexes.length;for(let t=0;t<n;t++)e.indexes[t]=-1,e.argValues[t]=void 0,e.args[e.argsNames[t]]=void 0}function pe(e){let n=!1,t=!0;const i=e.indexes.length;let o=i,s=!1,r=0;for(;r<i;r++){const l=e.argValues[r]==null;(l||s)&&(l&&(n=!0),e.argValues[r]=O(e,e.argsNames[r]));const c=I(e,r,r>o);if(c<0){t=!1,e.indexes[r]=-1;break}l&&(e.indexes[r]=0,e.args[e.argsNames[r]]=e.argValues[r][0]),(s||e.indexes[r]>c)&&(e.indexes[r]=c,e.args[e.argsNames[r]]=e.argValues[r][c],s=!0),o===i&&e.indexes[r]<c&&(o=r)}if(V(e))return L(e),!1;if(n&&t)return!0;for(r--;r>=0;r--){if(e.argValues[r]==null)continue;let l=r>o;const c=I(e,r,l),m=e.indexes[r]+1;if(m<=c){e.indexes[r]=m,e.args[e.argsNames[r]]=e.argValues[r][m],m<c&&(l=!0);for(let f=r+1;f<i;f++)e.args[e.argsNames[f]]=void 0;for(r++;r<i;r++){e.argValues[r]=O(e,e.argsNames[r]);const f=I(e,r,l);if(f<0)break;e.indexes[r]=0,e.args[e.argsNames[r]]=e.argValues[r][0],f>0&&(l=!0)}if(r>=i)return V(e)?(L(e),!1):!0}}return L(e),!1}function J(e){V(e)&&L(e);let n=!1,t=!0;const i=e.indexes.length;let o=i,s=!1,r=0;for(;r<i;r++){const l=e.argValues[r]==null;(l||s)&&(l&&(n=!0),e.argValues[r]=O(e,e.argsNames[r]));const c=I(e,r,r>o);if(c<0){t=!1,e.indexes[r]=-1;break}l&&(e.indexes[r]=c,e.args[e.argsNames[r]]=e.argValues[r][c]),(s||e.indexes[r]>c)&&(e.indexes[r]=c,e.args[e.argsNames[r]]=e.argValues[r][c],s=!0),o===i&&e.indexes[r]<c&&(o=r)}if((n||s)&&t&&!V(e))return!0;for(r--;r>=0;r--){if(e.argValues[r]==null)continue;let l=r>o;const c=I(e,r,l);let m=e.indexes[r]-1;if(m>c&&(m=c),m>=0){e.indexes[r]=m,e.args[e.argsNames[r]]=e.argValues[r][m],m<c&&(l=!0);for(let f=r+1;f<i;f++)e.args[e.argsNames[f]]=void 0;for(r++;r<i;r++){e.argValues[r]=O(e,e.argsNames[r]);const f=I(e,r,l);if(f<0)break;e.indexes[r]=f,e.args[e.argsNames[r]]=e.argValues[r][f],f>0&&(l=!0)}if(r>=i)return!0}}return L(e),!1}function rt(e,n){L(e);const t=e.argsNames,i=t.length;let o=!1;for(let s=0;s<i;s++){const r=t[s],l=n[r];if(l===void 0)return null;e.argValues[s]=O(e,r);const c=I(e,s,o);if(c<0)return null;const m=k(e.argValues[s],l,e.equals);if(m<0||m>c)return null;e.indexes[s]=m,e.args[e.argsNames[s]]=e.argValues[s][m],e.indexes[s]<c&&(o=!0)}return V(e)?null:e.indexes.slice()}function nt(e){const n=e.indexes.length;if(n===0)return!1;let t=!1;for(let i=0;i<n;i++){e.argValues[i]=O(e,e.argsNames[i]);const o=I(e,i,t);if(o<0)return Math.random()<.5?pe(e):J(e);e.indexes[i]=Math.floor(Math.random()*(o+1)),e.args[e.argsNames[i]]=e.argValues[i][e.indexes[i]],e.indexes[i]<o&&(t=!0)}return V(e)?J(e):!0}function D(e){return e.mode==="forward"||e.mode==="backward"}function ot(e,n,t,i){const o=n[t],s=e.templates[t];if(typeof s!="function"){if(k(s,o,i)>=0)return;s.push(o);return}const r=e.extra[t];if(r==null){e.extra[t]=[o];return}k(r,o,i)>=0||r.push(o)}function it(e,n,t){for(const i in n)if(Object.prototype.hasOwnProperty.call(n,i)){if(i==="seed")continue;ot(e,n,i,t)}}function ue(e,n){for(const t in n)if(Object.prototype.hasOwnProperty.call(n,t)){if(t==="seed")continue;if(!e[t])return!1}return!0}const st=[{mode:"forward"}];function at(e){const{argsTemplates:n,equals:t,limitArgOnError:i,includeErrorVariant:o,getSeed:s,iterationModes:r,onModeChange:l,limitCompletionCount:c,limitTests:m,limitTime:f}=e,b=e.timeController??Y.timeControllerDefault,y={templates:ee.deepCloneJsonLike(n),extra:{}},d=r==null||r.length===0?st:r,h=[];let v=null,w=null,p=0,M=0,A=!1,N=0;function $(){A||(A=!0,N=b.now(),Ee(),p=0,oe(),xe())}function Ee(){for(let a=0,u=d.length;a<u;a++)h.push(Se())}function Se(){return{navigationState:le(y,t??null,i??null,o??null),cycleCount:0,completedCount:0,testsInLastTurn:0,tryNextVariantAttempts:0,startTime:null}}function xe(){v=le(y,t??null,!1,!1)}function oe(){l?.({mode:d[p],modeIndex:p,tests:M})}function we(a){$(),ue(y.templates,a)&&it(y,a,t)}function ie(a,u){return $(),ue(y.templates,a)?(v.limitArgOnError=u?.limitArg??i??null,v.includeErrorVariant=u?.includeLimit??o??!1,rt(v,a)):null}function Me(a){const u=a?.args;if(u==null)return;$();const g=ie(u);if(g!=null){w={args:u,error:a?.error,tests:a?.tests??M},v.argLimits=g;for(let E=0,q=h.length;E<q;E++){const j=h[E].navigationState;j.argLimits=g}}}function Ie(){return $(),Te()}function Te(){for(;;){if(!Ve())return null;for(;;){const a=De();if(a!=null)return h[p].testsInLastTurn++,M++,a;if(Ne()){if(!$e())return null;qe();break}}}}function Ve(){return!(Ae()||Ce()||G()&&(Le()||!Oe())||!Pe())}function Ae(){return m!=null&&M>=m}function Ce(){return f!=null&&b.now()-N>=f}function Le(){if(!G())throw new Error("Unexpected behavior");return c!=null&&c<=0}function Oe(){if(!G())throw new Error("Unexpected behavior");for(let a=0,u=d.length;a<u;a++)if(C(d[a])&&R(a))return!0;return!1}function Pe(){for(let a=0,u=d.length;a<u;a++)if(R(a))return!0;return!1}function Ne(){p++;const a=p>=d.length;return a&&(p=0),oe(),a}function $e(){if(G()){const a=Ge();if(c!=null&&a>=c)return!1}return!0}function G(){for(let a=0,u=d.length;a<u;a++)if(D(d[a]))return!0;return!1}function Ge(){let a=!1,u=1/0;for(let g=0,E=h.length;g<E;g++){const q=h[g],j=d[g];D(j)&&(a=!0,R(g)&&q.completedCount<u&&(u=q.completedCount))}if(!a)throw new Error("Unexpected behavior");return u}function R(a){const u=d[a],g=h[a];return u.limitTests!=null&&u.limitTests<=0||C(u)&&(u.cycles!=null&&u.cycles<=0||u.attemptsPerVariant!=null&&u.attemptsPerVariant<=0)?!1:g.tryNextVariantAttempts<2}function qe(){p=0;for(let a=0,u=h.length;a<u;a++){const g=h[a];g.testsInLastTurn=0,g.startTime=null}}function De(){let a=0;for(;a<2;){if(!_e())return null;const u=Fe();if(u!=null)return u;if(C(d[p])&&Re())return null;a++}return null}function _e(){const a=d[p];return!(ke()||Ue()||C(a)&&!Be(p))}function ke(){const a=d[p],u=h[p];return a.limitTests!=null&&u.testsInLastTurn>=a.limitTests}function Ue(){const a=d[p],u=h[p];return a.limitTime!=null&&u.startTime!=null&&b.now()-u.startTime>=a.limitTime}function C(a){return D(a)}function Be(a){const u=d[a],g=h[a];if(!C(u))throw new Error("Unexpected behavior");return g.cycleCount<(u.cycles??1)}function Re(){const a=d[p],u=h[p];if(!C(a))throw new Error("Unexpected behavior");return u.cycleCount++,u.cycleCount>=(a.cycles??1)?(u.cycleCount=0,u.completedCount++,!0):!1}function Fe(){const a=d[p],u=h[p],g=u.navigationState;if(P(a)){if(F())return null;const E=je();if(E!=null)return u.startTime==null&&(u.startTime=b.now()),E}return ze()?(u.tryNextVariantAttempts=0,P(a)&&We(),u.startTime==null&&(u.startTime=b.now()),se(g.args)):(u.tryNextVariantAttempts++,null)}function je(){const a=d[p],g=h[p].navigationState;if(!P(a))throw new Error("Unexpected behavior");if(F())throw new Error("Unexpected behavior");const E=a.attemptsPerVariant??1;return g.attempts>0&&g.attempts<E?V(g)?null:(g.attempts++,se(g.args)):null}function We(){const a=d[p],g=h[p].navigationState;if(!P(a))throw new Error("Unexpected behavior");if(F())throw new Error("Unexpected behavior");g.attempts=1}function P(a){return D(a)}function F(){const a=d[p];if(!P(a))throw new Error("Unexpected behavior");return(a.attemptsPerVariant??1)<=0}function ze(){const a=d[p],g=h[p].navigationState;switch(a.mode){case"forward":return pe(g);case"backward":return J(g);case"random":return nt(g);default:throw new Error(`Unknown mode: ${a.mode}`)}}function se(a){const u={...a};return s!=null&&(u.seed=s({tests:M})),u}return{get limit(){return w},get modeIndex(){return p},get modeConfigs(){return d},get modeStates(){return h},get tests(){return M},calcIndexes:ie,extendTemplates:we,addLimit:Me,next:Ie}}function re(e){if(e==null||e<=0)throw new Error(`Iterations = ${e}`);e--;const n=S.waitMicrotasks().then(()=>e);return e<=0?n:n.then(re)}function lt(e,n,t){const i=n.limit?{error:n.limit.error,args:n.limit.args,tests:n.limit.tests}:null;if(i&&!t)throw i.error;return{iterations:e.iterations,bestError:i}}const ce=2**31;function ut(e){if(e==null)return{parallel:1,sequentialOnError:!1};if(typeof e=="boolean")return{parallel:e?ce:1,sequentialOnError:!1};if(typeof e=="number")return{parallel:e>0?e:1,sequentialOnError:!1};const n=e.count;let t=1;return n===!0?t=ce:typeof n=="number"&&n>0&&(t=n),{parallel:t,sequentialOnError:e.sequentialOnError??!1}}function ct(e){const n=e?.saveErrorVariants,t=n&&e.createSaveErrorVariantsStore?e.createSaveErrorVariantsStore(n):null,i=e?.findBestError,{parallel:o,sequentialOnError:s}=ut(e?.parallel);return{store:t,GC_Iterations:e?.GC_Iterations??1e6,GC_IterationsAsync:e?.GC_IterationsAsync??1e4,GC_Interval:e?.GC_Interval??1e3,logOptions:ge(e?.log),abortSignalExternal:e?.abortSignal,findBestError:i,dontThrowIfError:i?.dontThrowIfError,timeController:e?.timeController??Y.timeControllerDefault,parallel:o,sequentialOnError:s}}function U(e,n,t){const{options:i,variantsIterator:o}=e,s=o.limit?.args??n;if(!i.store)return;const r=i.store.save(s);if(t)return r}function ft(e,n,t,i){const{abortControllerParallel:o,state:s,options:r}=e,{logOptions:l}=r;if(e.options.findBestError)e.variantsIterator.addLimit({args:n,error:t,tests:i}),s.debugMode=!1,U(e,n,!1),r.sequentialOnError&&!o.signal.aborted?(l.debug&&l.func("debug","[test-variants] sequentialOnError: aborting parallel, switching to sequential"),o.abort(new T)):l.debug&&l.func("debug","[test-variants] parallel error in findBestError mode, continuing with new limits");else{if(o.signal.aborted)return;U(e,n,!1),o.abort(t)}}function fe(e,n,t,i){const{state:o}=e;if(e.options.findBestError){e.variantsIterator.addLimit({args:n,error:t,tests:i});const r=U(e,n,!0);if(r)return r.then(()=>{o.debugMode=!1});o.debugMode=!1;return}const s=U(e,n,!0);if(s)return s.then(()=>{throw t});throw t}function dt(e,n){const{GC_Iterations:t,GC_IterationsAsync:i,GC_Interval:o}=e.options;return t>0&&e.state.iterations-e.state.prevGcIterations>=t||i>0&&e.state.iterationsAsync-e.state.prevGcIterationsAsync>=i||o>0&&n-e.state.prevGcTime>=o}async function mt(e,n){e.prevGcIterations=e.iterations,e.prevGcIterationsAsync=e.iterationsAsync,e.prevGcTime=n,await re(1)}function ne(e){const n=e/1e3;if(n<60)return`${n.toFixed(1)}s`;const t=n/60;return t<60?`${t.toFixed(1)}m`:`${(t/60).toFixed(1)}h`}function X(e){const n=e/1073741824;if(n>=1)return n>=10?`${Math.round(n)}GB`:`${n.toFixed(1)}GB`;const t=e/(1024*1024);return t>=10?`${Math.round(t)}MB`:`${t.toFixed(1)}MB`}function gt(e,n){if(!e)return`mode[${n}]: null`;let t=`mode[${n}]: ${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=${ne(e.limitTime)}`),e.limitTests!=null&&(t+=`, limitTests=${e.limitTests}`),t}function he(e,n){const t=e-n,i=t>=0?"+":"";return`${X(e)} (${i}${X(t)})`}function pt(e,n){if(!e.start)return;let t="[test-variants] start";n!=null&&(t+=`, memory: ${X(n)}`),e.func("start",t)}function ht(e){const{options:n,state:t}=e,{logOptions:i,timeController:o}=n;if(!i.completed)return;const s=o.now()-t.startTime;let r=`[test-variants] end, tests: ${t.tests} (${ne(s)}), async: ${t.iterationsAsync}`;if(t.startMemory!=null){const l=te();l!=null&&(r+=`, memory: ${he(l,t.startMemory)}`)}i.func("completed",r)}function be(e){const{options:n,state:t}=e,{logOptions:i}=n,o=t.pendingModeChange;!i.modeChange||o==null||(i.func("modeChange",`[test-variants] ${gt(o.mode,o.modeIndex)}`),t.pendingModeChange=null)}function bt(e){const{options:n,state:t}=e,{logOptions:i,timeController:o}=n,s=o.now();if(!i.progress||s-t.prevLogTime<i.progress)return!1;be(e);const r=s-t.startTime;let l=`[test-variants] tests: ${t.tests} (${ne(r)}), async: ${t.iterationsAsync}`;if(t.prevLogMemory!=null){const c=te();c!=null&&(l+=`, memory: ${he(c,t.prevLogMemory)}`,t.prevLogMemory=c)}return i.func("progress",l),t.prevLogTime=s,!0}function Z(e,n){e.debugMode=!1,n&&(e.iterationsAsync+=n.iterationsAsync,e.iterations+=n.iterationsSync+n.iterationsAsync)}function K(e){e.state.debugMode=!0,e.abortControllerParallel.abort(new T)}function ye(e,n){const{testRun:t,testOptions:i,state:o}=e,s=o.tests;o.tests++;try{const r=t(n,s,i);if(S.isPromiseLike(r))return r.then(l=>{if(!l){K(e);return}Z(o,l)},l=>fe(e,n,l,s));if(!r){K(e);return}Z(o,r)}catch(r){return r instanceof T?void 0:fe(e,n,r,s)}}function yt(e,n){const{pool:t,abortSignal:i,testRun:o,testOptionsParallel:s,state:r}=e;if(!t)return;const l=r.tests;r.tests++,(async()=>{try{if(i.aborted)return;let c=o(n,l,s);if(S.isPromiseLike(c)&&(c=await c),!c){K(e);return}Z(r,c)}catch(c){if(c instanceof T)return;ft(e,n,c,l)}finally{t.release(1)}})()}function ve(e){const{options:n,state:t}=e,{logOptions:i,timeController:o,GC_Interval:s}=n;if(!i.progress&&!s)return;bt(e);const r=o.now();if(dt(e,r))return mt(t,r)}function B(e){return e.options.abortSignalExternal?.aborted??!1}function Q(e){return e.abortSignal.aborted}async function W(e,n){const{pool:t,state:i,options:o}=e,{parallel:s,logOptions:r}=o;let l=null;for(;!B(e);){const c=t&&!Q(e);let m=!1;c&&(t.hold(1)||await H.poolWait({pool:t,count:1,hold:!0}),m=!0);try{if(n!=null?(l=n,n=null):e.state.debugMode||(l=e.variantsIterator.next()),l==null)break;const f=ve(e);if(S.isPromiseLike(f)&&await f,B(e))continue;if(c)yt(e,l),m=!1;else{r.debug&&t&&Q(e)&&r.func("debug",`[test-variants] parallel aborted, running sequential: tests=${i.tests}`);const b=ye(e,l);S.isPromiseLike(b)&&await b}}finally{m&&t.release(1)}}t&&(await H.poolWait({pool:t,count:s,hold:!0}),t.release(s))}function vt(e){const{pool:n,state:t,options:i}=e,{logOptions:o}=i;if(n)return W(e);let s=null;for(;!B(e)&&(e.state.debugMode||(s=e.variantsIterator.next()),s!=null);){const r=ve(e);if(S.isPromiseLike(r))return r.then(()=>W(e,s));if(B(e))continue;o.debug&&Q(e)&&o.func("debug",`[test-variants] parallel aborted, running sequential: tests=${t.tests}`);const l=ye(e,s);if(S.isPromiseLike(l))return l.then(()=>W(e))}}async function Et(e,n,t,i){const o=ct(i),{store:s,logOptions:r,abortSignalExternal:l,findBestError:c,dontThrowIfError:m,timeController:f,parallel:b}=o,y=new z.AbortControllerFast,d=new z.AbortControllerFast,h=S.combineAbortSignals(l,y.signal),v=S.combineAbortSignals(h,d.signal),w={abortSignal:h,timeController:f},p={abortSignal:v,timeController:f};s&&await s.replay({testRun:e,variantsIterator:n,testOptions:w,findBestErrorEnabled:!!c});const M=b<=1?null:new H.Pool(b);pt(r,t.startMemory);const A={options:o,testRun:e,variantsIterator:n,testOptions:w,testOptionsParallel:p,abortControllerGlobal:y,abortControllerParallel:d,abortSignal:v,pool:M,state:t};be(A);try{await vt(A),v.throwIfAborted()}catch(N){throw y.abort(new T),N}return h.throwIfAborted(),y.abort(new T),ht(A),await re(1),lt(t,n,m)}function St(e){return function(t){return async function(o){const s=ge(o?.log),r=tt(e,{onStart:o?.onStart,onEnd:o?.onEnd,onError:o?.onError,log:s,pauseDebuggerOnError:o?.pauseDebuggerOnError}),l=o?.timeController??Y.timeControllerDefault,c=te(),m=Qe(l,c),f=o?.onModeChange;function b(d){m.pendingModeChange=d,f?.(d)}const y=at({argsTemplates:t,getSeed:o?.getSeed,iterationModes:o?.iterationModes,equals:o?.findBestError?.equals,limitArgOnError:o?.findBestError?.limitArgOnError,includeErrorVariant:o?.findBestError?.includeErrorVariant,timeController:l,onModeChange:b,limitCompletionCount:o?.cycles??1,limitTests:o?.limitTests,limitTime:o?.limitTime});return Et(r,y,m,o)}}}exports.createTestVariants=St;
|