Skip to content

Commit

Permalink
Merge pull request #516 from DavisRayM/503-select-from-repeat-interna…
Browse files Browse the repository at this point in the history
…l-reference

Generate correct refrence when selecting choices from current repeat question
  • Loading branch information
lognaturel authored Apr 16, 2021
2 parents a539996 + 9d12124 commit 3e60bcc
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
4 changes: 3 additions & 1 deletion pyxform/question.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ def build_xml(self):
itemset = self["itemset"]
itemset_label_ref = "jr:itext(itextId)"

choice_filter = survey.insert_xpaths(choice_filter, self, True, True)
choice_filter = survey.insert_xpaths(
choice_filter, self, True, is_previous_question
)
if is_previous_question:
path = (
survey.insert_xpaths(self["itemset"], self, reference_parent=True)
Expand Down
16 changes: 12 additions & 4 deletions pyxform/survey.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,24 @@ def _get_steps_and_target_xpath(context_parent, xpath_parent, include_parent=Fal
context_parent = is_parent_a_repeat(survey, context_xpath)
xpath_parent = is_parent_a_repeat(survey, xpath)
if context_parent and xpath_parent and xpath_parent in context_parent:
include_parent = False
if not context_parent == xpath_parent and reference_parent:
if (not context_parent == xpath_parent and reference_parent) or bool(
is_parent_a_repeat(survey, context_parent)
):
context_shared_ancestor = is_parent_a_repeat(survey, context_parent)
if context_shared_ancestor == xpath_parent:
# Check if context_parent is a child repeat of the xpath_parent
# If the context_parent is a child of the xpath_parent reference the entire
# xpath_parent in the generated nodeset
include_parent = True
context_parent = context_shared_ancestor
return _get_steps_and_target_xpath(context_parent, xpath_parent, include_parent)
elif context_parent == xpath_parent and context_shared_ancestor:
# If the context_parent is a child of another
# repeat and is equal to the xpath_parent
# we avoid refrencing the context_parent and instead reference the shared
# ancestor
reference_parent = False
return _get_steps_and_target_xpath(
context_parent, xpath_parent, reference_parent
)
elif context_parent and xpath_parent:
# Check if context_parent and xpath_parent share a common
# repeat ancestor
Expand Down
21 changes: 20 additions & 1 deletion pyxform/tests_v1/test_repeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,25 @@ def test_choice_from_previous_repeat_answers_in_nested_repeat_uses_current(self)
],
)

def test_choice_from_previous_repeat_in_current_repeat_parents_out_to_repeat(self):
"""Test choice from previous repeat in current repeat produces the correct reference"""
xlsform_md = """
| survey | | | | | | | |
| | type | name | label | choice_filter | appearance | relevant | calculation |
| | begin_repeat | pet | Pet | | field_list | | |
| | calculate | pos | | | | | position(..) |
| | select_one ${animal_type} | animal_select | Select the animal type | position() != current()/../pos and animal_type != '' | | | |
| | text | animal_type | Animal type | | | ${animal_select} = '' | |
| | end_repeat | pet | | | | | |
"""
self.assertPyxformXform(
name="data",
md=xlsform_md,
xml__contains=[
"<itemset nodeset=\"../../pet[position() != current()/../pos and animal_type != '']\">"
],
)

def test_indexed_repeat_regular_calculation_relative_path_exception(self):
"""Test relative path exception (absolute path) in indexed-repeat() using regular calculation."""
self.assertPyxformXform(
Expand Down Expand Up @@ -795,7 +814,7 @@ def test_relative_path_expansion_not_using_current_if_reference_path_is_predicat
| | calculate | pos2 | | 1 |
| | calculate | item2 | | ${rep1}[number(${pos2})]/label |
| | end repeat | | | |
"""
"""
self.assertPyxformXform(
name="data",
md=xlsform_md,
Expand Down

0 comments on commit 3e60bcc

Please sign in to comment.