feat(registry): register range as a bounded numeric type - #36
Merged
Merged
Conversation
`range` wasn't in the registry: TSV conversion threw, subset validation rejected it, and buildDdiXml without validation fell back to text, while qwacback (and survey2ddi before it) emitted numeric/contin. Registry: type:range, DDI numeric/contin (like decimal), LimeSurvey N. Three new schema fields drive the parameters column without range-specific code: - xlsform.parameters: keys the type reads, with pyxform's defaults (start=1 end=10 step=1) - limesurvey.parameterAttributes: start → min_num_value_n, end → max_num_value_n - limesurvey.integerOnly: num_value_int_only=1 when start and step are whole src/pipelines/xlsform2lstsv/parameters.ts applies them. A non-numeric bound throws, since LimeSurvey would otherwise import the question unbounded. LimeSurvey has no step on N, so step is enforced only as integer vs. decimal. Reverse (lstsv2xlsform): an N carrying both bounds reads back as range, with step=1 when integer-only. A non-1 step isn't recoverable (README known losses). Snapshots: new registry/entities/range (xlsform, tsv, ddi, docs, xlsx, live answers + blessed response); testA gets tsv/ddi snapshots, its reverse DDI diff (5-char code truncation) recorded in REVERSE_DDI_STRUCTURAL_DIFF. Tests: range unit tests (bounds, defaults, fractional step, bad bound, DDI, reverse); testA integration now checks the bounds; the live suite checks LimeSurvey stores them after import. The qwacback equivalence case for range passes, so its xfail is gone. Also fixed on the way: the live long-list vocab test read <entity>/xlsform.json instead of <entity>/fixtures/xlsform.json and failed on main. HANDOVER_CDL_WP_EINS.md's supported-type table predated #24 and this. Closes #33 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #33.
What
rangeis now a registered type:contin(likedecimal), which now matches qwacbackNwithmin_num_value_n/max_num_value_nfromstart/end, andnum_value_int_only=1whenstartandstepare whole numbersNwith both bounds becomesrange, withparametersrebuiltThree new registry schema fields drive the
parameterscolumn, so the converter has norange-specific code:xlsform.parameters: the keys the type reads, with pyxform's defaults (start=1 end=10 step=1)limesurvey.parameterAttributes: which parameter goes into which LS attributelimesurvey.integerOnly: when to setnum_value_int_onlyA non-numeric bound throws. Otherwise LimeSurvey would import the question without bounds.
Limits
Nhas no step attribute. Sostep=5is enforced only as "integers only", and it reads back asstep=1. This is documented inuseWhenand in the lstsv2xlsform README's known losses.K, so a range question renders as a bounded number input.Verified
npm run validateis clean. pytesttests/validation(XSD + Schematron, including the newddi.xml): 37 passed.npm run test:live: therangeentity imports and its response round-trips (blessedexpected/range.json). A new test imports testA and reads backmin_num_value_n=0,max_num_value_n=100,num_value_int_only=1from the stored question.main:rangenow matches, so its xfail is removed. Onlynoteremains, and that one is by design.Snapshots
registry/entities/range/(fixture, tsv, ddi, docs, xlsx).testAnow hastsv.tsv/ddi.xml. Its reverse DDI renames threeselect_multiplevariables through LimeSurvey's 5-character answer codes, which is recorded inREVERSE_DDI_STRUCTURAL_DIFF.Also fixed
test_long_list_vocab_roundtrip(live) read<entity>/xlsform.jsoninstead of<entity>/fixtures/xlsform.json, so it failed onmain. Fixed; it passes.HANDOVER_CDL_WP_EINS.md: its supported-type table predated Browser entry cannot convert select_*_from_file (registered long-list types) to TSV #24 (from_fileis convertible now) and this PR.HANDOVER_QWAC.md: now 14 of 15 types match qwacback.🤖 Generated with Claude Code