@livestore/utils-dev 0.0.0-snapshot-32f9ab29aa5827b3930b06a0c03bd5e34f9f60c3 → 0.0.0-snapshot-7977eab0a18ce87790c7d6aa9638323e194b9eb1

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.
@@ -16,17 +16,37 @@ export declare const withTestCtx: <R1 = never, E1 = never>(testContext: Vitest.T
16
16
  forceOtel?: boolean;
17
17
  }) => <A, E>(self: Effect.Effect<A, E, Scope.Scope | OtelTracer.OtelTracer | R1>) => Effect.Effect<A, E | Cause.TimeoutException | E1, Scope.Scope>;
18
18
  /**
19
- * Equivalent to Vitest.prop but provides extra prop context to the test function
19
+ * Shared properties for all enhanced test context phases
20
+ */
21
+ export interface EnhancedTestContextBase {
22
+ numRuns: number;
23
+ /** 0-based index */
24
+ runIndex: number;
25
+ /** Total number of executions including initial runs and shrinking attempts */
26
+ totalExecutions: number;
27
+ }
28
+ /**
29
+ * Enhanced context for property-based tests that includes shrinking phase information
30
+ */
31
+ export type EnhancedTestContext = (EnhancedTestContextBase & {
32
+ _tag: 'initial';
33
+ }) | (EnhancedTestContextBase & {
34
+ _tag: 'shrinking';
35
+ /** Number of shrinking attempts */
36
+ shrinkAttempt: number;
37
+ });
38
+ /**
39
+ * Equivalent to Vitest.prop but provides enhanced context including shrinking progress visibility
40
+ *
41
+ * This function enhances the standard property-based testing by providing clear information about
42
+ * whether FastCheck is in the initial testing phase or the shrinking phase, solving the confusion
43
+ * where tests show "Run 26/6" when FastCheck's shrinking algorithm is active.
20
44
  *
21
45
  * TODO: allow for upper timelimit instead of / additional to `numRuns`
22
46
  *
23
47
  * TODO: Upstream to Effect
24
48
  */
