@playfast/reform-proof 1.2.0 → 1.3.0

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.
Files changed (85) hide show
  1. package/dist/assert.d.ts +15 -0
  2. package/dist/assert.d.ts.map +1 -0
  3. package/dist/assert.js +39 -0
  4. package/dist/assert.js.map +1 -0
  5. package/dist/engine.d.ts +16 -0
  6. package/dist/engine.d.ts.map +1 -0
  7. package/dist/engine.js +119 -0
  8. package/dist/engine.js.map +1 -0
  9. package/dist/engineMounted.d.ts +18 -0
  10. package/dist/engineMounted.d.ts.map +1 -0
  11. package/dist/engineMounted.js +96 -0
  12. package/dist/engineMounted.js.map +1 -0
  13. package/dist/engineMounts.d.ts +13 -0
  14. package/dist/engineMounts.d.ts.map +1 -0
  15. package/dist/engineMounts.js +116 -0
  16. package/dist/engineMounts.js.map +1 -0
  17. package/dist/engineRender.d.ts +10 -0
  18. package/dist/engineRender.d.ts.map +1 -0
  19. package/dist/engineRender.js +64 -0
  20. package/dist/engineRender.js.map +1 -0
  21. package/dist/engineSink.d.ts +66 -0
  22. package/dist/engineSink.d.ts.map +1 -0
  23. package/dist/engineSink.js +72 -0
  24. package/dist/engineSink.js.map +1 -0
  25. package/dist/engineTree.d.ts +63 -0
  26. package/dist/engineTree.d.ts.map +1 -0
  27. package/dist/engineTree.js +137 -0
  28. package/dist/engineTree.js.map +1 -0
  29. package/dist/engineTreeDriver.d.ts +5 -0
  30. package/dist/engineTreeDriver.d.ts.map +1 -0
  31. package/dist/engineTreeDriver.js +187 -0
  32. package/dist/engineTreeDriver.js.map +1 -0
  33. package/dist/engineTreeFacade.d.ts +5 -0
  34. package/dist/engineTreeFacade.d.ts.map +1 -0
  35. package/dist/engineTreeFacade.js +105 -0
  36. package/dist/engineTreeFacade.js.map +1 -0
  37. package/dist/engineTreeTypes.d.ts +80 -0
  38. package/dist/engineTreeTypes.d.ts.map +1 -0
  39. package/dist/engineTreeTypes.js +11 -0
  40. package/dist/engineTreeTypes.js.map +1 -0
  41. package/dist/errors.d.ts +39 -0
  42. package/dist/errors.d.ts.map +1 -0
  43. package/dist/errors.js +30 -0
  44. package/dist/errors.js.map +1 -0
  45. package/dist/facade.d.ts +54 -0
  46. package/dist/facade.d.ts.map +1 -0
  47. package/dist/facade.js +2 -0
  48. package/dist/facade.js.map +1 -0
  49. package/dist/fingerprint.d.ts +2 -0
  50. package/dist/fingerprint.d.ts.map +1 -0
  51. package/dist/fingerprint.js +55 -0
  52. package/dist/fingerprint.js.map +1 -0
  53. package/dist/index.d.ts +88 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +73 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/product.d.ts +56 -0
  58. package/dist/product.d.ts.map +1 -0
  59. package/dist/product.js +35 -0
  60. package/dist/product.js.map +1 -0
  61. package/dist/proofCase.d.ts +24 -0
  62. package/dist/proofCase.d.ts.map +1 -0
  63. package/dist/proofCase.js +2 -0
  64. package/dist/proofCase.js.map +1 -0
  65. package/dist/runner.d.ts +15 -0
  66. package/dist/runner.d.ts.map +1 -0
  67. package/dist/runner.js +13 -0
  68. package/dist/runner.js.map +1 -0
  69. package/package.json +17 -5
  70. package/src/assert.ts +65 -0
  71. package/src/engine.ts +30 -1402
  72. package/src/engineMounted.ts +271 -0
  73. package/src/engineMounts.ts +165 -0
  74. package/src/engineRender.ts +136 -0
  75. package/src/engineSink.ts +195 -0
  76. package/src/engineTree.ts +298 -0
  77. package/src/engineTreeDriver.ts +247 -0
  78. package/src/engineTreeFacade.ts +183 -0
  79. package/src/engineTreeTypes.ts +103 -0
  80. package/src/errors.ts +19 -0
  81. package/src/facade.ts +78 -0
  82. package/src/index.ts +61 -276
  83. package/src/product.ts +108 -0
  84. package/src/proofCase.ts +46 -0
  85. package/src/test-clock.test.ts +135 -0
