Conversation
🎯 Action Plan: PR #186 – Add testsDate: 2025-12-09 📋 OverviewIssue Summary (#185)
PR Summary (#186)
Status: Needs work – PR is a skeleton; all testing work still to be implemented on 🎯 Gap Analysis✅ Completed Requirements (relative to #185)
❌ Missing Requirements (core for this PR)Everything described below is not yet implemented in the PR and forms the basis of the action plan:
➕ Additional Work Done
🧪 Test StatusOverall for PR #186: Existing Test Structure (from
Current coverage (before
The PR must add to this by creating 📝 Review Feedback
🔧 Code Quality AssessmentFor PR #186 itself:
The quality assessment and recommendations below are therefore prospective: they describe how tests should be written, not how they are currently written in this PR. 📋 Proposed Action Plan🔴 Critical Priority (blocking merge)
🟡 High Priority (should do before merge)
🟢 Medium Priority (nice to have before or shortly after merge)
🔵 Low Priority (can be deferred)
✅ Summary
Once confirmed, this plan can be implemented incrementally on branch |
Tests added in the
|
| File | Tests | Description |
|---|---|---|
test_utils_bis.jl |
59 | Expression manipulation utilities |
test_prefix_bis.jl |
42 | Backend/prefix management |
test_onepass_fun_bis.jl |
110 | :fun parsing backend (CTModels) |
test_onepass_exa_bis.jl |
123 | :exa parsing backend (ExaModels) |
test_utils_bis.jl (59 tests)
Additional tests for functions in src/utils.jl:
Expression substitution (subs, subs2-5)
- Literal replacement (numbers → symbols)
- Replacement of nested expressions (
g(x)→:h) - Multiple substitutions within the same expression
- Deep nesting (5+ levels)
- Pathological cases: symbol not present, expression unchanged
Call replacement (replace_call)
- Non-matching calls (wrong time symbol)
- Partial replacement (one of several symbols)
- Vector form with missing symbols
- Error: assertion on vector length mismatch
Membership checks (has)
- 2-argument form (symbol, time): symbol present but with wrong time
- Deeply nested symbols
- Full-expression matching
- Identity on symbols and numbers
Concatenation (concat)
- Two simple expressions → block
- Block + non-block and the reverse
- Blocks containing only
LineNumberNodes
AST traversal (expr_it)
- Identity transformation
- Leaf-only transformation
- Head/args transformation (wrapping calls)
Constraint classification (constraint_type)
- Mixed state/control expressions
- Variable with time argument →
variable_fun - Control evaluated only at t0/tf →
:other - Boundary cases: initial + final state
- Step ranges (
v[1:2:7])
test_prefix_bis.jl (42 tests)
Tests for backend and prefix management in src/onepass.jl and src/defaults.jl:
Backend activation/deactivation
- Full cycle: deactivate → check → activate → check
- Errors: unknown backend, attempts to (de)activate
:fun - Idempotence: repeated activations/deactivations
- Isolation:
:funis never affected by toggling:exa
Prefix setters (prefix_fun!, prefix_exa!, e_prefix!)
- Update and restore prefix values
- Pathological but valid values:
:_,Symbol("with-dash"),Symbol("with.dot")
Default values (defaults.jl)
- Check all
__default_*helpers:__default_parsing_backend()→:fun__default_scheme_exa()→:midpoint__default_grid_size_exa()→250__default_backend_exa()→nothing__default_init_exa()→(0.1, 0.1, 0.1)__default_base_type_exa()→Float64__default_prefix_fun()→:CTModels__default_prefix_exa()→:ExaModels__default_e_prefix()→:CTBase
test_onepass_fun_bis.jl (110 tests)
Unit tests for the :fun backend in src/onepass.jl:
Error helpers (__throw, __wrap)
__throwbuilds an expression that raisesParsingError__wrappreserves normal values and rethrows original exceptions
ParsingInfo structure
- Default values for all fields
vis a gensym whose name starts with"unset"aliasescontains R¹–R²⁰ and operator entries
Parsing function preconditions
| Function | Error cases covered |
|---|---|
p_dynamics! |
missing state/control/time, wrong symbols, forbidden label |
p_dynamics_coord! |
same as above + coordinate with label |
p_time! |
invalid time name (non-symbol), invalid variable dependencies |
p_state! |
invalid name |
p_control! |
invalid name |
p_variable! |
invalid name |
p_alias! |
invalid alias name + valid case updating aliases |
p_constraint! |
invalid label |
Cost functions
| Function | Error cases covered |
|---|---|
p_lagrange! |
missing state/control/time, :min/:max criteria |
p_mayer! |
missing state/t0/tf, trailing ∫ in objective |
p_bolza! |
missing state/t0/tf/control/time |
Other
parse!: unknown syntaxes →ParsingError- Autonomy detection: explicit
t→is_autonomous = false
test_onepass_exa_bis.jl (123 tests)
Unit tests for the :exa backend in src/onepass.jl:
Dispatch and structure
parsing(:alias, backend): returns a callable for valid backends- Errors: unknown backend, unknown primitive
PARSING_BACKENDScontains:funand:exaPARSING_DIRhas entries for all primitives
Utilities
is_range/as_range: ranges, expressions, fallbacks__symgen: symbol uniqueness with prefix__init_aliases: R¹–R²⁰ and operator aliases
:exa code generation
| Function | Tests |
|---|---|
p_dynamics_exa! |
error when dynamics is not coordinatewise |
p_dynamics_coord_exa! |
code generation + dyn_coords update |
p_variable_exa! |
code generation + box_v updated |
p_time_exa! |
code generation + dt set |
p_state_exa! |
code generation + box_x updated |
p_control_exa! |
code generation + box_u updated |
p_mayer_exa! |
wrapped objective code |
p_lagrange_exa! |
code with numerical scheme conditionals |
p_bolza_exa! |
wrapped Bolza objective code |
p_pragma_fun! / p_pragma_exa! |
backend comparison |
p_alias_exa! |
identical to p_alias_fun! |
:exa constraints
| Type | Test |
|---|---|
:boundary |
boundary constraints code generation |
:initial |
initial constraints with nothing range |
:final |
final constraints with nothing range |
:variable_range |
variable bounds via box_v |
:state_range |
state bounds via box_x |
:control_range |
control bounds via box_u |
:mixed |
mixed state + control constraints |
:state_fun |
state-function constraints |
:control_fun |
control-function constraints |
:variable_fun |
variable-function constraints |
constraint_type for :exa
state_range,control_range,variable_rangewithnothing:initialand:finalwith range expressions
Additional functional coverage
The _bis tests mainly cover:
- Precondition errors: every
p_*!function has explicit negative tests - Edge cases: empty or unrelated expressions, missing symbols, deep nesting
:exacode generation: allp_*_exa!functions produce validExprobjects- Default values: consistency of
defaults.jlhelpers - Backend management: activation, deactivation, and isolation between backends
|
@jbcaillau Please review and merge. |
|
@ocots 👍🏽 merging
|

No description provided.