25
- export declare const asProp: <Arbs extends Vitest.Vitest.Arbitraries, A, E, R>(api: Vitest.Vitest.Tester<R>, name: string, arbitraries: Arbs, test: Vitest.Vitest.TestFunction<A, E, R, [{ [K in keyof Arbs]: Arbs[K] extends FC.Arbitrary<infer T> ? T : Schema.Schema.Type<Arbs[K]>; }, Vitest.TestContext, {
26
- numRuns: number;
27
- /** 0-based index */
28
- runIndex: number;
29
- }]>, propOptions: number | (Vitest.TestOptions & {
49
+ export declare const asProp: <Arbs extends Vitest.Vitest.Arbitraries, A, E, R>(api: Vitest.Vitest.Tester<R>, name: string, arbitraries: Arbs, test: Vitest.Vitest.TestFunction<A, E, R, [{ [K in keyof Arbs]: Arbs[K] extends FC.Arbitrary<infer T> ? T : Schema.Schema.Type<Arbs[K]>; }, Vitest.TestContext, EnhancedTestContext]>, propOptions: number | (Vitest.TestOptions & {
30
50
  fastCheck?: FC.Parameters<{ [K in keyof Arbs]: Arbs[K] extends FC.Arbitrary<infer T> ? T : Schema.Schema.Type<Arbs[K]>; }>;
31
51
  })) => void;
32
52
  //# sourceMappingURL=Vitest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Vitest.d.ts","sourceRoot":"","sources":["../../src/node-vitest/Vitest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Vitest.d.ts","sourceRoot":"","sources":["../../src/node-vitest/Vitest.ts"],"names":[],"mappings":"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"}
@@ -22,20 +22,77 @@ export const withTestCtx = (testContext, { suffix, makeLayer, timeout = IS_CI ?
22
22
  Effect.annotateLogs({ suffix }));
23
23
  };
24
24
  /**
25
- * Equivalent to Vitest.prop but provides extra prop context to the test function
25
+ * Normalizes propOptions to ensure @effect/vitest receives correct fastCheck structure
26
+ */
27
+ const normalizePropOptions = (propOptions) => {
28
+ // If it's a number, treat as timeout and add our default fastCheck
29
+ if (!Predicate.isObject(propOptions)) {
30
+ return {
31
+ timeout: propOptions,
32
+ fastCheck: { numRuns: 100 },
33
+ };
34
+ }
35
+ // If no fastCheck property, add it with our default numRuns
36
+ if (!propOptions.fastCheck) {
37
+ return {
38
+ ...propOptions,
39
+ fastCheck: { numRuns: 100 },
40
+ };
41
+ }
42
+ // If fastCheck exists but no numRuns, add our default
43
+ if (propOptions.fastCheck && !propOptions.fastCheck.numRuns) {
44
+ return {
45
+ ...propOptions,
46
+ fastCheck: {
47
+ ...propOptions.fastCheck,
48
+ numRuns: 100,
49
+ },
50
+ };
51
+ }
52
+ // If everything is properly structured, pass through
53
+ return propOptions;
54
+ };
55
+ /**
56
+ * Equivalent to Vitest.prop but provides enhanced context including shrinking progress visibility
57
+ *
58
+ * This function enhances the standard property-based testing by providing clear information about
59
+ * whether FastCheck is in the initial testing phase or the shrinking phase, solving the confusion
60
+ * where tests show "Run 26/6" when FastCheck's shrinking algorithm is active.
26
61
  *
27
62
  * TODO: allow for upper timelimit instead of / additional to `numRuns`
28
63
  *
29
64
  * TODO: Upstream to Effect
30
65
  */
31
66
  export const asProp = (api, name, arbitraries, test, propOptions) => {
32
- const numRuns = Predicate.isObject(propOptions) ? (propOptions.fastCheck?.numRuns ?? 100) : 100;
67
+ const normalizedPropOptions = normalizePropOptions(propOptions);
68
+ const numRuns = normalizedPropOptions.fastCheck?.numRuns ?? 100;
33
69
  let runIndex = 0;
70
+ let shrinkAttempts = 0;
71
+ let totalExecutions = 0;
34
72
  return api.prop(name, arbitraries, (properties, ctx) => {
35
73
  if (ctx.signal.aborted) {
36
74
  return ctx.skip('Test aborted');
37
75
  }
38
- return test(properties, ctx, { numRuns, runIndex: runIndex++ });
39
- }, propOptions);
76
+ totalExecutions++;
77
+ const isInShrinkingPhase = runIndex >= numRuns;
78
+ if (isInShrinkingPhase) {
79
+ shrinkAttempts++;
80
+ }
81
+ const enhancedContext = isInShrinkingPhase
82
+ ? {
83
+ _tag: 'shrinking',
84
+ numRuns,
85
+ runIndex: runIndex++,
86
+ shrinkAttempt: shrinkAttempts,
87
+ totalExecutions,
88
+ }
89
+ : {
90
+ _tag: 'initial',
91
+ numRuns,
92
+ runIndex: runIndex++,
93
+ totalExecutions,
94
+ };
95
+ return test(properties, ctx, enhancedContext);
96
+ }, normalizedPropOptions);
40
97
  };
41
98
  //# sourceMappingURL=Vitest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Vitest.js","sourceRoot":"","sources":["../../src/node-vitest/Vitest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Vitest.js","sourceRoot":"","sources":["../../src/node-vitest/Vitest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Vitest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Vitest.test.d.ts","sourceRoot":"","sources":["../../src/node-vitest/Vitest.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,59 @@
1
+ import { Effect, FastCheck } from '@livestore/utils/effect';
2
+ import * as Vitest from "./Vitest.js";
3
+ // Demonstrate enhanced asProp functionality with clear shrinking progress
4
+ // This showcases the fix for the "Run 26/6" bug and accurate shrinking detection
5
+ Vitest.describe('Vitest.asProp', () => {
6
+ const IntArbitrary = FastCheck.integer({ min: 1, max: 100 });
7
+ // Always-passing test - should only show initial phase
8
+ Vitest.asProp(Vitest.scopedLive, 'always-pass test (shows only initial runs)', [IntArbitrary], (properties, _ctx, enhanced) => Effect.gen(function* () {
9
+ const [value] = properties;
10
+ if (value === undefined) {
11
+ return yield* Effect.fail(new Error('Value is undefined'));
12
+ }
13
+ console.log(`✅ ALWAYS-PASS [${enhanced._tag.toUpperCase()}]: ` +
14
+ (enhanced._tag === 'initial'
15
+ ? `Run ${enhanced.runIndex + 1}/${enhanced.numRuns}`
16
+ : `Shrink #${enhanced.shrinkAttempt} (finding minimal counterexample)`) +
17
+ `, value=${value}, total=${enhanced.totalExecutions}`);
18
+ // This test always passes, so no shrinking will occur
19
+ return;
20
+ }), { fastCheck: { numRuns: 4 } });
21
+ // Failing test - should show initial + shrinking phases
22
+ let alreadyFailed = false;
23
+ Vitest.asProp(Vitest.scopedLive, 'failing test (shows initial runs + shrinking)', [IntArbitrary], (properties, ctx, enhanced) => Effect.gen(function* () {
24
+ const [value] = properties;
25
+ if (value === undefined) {
26
+ return yield* Effect.fail(new Error('Value is undefined'));
27
+ }
28
+ const displayInfo = enhanced._tag === 'initial'
29
+ ? `Run ${enhanced.runIndex + 1}/${enhanced.numRuns}`
30
+ : `Shrink #${enhanced.shrinkAttempt} (finding minimal counterexample)`;
31
+ const status = value > 80 ? '💥' : '✅';
32
+ console.log(`${status} FAILING-TEST [${enhanced._tag.toUpperCase()}]: ${displayInfo}, value=${value}, total=${enhanced.totalExecutions}`);
33
+ // Fail when value is greater than 80 to trigger shrinking
34
+ if (value > 80) {
35
+ alreadyFailed = true;
36
+ return yield* Effect.fail(new Error(`Value ${value} is too large (> 80)`));
37
+ }
38
+ if (alreadyFailed && enhanced._tag === 'shrinking') {
39
+ ctx.skip("For the sake of this test, we don't want to fail but want to skip");
40
+ return;
41
+ }
42
+ return;
43
+ }), { fastCheck: { numRuns: 3 } });
44
+ // Test with endOnFailure: true - should not show shrinking
45
+ Vitest.asProp(Vitest.scopedLive, 'failing test with endOnFailure (no shrinking)', [IntArbitrary], (properties, _ctx, enhanced) => Effect.gen(function* () {
46
+ const [value] = properties;
47
+ if (value === undefined) {
48
+ return yield* Effect.fail(new Error('Value is undefined'));
49
+ }
50
+ console.log(`🚫 END-ON-FAILURE [${enhanced._tag.toUpperCase()}]: ` +
51
+ `Run ${enhanced.runIndex + 1}/${enhanced.numRuns}, value=${value}, total=${enhanced.totalExecutions}`);
52
+ // This will fail but shrinking is disabled
53
+ if (value > 50) {
54
+ yield* Effect.fail(new Error(`Value ${value} is too large (> 50) - but no shrinking!`));
55
+ }
56
+ return;
57
+ }), { fastCheck: { numRuns: 5, endOnFailure: true }, fails: true });
58
+ });
59
+ //# sourceMappingURL=Vitest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Vitest.test.js","sourceRoot":"","sources":["../../src/node-vitest/Vitest.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livestore/utils-dev",
3
- "version": "0.0.0-snapshot-32f9ab29aa5827b3930b06a0c03bd5e34f9f60c3",
3
+ "version": "0.0.0-snapshot-7977eab0a18ce87790c7d6aa9638323e194b9eb1",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "./src/node-vitest/global.ts"
@@ -18,7 +18,7 @@
18
18
  "@opentelemetry/sdk-metrics": "2.0.1",
19
19
  "@opentelemetry/sdk-trace-base": "2.0.1",
20
20
  "@opentelemetry/sdk-trace-node": "2.0.1",
21
- "@livestore/utils": "0.0.0-snapshot-32f9ab29aa5827b3930b06a0c03bd5e34f9f60c3"
21
+ "@livestore/utils": "0.0.0-snapshot-7977eab0a18ce87790c7d6aa9638323e194b9eb1"
22
22
  },
