@polintpro/proposit-core 0.2.3 → 0.2.4

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 (48) hide show
  1. package/README.md +14 -11
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/core/ArgumentEngine.d.ts +23 -19
  7. package/dist/lib/core/ArgumentEngine.d.ts.map +1 -1
  8. package/dist/lib/core/ArgumentEngine.js +11 -11
  9. package/dist/lib/core/ArgumentEngine.js.map +1 -1
  10. package/dist/lib/core/ChangeCollector.d.ts +13 -14
  11. package/dist/lib/core/ChangeCollector.d.ts.map +1 -1
  12. package/dist/lib/core/ChangeCollector.js.map +1 -1
  13. package/dist/lib/core/ExpressionManager.d.ts +15 -13
  14. package/dist/lib/core/ExpressionManager.d.ts.map +1 -1
  15. package/dist/lib/core/ExpressionManager.js +52 -22
  16. package/dist/lib/core/ExpressionManager.js.map +1 -1
  17. package/dist/lib/core/PremiseManager.d.ts +21 -20
  18. package/dist/lib/core/PremiseManager.d.ts.map +1 -1
  19. package/dist/lib/core/PremiseManager.js +19 -24
  20. package/dist/lib/core/PremiseManager.js.map +1 -1
  21. package/dist/lib/core/VariableManager.d.ts +7 -8
  22. package/dist/lib/core/VariableManager.d.ts.map +1 -1
  23. package/dist/lib/core/VariableManager.js +4 -1
  24. package/dist/lib/core/VariableManager.js.map +1 -1
  25. package/dist/lib/core/diff.d.ts +1 -1
  26. package/dist/lib/core/diff.d.ts.map +1 -1
  27. package/dist/lib/core/diff.js +19 -11
  28. package/dist/lib/core/diff.js.map +1 -1
  29. package/dist/lib/schemata/propositional.d.ts.map +1 -1
  30. package/dist/lib/schemata/propositional.js +0 -1
  31. package/dist/lib/schemata/propositional.js.map +1 -1
  32. package/dist/lib/schemata/shared.d.ts +4 -0
  33. package/dist/lib/schemata/shared.d.ts.map +1 -1
  34. package/dist/lib/types/diff.d.ts +15 -15
  35. package/dist/lib/types/diff.d.ts.map +1 -1
  36. package/dist/lib/types/mutation.d.ts +7 -20
  37. package/dist/lib/types/mutation.d.ts.map +1 -1
  38. package/dist/lib/utils/position.d.ts +9 -3
  39. package/dist/lib/utils/position.d.ts.map +1 -1
  40. package/dist/lib/utils/position.js +8 -3
  41. package/dist/lib/utils/position.js.map +1 -1
  42. package/package.json +3 -2
  43. package/skills/proposit-core/SKILL.md +35 -0
  44. package/skills/proposit-core/docs/api-usage.md +442 -0
  45. package/skills/proposit-core/docs/architecture.md +256 -0
  46. package/skills/proposit-core/docs/cli.md +304 -0
  47. package/skills/proposit-core/docs/testing.md +281 -0
  48. package/skills/proposit-core/docs/types-schemas.md +648 -0
