@calcit/procs 0.13.6 → 0.13.7

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.
Binary file
package/build.rs CHANGED
@@ -79,12 +79,22 @@ pub struct CodeEntry {
79
79
  #[serde(default)]
80
80
  pub examples: Vec<Cirru>,
81
81
  #[serde(default)]
82
+ pub tests: Vec<TestEntry>,
83
+ #[serde(default)]
82
84
  pub tags: Vec<String>,
83
85
  pub code: Cirru,
84
86
  #[serde(default)]
85
87
  pub schema: Option<Edn>,
86
88
  }
87
89
 
90
+ #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
91
+ pub struct TestEntry {
92
+ pub name: String,
93
+ pub code: Cirru,
94
+ #[serde(default)]
95
+ pub tags: Vec<String>,
96
+ }
97
+
88
98
  #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
89
99
  pub struct NsEntry {
90
100
  pub doc: String,
@@ -355,7 +365,7 @@ fn validate_schema_edn_no_legacy_quotes(value: &Edn, owner: &str) -> Result<(),
355
365
  walk(value, owner, &mut path)
356
366
  }
357
367
 
358
- fn parse_tags_from_edn(value: &Edn, owner: &str) -> Result<Vec<String>, String> {
368
+ fn parse_tags_from_edn(value: &Edn, owner: &str, field: &str) -> Result<Vec<String>, String> {
359
369
  match value {
360
370
  Edn::Set(set) => {
361
371
  let mut tags = Vec::with_capacity(set.0.len());
@@ -363,10 +373,7 @@ fn parse_tags_from_edn(value: &Edn, owner: &str) -> Result<Vec<String>, String>
363
373
  match item {
364
374
  Edn::Tag(tag) => tags.push(format!(":{}", tag.ref_str())),
365
375
  other => {
366
- return Err(format!(
367
- "{owner}: CodeEntry.tags expects tag items, got {}",
368
- format_edn_preview(other)
369
- ));
376
+ return Err(format!("{owner}: {field} expects tag items, got {}", format_edn_preview(other)));
370
377
  }
371
378
  }
372
379
  }
@@ -374,10 +381,7 @@ fn parse_tags_from_edn(value: &Edn, owner: &str) -> Result<Vec<String>, String>
374
381
  tags.dedup();
375
382
  Ok(tags)
376
383
  }
377
- other => Err(format!(
378
- "{owner}: CodeEntry.tags expects a hashset, got {}",
379
- format_edn_preview(other)
380
- )),
384
+ other => Err(format!("{owner}: {field} expects a hashset, got {}", format_edn_preview(other))),
381
385
  }
382
386
  }
383
387
 
@@ -388,6 +392,7 @@ fn parse_code_entry(edn: Edn, owner: &str) -> Result<CodeEntry, String> {
388
392
  };
389
393
  let mut doc = String::new();
390
394
  let mut examples: Vec<Cirru> = vec![];
395
+ let mut tests: Vec<TestEntry> = vec![];
391
396
  let mut tags: Vec<String> = Vec::new();
392
397
  let mut code: Option<Cirru> = None;
393
398
  let mut schema: Option<Edn> = None;