23
23
  "devDependencies": {},
24
24
  "files": [
@@ -0,0 +1,101 @@
1
+ import { Effect, FastCheck } from '@livestore/utils/effect'
2
+ import * as Vitest from './Vitest.ts'
3
+
4
+ // Demonstrate enhanced asProp functionality with clear shrinking progress
5
+ // This showcases the fix for the "Run 26/6" bug and accurate shrinking detection
6
+
7
+ Vitest.describe('Vitest.asProp', () => {
8
+ const IntArbitrary = FastCheck.integer({ min: 1, max: 100 })
9
+
10
+ // Always-passing test - should only show initial phase
11
+ Vitest.asProp(
12
+ Vitest.scopedLive,
13
+ 'always-pass test (shows only initial runs)',
14
+ [IntArbitrary],
15
+ (properties, _ctx, enhanced) =>
16
+ Effect.gen(function* () {
17
+ const [value] = properties
18
+ if (value === undefined) {
19
+ return yield* Effect.fail(new Error('Value is undefined'))
20
+ }
21
+
22
+ console.log(
23
+ `✅ ALWAYS-PASS [${enhanced._tag.toUpperCase()}]: ` +
24
+ (enhanced._tag === 'initial'
25
+ ? `Run ${enhanced.runIndex + 1}/${enhanced.numRuns}`
26
+ : `Shrink #${enhanced.shrinkAttempt} (finding minimal counterexample)`) +
27
+ `, value=${value}, total=${enhanced.totalExecutions}`,
28
+ )
29
+
30
+ // This test always passes, so no shrinking will occur
31
+ return
32
+ }),
33
+ { fastCheck: { numRuns: 4 } },
34
+ )
35
+
36
+ // Failing test - should show initial + shrinking phases
37
+ let alreadyFailed = false
38
+ Vitest.asProp(
39
+ Vitest.scopedLive,
40
+ 'failing test (shows initial runs + shrinking)',
41
+ [IntArbitrary],
42
+ (properties, ctx, enhanced) =>
43
+ Effect.gen(function* () {
44
+ const [value] = properties
45
+ if (value === undefined) {
46
+ return yield* Effect.fail(new Error('Value is undefined'))
47
+ }
48
+
49
+ const displayInfo =
50
+ enhanced._tag === 'initial'
51
+ ? `Run ${enhanced.runIndex + 1}/${enhanced.numRuns}`
52
+ : `Shrink #${enhanced.shrinkAttempt} (finding minimal counterexample)`
53
+
54
+ const status = value > 80 ? '💥' : '✅'
55
+ console.log(
56
+ `${status} FAILING-TEST [${enhanced._tag.toUpperCase()}]: ${displayInfo}, value=${value}, total=${enhanced.totalExecutions}`,
57
+ )
58
+
59
+ // Fail when value is greater than 80 to trigger shrinking
60
+ if (value > 80) {
61
+ alreadyFailed = true
62
+ return yield* Effect.fail(new Error(`Value ${value} is too large (> 80)`))
63
+ }
64
+
65
+ if (alreadyFailed && enhanced._tag === 'shrinking') {
66
+ ctx.skip("For the sake of this test, we don't want to fail but want to skip")
67
+ return
68
+ }
69
+
70
+ return
71
+ }),
72
+ { fastCheck: { numRuns: 3 } },
73
+ )
74
+
75
+ // Test with endOnFailure: true - should not show shrinking
76
+ Vitest.asProp(
77
+ Vitest.scopedLive,
78
+ 'failing test with endOnFailure (no shrinking)',
79
+ [IntArbitrary],
80
+ (properties, _ctx, enhanced) =>
81
+ Effect.gen(function* () {
82
+ const [value] = properties
83
+ if (value === undefined) {
84
+ return yield* Effect.fail(new Error('Value is undefined'))
85
+ }
86
+
87
+ console.log(
88
+ `🚫 END-ON-FAILURE [${enhanced._tag.toUpperCase()}]: ` +
89
+ `Run ${enhanced.runIndex + 1}/${enhanced.numRuns}, value=${value}, total=${enhanced.totalExecutions}`,
90
+ )
91
+
92
+ // This will fail but shrinking is disabled
93
+ if (value > 50) {
94
+ yield* Effect.fail(new Error(`Value ${value} is too large (> 50) - but no shrinking!`))
95
+ }
96
+
97
+ return
98
+ }),
99
+ { fastCheck: { numRuns: 5, endOnFailure: true }, fails: true },
100
+ )
101
+ })
@@ -75,7 +75,82 @@ export const withTestCtx =
75
75
  }