@@ -0,0 +1,56 @@
1
+ import { Option } from 'effect';
2
+ import type { AnyComposition } from '@playfast/reform/internal';
3
+ import type { ContractOf, EventNamesOf } from './facade.js';
4
+ export type ProductComposition = AnyComposition & {
5
+ readonly identity: symbol;
6
+ };
7
+ declare const RequirementCompositionTypeId: unique symbol;
8
+ export interface AnyRequirementClass {
9
+ new (): {};
10
+ readonly manifest: {
11
+ readonly kind: 'ProductRequirement';
12
+ readonly name: string;
13
+ readonly statement: string;
14
+ readonly composition: ProductComposition;
15
+ readonly events: Option.Option<ReadonlyArray<PropertyKey>>;
16
+ };
17
+ readonly capture: <Result>(visit: RequirementCapture<Result>) => Result;
18
+ }
19
+ export type RequirementCapture<Result> = <Comp extends ProductComposition, Statement extends string>(requirement: RequirementClass<Comp, Statement>) => Result;
20
+ export interface RequirementManifest<Comp extends ProductComposition, Statement extends string> {
21
+ readonly kind: 'ProductRequirement';
22
+ readonly name: Statement;
23
+ readonly statement: Statement;
24
+ readonly composition: Comp;
25
+ readonly events: Option.Option<ReadonlyArray<EventNamesOf<ContractOf<Comp>>>>;
26
+ }
27
+ export interface RequirementClass<Comp extends ProductComposition, Statement extends string> extends AnyRequirementClass {
28
+ readonly manifest: RequirementManifest<Comp, Statement>;
29
+ readonly [RequirementCompositionTypeId]: (composition: Comp) => Comp;
30
+ }
31
+ export interface ProductManifest<Comp extends ProductComposition> {
32
+ readonly kind: 'Product';
33
+ readonly name: string;
34
+ readonly composition: Comp;
35
+ readonly requirements: ReadonlyArray<AnyRequirementClass>;
36
+ }
37
+ export interface ProductClass<Comp extends ProductComposition = ProductComposition> {
38
+ new (): {};
39
+ readonly manifest: ProductManifest<Comp>;
40
+ }
41
+ interface MakeRequirementOptionsExternalApi<Comp extends ProductComposition> {
42
+ readonly events?: ReadonlyArray<EventNamesOf<ContractOf<Comp>>>;
43
+ }
44
+ declare const makeRequirement: <Comp extends ProductComposition, const Statement extends string>(composition: Comp, statement: Statement, options?: MakeRequirementOptionsExternalApi<Comp>) => RequirementClass<Comp, Statement>;
45
+ export declare const ProductRequirement: {
46
+ readonly make: typeof makeRequirement;
47
+ };
48
+ interface MakeProductConfig<Comp extends ProductComposition> {
49
+ readonly requirements: ReadonlyArray<RequirementClass<Comp, string>>;
50
+ }
51
+ declare const makeProduct: <Comp extends ProductComposition>(composition: Comp, config: MakeProductConfig<Comp>) => ProductClass<Comp>;
52
+ export declare const Product: {
53
+ readonly make: typeof makeProduct;
54
+ };
55
+ export {};
56
+ //# sourceMappingURL=product.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { Option } from 'effect';
2
+ const RequirementCompositionTypeId = Symbol.for('reform-proof/RequirementComposition');
3
+ const makeRequirement = (composition, statement, options) => {
4
+ const manifest = {
5
+ kind: 'ProductRequirement',
6
+ name: statement,
7
+ statement,
8
+ composition,
9
+ events: Option.fromNullable(options?.events),
10
+ };
11
+ class Requirement {
12
+ static manifest = manifest;
13
+ static [RequirementCompositionTypeId] = (exact) => exact;
14
+ static capture = (visit) => visit(Requirement);
15
+ }
16
+ return Requirement;
17
+ };
18
+ export const ProductRequirement = {
19
+ make: makeRequirement,
20
+ };
21
+ const makeProduct = (composition, config) => {
22
+ const manifest = {
23
+ kind: 'Product',
24
+ name: composition.manifest.name,
25
+ composition,
26
+ requirements: config.requirements,
27
+ };
28
+ return class {
29
+ static manifest = manifest;
30
+ };
31
+ };
32
+ export const Product = {
33
+ make: makeProduct,
34
+ };
35
+ //# sourceMappingURL=product.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAM/B,MAAM,4BAA4B,GAAkB,MAAM,CAAC,GAAG,CAC5D,qCAAqC,CACtC,CAAA;AAqDD,MAAM,eAAe,GAAG,CACtB,WAAiB,EACjB,SAAoB,EACpB,OAAiD,EACd,EAAE;IACrC,MAAM,QAAQ,GAAyC;QACrD,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,SAAS;QACf,SAAS;QACT,WAAW;QACX,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC;KAC7C,CAAA;IACD,MAAM,WAAW;QACf,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAA;QACnC,MAAM,CAAU,CAAC,4BAA4B,CAAC,GAAG,CAAC,KAAW,EAAQ,EAAE,CAAC,KAAK,CAAA;QAC7E,MAAM,CAAU,OAAO,GAAG,CAAS,KAAiC,EAAU,EAAE,CAC9E,KAAK,CAAC,WAAW,CAAC,CAAA;;IAEtB,OAAO,WAAW,CAAA;AACpB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAA8C;IAC3E,IAAI,EAAE,eAAe;CACtB,CAAA;AAMD,MAAM,WAAW,GAAG,CAClB,WAAiB,EACjB,MAA+B,EACX,EAAE;IACtB,MAAM,QAAQ,GAA0B;QACtC,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI;QAC/B,WAAW;QACX,YAAY,EAAE,MAAM,CAAC,YAAY;KAClC,CAAA;IACD,OAAO;QACL,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAA;KACpC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAA0C;IAC5D,IAAI,EAAE,WAAW;CAClB,CAAA"}
@@ -0,0 +1,24 @@
1
+ import type { Effect } from 'effect';
2
+ import type { YieldWrap } from 'effect/Utils';
3
+ import type { CapturedScene, UiContract } from '@playfast/reform';
4
+ import type { Facade } from './facade.js';
5
+ import type { ProductComposition, RequirementClass } from './product.js';
6
+ export type ProofGenerator = Generator<YieldWrap<Effect.Effect<unknown, unknown, never>>, void, unknown>;
7
+ export interface ProofCase<Comp extends ProductComposition, C extends UiContract, S extends ReadonlyArray<unknown>, Services, P, N extends string, Identity> {
8
+ readonly requirement: RequirementClass<Comp, string>;
9
+ readonly scene: CapturedScene<C, S, Services, P, N, Identity>;
10
+ readonly placement: 'Root' | 'Slot';
11
+ readonly body: (app: Facade<C, never>) => ProofGenerator;
12
+ }
13
+ export type ProofCapture<Result> = <Comp extends ProductComposition, C extends UiContract, S extends ReadonlyArray<unknown>, Services, P, N extends string, Identity>(proof: ProofCase<Comp, C, S, Services, P, N, Identity>) => Result;
14
+ export interface ProofResult {
15
+ readonly requirement: string;
16
+ readonly ok: boolean;
17
+ readonly error: string | undefined;
18
+ }
19
+ export interface SuiteResult {
20
+ readonly product: string;
21
+ readonly results: ReadonlyArray<ProofResult>;
22
+ readonly ok: boolean;
23
+ }
24
+ //# sourceMappingURL=proofCase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proofCase.d.ts","sourceRoot":"","sources":["../src/proofCase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAErE,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AAExG,MAAM,WAAW,SAAS,CACxB,IAAI,SAAS,kBAAkB,EAC/B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EAChC,QAAQ,EACR,CAAC,EACD,CAAC,SAAS,MAAM,EAChB,QAAQ;IAER,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACpD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC7D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,cAAc,CAAA;CACzD;AAED,MAAM,MAAM,YAAY,CAAC,MAAM,IAAI,CACjC,IAAI,SAAS,kBAAkB,EAC/B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EAChC,QAAQ,EACR,CAAC,EACD,CAAC,SAAS,MAAM,EAChB,QAAQ,EAER,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,KACnD,MAAM,CAAA;AAEX,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IAC5C,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;CACrB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=proofCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proofCase.js","sourceRoot":"","sources":["../src/proofCase.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { Context, Effect, Layer } from 'effect';
2
+ import type { DriveResult, Proof, ProofResult } from './index.js';
3
+ export interface ProofRunnerApi {
4
+ readonly executeProofEffect: (proof: Proof) => Effect.Effect<ProofResult, never, never>;
5
+ readonly driveProofEffect: (proof: Proof) => Effect.Effect<DriveResult, never, never>;
6
+ readonly executeProof: (proof: Proof) => Promise<ProofResult>;
7
+ readonly driveProof: (proof: Proof) => Promise<DriveResult>;
8
+ }
9
+ declare const ProofRunnerBase: Context.TagClass<ProofRunner, 'reform-proof/ProofRunner', ProofRunnerApi>;
10
+ export declare class ProofRunner extends ProofRunnerBase {
11
+ }
12
+ export declare const proofRunnerLayer: Layer.Layer<ProofRunner>;
13
+ export declare const withProofRunner: <A>(use: (runner: ProofRunnerApi) => Promise<A>) => Promise<A>;
14
+ export {};
15
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE9D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IACvF,QAAQ,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IACrF,QAAQ,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7D,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;CAC5D;AAED,QAAA,MAAM,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,0BAA0B,EAAE,cAAc,CACvB,CAAA;AAExE,qBAAa,WAAY,SAAQ,eAAe;CAAG;AAEnD,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAKpD,CAAA;AAEF,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAMvF,CAAA"}
package/dist/runner.js ADDED
@@ -0,0 +1,13 @@
1
+ import { Context, Effect, Layer } from 'effect';
2
+ import { driveProof, driveProofEffect, executeProof, executeProofEffect } from './engine.js';
3
+ const ProofRunnerBase = Context.Tag('reform-proof/ProofRunner')();
4
+ export class ProofRunner extends ProofRunnerBase {
5
+ }
6
+ export const proofRunnerLayer = Layer.succeed(ProofRunner, {
7
+ executeProofEffect,
8
+ driveProofEffect,
9
+ executeProof,
10
+ driveProof,
11
+ });
12
+ export const withProofRunner = (use) => Effect.runPromise(ProofRunner.pipe(Effect.flatMap((runner) => Effect.promise(() => use(runner))), Effect.provide(proofRunnerLayer)));
13
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAUzF,MAAM,eAAe,GACnB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,EAA+B,CAAA;AAExE,MAAM,OAAO,WAAY,SAAQ,eAAe;CAAG;AAEnD,MAAM,CAAC,MAAM,gBAAgB,GAA6B,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE;IACnF,kBAAkB;IAClB,gBAAgB;IAChB,YAAY;IACZ,UAAU;CACX,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,GAA2C,EAAc,EAAE,CAC5F,MAAM,CAAC,UAAU,CACf,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAC7D,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CACjC,CACF,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playfast/reform-proof",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Headless testing toolkit for reform — drive a scene's compositions and assert on the props they compute, with no DOM, timers, or text matching.",
5
5
  "keywords": [
6
6
  "effect",
@@ -19,15 +19,26 @@
19
19
  "directory": "packages/proof"
20
20
  },
