@ripplo/testing 0.7.10 → 0.7.12

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/DSL.md CHANGED
@@ -47,16 +47,14 @@ If you're unsure, it's backend. A value that's cached in the browser but owned b
47
47
  ### `field(options)`
48
48
 
49
49
  ```ts
50
- field({ value: v.email() }); // required, stable — Ripplo checks the app's value matches what the test expected
50
+ field({ value: v.email() }); // required — Ripplo checks the app's value matches what the test expected
51
51
  field({ value: v.word(), optional: true }); // nullable; `null` is a valid set/assert value
52
- field({ value: v.number({ min: 0, max: 100 }), stable: false }); // adopt-only, drift not checked
53
52
  ```
54
53
 
55
- | option | meaning |
56
- | ---------- | -------------------------------------------------------------------------------------------------------------------- |
57
- | `value` | the value-space (`v.*`) — required |
58
- | `optional` | `true` ⇒ the field is nullable (`null` allowed in `of`/`updated`/assertions); Ripplo treats `null ≡ absent` |
59
- | `stable` | default `true` (Ripplo checks the app's value matches what the test expected). `false` = adopt-only, drift unchecked |
54
+ | option | meaning |
55
+ | ---------- | ----------------------------------------------------------------------------------------------------------- |
56
+ | `value` | the value-space (`v.*`) — required |
57
+ | `optional` | `true` ⇒ the field is nullable (`null` allowed in `of`/`updated`/assertions); Ripplo treats `null ≡ absent` |
60
58
 
61
59
  ### Identity: `id()` and `key(options)`
62
60
 
@@ -143,7 +143,6 @@ declare const propSpecSchema: z.ZodObject<{
143
143
  eventual: "eventual";
144
144
  }>>;
145
145
  optional: z.ZodBoolean;
146
- stable: z.ZodBoolean;
147
146
  type: z.ZodEnum<{
148
147
  string: "string";
149
148
  number: "number";
@@ -171,7 +170,6 @@ declare const entitySchemaSchema: z.ZodObject<{
171
170
  eventual: "eventual";
172
171
  }>>;
173
172
  optional: z.ZodBoolean;
174
- stable: z.ZodBoolean;
175
173
  type: z.ZodEnum<{
176
174
  string: "string";
177
175
  number: "number";
@@ -396,7 +394,6 @@ declare const workflowSchema: z.ZodObject<{
396
394
  }, z.core.$strip>>>;
397
395
  name: z.ZodString;
398
396
  params: z.ZodRecord<z.ZodString, z.ZodObject<{
399
- example: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
400
397
  valueSpace: z.ZodString;
401
398
  }, z.core.$strip>>;
402
399
  singletons: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
@@ -482,7 +479,6 @@ declare const workflowSchema: z.ZodObject<{
482
479
  intent: z.ZodString;
483
480
  name: z.ZodString;
484
481
  params: z.ZodRecord<z.ZodString, z.ZodObject<{
485
- example: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
486
482
  valueSpace: z.ZodString;
487
483
  }, z.core.$strip>>;
488
484
  singletons: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
@@ -593,7 +589,6 @@ declare const lockfileSchema: z.ZodObject<{
593
589
  eventual: "eventual";
594
590
  }>>;
595
591
  optional: z.ZodBoolean;
596
- stable: z.ZodBoolean;
597
592
  type: z.ZodEnum<{
598
593
  string: "string";
599
594
  number: "number";
@@ -687,7 +682,6 @@ declare const lockfileSchema: z.ZodObject<{
687
682
  }, z.core.$strip>>>;
688
683
  name: z.ZodString;
689
684
  params: z.ZodRecord<z.ZodString, z.ZodObject<{
690
- example: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
691
685
  valueSpace: z.ZodString;
692
686
  }, z.core.$strip>>;
693
687
  singletons: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
@@ -773,7 +767,6 @@ declare const lockfileSchema: z.ZodObject<{
773
767
  intent: z.ZodString;
774
768
  name: z.ZodString;
775
769
  params: z.ZodRecord<z.ZodString, z.ZodObject<{
776
- example: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
777
770
  valueSpace: z.ZodString;
778
771
  }, z.core.$strip>>;
779
772
  singletons: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
@@ -944,7 +937,6 @@ type Primitive = string | number | boolean;
944
937
  type Fields = Record<string, Primitive>;
945
938
  interface ParamToken {
946
939
  readonly base: string;
947
- readonly example: Primitive | undefined;
948
940
  readonly valueSpace: string;
949
941
  }
950
942
  type EntityKind = "of" | "only" | "maybe";
@@ -1080,7 +1072,6 @@ interface PropBuilder<T extends Primitive, Opt extends boolean = boolean> {
1080
1072
  type Mods = Partial<{
1081
1073
  readonly consistency: ConsistencyClass;
1082
1074
  readonly optional: boolean;
1083
- readonly stable: boolean;
1084
1075
  }>;
1085
1076
  type IsOptional = {
1086
1077
  readonly optional: true;
package/dist/express.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Router } from 'express';
2
- import { E as Engine } from './engine-mt1A6IKW.js';
2
+ import { E as Engine } from './engine-CeG-3Q7o.js';
3
3
  import 'neverthrow';
4
4
  import 'zod';
5
5
 
package/dist/express.js CHANGED
@@ -71,7 +71,6 @@ var valueSpaceSchema = z.object({
71
71
  var propSpecSchema = z.object({
72
72
  consistency: consistencyClassSchema.default("strict"),
73
73
  optional: z.boolean(),
74
- stable: z.boolean(),
75
74
  type: primitiveTypeSchema,
76
75
  valueSpace: z.string().min(1).optional()
77
76
  });
@@ -260,7 +259,6 @@ var stepSchema = z4.object({
260
259
  expect: z4.array(predicateSchema).default([])
261
260
  });
262
261
  var paramSchema = z4.object({
263
- example: primitiveSchema.optional(),
264
262
  valueSpace: z4.string().min(1)
265
263
  });
266
264
  var setupSchema = z4.object({
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as Capture, S as Step, P as PredicateInput, L as Locator, B as Binding, A as AnyBinding, G as GivenItem, W as Workflow, a as EntityList, b as SingletonList, c as Lockfile, U as UniqueNames, d as BrowserSingleton, e as LeafPredicate, f as Primitive, F as FieldHandle, D as DeclSource, R as Row, g as Primitive$1, h as SingletonDef } from './engine-mt1A6IKW.js';
2
- export { i as AbsenceHandle, j as BranchInput, k as CLIENT_MOUNT_KEY, l as CLIENT_SEED_KEY, m as ConditionInput, n as ConditionPredicate, o as ConditionedBranch, p as CountCondition, q as DuplicateEntityName, E as Engine, r as EngineError, s as EngineImpls, t as EngineRead, u as EntityDef, v as EntityHandle, w as EntityImpl, x as FieldOptions, y as Fields, H as Handle, N as NamedBranch, z as Selection, I as SingletonConfig, J as SingletonImpl, K as SingletonValue, M as WithinMatcher, O as and, Q as branch, T as changed, V as count, X as createEngine, Y as disabled, Z as enabled, _ as entity, $ as field, a0 as focused, a1 as id, a2 as key, a3 as not, a4 as singleton, a5 as text, a6 as v, a7 as value, a8 as visible, a9 as when, aa as within } from './engine-mt1A6IKW.js';
1
+ import { C as Capture, S as Step, P as PredicateInput, L as Locator, B as Binding, A as AnyBinding, G as GivenItem, W as Workflow, a as EntityList, b as SingletonList, c as Lockfile, U as UniqueNames, d as BrowserSingleton, e as LeafPredicate, f as Primitive, F as FieldHandle, D as DeclSource, R as Row, g as Primitive$1, h as SingletonDef } from './engine-CeG-3Q7o.js';
2
+ export { i as AbsenceHandle, j as BranchInput, k as CLIENT_MOUNT_KEY, l as CLIENT_SEED_KEY, m as ConditionInput, n as ConditionPredicate, o as ConditionedBranch, p as CountCondition, q as DuplicateEntityName, E as Engine, r as EngineError, s as EngineImpls, t as EngineRead, u as EntityDef, v as EntityHandle, w as EntityImpl, x as FieldOptions, y as Fields, H as Handle, N as NamedBranch, z as Selection, I as SingletonConfig, J as SingletonImpl, K as SingletonValue, M as WithinMatcher, O as and, Q as branch, T as changed, V as count, X as createEngine, Y as disabled, Z as enabled, _ as entity, $ as field, a0 as focused, a1 as id, a2 as key, a3 as not, a4 as singleton, a5 as text, a6 as v, a7 as value, a8 as visible, a9 as when, aa as within } from './engine-CeG-3Q7o.js';
3
3
  import 'neverthrow';
4
4
  import 'zod';
5
5
 
@@ -99,7 +99,7 @@ declare const url: BrowserSingletonDef<"url">;
99
99
  declare const title: BrowserSingletonDef<"title">;
100
100
  declare const viewport: BrowserSingletonDef<"viewport">;
101
101
 
102
- declare function arbitrary<T extends Primitive>(field: FieldHandle<T>, example?: T): Binding<T>;
102
+ declare function arbitrary<T extends Primitive>(field: FieldHandle<T>): Binding<T>;
103
103
 
104
104
  interface ClientSingletonImpl<T extends Primitive$1> {
105
105
  readonly read: () => T | null;
package/dist/index.js CHANGED
@@ -270,7 +270,6 @@ function field(options) {
270
270
  spec: {
271
271
  consistency: options.consistency ?? "strict",
272
272
  optional: options.optional ?? false,
273
- stable: options.stable ?? true,
274
273
  type: options.value.primitive
275
274
  },
276
275
  valueSpace: options.value
@@ -280,7 +279,7 @@ function id() {
280
279
  return {
281
280
  idKind: "surrogate",
282
281
  prop: propBuilder({
283
- spec: { consistency: "strict", optional: false, stable: true, type: "string" },
282
+ spec: { consistency: "strict", optional: false, type: "string" },
284
283
  valueSpace: void 0
285
284
  })
286
285
  };
@@ -292,7 +291,6 @@ function key(options) {
292
291
  spec: {
293
292
  consistency: "strict",
294
293
  optional: false,
295
- stable: true,
296
294
  type: options.value.primitive
297
295
  },
298
296
  valueSpace: options.value
@@ -598,6 +596,20 @@ function stepBuilder(action, expected, captures) {
598
596
  };
599
597
  }
600
598
 
599
+ // src/coherence.ts
600
+ function assertEntityCoherence(entities) {
601
+ const counts = entities.reduce(
602
+ (acc, d) => new Map([...acc, [d.entity, (acc.get(d.entity) ?? 0) + 1]]),
603
+ /* @__PURE__ */ new Map()
604
+ );
605
+ const over = entities.find((d) => d.kind === "only" && (counts.get(d.entity) ?? 0) > 1);
606
+ if (over != null) {
607
+ throw new Error(
608
+ `entity "${over.entity}" is declared only() but seeded ${String(counts.get(over.entity) ?? 0)} times \u2014 only() means a single exclusive instance; use of() for multiple instances`
609
+ );
610
+ }
611
+ }
612
+
601
613
  // src/finalize.ts
602
614
  function finalize(body) {
603
615
  const descriptors = [...new Set(body.given.map((item) => item.__entity))];
@@ -611,6 +623,7 @@ function finalize(body) {
611
623
  )
612
624
  );
613
625
  assertNoMaybeRefs({ absences, entities, singletonStates });
626
+ assertEntityCoherence(entities);
614
627
  const captures = body.steps.flatMap((builder) => builder.captures);
615
628
  assertScopedConditions(body.steps, new Set(singletonStates.map((s) => s.singleton)));
616
629
  const aliases = assignAliases([...entities, ...captures.map((c) => c.descriptor)]);
@@ -759,7 +772,7 @@ function assignParams(bindings) {
759
772
  return {
760
773
  counts: { ...acc.counts, [token.base]: ordinal + 1 },
761
774
  names: new Map([...acc.names, [b, name]]),
762
- params: { ...acc.params, [name]: { example: token.example, valueSpace: token.valueSpace } }
775
+ params: { ...acc.params, [name]: { valueSpace: token.valueSpace } }
763
776
  };
764
777
  },
765
778
  { counts: {}, names: /* @__PURE__ */ new Map(), params: {} }
@@ -1125,10 +1138,9 @@ function slugify(intent) {
1125
1138
  }
1126
1139
 
1127
1140
  // src/params.ts
1128
- function arbitrary(field2, example) {
1141
+ function arbitrary(field2) {
1129
1142
  const token = {
1130
1143
  base: `${field2.entity}_${field2.field}`,
1131
- example,
1132
1144
  valueSpace: field2.valueSpaceName
1133
1145
  };
1134
1146
  return paramBinding(token);
@@ -1367,7 +1379,6 @@ var valueSpaceSchema = z.object({
1367
1379
  var propSpecSchema = z.object({
1368
1380
  consistency: consistencyClassSchema.default("strict"),
1369
1381
  optional: z.boolean(),
1370
- stable: z.boolean(),
1371
1382
  type: primitiveTypeSchema,
1372
1383
  valueSpace: z.string().min(1).optional()
1373
1384
  });
@@ -1560,7 +1571,6 @@ var stepSchema = z4.object({
1560
1571
  expect: z4.array(predicateSchema).default([])
1561
1572
  });
1562
1573
  var paramSchema = z4.object({
1563
- example: primitiveSchema.optional(),
1564
1574
  valueSpace: z4.string().min(1)
1565
1575
  });
1566
1576
  var setupSchema = z4.object({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ripplo/testing",
3
- "version": "0.7.10",
3
+ "version": "0.7.12",
4
4
  "description": "Typed test DSL for Ripplo — declare entities and user flows, compile to a lockfile",
5
5
  "homepage": "https://ripplo.ai",
6
6
  "license": "SEE LICENSE IN LICENSE.md",