@@ -0,0 +1,281 @@
1
+ # Testing Guide
2
+
3
+ Reference for proposit-core test structure, conventions, and how to add new tests.
4
+
5
+ ---
6
+
7
+ ## Test File
8
+
9
+ All tests live in a single file: `test/ExpressionManager.test.ts` (~6500 lines, Vitest).
10
+
11
+ ```bash
12
+ pnpm run test # run all tests
13
+ pnpm run typecheck # tsc --noEmit
14
+ pnpm run lint # prettier --check + eslint
15
+ pnpm run check # typecheck + lint + test + build (all in sequence)
16
+ ```
17
+
18
+ ---
19
+
20
+ ## Structure
21
+
22
+ Each `describe` block corresponds to a method or logical grouping. New features get a new `describe` at the bottom. Do not modify existing blocks unless fixing them.
23
+
24
+ ---
25
+
26
+ ## Fixture Convention
27
+
28
+ No shared `beforeEach`. Every test builds fixtures inline using helpers defined at the top of the test file.
29
+
30
+ ### Constants and factory functions
31
+
32
+ ```typescript
33
+ const ARG: Omit<TCoreArgument, "checksum"> = { id: "arg-1", version: 1 }
34
+
35
+ function makeVar(id: string, symbol: string): TVariableInput {
36
+ return { id, argumentId: ARG.id, argumentVersion: ARG.version, symbol }
37
+ }
38
+
39
+ function makeVarExpr(
40
+ id: string,
41
+ variableId: string,
42
+ opts: { parentId?: string | null; position?: number } = {}
43
+ ): TExpressionInput {
44
+ return {
45
+ id,
46
+ argumentId: ARG.id,
47
+ argumentVersion: ARG.version,
48
+ type: "variable",
49
+ variableId,
50
+ parentId: opts.parentId ?? null,
51
+ position: opts.position ?? POSITION_INITIAL,
52
+ }
53
+ }
54
+
55
+ function makeOpExpr(
56
+ id: string,
57
+ operator: "not" | "and" | "or" | "implies" | "iff",
58
+ opts: { parentId?: string | null; position?: number } = {}
59
+ ): TExpressionInput {
60
+ return {
61
+ id,
62
+ argumentId: ARG.id,
63
+ argumentVersion: ARG.version,
64
+ type: "operator",
65
+ operator,
66
+ parentId: opts.parentId ?? null,
67
+ position: opts.position ?? POSITION_INITIAL,
68
+ }
69
+ }
70
+
71
+ function makeFormulaExpr(
72
+ id: string,
73
+ opts: { parentId?: string | null; position?: number } = {}
74
+ ): TExpressionInput {
75
+ return {
76
+ id,
77
+ argumentId: ARG.id,
78
+ argumentVersion: ARG.version,
79
+ type: "formula",
80
+ parentId: opts.parentId ?? null,
81
+ position: opts.position ?? POSITION_INITIAL,
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### Pre-built variables
87
+
88
+ ```typescript
89
+ const VAR_P = makeVar("var-p", "P")
90
+ const VAR_Q = makeVar("var-q", "Q")
91
+ const VAR_R = makeVar("var-r", "R")
92
+ ```
93
+
94
+ ### Helper functions
95
+
96
+ ```typescript
97
+ /** Create a premise (via ArgumentEngine) with P, Q, R pre-loaded. */
98
+ function premiseWithVars(): PremiseManager {
99
+ const eng = new ArgumentEngine(ARG)
100
+ eng.addVariable(VAR_P)
101
+ eng.addVariable(VAR_Q)
102
+ eng.addVariable(VAR_R)
103
+ const { result: pm } = eng.createPremise()
104
+ return pm
105
+ }
106
+
107
+ /** Create a PremiseManager directly with a deterministic ID (for toData tests). */
108
+ function makePremise(extras?: Record<string, unknown>): PremiseManager {
109
+ const vm = new VariableManager()
110
+ return new PremiseManager("premise-1", ARG, vm, extras)
111
+ }
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Adding a New Test
117
+
118
+ 1. Add a new `describe` block at the bottom of the file.
119
+ 2. Build fixtures inline using the helpers above (`premiseWithVars()`, `makeVarExpr()`, etc.).
120
+ 3. Destructure mutation results: `const { result, changes } = ...`
121
+ 4. Assert on both the return value and changeset side effects.
122
+ 5. Run `pnpm run test` to verify.
123
+
124
+ ### Example: testing a new PremiseManager method
125
+
126
+ ```typescript
127
+ describe("PremiseManager —myNewMethod", () => {
128
+ it("does the expected thing", () => {
129
+ const pm = premiseWithVars()
130
+ const { result: root } = pm.addExpression(makeOpExpr("op-1", "and"))
131
+ const { result, changes } = pm.myNewMethod("op-1")
132
+
133
+ // Assert on the direct return value
134
+ expect(result).toBeDefined()
135
+
136
+ // Assert on changeset side effects
137
+ expect(changes.expressions?.modified).toHaveLength(1)
138
+ })
139
+ })
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Existing Describe Blocks
145
+
146
+ Full ordered list (42 blocks):
147
+
148
+ | # | Block name |
149
+ | --- | ------------------------------------------------------------------------ |
150
+ | 1 | `addExpression` |
151
+ | 2 | `insertExpression` |
152
+ | 3 | `removeExpression` |
153
+ | 4 | `removeExpression —operator collapse` |
154
+ | 5 | `removeVariable` |
155
+ | 6 | `addExpression ordering` |
156
+ | 7 | `toArray behaviour (via toData().expressions)` |
157
+ | 8 | `stress test` |
158
+ | 9 | `formula` |
159
+ | 10 | `ArgumentEngine premise CRUD` |
160
+ | 11 | `ArgumentEngine —addVariable / removeVariable` |
161
+ | 12 | `PremiseManager —single-root enforcement` |
162
+ | 13 | `PremiseManager —addExpression / removeExpression / insertExpression` |
163
+ | 14 | `PremiseManager —toDisplayString` |
164
+ | 15 | `PremiseManager —toData` |
165
+ | 16 | `PremiseManager —validation and evaluation` |
166
+ | 17 | `ArgumentEngine —roles and evaluation` |
167
+ | 18 | `ArgumentEngine —complex argument scenarios across multiple evaluations` |
168
+ | 19 | `diffArguments` |
169
+ | 20 | `Kleene three-valued logic helpers` |
170
+ | 21 | `PremiseManager —three-valued evaluation` |
171
+ | 22 | `ArgumentEngine —three-valued evaluation` |
172
+ | 23 | `schema shapes with additionalProperties` |
173
+ | 24 | `field preservation —unknown fields survive round-trips` |
174
+ | 25 | `buildPremiseProfile` |
175
+ | 26 | `analyzePremiseRelationships —direct relationships` |
176
+ | 27 | `analyzePremiseRelationships —transitive relationships` |
177
+ | 28 | `analyzePremiseRelationships —precedence and edge cases` |
178
+ | 29 | `position utilities` |
179
+ | 30 | `PremiseManager —appendExpression and addExpressionRelative` |
180
+ | 31 | `ChangeCollector` |
181
+ | 32 | `PremiseManager —mutation changesets` |
182
+ | 33 | `ArgumentEngine —mutation changesets` |
183
+ | 34 | `checksum utilities` |
184
+ | 35 | `entity checksum fields` |
185
+ | 36 | `createChecksumConfig` |
186
+ | 37 | `ArgumentEngine —variable management` |
187
+ | 38 | `PremiseManager —deleteExpressionsUsingVariable` |
188
+ | 39 | `variable expressions cannot have children` |
189
+ | 40 | `ArgumentEngine —auto-conclusion on first premise` |
190
+ | 41 | `PremiseManager —updateExpression` |
191
+ | 42 | `removeExpression —deleteSubtree parameter` |
192
+
193
+ ---
194
+
195
+ ## Key Testing Patterns
196
+
197
+ ### Destructure mutation results
198
+
199
+ All mutating methods return `TCoreMutationResult<T>`. Always destructure and assert on both parts:
200
+
201
+ ```typescript
202
+ const { result, changes } = pm.addExpression(makeVarExpr("v1", "var-p"))
203
+ expect(result.id).toBe("v1")
204
+ expect(changes.expressions?.added).toHaveLength(1)
205
+ ```
206
+
207
+ ### Operator collapse after removal
208
+
209
+ When removing an expression, assert on the parent/child state afterward. Operator collapse may delete the parent or promote a surviving child:
210
+
211
+ ```typescript
212
+ const { changes } = pm.removeExpression("child-2", true)
213
+ // Parent operator collapsed -- check it was removed
214
+ expect(changes.expressions?.removed?.map((e) => e.id)).toContain("op-1")
215
+ ```
216
+
217
+ ### Cascade operations (e.g. removeVariable)
218
+
219
+ Check `changes.expressions.removed` across all affected premises:
220
+
221
+ ```typescript
222
+ const { changes } = engine.removeVariable("var-p")
223
+ expect(changes.expressions?.removed?.length).toBeGreaterThan(0)
224
+ expect(changes.variables?.removed).toHaveLength(1)
225
+ ```
226
+
227
+ ### Verify tree structure
228
+
229
+ Use `pm.toData().expressions` to inspect the full expression array:
230
+
231
+ ```typescript
232
+ const exprs = pm.toData().expressions
233
+ expect(exprs).toHaveLength(3)
234
+ expect(exprs[0].parentId).toBeNull() // root
235
+ ```
236
+
237
+ ### Verify rendered formula
238
+
239
+ Use `pm.toDisplayString()` to check the human-readable form:
240
+
241
+ ```typescript
242
+ expect(pm.toDisplayString()).toBe("(P AND Q) IMPLIES R")
243
+ ```
244
+
245
+ ### Evaluation tests
246
+
247
+ Build an assignment and check evaluation results:
248
+
249
+ ```typescript
250
+ const assignment: TCoreExpressionAssignment = {
251
+ variables: { "var-p": true, "var-q": false },
252
+ rejectedExpressionIds: [],
253
+ }
254
+ const evalResult = pm.evaluate(assignment)
255
+ expect(evalResult.rootValue).toBe(false)
256
+ ```
257
+
258
+ ### Root-only operator enforcement
259
+
260
+ `implies` and `iff` must have `parentId: null`. Tests should verify that nesting them throws:
261
+
262
+ ```typescript
263
+ expect(() =>
264
+ pm.addExpression(
265
+ makeOpExpr("nested-implies", "implies", { parentId: "op-1" })
266
+ )
267
+ ).toThrow()
268
+ ```
269
+
270
+ ---
271
+
272
+ ## Commands Reference
273
+
274
+ | Command | Purpose |
275
+ | --------------------- | ----------------------------------------------- |
276
+ | `pnpm run test` | Run all tests (vitest run) |
277
+ | `pnpm run check` | Typecheck + lint + test + build (full pipeline) |
278
+ | `pnpm run typecheck` | tsc --noEmit |
279
+ | `pnpm run lint` | prettier --check + eslint |
280
+ | `pnpm run prettify` | prettier --write (auto-fix formatting) |
281
+ | `pnpm eslint . --fix` | Auto-fix lint errors |