Skip to content

fix(lstsv): an optional select_multiple with a lower bound can be left empty (#217) - #244

Merged
jstet merged 1 commit into
mainfrom
fix/min-answers-empty-217
Nov 4, 2026
Merged

jstet merged 1 commit into
mainfrom
fix/min-answers-empty-217

Conversation

@jstet

@jstet jstet commented Nov 4, 2026

Copy link
Copy Markdown
Member

Fixes #217.

LimeSurvey builds min_answers as an unguarded count(<subquestions>) >= n (em_manager_helper.php), so it also rejects an empty multiple choice, while ODK skips the constraint on an empty answer. #216 guarded the validation equation but not the lower bound moved to min_answers (#186).

On a question that is not required, the lower bound of a count-selected(.) constraint now stays in the guarded validation equation instead of min_answers. A bound of 1 or less only excludes the empty answer, so it is dropped. max_answers stays an attribute (0 ticks satisfy it), and a required question keeps min_answers. lstsv2xlsform drops the guard again and reads the equation back as the same count-selected(.) constraint (the term order may differ: upper bound first). The selectionCount / emptyAnswer convention rules and the README are updated.

Before (optional, count-selected(.) >= 2):

min_answers	em_validation_q
2

After:

min_answers	em_validation_q
	count(k04_a.NAOK, k04_b.NAOK, k04_c.NAOK) == 0 or (count(k04_a.NAOK, k04_b.NAOK, k04_c.NAOK) >= 2)

Tests

  • Unit tests for optional lower bounds (>=, >, =, with a max, with another term, bound of 1), required ones unchanged, round trip through lstsv2xlsform. The property test now runs on a required question and its comment is corrected.
  • npm run bless: no survey fixture snapshot changes (none has an optional select_multiple with a lower bound); only the generated conventions changed.
  • npm test: 108 files and 1781 tests pass. npm run validate is clean.

🤖 Generated with Claude Code

…t empty (#217)

LimeSurvey enforces min_answers as `count(...) >= n` also on 0 ticks
(em_manager_helper.php), while ODK skips the constraint on an empty answer.
On a question that is not required the lower bound now goes into the guarded
validation equation (`count(...) == 0 or (count(...) >= n)`) instead of
min_answers; a bound of 1 or less only excludes the empty answer and is
dropped. max_answers stays an attribute. A required question keeps
min_answers. lstsv2xlsform drops the guard and reads the equation back as the
same constraint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jstet
jstet force-pushed the fix/min-answers-empty-217 branch from 4b15133 to e470f45 Compare November 4, 2026 20:09
@jstet
jstet merged commit 1795f3b into main Nov 4, 2026
@jstet jstet mentioned this pull request Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

xlsform2lstsv: min_answers blocks an empty optional select_multiple in LimeSurvey (ODK skips the constraint)

1 participant