kumi 0.0.29 → 0.0.30
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +12 -0
- data/README.md +5 -6
- data/docs/DEVELOPMENT.md +23 -1
- data/docs/GOLDEN_QUICK_START.md +141 -0
- data/docs/GOLDEN_TESTS.md +240 -0
- data/golden/array_element/expected/schema_ruby.rb +1 -1
- data/golden/array_index/expected/schema_ruby.rb +1 -1
- data/golden/array_operations/expected/schema_ruby.rb +1 -1
- data/golden/cascade_logic/expected/schema_ruby.rb +1 -1
- data/golden/chained_fusion/expected/schema_ruby.rb +1 -1
- data/golden/decimal_explicit/expected/schema_ruby.rb +1 -1
- data/golden/element_arrays/expected/schema_ruby.rb +1 -1
- data/golden/empty_and_null_inputs/expected/schema_ruby.rb +1 -1
- data/golden/function_overload/expected/schema_ruby.rb +1 -1
- data/golden/game_of_life/expected/schema_ruby.rb +1 -1
- data/golden/hash_keys/expected/schema_ruby.rb +1 -1
- data/golden/hash_value/expected/schema_ruby.rb +1 -1
- data/golden/hierarchical_complex/expected/schema_ruby.rb +1 -1
- data/golden/inline_rename_scope_leak/expected/schema_ruby.rb +1 -1
- data/golden/input_reference/expected/schema_ruby.rb +1 -1
- data/golden/interleaved_fusion/expected/schema_ruby.rb +1 -1
- data/golden/let_inline/expected/schema_ruby.rb +1 -1
- data/golden/loop_fusion/expected/schema_ruby.rb +1 -1
- data/golden/min_reduce_scope/expected/schema_ruby.rb +1 -1
- data/golden/mixed_dimensions/expected/schema_ruby.rb +1 -1
- data/golden/multirank_hoisting/expected/schema_ruby.rb +1 -1
- data/golden/nested_hash/expected/schema_ruby.rb +1 -1
- data/golden/reduction_broadcast/expected/schema_ruby.rb +1 -1
- data/golden/roll/expected/schema_ruby.rb +1 -1
- data/golden/shift/expected/schema_ruby.rb +1 -1
- data/golden/shift_2d/expected/schema_ruby.rb +1 -1
- data/golden/simple_math/expected/schema_ruby.rb +1 -1
- data/golden/streaming_basics/expected/schema_ruby.rb +1 -1
- data/golden/tuples/expected/schema_ruby.rb +1 -1
- data/golden/tuples_and_arrays/expected/schema_ruby.rb +1 -1
- data/golden/us_tax_2024/expected/schema_ruby.rb +1 -1
- data/golden/with_constants/expected/schema_ruby.rb +1 -1
- data/lib/kumi/analyzer.rb +39 -79
- data/lib/kumi/core/analyzer/analysis_state.rb +2 -0
- data/lib/kumi/core/analyzer/constant_evaluator.rb +0 -2
- data/lib/kumi/core/analyzer/execution_phase.rb +24 -0
- data/lib/kumi/core/analyzer/execution_result.rb +38 -0
- data/lib/kumi/core/analyzer/pass_failure.rb +26 -0
- data/lib/kumi/core/analyzer/pass_manager.rb +136 -0
- data/lib/kumi/core/analyzer/passes/codegen/js/declaration_emitter.rb +1 -1
- data/lib/kumi/core/analyzer/passes/codegen/js_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/codegen/ruby/declaration_emitter.rb +1 -1
- data/lib/kumi/core/analyzer/passes/codegen/ruby_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/constant_folding_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/formal_constraint_propagator.rb +13 -31
- data/lib/kumi/core/analyzer/passes/input_access_planner_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/input_collector.rb +1 -1
- data/lib/kumi/core/analyzer/passes/input_form_schema_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/lir/loop_invariant_code_motion_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/lir/stencil_emitter.rb +0 -2
- data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +5 -1
- data/lib/kumi/core/analyzer/passes/output_schema_pass.rb +2 -1
- data/lib/kumi/core/analyzer/passes/snast_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/unsat_detector.rb +8 -10
- data/lib/kumi/core/compiler/access_planner_v2.rb +1 -2
- data/lib/kumi/core/functions/overload_resolver.rb +15 -19
- data/lib/kumi/core/functions/type_categories.rb +3 -3
- data/lib/kumi/core/functions/type_error_reporter.rb +1 -3
- data/lib/kumi/core/input/type_matcher.rb +1 -1
- data/lib/kumi/core/types/normalizer.rb +8 -10
- data/lib/kumi/core/types/validator.rb +1 -1
- data/lib/kumi/core/types/value_objects.rb +5 -2
- data/lib/kumi/core/types.rb +2 -4
- data/lib/kumi/dev/codegen.rb +1 -1
- data/lib/kumi/dev/golden/generator.rb +14 -10
- data/lib/kumi/dev/golden/reporter.rb +5 -5
- data/lib/kumi/dev/golden/representation.rb +1 -3
- data/lib/kumi/dev/golden/result.rb +1 -1
- data/lib/kumi/dev/golden/runtime_test.rb +0 -2
- data/lib/kumi/dev/golden/suite.rb +20 -4
- data/lib/kumi/dev/golden/value_normalizer.rb +1 -3
- data/lib/kumi/doc_generator/formatters/json.rb +11 -11
- data/lib/kumi/doc_generator/formatters/markdown.rb +35 -37
- data/lib/kumi/doc_generator/loader.rb +8 -6
- data/lib/kumi/doc_generator/merger.rb +12 -12
- data/lib/kumi/frontends/text.rb +4 -6
- data/lib/kumi/registry_v2/loader.rb +32 -33
- data/lib/kumi/schema.rb +2 -2
- data/lib/kumi/version.rb +1 -1
- metadata +13 -14
- data/debug_ordering.rb +0 -52
- data/examples/deep_schema_compilation_and_evaluation_benchmark.rb +0 -106
- data/examples/federal_tax_calculator_2024.rb +0 -115
- data/examples/game_of_life.rb +0 -95
- data/examples/simple_rpg_game.rb +0 -1000
- data/examples/static_analysis_errors.rb +0 -178
- data/examples/wide_schema_compilation_and_evaluation_benchmark.rb +0 -80
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 503db021324e5fd3b8dde90f06b95e3d332aefdfbad751aa98d66cd960199b79
|
|
4
|
+
data.tar.gz: 80a6d8331e8547c5fbdbcec66f6465a0862c32af24a17f836a45e5d9ee6f6d8d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 72a2a409eee0c8dae3209a78d08d76dcddccf0f00d766a50ab26d2286ca33226e6470f75f4b74e91053e90c8c03cb44672db74d842f48bd3fa7287cdbea575f1
|
|
7
|
+
data.tar.gz: c6351443907aae95822e4d89c7710a65a6e4f58657029d67e544e943f7693efbbaac394b5a1cda261ab5b4881a925fdbb7b0fc76bc41d1aae69fc3842d3bed38
|
data/.rubocop.yml
CHANGED
|
@@ -7,12 +7,13 @@ AllCops:
|
|
|
7
7
|
TargetRubyVersion: 3.1
|
|
8
8
|
SuggestExtensions: false
|
|
9
9
|
Exclude:
|
|
10
|
-
- 'bin/*'
|
|
10
|
+
- 'bin/*'
|
|
11
11
|
- 'spec/fixtures/**/*'
|
|
12
12
|
- 'examples/**/*' # Examples may use deprecated syntax
|
|
13
13
|
- '*.txt'
|
|
14
14
|
- 'test_*.rb' # Temporary test files
|
|
15
15
|
- 'spec/integration/performance_spec.rb'
|
|
16
|
+
- 'golden/**/*' # Golden test files are generated/expected outputs
|
|
16
17
|
|
|
17
18
|
# Common stylistic choices
|
|
18
19
|
Style/StringLiterals:
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
|
+
## [0.0.30] – 2025-10-21
|
|
3
|
+
### Changed
|
|
4
|
+
- **Analyzer Refactoring:** PassManager now centralizes pass orchestration, replacing manual orchestration in Analyzer.run_analysis_passes
|
|
5
|
+
- Removed unused API surface: batch_update, .phases, with_phase, recoverable, phase_id methods
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- ExecutionPhase, ExecutionResult, PassFailure for structured pass execution metadata
|
|
9
|
+
- PassManager handles checkpoint integration, debug logging, profiling, and error handling
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- PassManager error handling now returns failures instead of raising, allowing proper error threshold checks
|
|
13
|
+
|
|
2
14
|
## [0.0.29] – 2025-10-21
|
|
3
15
|
### Changed
|
|
4
16
|
- Tests and development cleanup
|
data/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/amuta/kumi/actions)
|
|
4
4
|
[](https://badge.fury.io/rb/kumi)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
6
|
|
|
6
7
|
**[Try the interactive demo →](https://kumi-play-web.fly.dev/)**
|
|
7
8
|
|
|
@@ -158,14 +159,12 @@ Try the [interactive demo](https://kumi-play-web.fly.dev/) (no setup required).
|
|
|
158
159
|
|
|
159
160
|
## Documentation
|
|
160
161
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
- **[Functions Reference](docs/FUNCTIONS.md)** - Human-readable docs with parameters and kernels
|
|
162
|
+
- **[Syntax Reference](docs/SYNTAX.md)** - DSL syntax, types, operators, and functions
|
|
163
|
+
- **[Functions Reference](docs/FUNCTIONS.md)** - Auto-generated docs for all functions and kernels
|
|
164
164
|
- **[functions-reference.json](docs/functions-reference.json)** - Machine-readable format for IDEs (VSCode, Monaco, etc.)
|
|
165
|
+
- **[Development Guide](docs/DEVELOPMENT.md)** - Testing, debugging, and contributing
|
|
165
166
|
|
|
166
|
-
To regenerate: `bin/kumi-doc-gen`
|
|
167
|
-
|
|
168
|
-
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for development workflows.
|
|
167
|
+
To regenerate function docs: `bin/kumi-doc-gen`
|
|
169
168
|
|
|
170
169
|
---
|
|
171
170
|
|
data/docs/DEVELOPMENT.md
CHANGED
|
@@ -57,6 +57,28 @@ The extension reads from `docs/functions-reference.json`, so always regenerate d
|
|
|
57
57
|
bin/kumi-doc-gen
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
## Testing: Golden Tests
|
|
61
|
+
|
|
62
|
+
Kumi uses "golden tests" to verify correct behavior across all compilation stages. Each golden test captures:
|
|
63
|
+
- Schema definition (schema.kumi)
|
|
64
|
+
- Sample input (input.json)
|
|
65
|
+
- Expected output (expected.json)
|
|
66
|
+
- Expected intermediate representations (expected/ directory)
|
|
67
|
+
|
|
68
|
+
See [GOLDEN_TESTS.md](GOLDEN_TESTS.md) for a comprehensive guide to:
|
|
69
|
+
- Creating new golden tests
|
|
70
|
+
- Understanding test structure
|
|
71
|
+
- Verifying tests pass
|
|
72
|
+
- Common patterns and best practices
|
|
73
|
+
|
|
74
|
+
Quick start:
|
|
75
|
+
```bash
|
|
76
|
+
bin/kumi golden list # See all tests
|
|
77
|
+
bin/kumi golden test EXAMPLE # Run specific test
|
|
78
|
+
bin/kumi golden test # Run all tests
|
|
79
|
+
bin/kumi golden update EXAMPLE # Regenerate expected files
|
|
80
|
+
```
|
|
81
|
+
|
|
60
82
|
---
|
|
61
83
|
|
|
62
|
-
*
|
|
84
|
+
*For more development documentation, see the other guides in this directory.*
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Golden Tests: Quick Start
|
|
2
|
+
|
|
3
|
+
## 30-Second Summary
|
|
4
|
+
|
|
5
|
+
A golden test verifies that a Kumi schema compiles correctly and produces expected output.
|
|
6
|
+
|
|
7
|
+
**Structure:**
|
|
8
|
+
```
|
|
9
|
+
golden/my_test/
|
|
10
|
+
├── schema.kumi # Your schema
|
|
11
|
+
├── input.json # Test input
|
|
12
|
+
├── expected.json # Expected output
|
|
13
|
+
└── expected/ # Generated intermediate files (auto-created)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Workflow:**
|
|
17
|
+
```bash
|
|
18
|
+
# 1. Create files
|
|
19
|
+
mkdir -p golden/my_test
|
|
20
|
+
# Write schema.kumi, input.json, expected.json
|
|
21
|
+
|
|
22
|
+
# 2. Generate expected outputs
|
|
23
|
+
bin/kumi golden update my_test
|
|
24
|
+
|
|
25
|
+
# 3. Test it
|
|
26
|
+
bin/kumi golden test my_test
|
|
27
|
+
|
|
28
|
+
# 4. Done!
|
|
29
|
+
git add golden/my_test/
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Common Commands
|
|
33
|
+
|
|
34
|
+
| What | Command |
|
|
35
|
+
|------|---------|
|
|
36
|
+
| List all tests | `bin/kumi golden list` |
|
|
37
|
+
| Run one test | `bin/kumi golden test test_name` |
|
|
38
|
+
| Run all tests | `bin/kumi golden test` |
|
|
39
|
+
| Generate expected files | `bin/kumi golden update test_name` |
|
|
40
|
+
| See what changed | `bin/kumi golden diff test_name` |
|
|
41
|
+
|
|
42
|
+
## File Templates
|
|
43
|
+
|
|
44
|
+
### schema.kumi
|
|
45
|
+
```ruby
|
|
46
|
+
schema do
|
|
47
|
+
input do
|
|
48
|
+
# Define input fields
|
|
49
|
+
integer :age
|
|
50
|
+
float :salary
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Define outputs
|
|
54
|
+
value :result, input.age * 2
|
|
55
|
+
end
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### input.json
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"age": 30,
|
|
62
|
+
"salary": 50000.0
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### expected.json
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"result": 60
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Example: Age Eligibility Test
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# 1. Create directory
|
|
77
|
+
mkdir -p golden/age_eligibility
|
|
78
|
+
|
|
79
|
+
# 2. Create schema.kumi
|
|
80
|
+
cat > golden/age_eligibility/schema.kumi << 'EOF'
|
|
81
|
+
schema do
|
|
82
|
+
input do
|
|
83
|
+
integer :age
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
value :can_vote, input.age >= 18
|
|
87
|
+
value :can_drink, input.age >= 21
|
|
88
|
+
value :senior, input.age >= 65
|
|
89
|
+
end
|
|
90
|
+
EOF
|
|
91
|
+
|
|
92
|
+
# 3. Create input.json
|
|
93
|
+
cat > golden/age_eligibility/input.json << 'EOF'
|
|
94
|
+
{
|
|
95
|
+
"age": 25
|
|
96
|
+
}
|
|
97
|
+
EOF
|
|
98
|
+
|
|
99
|
+
# 4. Create expected.json
|
|
100
|
+
cat > golden/age_eligibility/expected.json << 'EOF'
|
|
101
|
+
{
|
|
102
|
+
"can_vote": true,
|
|
103
|
+
"can_drink": true,
|
|
104
|
+
"senior": false
|
|
105
|
+
}
|
|
106
|
+
EOF
|
|
107
|
+
|
|
108
|
+
# 5. Generate expected representations
|
|
109
|
+
bin/kumi golden update age_eligibility
|
|
110
|
+
|
|
111
|
+
# 6. Test
|
|
112
|
+
bin/kumi golden test age_eligibility
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Expected output:
|
|
116
|
+
```
|
|
117
|
+
✓ age_eligibility: PASS
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Tips
|
|
121
|
+
|
|
122
|
+
1. **Keep it simple** - One feature per test
|
|
123
|
+
2. **Use round numbers** - Makes verification easier (25, 100, 50.0)
|
|
124
|
+
3. **Check generated code** - Review `expected/schema_ruby.rb`
|
|
125
|
+
4. **Test edge cases** - Null, zero, negative values
|
|
126
|
+
5. **Write clear names** - `cascade_logic`, `array_operations`, not `test1`
|
|
127
|
+
|
|
128
|
+
## Common Issues
|
|
129
|
+
|
|
130
|
+
| Issue | Solution |
|
|
131
|
+
|-------|----------|
|
|
132
|
+
| "Output doesn't match" | Verify expected.json calculation by hand |
|
|
133
|
+
| "Schema fails to compile" | Check schema.kumi syntax |
|
|
134
|
+
| "File not found" | Make sure you're in `golden/` directory |
|
|
135
|
+
| "No such subcommand" | Use `bin/kumi golden test` not `bin/kumi verify` |
|
|
136
|
+
|
|
137
|
+
## Next Steps
|
|
138
|
+
|
|
139
|
+
- Read [GOLDEN_TESTS.md](GOLDEN_TESTS.md) for detailed guide
|
|
140
|
+
- Check existing tests: `ls golden/`
|
|
141
|
+
- Create your first test!
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Golden Tests Guide
|
|
2
|
+
|
|
3
|
+
Golden tests verify schema compilation and execution correctness across all stages: parsing → code generation → execution.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
A golden test contains:
|
|
8
|
+
- **schema.kumi** - Schema under test
|
|
9
|
+
- **input.json** - Test input data
|
|
10
|
+
- **expected.json** - Expected execution output
|
|
11
|
+
- **expected/** - Generated intermediate representations (AST, NAST, SNAST, LIR, codegen)
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
golden/my_test/
|
|
15
|
+
├── schema.kumi
|
|
16
|
+
├── input.json
|
|
17
|
+
├── expected.json
|
|
18
|
+
└── expected/
|
|
19
|
+
├── ast.txt
|
|
20
|
+
├── nast.txt
|
|
21
|
+
├── snast.txt
|
|
22
|
+
├── schema_ruby.rb
|
|
23
|
+
├── schema_javascript.mjs
|
|
24
|
+
└── lir_*.txt
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Creating a Golden Test
|
|
28
|
+
|
|
29
|
+
### Step 1: Plan
|
|
30
|
+
What feature? Complexity level? Edge cases?
|
|
31
|
+
|
|
32
|
+
### Step 2: Create directory
|
|
33
|
+
```bash
|
|
34
|
+
mkdir -p golden/my_test
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Step 3: Write schema.kumi
|
|
38
|
+
```ruby
|
|
39
|
+
schema do
|
|
40
|
+
input do
|
|
41
|
+
integer :age
|
|
42
|
+
float :salary
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
value :adjusted, input.salary * 1.05
|
|
46
|
+
end
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Keep schemas focused on one feature (10-30 lines).
|
|
50
|
+
|
|
51
|
+
### Step 4: Create input.json
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"age": 30,
|
|
55
|
+
"salary": 100000.0
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Use realistic, round numbers for easy verification.
|
|
60
|
+
|
|
61
|
+
### Step 5: Create expected.json
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"adjusted": 105000.0
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Calculate by hand first. Verify math.
|
|
69
|
+
|
|
70
|
+
### Step 6: Generate representations
|
|
71
|
+
```bash
|
|
72
|
+
bin/kumi golden update my_test
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This creates `expected/` with all intermediate files.
|
|
76
|
+
|
|
77
|
+
### Step 7: Test
|
|
78
|
+
```bash
|
|
79
|
+
bin/kumi golden test my_test
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Expected: `✓ my_test: PASS`
|
|
83
|
+
|
|
84
|
+
## Commands
|
|
85
|
+
|
|
86
|
+
| Command | Purpose |
|
|
87
|
+
|---------|---------|
|
|
88
|
+
| `bin/kumi golden list` | List all tests |
|
|
89
|
+
| `bin/kumi golden update [name]` | Generate expected files |
|
|
90
|
+
| `bin/kumi golden test [name]` | Run test |
|
|
91
|
+
| `bin/kumi golden diff [name]` | See changes |
|
|
92
|
+
|
|
93
|
+
Use multiple names: `bin/kumi golden test test1 test2`
|
|
94
|
+
|
|
95
|
+
## Common Issues
|
|
96
|
+
|
|
97
|
+
**"Output doesn't match"**
|
|
98
|
+
- Recalculate expected.json by hand
|
|
99
|
+
- Check input.json values
|
|
100
|
+
- Regenerate: `bin/kumi golden update my_test`
|
|
101
|
+
|
|
102
|
+
**"Schema fails to compile"**
|
|
103
|
+
```bash
|
|
104
|
+
bin/kumi analyze golden/my_test/schema.kumi
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**"Generated code is wrong"**
|
|
108
|
+
```bash
|
|
109
|
+
cat golden/my_test/expected/schema_ruby.rb
|
|
110
|
+
cat golden/my_test/expected/lir_00_unoptimized.txt
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Patterns
|
|
114
|
+
|
|
115
|
+
### Array Vectorization
|
|
116
|
+
When testing operations on arrays with multiple dimensions:
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
schema do
|
|
120
|
+
input do
|
|
121
|
+
people: [{name: string, salary: float}]
|
|
122
|
+
department: string
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
let total = fn(:sum, input.people.salary)
|
|
126
|
+
value avg, total / fn(:size, input.people)
|
|
127
|
+
end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Cascade Logic
|
|
131
|
+
```ruby
|
|
132
|
+
schema do
|
|
133
|
+
input { age: integer }
|
|
134
|
+
|
|
135
|
+
value category,
|
|
136
|
+
on input.age < 18 do
|
|
137
|
+
"youth"
|
|
138
|
+
on input.age < 65 do
|
|
139
|
+
"adult"
|
|
140
|
+
base
|
|
141
|
+
"senior"
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Error Handling
|
|
146
|
+
Schema compilation errors are caught at compile time:
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
schema do
|
|
150
|
+
input { age: integer }
|
|
151
|
+
value invalid, unknown_function(input.age)
|
|
152
|
+
end
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Result: `✗ invalid_function: SKIP (Compilation Error)`
|
|
156
|
+
|
|
157
|
+
## Best Practices
|
|
158
|
+
|
|
159
|
+
1. **Test one feature per schema** - Keep it focused
|
|
160
|
+
2. **Use descriptive names** - `cascade_logic`, not `test1`
|
|
161
|
+
3. **Round numbers** - Easier to verify by hand
|
|
162
|
+
4. **Review generated code** - Check `expected/schema_ruby.rb`
|
|
163
|
+
5. **Test edge cases** - Null, zero, negative values
|
|
164
|
+
6. **Commit to git** - Track all files including `expected/`
|
|
165
|
+
|
|
166
|
+
## Maintenance
|
|
167
|
+
|
|
168
|
+
### Update Expected Files
|
|
169
|
+
|
|
170
|
+
When behavior changes intentionally:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
bin/kumi golden update my_test
|
|
174
|
+
git diff golden/my_test/expected/
|
|
175
|
+
# Review changes
|
|
176
|
+
git add golden/my_test/expected/
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### View Differences
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
bin/kumi golden diff my_test
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Shows side-by-side comparison of what changed.
|
|
186
|
+
|
|
187
|
+
## Example: Complete Workflow
|
|
188
|
+
|
|
189
|
+
Create `golden/eligibility/`:
|
|
190
|
+
|
|
191
|
+
**schema.kumi:**
|
|
192
|
+
```ruby
|
|
193
|
+
schema do
|
|
194
|
+
input do
|
|
195
|
+
integer :age
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
value :can_vote, input.age >= 18
|
|
199
|
+
value :can_drink, input.age >= 21
|
|
200
|
+
end
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**input.json:**
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"age": 25
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**expected.json:**
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"can_vote": true,
|
|
214
|
+
"can_drink": true
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Generate and test:**
|
|
219
|
+
```bash
|
|
220
|
+
bin/kumi golden update eligibility
|
|
221
|
+
bin/kumi golden test eligibility
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Result: `✓ eligibility: PASS`
|
|
225
|
+
|
|
226
|
+
## Quick Troubleshooting
|
|
227
|
+
|
|
228
|
+
| Issue | Fix |
|
|
229
|
+
|-------|-----|
|
|
230
|
+
| "File not found" | Make sure you're in `golden/` directory |
|
|
231
|
+
| "Floating point mismatch" | Check precision in input/expected |
|
|
232
|
+
| "Test passes locally but fails in CI" | Look for non-deterministic IR generation |
|
|
233
|
+
|
|
234
|
+
## Next Steps
|
|
235
|
+
|
|
236
|
+
1. List existing tests: `bin/kumi golden list`
|
|
237
|
+
2. Review a simple one: `cat golden/simple_math/`
|
|
238
|
+
3. Create your first test following this guide
|
|
239
|
+
4. Verify it passes
|
|
240
|
+
5. Review generated code to understand compilation
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_725efd5a4f23c00477d27b4ef387748badd6021792c93c954293b9f0e515a72a
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_db1e731032ea8c98ca0f2b4ae89d1cc32aeb5742ca64d0876db405d2fa8b8629
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_3d1e29e6240c3a8d445c4a817207b8947c3d74f3a25c3d18b9c7987471e50734
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_a155a3c0e8dcb44547c931f4e510de1217a1044900d52385389bed8b6e5adaf4
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_849092b69396f8ec3e0f0deef2a98c2ace6d934d94bac9cc887bf0cbc2399dbe
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_ae7ebcf0b663c16925a03a4c159b8dc50e8a35bbce4c7e8b4f67104d1072ee5f
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_401fa074a7fd129c705cf2357bd65dfaa8cff4ab7955a9a23d7ec19e8901c532
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_80c4084bbdeb901911f5e3b0a931bdf8170ef074f23c693b9d337c8dd60f818d
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_efbcaa6076c66e32f6a3a9bdf152fdc9d800cdcae64dd7dde617584a1b9843ef
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_da8a14f5173aeacc57a51c4ce575639861c36278e0af1886b5340976ef99de82
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_df570c0a7440e6c42f61808ead694fc643f737a548b2afb9b78c280e8df472ea
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_20851df9e37717955d2f6618a6c66f18be4297a15b09489940b557582645f688
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_8ec94ceea868d100e7236c5727a53dd266057cbfa5edb5c01dfc526cb7ba2ac3
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_e896af406023cdb9bef06f70f0dd300b87ca6f23151bc9f9f5b6fabb97cb8505
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_e5a63c0ea318c059da2823266d32fe23fa0da1f4b7a7ea14ee37ceb768ad0041
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_4323eb829f35622b045d2fd46bf95a877a7a4caa6feea5cfb6943797c4a90ff6
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_1ccdbe0762a298109d4f44718d2c4c7ff3c0f1c418f4e6e04956c0fd9bbcd33c
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_be7f942a1922a7234acbdd6dfbe63e3125a7ea18ddada895403ff01255602976
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_cf23e8e7c8d8426eee61228bb8e1cf1452d26d65d0c304f0341a1b3b3b8c9d87
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_cdffe121fdc762472c12af1078546c29f5339df58b3d1ed602ab70fccbc9a430
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_38e52950a42d13f281d275be711f674d914feaf059f72c64a582b8de5c8f192c
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_968c950e9550ea6866e905fc32ac2ae9aee50f3d8316a0580fb2ed0efb31b47b
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
|
2
|
-
module Kumi::Compiled::
|
|
2
|
+
module Kumi::Compiled::KUMI_4d7e7d13cea88587529ab5ca02b7786b61419b3ed17afe69d36b2d1947311324
|
|
3
3
|
def self.from(input_data = nil)
|
|
4
4
|
instance = Object.new
|
|
5
5
|
instance.extend(self)
|