@ripplo/testing 0.7.11 → 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";
@@ -591,7 +589,6 @@ declare const lockfileSchema: z.ZodObject<{
591
589
  eventual: "eventual";
592
590
  }>>;
593
591
  optional: z.ZodBoolean;
594
- stable: z.ZodBoolean;
595
592
  type: z.ZodEnum<{
596
593
  string: "string";
597
594
  number: "number";
@@ -1075,7 +1072,6 @@ interface PropBuilder<T extends Primitive, Opt extends boolean = boolean> {
1075
1072
  type Mods = Partial<{
1076
1073
  readonly consistency: ConsistencyClass;
1077
1074
  readonly optional: boolean;
1078
- readonly stable: boolean;
1079
1075
  }>;
1080
1076
  type IsOptional = {
1081
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-Dv3trweR.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
  });
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-Dv3trweR.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-Dv3trweR.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
 
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)]);
@@ -1366,7 +1379,6 @@ var valueSpaceSchema = z.object({
1366
1379
  var propSpecSchema = z.object({
1367
1380
  consistency: consistencyClassSchema.default("strict"),
1368
1381
  optional: z.boolean(),
1369
- stable: z.boolean(),
1370
1382
  type: primitiveTypeSchema,
1371
1383
  valueSpace: z.string().min(1).optional()
1372
1384
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ripplo/testing",
3
- "version": "0.7.11",
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",