21
21
  "files": [
22
+ "dist",
22
23
  "src",
23
24
  "README.md"
24
25
  ],
25
26
  "type": "module",
26
27
  "sideEffects": false,
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
27
30
  "exports": {
28
31
  "./package.json": "./package.json",
29
- ".": "./src/index.ts",
30
- "./*": "./src/*.ts"
32
+ ".": {
33
+ "playfast-src": "./src/index.ts",
34
+ "types": "./dist/index.d.ts",
35
+ "default": "./dist/index.js"
36
+ },
37
+ "./*": {
38
+ "playfast-src": "./src/*.ts",
39
+ "types": "./dist/*.d.ts",
40
+ "default": "./dist/*.js"
41
+ }
31
42
  },
32
43
  "publishConfig": {
33
44
  "access": "public"
@@ -35,12 +46,13 @@
35
46
  "scripts": {
36
47
  "clean": "rm -rf dist .tsbuildinfo",
37
48
  "check": "tsc --noEmit",
38
- "build": "tsc -p tsconfig.build.json",
49
+ "build": "rm -rf dist .tsbuildinfo && tsc -p tsconfig.build.json && bun ../../scripts/fix-esm-extensions.ts dist",
39
50
  "test": "vitest run",
40
51
  "test:watch": "vitest",
41
52
  "coverage": "vitest run --coverage",
42
53
  "lint": "oxlint src",
43
- "lint:fix": "oxlint --fix src"
54
+ "lint:fix": "oxlint --fix src",
55
+ "prepack": "bun run build"
44
56
  },
45
57
  "peerDependencies": {
46
58
  "@playfast/reform": "*",
package/src/assert.ts ADDED
@@ -0,0 +1,65 @@
1
+ import { Array as Arr, Effect, Option, Record as Rec } from 'effect'
2
+ import { AssertionFailed } from './errors'
3
+ import { formatFingerprint } from './fingerprint'
4
+
5
+ interface ComparePair {
6
+ readonly left: unknown
7
+ readonly right: unknown
8
+ }
9
+
10
+ const show = (subject: unknown): string => formatFingerprint(subject)
11
+
12
+ const deepEqual = ({ left, right }: ComparePair): boolean =>
13
+ Object.is(left, right) || show(left) === show(right)
14
+
15
+ const fail = (message: string): Effect.Effect<never> =>
16
+ Effect.dieMessage(new AssertionFailed({ detail: message }).message)
17
+
18
+ export const expect = <A>(actual: A) => ({
19
+ toBe: (expected: A): Effect.Effect<void> =>
20
+ Object.is(actual, expected)
21
+ ? Effect.void
22
+ : fail(`expected ${show(actual)} to be ${show(expected)}`),
23
+ toEqual: (expected: A): Effect.Effect<void> =>
24
+ deepEqual({ left: actual, right: expected })
25
+ ? Effect.void
26
+ : fail(`expected ${show(actual)} to equal ${show(expected)}`),
27
+ toContain: (expected: A extends ReadonlyArray<infer E> ? E : unknown): Effect.Effect<void> =>
28
+ Array.isArray(actual) && actual.some((element) => deepEqual({ left: element, right: expected }))
29
+ ? Effect.void
30
+ : fail(`expected ${show(actual)} to contain ${show(expected)}`),
31
+ toMatchObject: (expected: Partial<A>): Effect.Effect<void> => {
32
+ const mismatch = matchPartial({ actual, expected })
33
+ return mismatch === undefined ? Effect.void : fail(mismatch)
34
+ },
35
+ })
36
+
37
+ export const isRecord = (candidate: unknown): candidate is Record<string, unknown> =>
38
+ typeof candidate === 'object' && candidate !== null
39
+
40
+ interface MatchInput {
41
+ readonly actual: unknown
42
+ readonly expected: unknown
43
+ }
44
+
45
+ const matchPartial = ({ actual, expected }: MatchInput): string | undefined => {
46
+ if (!isRecord(expected)) {
47
+ return deepEqual({ left: actual, right: expected })
48
+ ? undefined
49
+ : `expected ${show(actual)} to match ${show(expected)}`
50
+ }
51
+ if (!isRecord(actual)) {
52
+ return `expected ${show(actual)} to be an object matching ${show(expected)}`
53
+ }
54
+ const mismatch = Arr.findFirst(
55
+ Rec.keys(expected),
56
+ (key) => !deepEqual({ left: actual[key], right: expected[key] }),
57
+ )
58
+ return Option.match(mismatch, {
59
+ onNone: () => undefined,
60
+ onSome: (key) =>
61
+ `expected key ${show(key)} to match ${show(expected[key])}, got ${show(actual[key])}`,
62
+ })
63
+ }
64
+
65
+ export const matchProps: (input: MatchInput) => string | undefined = matchPartial