v3.2.0 — Conditional navigation fixes
Conditional navigation was broken for most answer types. This release fixes the
expression evaluators, a regression shipped in 3.1, and the silent loss of date
answers.
Fixed
- Numeric conditions never matched. The operand was compared as a string
against a number, so= 5on a rating, slider, NPS or OTP answer was always
false and!= 5always true. Comparison is numeric, and<,<=,>and
>=are supported. - Decimal answers matched every condition. Dispatch tested
is int, so a
slider'sdoublefell through to the catch-all evaluator. - Boolean and other answers matched every condition. The catch-all
evaluator returnedtrueunconditionally, so a boolean question always took
its first branch and could never reach its "no" path. NOT_INmeant "not all of these".NOT_IN a,bmatched a selection
containinga, because it negated "every one is present" rather than "any
one is present". It also comparedOptionsobjects against strings, so on a
multiple-choice answer it matched whatever was selected.- Operands containing spaces were truncated. Conditions were split on every
space, so= New Yorkcompared against"New"and never matched. < DAY(01-01-2025)threw. The two-term date form parsed the operator as
a date expression and raised aRangeErrorbefore comparing anything. A bare
date operand —< 01-01-2025— threw for the same reason.- Date answers were dropped from results.
generateResultonly recorded a
DateTimewhen the step carried aDateResultType, so with any other
validator — or none — the answer was missing fromexportAsJson, from saved
drafts, and from the map handed toonFinish. Dates are now always recorded,
formatted when the step says how and ISO-8601 otherwise. - Container steps disposed their children twice. Introduced in 3.1: nested
and repeat steps build child views into the tree, so the framework disposes
each as it unmounts, but they also cascaded from their owndispose(). Any
form containing aNestedSteporRepeatStepasserted with "A
TextEditingController was used after being disposed" when it was torn down. - Restoring a draft threw on a repeat group. A JSON round-trip widens the
element type, which the unchecked cast on resume rejected. Rating and NPS
inputs likewise assumedintwhere a restored draft can hold a double or a
numeric string.
Changed
- Unknown operators now raise
ArgumentErrorconsistently across every answer
type, rather than silently matching.
Added
test/unit/expression_test.dartcovers every operator against every answer
type; each case was checked against the behaviour before the fix.test/integration/draft_restore_test.dartround-trips a form through JSON
and rebuilds each restored step, which is what surfaced the container
double-dispose.