@@ -395,7 +400,24 @@ fn parse_code_entry(edn: Edn, owner: &str) -> Result<CodeEntry, String> {
395
400
  match key.arc_str().as_ref() {
396
401
  "doc" => doc = from_edn(value.clone()).map_err(|e| format!("{owner}: invalid `:doc`: {e}"))?,
397
402
  "examples" => examples = from_edn(value.clone()).map_err(|e| format!("{owner}: invalid `:examples`: {e}"))?,
398
- "tags" => tags = parse_tags_from_edn(value, owner)?,
403
+ "tests" => {
404
+ let Edn::List(items) = value else {
405
+ return Err(format!("{owner}: `:tests` expects a list, got {}", format_edn_preview(value)));
406
+ };
407
+ tests = items
408
+ .0
409
+ .iter()
410
+ .cloned()
411
+ .map(|item| parse_test_entry(item, owner))
412
+ .collect::<Result<Vec<_>, _>>()?;
413
+ let mut names = std::collections::HashSet::new();
414
+ for test in &tests {
415
+ if !names.insert(test.name.as_str()) {
416
+ return Err(format!("{owner}: duplicate test name `{}`", test.name));
417
+ }
418
+ }
419
+ }
420
+ "tags" => tags = parse_tags_from_edn(value, owner, "CodeEntry.tags")?,
399
421
  "code" => code = Some(from_edn(value.clone()).map_err(|e| format!("{owner}: invalid `:code`: {e}"))?),
400
422
  "schema" if !matches!(value, Edn::Nil) => {
401
423
  schema = Some(parse_schema_from_edn(value, owner).map_err(|e| format!("{owner}: invalid `:schema`: {e}"))?);
@@ -406,12 +428,40 @@ fn parse_code_entry(edn: Edn, owner: &str) -> Result<CodeEntry, String> {
406
428
  Ok(CodeEntry {
407
429
  doc,
408
430
  examples,
431
+ tests,
409
432
  tags,
410
433
  code: code.ok_or_else(|| format!("{owner}: missing `:code` field in CodeEntry"))?,
411
434
  schema,
412
435
  })
413
436
  }
414
437
 
438
+ fn parse_test_entry(edn: Edn, owner: &str) -> Result<TestEntry, String> {
439
+ let struct_value = match edn {
440
+ Edn::Struct(value) => value,
441
+ other => return Err(format!("{owner}: expected TestEntry struct, got {}", format_edn_preview(&other))),
442
+ };
443
+ let mut name = None;
444
+ let mut code = None;
445
+ let mut tags = Vec::new();
446
+ for (key, value) in &struct_value.pairs {
447
+ match key.ref_str() {
448
+ "name" => name = Some(from_edn(value.clone()).map_err(|error| format!("{owner}: invalid test `:name`: {error}"))?),
449
+ "code" => code = Some(from_edn(value.clone()).map_err(|error| format!("{owner}: invalid test `:code`: {error}"))?),
450
+ "tags" => tags = parse_tags_from_edn(value, owner, "TestEntry.tags")?,
451
+ _ => {}
452
+ }
453
+ }
454
+ let name: String = name.ok_or_else(|| format!("{owner}: test is missing `:name`"))?;
455
+ if name.trim().is_empty() {
456
+ return Err(format!("{owner}: test name must not be empty"));
457
+ }
458
+ Ok(TestEntry {
459
+ name,
460
+ code: code.ok_or_else(|| format!("{owner}: test is missing `:code`"))?,
461
+ tags,
462
+ })
463
+ }
464
+
415
465
  fn parse_ns_entry(edn: Edn, owner: &str) -> Result<NsEntry, String> {
416
466
  let struct_value: EdnStructView = match edn {
417
467
  Edn::Struct(r) => r,
@@ -0,0 +1,38 @@
1
+ # Migrate remaining record/tuple naming to struct/enum
2
+
3
+ Follow-up to the earlier terminology migration: located and updated the
4
+ remaining stale `record`/`tuple` naming that refers to the current
5
+ struct/enum data model, keeping genuine legacy-compat and EDN semantics.
6
+
7
+ ## Updated
8
+
9
+ - `calcit/test-wasm.cirru`: renamed `test-record-*` → `test-struct-*` and
10
+ `test-tuple-*` → `test-enum-*` (incl. `test-type-of-tuple` →
11
+ `test-type-of-enum`) via `cr edit rename`; updated 12 doc strings. Kept
12
+ `defrecord Point :x :y` as the WASM legacy-compat coverage.
13
+ - `scripts/test-wasm.mjs`: synced the renamed def references and section
14
+ labels.
15
+ - `src/runner/preprocess/mod.rs`: test-namespace labels `tests.record` →
16
+ `tests.struct` (kept the legacy `record` tag coverage in the loose-struct
17
+ test).
18
+ - `src/builtins/meta.rs`: `Calcit::Enum(tuple)` local bindings →
19
+ `enum_value`.
20
+ - `src/codegen/emit_wasm.rs`: comments `tuple fields`/`tuple pointer` →
21
+ `enum fields`/`enum pointer`.
22
+ - `src/bin/cli_handlers/query.rs`: test message `tuple operations` →
23
+ `enum operations`.
24
+
25
+ ## Deliberately kept
26
+
27
+ - Legacy migration tables in `docs/`, `deprecated_api.rs`, and
28
+ `removed_data_api_replacement`.
29
+ - Type-name aliases (`record`/`tuple` → Struct/Enum parsing), `SIMPLE_TYPES`
30
+ `tuple` query name, and IR/format-stable kind tags.
31
+ - `cirru_edn` `Edn::Record`/`Edn::Enum` contexts and hash prefixes.
32
+
33
+ Validation:
34
+
35
+ - `cargo test -q`(368 lib + 192 integration)
36
+ - `cargo clippy --lib --bin cr -- -D warnings`
37
+ - `cargo fmt --check`
38
+ - `yarn try-wasm`(含重命名后的 `test-struct-*` / `test-enum-*`)
@@ -0,0 +1,15 @@
1
+ # Import rule CLI regression coverage
2
+
3
+ - Added direct handler regressions for `cr edit imports` and
4
+ `cr edit add-import` when an import rule has the wrong arity.
5
+ - Both tests assert the indexed validation diagnostic and verify that the
6
+ snapshot remains byte-for-byte unchanged after rejection.
7
+ - This protects the persistence boundary in addition to the existing
8
+ `validate_import_rules` unit coverage.
9
+
10
+ Validation:
11
+
12
+ - `cargo fmt`
13
+ - `cargo clippy --bin cr -- -D warnings`
14
+ - `cargo test --bin cr` (194 passed)
15
+ - `git diff --check`
@@ -0,0 +1,12 @@
1
+ # Import rule regression review follow-up
2
+
3
+ - Changed the malformed-import persistence assertions to compare raw file
4
+ bytes instead of UTF-8 strings, matching the byte-for-byte guarantee and
5
+ keeping the tests independent of snapshot text encoding.
6
+
7
+ Validation:
8
+
9
+ - `cargo fmt`
10
+ - `cargo clippy --bin cr -- -D warnings`
11
+ - `cargo test --bin cr malformed_rule`
12
+ - `git diff --check`
@@ -0,0 +1,43 @@
1
+ # Definition-attached core tests: consolidated history
2
+
3
+ This development window introduced and completed definition-attached tests in
4
+ `src/cirru/calcit-core.cirru`, so pure `calcit.core` API contracts can run from
5
+ the definition that implements them while target-specific and integration
6
+ coverage remains in the legacy fixtures.
7
+
8
+ ## Durable design decisions
9
+
10
+ - Added backward-compatible `:tests` metadata and embedded `calcit.test`
11
+ assertions (`is`, `is=`, `is-not=`, `throws?`, `is-throws`, and `fail`).
12
+ - `cr test` discovers named tests with namespace, definition, name, and tag
13
+ filters, supports list/fail-fast/JSON modes, and uses conservative static
14
+ dependency analysis for `--affected` selection.
15
+ - Unscoped `cr test` stays project-local to the namespaces in the input
16
+ snapshot; core tests are run explicitly (including by CI) so external
17
+ projects do not execute `calcit.core` tests accidentally.
18
+ - Ordinary test execution preprocesses lazily, while `--affected` builds its
19
+ static candidate index once. This keeps fail-fast and normal runs from
20
+ compiling tests that will not execute.
21
+ - Migrated pure guards for collection, string, parsing, numeric, math, set,
22
+ destructuring, and update APIs into `calcit.core` definitions. Removed their
23
+ duplicate assertions from `calcit/test-*.cirru` while retaining method,
24
+ macro, type/preprocess, multi-definition, JavaScript, and WASM fixtures.
25
+ - CI and release workflows explicitly run the embedded core suite. A compact
26
+ JavaScript fixture remains for target-specific bitwise execution.
27
+ - Review fixes standardized whitespace/duplicate test-name validation,
28
+ preserved empty JSON report envelopes on selection errors, corrected built-in
29
+ `query tests` behavior and affected-test diagnostics, executed the
30
+ `test-comma` fixture, corrected `&map:diff-new` documentation, and removed
31
+ 25 duplicate or strict-subset attached tests. The final core suite contains
32
+ 166 tests.
33
+
34
+ ## Verification
35
+
36
+ - `yarn try-core-tests` (166 passed)
37
+ - `yarn try-rs` and `yarn try-js`
38
+ - `yarn check-all` (core, native, JavaScript, IR, WASM, and agent interface)
39
+ - `cargo fmt`, `cargo clippy -- -D warnings`, `cargo test`, `yarn compile`
40
+ - JSON test output remains one parseable report envelope.
41
+
42
+ The detailed per-commit notes were merged into this record; their exact text
43
+ remains recoverable from Git history.
@@ -0,0 +1,21 @@
1
+ # Migrate set, string, and number method tests
2
+
3
+ Move deterministic set, string, and number method assertions from the legacy
4
+ `calcit/test-*.cirru` fixtures to definition-attached tests in
5
+ `src/cirru/calcit-core.cirru`.
6
+
7
+ - Cover the internal set and string primitives at their implementation entries,
8
+ including Unicode character indexing and slicing.
9
+ - Add the remaining public numeric `empty` and `inc` checks at their definitions.
10
+ - Correct `&number:format` metadata to declare its required decimal-place
11
+ argument, which the migrated test made explicit.
12
+ - Delete the redundant `test-methods` blocks from the set, math, and string
13
+ fixtures. Keep a compact set method-dispatch smoke check plus the existing
14
+ target-specific, eval, formatting, Unicode, and WASM coverage.
15
+
16
+ Validation:
17
+
18
+ - `yarn try-core-tests` (210 passed)
19
+ - `target/debug/cr calcit/test-set.cirru`
20
+ - `target/debug/cr calcit/test-math.cirru`
21
+ - `target/debug/cr calcit/test-string.cirru`
@@ -0,0 +1,34 @@
1
+ # Improve cr edit accuracy and output
2
+
3
+ Recent definition-test migrations exposed three CLI failure modes worth fixing:
4
+
5
+ - Running a source `calcit-core.cirru` through an older `cr` binary silently
6
+ replaced its `calcit.core` namespace with the binary's embedded snapshot.
7
+ - Numeric tree paths could still point at a valid adjacent node, allowing a
8
+ delete or insertion to succeed at the wrong location.
9
+ - Tree mutations repeated the same before/after fragments, command echoes
10
+ included every inactive default, and the core suite printed hundreds of PASS
11
+ rows during the normal repository gate.
12
+
13
+ Changes:
14
+
15
+ - Preserve namespaces supplied by the input snapshot while filling only missing
16
+ core namespaces from the embedded snapshot.
17
+ - Add optional quoted-Cirru/JSON `--expect` guards to path-based replace,
18
+ delete, and insert operations. A mismatch fails before the snapshot is saved.
19
+ - Include non-default snapshot paths and all active test filters in command
20
+ echoes. Hide inactive/default options unless `--verbose` is requested.
21
+ - Remove duplicated tree insertion/deletion previews, honor `--depth`, and show
22
+ the actually modified container after child insertion. Run
23
+ `yarn try-core-tests` with `--summary-only`; summary mode also suppresses
24
+ program output from intentionally failing assertion tests.
25
+
26
+ Focused validation:
27
+
28
+ - Unit tests for exact/mismatched node guards and source-core precedence.
29
+ - A guarded deletion with the wrong expected node exited unsuccessfully and
30
+ preserved the temporary snapshot SHA-256.
31
+ - A temporary source core containing one extra test ran 211 tests while the
32
+ binary embedded 210, proving the source namespace won.
33
+ - `cargo fmt --check`, `cargo clippy -- -D warnings`, `cargo test`,
34
+ `yarn compile`, `yarn check-agent-interface`, and `yarn check-all` passed.
@@ -0,0 +1,21 @@
1
+ # Internal method and proc test migration
2
+
3
+ - Added 19 definition-attached `:unit :core` tests beside list and map method
4
+ implementations, including `&list:find-last`, `&list:find-last-index`,
5
+ `&list:map`, `&list:map-pair`, sorting, direct list primitives, map filters,
6
+ mapping, association, removal, emptiness, values, and pair conversion.
7
+ - Attached tests directly to Rust-backed core procs such as `&list:first`,
8
+ `&list:nth`, `&list:sort`, `&map:vals`, and `&map:to-list`. These tests verify
9
+ the proc contract in the core snapshot; backend-specific execution remains in
10
+ the JS/WASM fixtures.
11
+ - Removed the duplicated pure method assertion blocks from `calcit/test-list.cirru`
12
+ and `calcit/test-map.cirru`. Kept list shorthand method coverage and the
13
+ remaining method/type/backend integration fixtures.
14
+
15
+ Validation:
16
+
17
+ - `yarn try-core-tests` (186 passed)
18
+ - `yarn check-all` (core, native, JavaScript, IR, WASM, and agent interface)
19
+ - `cr calcit/test-list.cirru`, `cr calcit/test-map.cirru`, and
20
+ `cr calcit/test-string.cirru`
21
+ - `git diff --check`
@@ -0,0 +1,8 @@
1
+ # Review history terminology
2
+
3
+ - Corrected the retained definition-attached-test history to use the standard
4
+ spelling “built-in” when referring to the `query tests` behavior.
5
+
6
+ Validation:
7
+
8
+ - `git diff --check`
@@ -0,0 +1,8 @@
1
+ # Release 0.13.7
2
+
3
+ Released the merged definition-attached core test and `cr` CLI accuracy work.
4
+
5
+ - Bumped the Rust crate and npm package versions from `0.13.6` to `0.13.7`.
6
+ - Updated `Cargo.lock` with the workspace version through `cargo update --workspace`.
7
+ - Release validation covers the merged PR's core tests, native/JS/WASM targets,
8
+ Agent CLI interface, and the repository test workflow before tagging.
@@ -0,0 +1,23 @@
1
+ # Test runner selection and reporting guardrails
2
+
3
+ - Added `cr test --exclude-tag` so CI and agents can leave slow or integration
4
+ guards out of a focused run without weakening the default suite.
5
+ - Added `--require-match` to make an empty scoped/tagged/affected selection fail
6
+ instead of producing an accidental green result.
7
+ - Added `--summary-only` for compact large-suite output. JSON reports now state
8
+ `detail`, distinguish selected from executed tests, and include per-test
9
+ execution durations in full reports.
10
+ - Kept test execution native-only. JS/WASM checks remain dedicated fixtures;
11
+ an in-process timeout was intentionally not added because the interpreter
12
+ cannot safely cancel a running test thread.
13
+
14
+ Validation:
15
+
16
+ - `cargo fmt --check`
17
+ - `cargo clippy -- -D warnings`
18
+ - `cargo test`
19
+ - `yarn compile`
20
+ - `yarn check-agent-interface`
21
+ - `yarn check-all`
22
+ - JSON summary and empty-selection CLI smoke checks
23
+ - `git diff --check`
@@ -23,6 +23,7 @@ export declare const calcit_package_json: {
23
23
  "check-all": string;
24
24
  "check-agent-interface": string;
25
25
  "try-all": string;
26
+ "try-core-tests": string;
26
27
  "try-rs": string;
27
28
  "warn-dyn-method": string;
28
29
  "try-js-brk": string;
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.13.6",
3
+ "version": "0.13.7",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.7.0",
@@ -19,9 +19,10 @@
19
19
  "check-js-runtime": "node scripts/check-js-runtime-identity.mjs",
20
20
  "bench-recur-smoke": "cargo run --bin cr -- calcit/test.cirru js && node --input-type=module -e \"import { test_loop } from './js-out/test-recursion.main.mjs'; const n=3000; const t0=process.hrtime.bigint(); for(let i=0;i<n;i++) test_loop(); const dt=Number(process.hrtime.bigint()-t0)/1e6; console.log('test_loop_ms='+dt.toFixed(3));\"",
21
21
  "check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
22
- "check-all": "yarn compile && yarn check-js-runtime && yarn check-agent-interface && yarn try-rs && yarn try-js && yarn try-ir && yarn try-wasm",
22
+ "check-all": "yarn compile && yarn check-js-runtime && yarn check-agent-interface && yarn try-core-tests && yarn try-rs && yarn try-js && yarn try-ir && yarn try-wasm",
23
23
  "check-agent-interface": "cargo build --bin cr && node scripts/check-agent-interface.mjs",
24
24
  "try-all": "yarn check-all",
25
+ "try-core-tests": "cargo run --bin cr -- src/cirru/calcit-core.cirru test --tag unit --summary-only",
25
26
  "try-rs": "cargo run --bin cr -- calcit/test.cirru",
26
27
  "warn-dyn-method": "cargo run --bin cr -- calcit/test.cirru --warn-dyn-method",
27
28
  "try-js-brk": "cargo run --bin cr -- calcit/test.cirru js && node --inspect-brk js-out/main.mjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.13.6",
3
+ "version": "0.13.7",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.7.0",
@@ -19,9 +19,10 @@
19
19
  "check-js-runtime": "node scripts/check-js-runtime-identity.mjs",
20
20
  "bench-recur-smoke": "cargo run --bin cr -- calcit/test.cirru js && node --input-type=module -e \"import { test_loop } from './js-out/test-recursion.main.mjs'; const n=3000; const t0=process.hrtime.bigint(); for(let i=0;i<n;i++) test_loop(); const dt=Number(process.hrtime.bigint()-t0)/1e6; console.log('test_loop_ms='+dt.toFixed(3));\"",
21
21
  "check-smooth": "yarn fmt-rs && yarn lint-rs && yarn test-rs && yarn check-all",
22
- "check-all": "yarn compile && yarn check-js-runtime && yarn check-agent-interface && yarn try-rs && yarn try-js && yarn try-ir && yarn try-wasm",
22
+ "check-all": "yarn compile && yarn check-js-runtime && yarn check-agent-interface && yarn try-core-tests && yarn try-rs && yarn try-js && yarn try-ir && yarn try-wasm",
23
23
  "check-agent-interface": "cargo build --bin cr && node scripts/check-agent-interface.mjs",
24
24
  "try-all": "yarn check-all",
25
+ "try-core-tests": "cargo run --bin cr -- src/cirru/calcit-core.cirru test --tag unit --summary-only",
25
26
  "try-rs": "cargo run --bin cr -- calcit/test.cirru",
26
27
  "warn-dyn-method": "cargo run --bin cr -- calcit/test.cirru --warn-dyn-method",
27
28
  "try-js-brk": "cargo run --bin cr -- calcit/test.cirru js && node --inspect-brk js-out/main.mjs",