refactor(scalars): generalize the test harness (catalog-driven shape, temporal_values!, unified scalar_matrix!)#261
Conversation
…p [temporal] marker
…a is_eq_only_token The ordered_numeric_matrix! suite exercises </>/min/max; an equality-only scalar (no _ord domain in eql-scalars::CATALOG) does not support those. Route the matrix emitter through matrix_suite_for_entry, which reads eq-only-ness from the catalog (is_eq_only_token) and emits a compile_error! for an eq-only token instead of silently generating ordering tests it cannot pass. Makes the catalog-derived is_eq_only accessor load-bearing and leaves a clean seam for an equality-only matrix path. Both arms unit-tested.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… ord]) Single entry point selected by a capability marker, replacing the two parallel wrappers. caps = [eq, ord] is the ordered-numeric body (verbatim from ordered_numeric_matrix!); caps = [eq] is the equality-only body with pivots derived from the ScalarType impl (min/max/Default), matching the proven timestamptz-era eq-only form so the eq-only name set stays a clean subset of the ordered snapshot. Old wrappers still present; removed next.
…rappers The matrix-suite emitter now routes every type through scalar_matrix! with a caps marker derived from the catalog (is_eq_only_token): ordered types get caps = [eq, ord], equality-only types caps = [eq]. This replaces the prior ordered-only emission + eq-only compile_error! seam with a real eq-only path, and deletes ordered_numeric_matrix! / eq_only_scalar_matrix! from matrix.rs. Generated test names are byte-identical (inventory OK, 4 types match the canonical snapshot) and the scalar matrix is green at the baseline (844 passed, 0 failed). release/*.sql unchanged. Doc comments naming the old wrappers updated to scalar_matrix!.
Each discovered scalar type now matches EITHER the full canonical snapshot (ordered shape) OR a subset derived from it on the fly — the ordered names minus the ord-only lines (_ord / order_by / routes_through_ob). An equality-only scalar (timestamptz, next) is validated against that derivation, so it needs no second committed snapshot. The per-type shape (ordered/eq_only) is now printed. All four current types are ordered; the eq-only branch is dormant but unit-proven (51-line strict subset of the 211-line baseline).
Document that there is ONE committed snapshot (the ordered shape) and that equality-only types are validated against a subset derived from it on the fly (baseline minus _ord/order_by/routes_through_ob), so an eq-only scalar needs no second snapshot. Update the stale ordered_numeric_matrix! references to scalar_matrix! and describe the printed per-type shape.
There was a problem hiding this comment.
Pull request overview
This PR refactors the SQLx encrypted-domain scalar test harness so scalar “shape” (temporal vs non-temporal, ordered vs equality-only) is derived from eql-scalars::CATALOG, eliminating per-type shape markers and consolidating matrix generation behind a single scalar_matrix! wrapper.
Changes:
- Removed
[temporal]dispatch markers from the scalar harness list; temporal / eq-only classification now comes from catalog helpers (ScalarKind::is_temporal,ScalarSpec::is_eq_only). - Introduced
temporal_values!in the SQLx harness to generate chrono-backed scalar wiring (fixtures parsing +ScalarTypeimpl + invariants). - Unified the matrix wrapper macros into
scalar_matrix! { caps = [...] }and updated snapshot inventory tooling/docs to validate eq-only types via a derived subset from the single canonical snapshot.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/sqlx/tests/encrypted_domain/scalars/mod.rs | Updates generated-suite docs to reference scalar_matrix!. |
| tests/sqlx/src/scalar_types.rs | Removes temporal marker usage and documents catalog-driven shape. |
| tests/sqlx/src/scalar_domains.rs | Adds temporal_values! macro and migrates date wiring to it. |
| tests/sqlx/src/matrix.rs | Replaces dual wrappers with unified scalar_matrix! using caps = [eq] vs [eq, ord]. |
| tests/sqlx/snapshots/README.md | Documents single snapshot + derived eq-only subset approach. |
| mise.toml | Updates matrix inventory task to accept either ordered baseline or derived eq-only subset. |
| crates/eql-tests-macros/src/lib.rs | Removes marker parsing; consults eql-scalars::CATALOG to derive temporal/eq-only and emit scalar_matrix! with caps. |
| crates/eql-tests-macros/Cargo.toml | Adds eql-scalars dependency for catalog-driven emission. |
| crates/eql-scalars/src/lib.rs | Adds ScalarKind::is_temporal and ScalarSpec::is_eq_only helpers + tests. |
| Cargo.lock | Records the new eql-tests-macros -> eql-scalars dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if cmp -s "/tmp/matrix-norm-${t}.txt" snapshots/matrix_tests.txt; then | ||
| shape="ordered" | ||
| elif [ "$(cat "/tmp/matrix-norm-${t}.txt")" = "$eq_only_expected" ]; then | ||
| shape="eq_only" |
The eq-only inventory check captured the derived subset into a shell variable and compared with [ string equality, which strips trailing newlines on capture and forced the failure diff to reconstruct the string via printf. Materialise the subset to a file so both shapes compare through the same cmp/diff path as the ordered snapshot.
refactor(scalars): generalize the test harness (catalog-driven shape, temporal_values!, unified scalar_matrix!)
What
Generalize the scalar test harness so a type's shape — temporal vs integer, ordered vs equality-only — is catalog-driven, not hand-declared. Adding a scalar drops from ~hundreds of lines to ~one catalog row.
Four levers
1. Catalog is the source of truth — drop the
[temporal]/[eq_only]dispatch markers; shape is read fromeql-scalars::CATALOG.scalar_types! { int4 => i32, - date => chrono::NaiveDate [temporal], + date => chrono::NaiveDate, }2.
temporal_values!— one macro generates a chrono-backed scalar'sScalarTypewiring, so the next temporal type is a one-liner.3. Unified
scalar_matrix!— one wrapper replacesordered_numeric_matrix!+eq_only_scalar_matrix!, selected by acapsmarker the emitter derives from the catalog.4. Single snapshot — the inventory derives the eq-only name set from the one ordered baseline (
matrix_tests.txtminus_ord/order_by/routes_through_ob); no second committed file.Verification
cargo test -p eql-scalars -p eql-tests-macros→ 40 + 13 greenclean && build→release/*.sqlunchanged (harness/metadata-only)Test-harness-only; no CHANGELOG entry. The payoff is #257 (timestamptz), which rebases on top and collapses from +671 to +259.
Summary by CodeRabbit
Refactor
Tests