76
76
 
77
77
  /**
78
- * Equivalent to Vitest.prop but provides extra prop context to the test function
78
+ * Shared properties for all enhanced test context phases
79
+ */
80
+ export interface EnhancedTestContextBase {
81
+ numRuns: number
82
+ /** 0-based index */
83
+ runIndex: number
84
+ /** Total number of executions including initial runs and shrinking attempts */
85
+ totalExecutions: number
86
+ }
87
+
88
+ /**
89
+ * Enhanced context for property-based tests that includes shrinking phase information
90
+ */
91
+ export type EnhancedTestContext =
92
+ | (EnhancedTestContextBase & {
93
+ _tag: 'initial'
94
+ })
95
+ | (EnhancedTestContextBase & {
96
+ _tag: 'shrinking'
97
+ /** Number of shrinking attempts */
98
+ shrinkAttempt: number
99
+ })
100
+
101
+ /**
102
+ * Normalizes propOptions to ensure @effect/vitest receives correct fastCheck structure
103
+ */
104
+ const normalizePropOptions = <Arbs extends Vitest.Vitest.Arbitraries>(
105
+ propOptions:
106
+ | number
107
+ | (Vitest.TestOptions & {
108
+ fastCheck?: FC.Parameters<{
109
+ [K in keyof Arbs]: Arbs[K] extends FC.Arbitrary<infer T> ? T : Schema.Schema.Type<Arbs[K]>
110
+ }>
111
+ }),
112
+ ): Vitest.TestOptions & {
113
+ fastCheck?: FC.Parameters<{
114
+ [K in keyof Arbs]: Arbs[K] extends FC.Arbitrary<infer T> ? T : Schema.Schema.Type<Arbs[K]>
115
+ }>
116
+ } => {
117
+ // If it's a number, treat as timeout and add our default fastCheck
118
+ if (!Predicate.isObject(propOptions)) {
119
+ return {
120
+ timeout: propOptions,
121
+ fastCheck: { numRuns: 100 },
122
+ }
123
+ }
124
+
125
+ // If no fastCheck property, add it with our default numRuns
126
+ if (!propOptions.fastCheck) {
127
+ return {
128
+ ...propOptions,
129
+ fastCheck: { numRuns: 100 },
130
+ }
131
+ }
132
+
133
+ // If fastCheck exists but no numRuns, add our default
134
+ if (propOptions.fastCheck && !propOptions.fastCheck.numRuns) {
135
+ return {
136
+ ...propOptions,
137
+ fastCheck: {
138
+ ...propOptions.fastCheck,
139
+ numRuns: 100,
140
+ },
141
+ }
142
+ }
143
+
144
+ // If everything is properly structured, pass through
145
+ return propOptions
146
+ }
147
+
148
+ /**
149
+ * Equivalent to Vitest.prop but provides enhanced context including shrinking progress visibility
150
+ *
151
+ * This function enhances the standard property-based testing by providing clear information about
152
+ * whether FastCheck is in the initial testing phase or the shrinking phase, solving the confusion
153
+ * where tests show "Run 26/6" when FastCheck's shrinking algorithm is active.
79
154
  *
80
155
  * TODO: allow for upper timelimit instead of / additional to `numRuns`
81
156
  *
@@ -92,11 +167,7 @@ export const asProp = <Arbs extends Vitest.Vitest.Arbitraries, A, E, R>(
92
167
  [
93
168
  { [K in keyof Arbs]: Arbs[K] extends FC.Arbitrary<infer T> ? T : Schema.Schema.Type<Arbs[K]> },
94
169
  Vitest.TestContext,
95
- {
96
- numRuns: number
97
- /** 0-based index */
98
- runIndex: number
99
- },
170
+ EnhancedTestContext,
100
171
  ]
