-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix relevance for prompts #595
Conversation
I did a little more digging and realized that the repeat template is actually part of the
It could also be written as a boolean expression but this feels clearer to me. It also doesn't really feel like it belongs in I don't think there's anything else from the logic at https://github.com/getodk/javarosa/pull/581/files#diff-b60f702426880ccc5f1b079019104bd4L537 that we need. To be extra safe, it might make sense to have a test where there's an outer group that's irrelevant and check that it's indeed impossible to add an instance of an inner repeat. But it shouldn't even be possible to navigate inside the outer group to try. Looking forward to seeing what you think, @seadowg. Side note: I forgot the |
And to be extra clear, would be great if you could finalize the PR, @seadowg! Since this is a bug, I think we can do a point release. And I think it would be ok to change the public interface by getting rid of |
3757f31
to
4bf7cad
Compare
Codecov Report
@@ Coverage Diff @@
## master #595 +/- ##
============================================
+ Coverage 54.68% 54.72% +0.04%
- Complexity 3218 3219 +1
============================================
Files 242 242
Lines 13320 13332 +12
Branches 2562 2563 +1
============================================
+ Hits 7284 7296 +12
- Misses 5230 5232 +2
+ Partials 806 804 -2
Continue to review full report at Codecov.
|
@lognaturel I agree but there is test coverage to move around, so I think for this PR it'd be best to just add the implementation in |
@lognaturel ach it looks like the template solution doesn't work for dynamic relevance. I've added a test and will keep exploring. |
@@ -173,6 +174,7 @@ public void repeatIsIrrelevant_whenGrandparentRelevanceSetToFalse() throws IOExc | |||
} | |||
|
|||
@Test | |||
@Ignore("Test needs rewritten") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test could possibly have helped us notice the bug here. The relevance of the inner group is based on the position of the outer group but I think I convinced myself it was based on the position of the inner group (and that's what I was thinking when we talked, @seadowg).
In the original test, the first assertion is:
scenario.next();
scenario.next();
assertThat(scenario.refAtIndex(), is(getRef("/data/outer[0]/inner[1]")));
This is wrong because of the bug this PR fixes. Any inner group should be non-relevant based on the outer group's index. The form definition instance only has one instance of the inner repeat. It turns out the event emitted is actually a repeat prompt (because of this bug). The rest of the test makes sense.
Below is a more explicit proposal. I put two instances of the outer repeat and two inner instances in the first outer instance. That way we can check that initially none of the inner repeats in the first outer repeat are relevant and that there's no prompt.
Test
public void nestedRepeatRelevance_updatesBasedOnParentPosition() throws IOException {
Scenario scenario = Scenario.init("Nested repeat relevance", html(
head(
title("Nested repeat relevance"),
model(
mainInstance(t("data id=\"nested-repeat-relevance\"",
t("outer",
t("inner",
t("q1")
),
t("inner",
t("q1")
)
),
t("outer",
t("inner",
t("q1")
)
),
t("relevance-condition", "0")
)),
bind("/data/relevance-condition").type("string"),
bind("/data/outer/inner").relevant("position(..) mod 2 = /data/relevance-condition")
),
body(
repeat("/data/outer",
repeat("/data/outer/inner",
input("/data/outer/inner/q1")
)
),
input("/data/relevance-condition")
))));
FormDef formDef = scenario.getFormDef();
FormEntryModel formEntryModel = new FormEntryModel(formDef);
// For ref /data/outer[0]/inner[0], the parent position is 1 so the boolean expression is false. That means
// none of the inner groups in /data/outer[0] can be relevant.
assertThat(formEntryModel.isIndexRelevant(scenario.indexOf("/data/outer[0]/inner[0]")), is(false));
scenario.next();
// The repeat is relevant but nothing inside it is.
assertThat(scenario.refAtIndex(), is(getRef("/data/outer[0]")));
scenario.next();
assertThat(scenario.refAtIndex(), is(getRef("/data/outer[1]")));
scenario.next();
assertThat(scenario.refAtIndex(), is(getRef("/data/outer[1]/inner[0]")));
scenario.next();
assertThat(scenario.refAtIndex(), is(getRef("/data/outer[1]/inner[0]/q1[0]")));
scenario.answer("/data/relevance-condition", "1");
scenario.jumpToBeginningOfForm();
scenario.next();
assertThat(scenario.refAtIndex(), is(getRef("/data/outer[0]")));
scenario.next();
assertThat(scenario.refAtIndex(), is(getRef("/data/outer[0]/inner[0]")));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right this makes a lot more sense to me now. The way we were thinking about position before was hurting my brain. I think we can incorporate this in this PR.
c62801f
to
067163a
Compare
067163a
to
34dfb8d
Compare
34dfb8d
to
1e87049
Compare
We tried to use relevance updated by the DAG exclusively in getodk#581 and getodk#595 but ran into problems related to Triggerables' context. For most forms, this will only involve a small performance difference. There's not enough gain to take on the risk. This does leave in the change to remove an explicit walk up the tree to determine non-repeat node relevance and instead uses the TreeElement relevance which depends on DAG updates for that: https://github.com/getodk/javarosa/pull/581/files\#diff-1cf9266e21581c3fdea78db8d579c7ebL395
We tried to use relevance updated by the DAG exclusively in getodk#581 and getodk#595 but ran into problems related to Triggerables' context. For most forms, this will only involve a small performance difference. There's not enough gain to take on the risk. This does leave in the change to remove an explicit walk up the tree to determine non-repeat node relevance and instead uses the TreeElement relevance which depends on DAG updates for that: https://github.com/getodk/javarosa/pull/581/files\#diff-1cf9266e21581c3fdea78db8d579c7ebL395
Closes getodk/collect#4090.
This changes how repeat relevance is calculated so that it checks the template as well as the node.
What has been done to verify that this works as intended?
Added new tests and verified in Colllect.
Why is this the best possible solution? Were any other approaches considered?
There are a few things to improve:
@Ignored
FormDefTest
test needs rewritten so it works with this new implementationFormDef#isRepeatRelevant
How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
Should just fix the bug! Might be good to check any weird repeat relevance cases that can be thought of.
Do we need any specific form for testing your changes? If so, please attach one.
This is a good form to check the fix works: https://docs.google.com/spreadsheets/d/1pc9LPOR8s5C2uFjMj1JbuF6_PPLQ_Q2l6X6ytAZvul0/edit#gid=0