@flemist/test-variants 2.0.0 → 2.0.1

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.
@@ -146,7 +146,7 @@ m=null})}())}function S(t,e,n){j(()=>{try{
146
146
  const r=e?e(t):t;n._resolve(r)}catch(t){
147
147
  n._reject(t)}})}function x(t,e,n){j(()=>{if(e)try{
148
148
  const r=e(t);n._resolve(r)}catch(t){n._reject(t)
149
- }else n._reject(t)})}const E=function(){};class A{
149
+ }else n._reject(t)})}const E=function(){};class P{
150
150
  constructor(t){
151
151
  this.status="pending",this.value=void 0,this.reason=void 0,this._handlers=null
152
152
  ;const e=this._resolve,n=this._reject,r=this._resolveAsync,s=this._rejectAsync,i=this
@@ -168,25 +168,25 @@ this.status="rejected",g(t)?t.then(this._rejectAsync,this._rejectAsync):this._re
168
168
  }_rejectSync(t){const e=this._handlers
169
169
  ;if(this.reason=t,null!=e){this._handlers=null
170
170
  ;for(let n=0,r=e.length;n<r;n++){const[,r,s]=e[n]
171
- ;x(t,r,s)}}}then(t,e){const n=new A(E)
171
+ ;x(t,r,s)}}}then(t,e){const n=new P(E)
172
172
  ;return"pending"===this.status?(null==this._handlers&&(this._handlers=[]),
173
173
  this._handlers.push([t,e,n])):"fulfilled"===this.status?S(this.value,t,n):x(this.reason,e,n),
174
174
  n}catch(t){return this.then(void 0,t)}finally(t){
175
175
  const e=t&&function(e){const n=t()
176
- ;return g(n)?n.then(()=>e):A.resolve(e)
176
+ ;return g(n)?n.then(()=>e):P.resolve(e)
177
177
  },n=t&&function(e){const n=t()
178
- ;return g(n)?n.then(()=>A.reject(e)):A.reject(e)}
178
+ ;return g(n)?n.then(()=>P.reject(e)):P.reject(e)}
179
179
  ;return this.then(e,n)}static resolve(t){
180
- const e=new A(E);return e._resolve(t),e}
181
- static reject(t){const e=new A(E)
180
+ const e=new P(E);return e._resolve(t),e}
181
+ static reject(t){const e=new P(E)
182
182
  ;return e._reject(t),e}get[Symbol.toStringTag](){
183
183
  return"Promise"}static get[Symbol.species](){
184
- return A}static all(t){return function(t,e){
184
+ return P}static all(t){return function(t,e){
185
185
  let n,r;e||(e=Promise);const s=new e((t,e)=>{
186
186
  n=t,r=e});let i=t.length;const o=[]
187
187
  ;return t.forEach((t,e)=>{g(t)?t.then(t=>{
188
188
  o[e]=t,0===--i&&n(o)},r):(o[e]=t,0===--i&&n(o))
189
- }),s}(t,A)}static allSettled(t){
189
+ }),s}(t,P)}static allSettled(t){
190
190
  return function(t,e){let n;e||(e=Promise)
191
191
  ;const r=new e((t,e)=>{n=t});let s=t.length
192
192
  ;const i=[];return t.forEach((t,e)=>{
@@ -194,18 +194,18 @@ g(t)?t.then(t=>{i[e]={status:"fulfilled",value:t
194
194
  },0===--s&&n(i)},t=>{i[e]={status:"rejected",
195
195
  reason:t},0===--s&&n(i)}):(i[e]={
196
196
  status:"fulfilled",value:t},0===--s&&n(i))}),r
197
- }(t,A)}static any(t){return function(t,e){let n,r
197
+ }(t,P)}static any(t){return function(t,e){let n,r
198
198
  ;e||(e=Promise);const s=new e((t,e)=>{n=t,r=e})
199
199
  ;let i=t.length;const o=[]
200
200
  ;return t.forEach((t,e)=>{g(t)?t.then(n,t=>{
201
201
  o[e]=t,0===--i&&r(new AggregateError(o))}):n(t)
202
- }),s}(t,A)}static race(t){return function(t,e){
202
+ }),s}(t,P)}static race(t){return function(t,e){
203
203
  let n,r;e||(e=Promise);const s=new e((t,e)=>{
204
204
  n=t,r=e});return t.forEach(t=>{
205
- g(t)?t.then(n,r):n(t)}),s}(t,A)}}
206
- const P=function(){};class k{constructor(t){
207
- if(this._status="pending",t&&t.aborted)this.promise=A.reject(t.reason),
208
- this.resolve=P,this.reject=P;else{let e,n
205
+ g(t)?t.then(n,r):n(t)}),s}(t,P)}}
206
+ const A=function(){};class k{constructor(t){
207
+ if(this._status="pending",t&&t.aborted)this.promise=P.reject(t.reason),
208
+ this.resolve=A,this.reject=A;else{let e,n
209
209
  ;if(this.promise=new Promise(function(t){
210
210
  e=t,n=function(e){p(t,e)}}),t){
211
211
  const r=t.subscribe(function(t){n(t)})
@@ -230,10 +230,10 @@ this._callbacks.add(t),()=>{var e
230
230
  ;this.aborted=!0,this.reason=t,null===(e=this._callbacks)||void 0===e||e.forEach(t=>{
231
231
  t.call(this,this.reason)}),this._callbacks=void 0}
232
232
  throwIfAborted(){if(this.aborted)throw this.reason
233
- }}class M{constructor(){this.signal=new O}
233
+ }}class I{constructor(){this.signal=new O}
234
234
  abort(t){
235
235
  this.signal.aborted||(void 0===t&&((t=new T("Aborted with no reason",t))._internal=!0),
236
- this.signal.abort(t))}}function F(t,e){
236
+ this.signal.abort(t))}}function M(t,e){
237
237
  var n=0,r=null;function s(t,s,i){
238
238
  return c(this,void 0,void 0,function(){var o
239
239
  ;return l(this,function(c){switch(c.label){case 0:
@@ -254,7 +254,7 @@ return s(t,e,n)});return"number"==typeof i?{
254
254
  iterationsAsync:0,iterationsSync:i
255
255
  }:null!==i&&"object"==typeof i?i:{
256
256
  iterationsAsync:0,iterationsSync:1}}catch(t){
257
- return s(t,e,n)}}}class I{constructor(t,e){
257
+ return s(t,e,n)}}}class F{constructor(t,e){
258
258
  this._branch=null,this.order=t,this.parent=e}
259
259
  get branch(){if(!this._branch){
260
260
  const t=[this.order];let e=this.parent
@@ -262,15 +262,15 @@ const t=[this.order];let e=this.parent
262
262
  ;this._branch=t}return this._branch}}
263
263
  function D(t){
264
264
  return null!=t&&"object"==typeof t&&"function"==typeof t.then
265
- }let C,R=[];function J(t){
266
- R.push(t),C||(C=function(){
265
+ }let C,V=[];function R(t){
266
+ V.push(t),C||(C=function(){
267
267
  return c(this,void 0,void 0,function*(){
268
- for(;R.length>0;){yield 0;const t=R
269
- ;R=[],t.forEach(t=>{try{t()}catch(t){
268
+ for(;V.length>0;){yield 0;const t=V
269
+ ;V=[],t.forEach(t=>{try{t()}catch(t){
270
270
  console.error("Unhandled promise rejection",t)}})}
271
- C=null})}())}function N(t,e,n){J(()=>{try{
271
+ C=null})}())}function J(t,e,n){R(()=>{try{
272
272
  const r=e?e(t):t;n._resolve(r)}catch(t){
273
- n._reject(t)}})}function V(t,e,n){J(()=>{if(e)try{
273
+ n._reject(t)}})}function N(t,e,n){R(()=>{if(e)try{
274
274
  const r=e(t);n._resolve(r)}catch(t){n._reject(t)
275
275
  }else n._reject(t)})}const $=function(){};class G{
276
276
  constructor(t){
@@ -287,16 +287,16 @@ D(t)?t.then(this._resolveAsync,this._rejectAsync):this._resolveSync(t)
287
287
  }_resolveSync(t){const e=this._handlers
288
288
  ;if(this.value=t,null!=e){this._handlers=null
289
289
  ;for(let n=0,r=e.length;n<r;n++){const[r,,s]=e[n]
290
- ;N(t,r,s)}}}_reject(t){
290
+ ;J(t,r,s)}}}_reject(t){
291
291
  "pending"===this.status&&this._rejectAsync(t)}
292
292
  _rejectAsync(t){
293
293
  this.status="rejected",D(t)?t.then(this._rejectAsync,this._rejectAsync):this._rejectSync(t)
294
294
  }_rejectSync(t){const e=this._handlers
295
295
  ;if(this.reason=t,null!=e){this._handlers=null
296
296
  ;for(let n=0,r=e.length;n<r;n++){const[,r,s]=e[n]
297
- ;V(t,r,s)}}}then(t,e){const n=new G($)
297
+ ;N(t,r,s)}}}then(t,e){const n=new G($)
298
298
  ;return"pending"===this.status?(null==this._handlers&&(this._handlers=[]),
299
- this._handlers.push([t,e,n])):"fulfilled"===this.status?N(this.value,t,n):V(this.reason,e,n),
299
+ this._handlers.push([t,e,n])):"fulfilled"===this.status?J(this.value,t,n):N(this.reason,e,n),
300
300
  n}catch(t){return this.then(void 0,t)}finally(t){
301
301
  const e=t&&function(e){const n=t()
302
302
  ;return D(n)?n.then(()=>e):G.resolve(e)
@@ -388,7 +388,7 @@ constructor(){this._queue=new _({lessThanFunc:L})}
388
388
  run(t,e,n){return this._run(!1,t,e,n)}
389
389
  runTask(t,e,n){return this._run(!0,t,e,n)}
390
390
  _run(t,e,n,r){const s=new W(r),i={
391
- priority:(o=Q++,c=n,null==o?null==c?null:c:new I(o,c)),
391
+ priority:(o=Q++,c=n,null==o?null==c?null:c:new F(o,c)),
392
392
  func:e,abortSignal:r,resolve:s.resolve,
393
393
  reject:s.reject,readyToRun:!t};var o,c
394
394
  ;if(this._queue.add(i),t){const t=this;return{
@@ -452,59 +452,65 @@ return c(this,void 0,void 0,function(){
452
452
  var n,r=this;return l(this,function(s){
453
453
  switch(s.label){case 0:n=function(){
454
454
  var e,n,s,i,a,u,h;return l(this,function(d){
455
- switch(d.label){case 0:return e=q,n=o(o({},B),{
456
- seed:null==U?void 0:U.value
457
- }),s=(R||C)&&Date.now(),R&&s-nt>=R&&(console.log(tt),
458
- nt=s),I&&tt-st>=I||D&&et-it>=D||C&&s-rt>=C?(st=tt,
459
- it=et,rt=s,[4,Y(1)]):[3,2];case 1:
455
+ switch(d.label){case 0:return e=L,n=o(o({},Q),{
456
+ seed:q
457
+ }),s=(V||C)&&Date.now(),V&&s-st>=V&&(console.log(nt),st=s),F&&nt-ot>=F||D&&rt-ct>=D||C&&s-it>=C?(ot=nt,
458
+ ct=rt,it=s,[4,Y(1)]):[3,2];case 1:
460
459
  d.sent(),d.label=2;case 2:
461
- if(null==N?void 0:N.aborted)return[2,"continue"]
462
- ;if(ot&&!K.aborted)return[3,10];d.label=3;case 3:
463
- return d.trys.push([3,6,,9]),g(i=t(n,e,K))?[4,i]:[3,5]
460
+ if(null==J?void 0:J.aborted)return[2,"continue"]
461
+ ;if(lt&&!Z.aborted)return[3,10];d.label=3;case 3:
462
+ return d.trys.push([3,6,,9]),g(i=t(n,e,Z))?[4,i]:[3,5]
464
463
  ;case 4:i=d.sent(),d.label=5;case 5:
465
464
  return i?(a=i.iterationsAsync,u=i.iterationsSync,
466
- et+=a,tt+=u+a,[3,9]):(Z=!0,Q.abort(),
465
+ rt+=a,nt+=u+a,[3,9]):(et=!0,H.abort(),
467
466
  [2,"continue"]);case 6:
468
467
  return h=d.sent(),E?[4,f(n,E,j.argsToJson)]:[3,8]
469
- ;case 7:d.sent(),d.label=8;case 8:if(!V)throw h
470
- ;return W={error:h,args:n,index:e},Z=!1,[3,9]
468
+ ;case 7:d.sent(),d.label=8;case 8:if(!N)throw h
469
+ ;return B={error:h,args:n,index:e},et=!1,[3,9]
471
470
  ;case 9:return[3,13];case 10:
472
- return ot.hold(1)?[3,12]:[4,ot.holdWait(1)]
471
+ return lt.hold(1)?[3,12]:[4,lt.holdWait(1)]
473
472
  ;case 11:d.sent(),d.label=12;case 12:
474
473
  c(r,void 0,void 0,function(){var r,s,i,o
475
474
  ;return l(this,function(c){switch(c.label){case 0:
476
475
  return c.trys.push([0,3,6,7]),
477
- (null==K?void 0:K.aborted)?[2]:g(r=t(n,e,K))?[4,r]:[3,2]
476
+ (null==Z?void 0:Z.aborted)?[2]:g(r=t(n,e,Z))?[4,r]:[3,2]
478
477
  ;case 1:r=c.sent(),c.label=2;case 2:
479
478
  return r?(s=r.iterationsAsync,i=r.iterationsSync,
480
- et+=s,tt+=i+s,[3,7]):(Z=!0,Q.abort(),[2]);case 3:
479
+ rt+=s,nt+=i+s,[3,7]):(et=!0,H.abort(),[2]);case 3:
481
480
  return o=c.sent(),E?[4,f(n,E,j.argsToJson)]:[3,5]
482
- ;case 4:c.sent(),c.label=5;case 5:if(!V)throw o
483
- ;return W={error:o,args:n,index:e},Z=!1,[3,7]
484
- ;case 6:return ot.release(1),[7];case 7:return[2]}
481
+ ;case 4:c.sent(),c.label=5;case 5:if(!N)throw o
482
+ ;return B={error:o,args:n,index:e},et=!1,[3,7]
483
+ ;case 6:return lt.release(1),[7];case 7:return[2]}
485
484
  })}),d.label=13;case 13:return[2]}})},s.label=1
486
485
  ;case 1:
487
- return(null==N?void 0:N.aborted)||!Z&&!function(){
488
- for(;;){if(q++,U&&U.done)return!1
489
- ;if(null==W||q<W.index){var t=L.next()
490
- ;if(!t.done)return B=t.value,!0}if(!G)return!1
491
- ;if((U=G.next()).done)return!1
492
- ;q=-1,L=e[Symbol.iterator]()}}()?[3,3]:[5,n()]
486
+ return(null==J?void 0:J.aborted)||!et&&!function(){
487
+ for(;;){
488
+ if(N&&L>=0&&(null==B||L<B.index)&&++W<N.repeatsPerVariant)return q=N.getSeed({
489
+ variantIndex:L,cycleIndex:U,repeatIndex:W,
490
+ totalIndex:U*N.repeatsPerVariant+W}),!0
491
+ ;if(W=0,L++,N&&U>=N.cycles)return!1
492
+ ;if((null==G||L<G)&&(null==B||L<B.index)){
493
+ var t=K.next()
494
+ ;if(!t.done)return Q=t.value,N&&(q=N.getSeed({
495
+ variantIndex:L,cycleIndex:U,repeatIndex:W,
496
+ totalIndex:U*N.repeatsPerVariant+W})),!0}
497
+ if(!N)return!1;if(++U>=N.cycles)return!1
498
+ ;L=-1,K=e[Symbol.iterator]()}}()?[3,3]:[5,n()]
493
499
  ;case 2:return s.sent(),[3,1];case 3:
494
- return ot?[4,ot.holdWait($)]:[3,5];case 4:
495
- s.sent(),ot.release($),s.label=5;case 5:
496
- if(null==H?void 0:H.aborted)throw H.reason
497
- ;return J&&console.log("[test-variants] variants: ".concat(q,", iterations: ").concat(tt,", async: ").concat(et)),
498
- [4,Y(1)];case 6:return s.sent(),[2,tt]}})})}
499
- var j,S,x,E,A,P,k,T,z,O,F,I,D,C,R,J,N,V,$,G,U,W,q,B,L,Q,K,H,Z,tt,et,nt,rt,st,it,ot,ct,lt
500
+ return lt?[4,lt.holdWait($)]:[3,5];case 4:
501
+ s.sent(),lt.release($),s.label=5;case 5:
502
+ if(null==tt?void 0:tt.aborted)throw tt.reason
503
+ ;return R&&console.log("[test-variants] variants: ".concat(L,", iterations: ").concat(nt,", async: ").concat(rt)),
504
+ [4,Y(1)];case 6:return s.sent(),[2,nt]}})})}
505
+ var j,S,x,E,P,A,k,T,z,O,M,F,D,C,V,R,J,N,$,G,U,W,q,B,L,Q,K,H,Z,tt,et,nt,rt,st,it,ot,ct,lt,at,ut
500
506
  ;return l(this,function(o){switch(o.label){case 0:
501
507
  return j=n.saveErrorVariants,S=null!==(r=null==j?void 0:j.retriesPerVariant)&&void 0!==r?r:1,
502
508
  x=new Date,
503
509
  E=j?i.resolve(j.dir,null!==(d=null===(s=j.getFilePath)||void 0===s?void 0:s.call(j,{
504
510
  sessionDate:x}))&&void 0!==d?d:h({sessionDate:x
505
511
  })):null,j?[4,a(j.dir)]:[3,12];case 1:
506
- A=o.sent(),o.label=2;case 2:
507
- o.trys.push([2,10,11,12]),P=function(t){
512
+ P=o.sent(),o.label=2;case 2:
513
+ o.trys.push([2,10,11,12]),A=function(t){
508
514
  var e="function"==typeof Symbol&&Symbol.iterator,n=e&&t[e],r=0
509
515
  ;if(n)return n.call(t)
510
516
  ;if(t&&"number"==typeof t.length)return{
@@ -512,37 +518,37 @@ next:function(){
512
518
  return t&&r>=t.length&&(t=void 0),{
513
519
  value:t&&t[r++],done:!t}}}
514
520
  ;throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")
515
- }(A),k=P.next(),o.label=3;case 3:
521
+ }(P),k=A.next(),o.label=3;case 3:
516
522
  return k.done?[3,9]:[4,u(k.value,j.jsonToArgs)]
517
523
  ;case 4:T=o.sent(),z=0,o.label=5;case 5:
518
524
  return z<S?g(O=t(T,-1,null))?[4,O]:[3,7]:[3,8]
519
525
  ;case 6:o.sent(),o.label=7;case 7:return z++,[3,5]
520
- ;case 8:return k=P.next(),[3,3];case 9:
521
- return[3,12];case 10:return F=o.sent(),ct={error:F
526
+ ;case 8:return k=A.next(),[3,3];case 9:
527
+ return[3,12];case 10:return M=o.sent(),at={error:M
522
528
  },[3,12];case 11:try{
523
- k&&!k.done&&(lt=P.return)&&lt.call(P)}finally{
524
- if(ct)throw ct.error}return[7];case 12:
525
- return I=null!==(v=n.GC_Iterations)&&void 0!==v?v:1e6,
529
+ k&&!k.done&&(ut=A.return)&&ut.call(A)}finally{
530
+ if(at)throw at.error}return[7];case 12:
531
+ return F=null!==(v=n.GC_Iterations)&&void 0!==v?v:1e6,
526
532
  D=null!==(_=n.GC_IterationsAsync)&&void 0!==_?_:1e4,
527
533
  C=null!==(y=n.GC_Interval)&&void 0!==y?y:1e3,
528
- R=null!==(b=n.logInterval)&&void 0!==b?b:5e3,
529
- J=null===(p=n.logCompleted)||void 0===p||p,
530
- N=n.abortSignal,V=n.findBestError,$=!0===n.parallel?Math.pow(2,31):!n.parallel||n.parallel<=0?1:n.parallel,
531
- G=null!==(m=null==V?void 0:V.seeds[Symbol.iterator]())&&void 0!==m?m:null,
532
- U=null==G?void 0:G.next(),
533
- W=null,q=-1,B={},L=e[Symbol.iterator](),Q=new M,K=function(...t){
534
+ V=null!==(b=n.logInterval)&&void 0!==b?b:5e3,
535
+ R=null===(p=n.logCompleted)||void 0===p||p,
536
+ J=n.abortSignal,N=n.findBestError,$=!0===n.parallel?Math.pow(2,31):!n.parallel||n.parallel<=0?1:n.parallel,
537
+ G=null!==(m=n.limitVariantsCount)&&void 0!==m?m:null,
538
+ U=0,W=0,q=void 0,B=null,L=-1,
539
+ Q={},K=e[Symbol.iterator](),H=new I,Z=function(...t){
534
540
  let e,n;function r(t){e.abort(t)}
535
541
  for(let s=0;s<t.length;s++){const i=t[s];if(i){
536
542
  if(i.aborted)return i
537
- ;n?(e||(e=new M,n.subscribe(r)),i.subscribe(r)):n=i
538
- }}return e?e.signal:n||(new M).signal
539
- }(N,Q.signal),H=K,Z=!1,tt=0,et=0,nt=Date.now(),
540
- rt=nt,st=tt,it=et,ot=$<=1?null:new X($),[4,w()]
541
- ;case 13:return[2,{iterations:o.sent(),bestError:W
543
+ ;n?(e||(e=new I,n.subscribe(r)),i.subscribe(r)):n=i
544
+ }}return e?e.signal:n||(new I).signal
545
+ }(J,H.signal),tt=Z,et=!1,nt=0,rt=0,st=Date.now(),
546
+ it=st,ot=nt,ct=rt,lt=$<=1?null:new X($),[4,w()]
547
+ ;case 13:return[2,{iterations:o.sent(),bestError:B
542
548
  }]}})})}t.createTestVariants=function(t){
543
549
  return function(e){return function(n){
544
550
  return c(this,void 0,void 0,function(){var r,s
545
- ;return l(this,function(i){return r=F(t,{
551
+ ;return l(this,function(i){return r=M(t,{
546
552
  onError:null==n?void 0:n.onError}),s=d({
547
553
  argsTemplates:e}),[2,Z(r,s,n)]})})}}
548
554
  },t.generateErrorVariantFilePath=h,Object.defineProperty(t,"__esModule",{
@@ -2,5 +2,5 @@ export { type Obj, type GenerateErrorVariantFilePathOptions, type SaveErrorVaria
2
2
  export { generateErrorVariantFilePath, } from "./test-variants/saveErrorVariants";
3
3
  export { type TestVariantsTemplate, type TestVariantsTemplates, type TestVariantsTemplatesExt, } from "./test-variants/testVariantsIterable";
4
4
  export { type ErrorEvent, type OnErrorCallback, type TestVariantsTest, type TestVariantsTestResult, type TestVariantsCreateTestRunOptions, type TestVariantsTestRun, type TestVariantsTestRunResult, } from "./test-variants/testVariantsCreateTestRun";
5
- export { type TestVariantsFindBestErrorOptions, type TestVariantsRunOptions, type TestVariantsBestError, type TestVariantsRunResult, } from "./test-variants/testVariantsRun";
5
+ export { type GetSeedParams, type TestVariantsFindBestErrorOptions, type TestVariantsRunOptions, type TestVariantsBestError, type TestVariantsRunResult, } from "./test-variants/testVariantsRun";
6
6
  export { type TestVariantsSetArgs, type TestVariantsCall, createTestVariants, } from './test-variants/createTestVariants';
@@ -65,30 +65,55 @@ function testVariantsRun(testRun, variants, options = {}) {
65
65
  : !options.parallel || options.parallel <= 0
66
66
  ? 1
67
67
  : options.parallel;
68
- const seedsIterator = (_j = findBestError === null || findBestError === void 0 ? void 0 : findBestError.seeds[Symbol.iterator]()) !== null && _j !== void 0 ? _j : null;
69
- let seedResult = seedsIterator === null || seedsIterator === void 0 ? void 0 : seedsIterator.next();
68
+ const limitVariantsCount = (_j = options.limitVariantsCount) !== null && _j !== void 0 ? _j : null;
69
+ let cycleIndex = 0;
70
+ let repeatIndex = 0;
71
+ let seed = void 0;
70
72
  let bestError = null;
71
73
  let index = -1;
72
74
  let args = {};
73
75
  let variantsIterator = variants[Symbol.iterator]();
74
76
  function nextVariant() {
75
77
  while (true) {
78
+ // Try next repeat for current variant
79
+ if (findBestError && index >= 0 && (bestError == null || index < bestError.index)) {
80
+ repeatIndex++;
81
+ if (repeatIndex < findBestError.repeatsPerVariant) {
82
+ seed = findBestError.getSeed({
83
+ variantIndex: index,
84
+ cycleIndex,
85
+ repeatIndex,
86
+ totalIndex: cycleIndex * findBestError.repeatsPerVariant + repeatIndex,
87
+ });
88
+ return true;
89
+ }
90
+ }
91
+ repeatIndex = 0;
76
92
  index++;
77
- if (seedResult && seedResult.done) {
93
+ if (findBestError && cycleIndex >= findBestError.cycles) {
78
94
  return false;
79
95
  }
80
- if (bestError == null || index < bestError.index) {
96
+ if ((limitVariantsCount == null || index < limitVariantsCount)
97
+ && (bestError == null || index < bestError.index)) {
81
98
  const result = variantsIterator.next();
82
99
  if (!result.done) {
83
100
  args = result.value;
101
+ if (findBestError) {
102
+ seed = findBestError.getSeed({
103
+ variantIndex: index,
104
+ cycleIndex,
105
+ repeatIndex,
106
+ totalIndex: cycleIndex * findBestError.repeatsPerVariant + repeatIndex,
107
+ });
108
+ }
84
109
  return true;
85
110
  }
86
111
  }
87
- if (!seedsIterator) {
112
+ if (!findBestError) {
88
113
  return false;
89
114
  }
90
- seedResult = seedsIterator.next();
91
- if (seedResult.done) {
115
+ cycleIndex++;
116
+ if (cycleIndex >= findBestError.cycles) {
92
117
  return false;
93
118
  }
94
119
  index = -1;
@@ -117,7 +142,7 @@ function testVariantsRun(testRun, variants, options = {}) {
117
142
  return tslib.__awaiter(this, void 0, void 0, function* () {
118
143
  while (!(abortSignalExternal === null || abortSignalExternal === void 0 ? void 0 : abortSignalExternal.aborted) && (debug || nextVariant())) {
119
144
  const _index = index;
120
- const _args = Object.assign(Object.assign({}, args), { seed: seedResult === null || seedResult === void 0 ? void 0 : seedResult.value });
145
+ const _args = Object.assign(Object.assign({}, args), { seed });
121
146
  const now = (logInterval || GC_Interval) && Date.now();
122
147
  if (logInterval && now - prevLogTime >= logInterval) {
123
148
  // the log is required to prevent the karma browserNoActivityTimeout
@@ -1,8 +1,25 @@
1
1
  import { TestVariantsTestRun } from './testVariantsCreateTestRun';
2
2
  import { type IAbortSignalFast } from '@flemist/abort-controller-fast';
3
3
  import { Obj, type SaveErrorVariantsOptions } from "./types";
4
+ /** Parameters passed to getSeed function for generating test seeds */
5
+ export declare type GetSeedParams = {
6
+ /** Index of current variant/parameter-combination being tested */
7
+ variantIndex: number;
8
+ /** Index of current cycle - full pass through all variants (0..cycles-1) */
9
+ cycleIndex: number;
10
+ /** Index of repeat for current variant within this cycle (0..repeatsPerVariant-1) */
11
+ repeatIndex: number;
12
+ /** Total index across all cycles: cycleIndex × repeatsPerVariant + repeatIndex */
13
+ totalIndex: number;
14
+ };
15
+ /** Options for finding the earliest failing variant across multiple test runs */
4
16
  export declare type TestVariantsFindBestErrorOptions = {
5
- seeds: Iterable<any>;
17
+ /** Function to generate seed based on current iteration state */
18
+ getSeed: (params: GetSeedParams) => any;
19
+ /** Number of full passes through all variants */
20
+ cycles: number;
21
+ /** Number of repeat tests per variant within each cycle */
22
+ repeatsPerVariant: number;
6
23
  };
7
24
  export declare type TestVariantsRunOptions<Args extends Obj = Obj, SavedArgs = Args> = {
8
25
  /** Wait for garbage collection after iterations */
@@ -20,6 +37,8 @@ export declare type TestVariantsRunOptions<Args extends Obj = Obj, SavedArgs = A
20
37
  findBestError?: null | TestVariantsFindBestErrorOptions;
21
38
  /** Save error-causing args to files and replay them before normal iteration */
22
39
  saveErrorVariants?: null | SaveErrorVariantsOptions<Args, SavedArgs>;
40
+ /** Tests only first N variants, ignores the rest. If null or not specified, tests all variants */
41
+ limitVariantsCount?: null | number;
23
42
  };
24
43
  export declare type TestVariantsBestError<Args extends Obj> = {
25
44
  error: any;
@@ -41,30 +41,55 @@ function testVariantsRun(testRun, variants, options = {}) {
41
41
  : !options.parallel || options.parallel <= 0
42
42
  ? 1
43
43
  : options.parallel;
44
- const seedsIterator = (_j = findBestError === null || findBestError === void 0 ? void 0 : findBestError.seeds[Symbol.iterator]()) !== null && _j !== void 0 ? _j : null;
45
- let seedResult = seedsIterator === null || seedsIterator === void 0 ? void 0 : seedsIterator.next();
44
+ const limitVariantsCount = (_j = options.limitVariantsCount) !== null && _j !== void 0 ? _j : null;
45
+ let cycleIndex = 0;
46
+ let repeatIndex = 0;
47
+ let seed = void 0;
46
48
  let bestError = null;
47
49
  let index = -1;
48
50
  let args = {};
49
51
  let variantsIterator = variants[Symbol.iterator]();
50
52
  function nextVariant() {
51
53
  while (true) {
54
+ // Try next repeat for current variant
55
+ if (findBestError && index >= 0 && (bestError == null || index < bestError.index)) {
56
+ repeatIndex++;
57
+ if (repeatIndex < findBestError.repeatsPerVariant) {
58
+ seed = findBestError.getSeed({
59
+ variantIndex: index,
60
+ cycleIndex,
61
+ repeatIndex,
62
+ totalIndex: cycleIndex * findBestError.repeatsPerVariant + repeatIndex,
63
+ });
64
+ return true;
65
+ }
66
+ }
67
+ repeatIndex = 0;
52
68
  index++;
53
- if (seedResult && seedResult.done) {
69
+ if (findBestError && cycleIndex >= findBestError.cycles) {
54
70
  return false;
55
71
  }
56
- if (bestError == null || index < bestError.index) {
72
+ if ((limitVariantsCount == null || index < limitVariantsCount)
73
+ && (bestError == null || index < bestError.index)) {
57
74
  const result = variantsIterator.next();
58
75
  if (!result.done) {
59
76
  args = result.value;
77
+ if (findBestError) {
78
+ seed = findBestError.getSeed({
79
+ variantIndex: index,
80
+ cycleIndex,
81
+ repeatIndex,
82
+ totalIndex: cycleIndex * findBestError.repeatsPerVariant + repeatIndex,
83
+ });
84
+ }
60
85
  return true;
61
86
  }
62
87
  }
63
- if (!seedsIterator) {
88
+ if (!findBestError) {
64
89
  return false;
65
90
  }
66
- seedResult = seedsIterator.next();
67
- if (seedResult.done) {
91
+ cycleIndex++;
92
+ if (cycleIndex >= findBestError.cycles) {
68
93
  return false;
69
94
  }
70
95
  index = -1;
@@ -93,7 +118,7 @@ function testVariantsRun(testRun, variants, options = {}) {
93
118
  return __awaiter(this, void 0, void 0, function* () {
94
119
  while (!(abortSignalExternal === null || abortSignalExternal === void 0 ? void 0 : abortSignalExternal.aborted) && (debug || nextVariant())) {
95
120
  const _index = index;
96
- const _args = Object.assign(Object.assign({}, args), { seed: seedResult === null || seedResult === void 0 ? void 0 : seedResult.value });
121
+ const _args = Object.assign(Object.assign({}, args), { seed });
97
122
  const now = (logInterval || GC_Interval) && Date.now();
98
123
  if (logInterval && now - prevLogTime >= logInterval) {
99
124
  // the log is required to prevent the karma browserNoActivityTimeout
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flemist/test-variants",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Runs a test function with all possible combinations of its parameters.",
5
5
  "main": "dist/lib/index.cjs",
6
6
  "module": "dist/lib/index.mjs",
@@ -32,24 +32,6 @@
32
32
  "publishConfig": {
33
33
  "access": "public"
34
34
  },
35
- "scripts": {
36
- "_prepublishOnly": "pnpm run audit && pnpm run lint && pnpm run build && pnpm run test:mocha:ci && pnpm run test:karma && npm login",
37
- "audit": "pnpm audit --prod",
38
- "lint": "eslint ./**/*.{js,cjs,mjs,ts,tsx}",
39
- "lint:fix": "eslint --fix ./**/*.{js,cjs,mjs,ts,tsx}",
40
- "lint:wizard": "eslint-nibble --cache --multi ./**/*.{js,cjs,mjs,ts,tsx}",
41
- "build:js": "rimraf dist/lib && cpy \"**/assets/**\" \"**/*.{js,cjs,mjs}\" \"../dist/lib/\" --parents --cwd=src && rollup -c",
42
- "build": "rimraf dist && pnpm run build:js",
43
- "coverage:merge": "rimraf tmp/coverage/{all,merge} && cp-flat \"tmp/coverage/*/json/**/*.json\" \"tmp/coverage/merge\" && nyc report -r lcov --report-dir tmp/coverage/all/lcov --temp-dir \"tmp/coverage/merge/\"",
44
- "coverage:check": "pnpm run coverage:merge && nyc check-coverage --report-dir tmp/coverage/all/lcov --lines 50 --functions 50 --branches 50 --statements 50",
45
- "test:mocha": "mocha ./src/**/*.test.*",
46
- "test:mocha:coverage": "rimraf tmp/coverage/mocha && nyc --all mocha ./src/**/*.test.*",
47
- "test:mocha:watch": "mocha --watch ./src/**/*.test.*",
48
- "test:karma": "rimraf tmp/coverage/karma && karma start --single-run --log-level debug",
49
- "test:mocha:ci": "rimraf tmp/coverage/mocha && nyc --all mocha ./{src,dist/lib}/**/*.test.*",
50
- "coveralls": "pnpm run coverage:check && nyc report --reporter=text-lcov --temp-dir \"tmp/coverage/merge/\" | coveralls",
51
- "mcp:tools": "mcp-project-tools"
52
- },
53
35
  "devDependencies": {
54
36
  "@anthropic-ai/claude-code": "^2.0.76",
55
37
  "@babel/core": "7.18.5",
@@ -105,5 +87,22 @@
105
87
  "@flemist/async-utils": "^1.0.0",
106
88
  "@flemist/time-limits": "^1.0.1",
107
89
  "tslib": "2.5.3"
90
+ },
91
+ "scripts": {
92
+ "audit": "pnpm audit --prod",
93
+ "lint": "eslint ./**/*.{js,cjs,mjs,ts,tsx}",
94
+ "lint:fix": "eslint --fix ./**/*.{js,cjs,mjs,ts,tsx}",
95
+ "lint:wizard": "eslint-nibble --cache --multi ./**/*.{js,cjs,mjs,ts,tsx}",
96
+ "build:js": "rimraf dist/lib && cpy \"**/assets/**\" \"**/*.{js,cjs,mjs}\" \"../dist/lib/\" --parents --cwd=src && rollup -c",
97
+ "build": "rimraf dist && pnpm run build:js",
98
+ "coverage:merge": "rimraf tmp/coverage/{all,merge} && cp-flat \"tmp/coverage/*/json/**/*.json\" \"tmp/coverage/merge\" && nyc report -r lcov --report-dir tmp/coverage/all/lcov --temp-dir \"tmp/coverage/merge/\"",
99
+ "coverage:check": "pnpm run coverage:merge && nyc check-coverage --report-dir tmp/coverage/all/lcov --lines 50 --functions 50 --branches 50 --statements 50",
100
+ "test:mocha": "mocha ./src/**/*.test.*",
101
+ "test:mocha:coverage": "rimraf tmp/coverage/mocha && nyc --all mocha ./src/**/*.test.*",
102
+ "test:mocha:watch": "mocha --watch ./src/**/*.test.*",
103
+ "test:karma": "rimraf tmp/coverage/karma && karma start --single-run --log-level debug",
104
+ "test:mocha:ci": "rimraf tmp/coverage/mocha && nyc --all mocha ./{src,dist/lib}/**/*.test.*",
105
+ "coveralls": "pnpm run coverage:check && nyc report --reporter=text-lcov --temp-dir \"tmp/coverage/merge/\" | coveralls",
106
+ "mcp:tools": "mcp-project-tools"
108
107
  }
109
- }
108
+ }