101
172
  >,
102
173
  propOptions:
@@ -107,8 +178,12 @@ export const asProp = <Arbs extends Vitest.Vitest.Arbitraries, A, E, R>(
107
178
  }>
108
179
  }),
109
180
  ) => {
110
- const numRuns = Predicate.isObject(propOptions) ? (propOptions.fastCheck?.numRuns ?? 100) : 100
181
+ const normalizedPropOptions = normalizePropOptions(propOptions)
182
+ const numRuns = normalizedPropOptions.fastCheck?.numRuns ?? 100
111
183
  let runIndex = 0
184
+ let shrinkAttempts = 0
185
+ let totalExecutions = 0
186
+
112
187
  return api.prop(
113
188
  name,
114
189
  arbitraries,
@@ -116,8 +191,31 @@ export const asProp = <Arbs extends Vitest.Vitest.Arbitraries, A, E, R>(
116
191
  if (ctx.signal.aborted) {
117
192
  return ctx.skip('Test aborted')
118
193
  }
119
- return test(properties, ctx, { numRuns, runIndex: runIndex++ })
194
+
195
+ totalExecutions++
196
+ const isInShrinkingPhase = runIndex >= numRuns
197
+
198
+ if (isInShrinkingPhase) {
199
+ shrinkAttempts++
200
+ }
201
+
202
+ const enhancedContext: EnhancedTestContext = isInShrinkingPhase
203
+ ? {
204
+ _tag: 'shrinking',
205
+ numRuns,
206
+ runIndex: runIndex++,
207
+ shrinkAttempt: shrinkAttempts,
208
+ totalExecutions,
209
+ }
210
+ : {
211
+ _tag: 'initial',
212
+ numRuns,
213
+ runIndex: runIndex++,
214
+ totalExecutions,
215
+ }
216
+
217
+ return test(properties, ctx, enhancedContext)
120
218
  },
121
- propOptions,
219
+ normalizedPropOptions,
122
220
  )
123
221
  }