-
Notifications
You must be signed in to change notification settings - Fork 105
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
Allow fields in group to trigger action outside #671
Conversation
ecec66f
to
12480f9
Compare
Quick way to keep predicates with position().
Given the comment, I believe this restriction was put in to guard against repeat insert events triggering actions elsewhere. I wasn't able to come up with a problematic case without the check.
12480f9
to
12b355b
Compare
} | ||
} | ||
|
||
//TODO: either the target or the value's node might not exist here, catch and throw reasonably |
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.
As far as I can tell, this can never happen. In fact, as I wrote elsewhere, I think FormInstanceParser.verifyActions
is being too restrictive at parse time.
if (references.size() == 0) { | ||
// If after finding our concrete reference it is a template, this action is outside of the | ||
// scope of the current target, so we can leave. | ||
if (model.getMainInstance().hasTemplatePath(target)) { |
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.
I have been unable to come up with a form that would result in either an expanded reference set of size 0 or a reference with a template path. It feels safer to leave these cases in for now, though.
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.
For 0 refs, I believe FormInstanceParser.verifyActions makes that impossible.
TODO: try a predicate that does lead to a node being found at parse time but not at event time.
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.
I can get to the references.size() == 0
and then hasTemplatePath
code path here if I comment out the contents of verifyActions
and run the following:
@Test
public void foo() throws IOException {
Scenario scenario = Scenario.init("Setvalue into repeat", html(
head(
title("Setvalue into repeat"),
model(
mainInstance(t("data id=\"setvalue-into-repeat\"",
t("dest_index", "1"),
t("source"),
t("repeat",
t("destination")
)
))
)
),
body(
input("/data/dest_index"),
input("/data/source",
setvalue("xforms-value-changed", "/data/repeat[position()=/data/dest_index]/destination", "/data/source")),
repeat("/data/repeat",
input("/data/repeat/destination")
))));
scenario.createNewRepeat("/data/repeat");
scenario.createNewRepeat("/data/repeat");
scenario.createNewRepeat("/data/repeat");
scenario.answer("/data/source", "foo");
assertThat(scenario.answerOf("/data/repeat[0]/destination").getDisplayText(), is("foo"));
scenario.answer("/data/dest_index", "7");
scenario.answer("/data/source", "bar");
}
Again, I think verifyActions
is doing more than it should be, but it makes sense to me to wait for a user to report.
@@ -113,18 +94,14 @@ public TreeReference processAction(FormDef model, TreeReference contextRef) { | |||
//an unbound template, so see if such a reference could exist. Unfortunately this | |||
//won't be included in the above walk if the template is nested, since only the | |||
//top level template retains its subelement templates | |||
if(model.getMainInstance().hasTemplatePath(target)) { | |||
if (model.getMainInstance().hasTemplatePath(target)) { |
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.
Same as above -- I tried to come up with a form def that would lead to a null resolved reference and couldn't do it but feel it's safer to leave the case in for now.
src/test/java/org/javarosa/core/model/actions/OdkNewRepeatEventTest.java
Outdated
Show resolved
Hide resolved
src/test/java/org/javarosa/core/model/actions/OdkNewRepeatEventTest.java
Outdated
Show resolved
Hide resolved
It makes sense to expand the reference and guard against a nodeset target. I see no reason to only make this check if the target reference has a predicate. I've added tests with and without predicates.
12b355b
to
8598258
Compare
@seadowg and I had a good chat about this. He's going to chew on it and see if he thinks the tests I added are meaningful and whether he can think of cases we should add. Whether or not he gets feedback to me by then, I'll merge tomorrow and do a beta. |
@lognaturel just a heads-up that I won't have a chance to review again today |
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.
Approving blindly
Merging so we can do the beta. @seadowg will take a look before we release! |
Closes #670
What has been done to verify that this works as intended?
Tests.
Why is this the best possible solution? Were any other approaches considered?
I briefly looked for a way to address groups separately from repeats. However, as far as I know, there’s no way to know whether a step in a reference is repeatable.
Removing the check for a predicate is not necessary to solve the problem but once I understood the code it felt like something low risk I wanted to change so we get good error messages in the case of a target ref that isn’t fully qualified (targeting a repeated field).
I spent a little bit of time trying to get full test coverage for
processAction
but I didn't want to spend too much time on it. I thinkFormInstanceParser.verifyActions
fails in so many repeat-related cases that we might not be able to get toprocessAction
with the cases that are not tested.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?
it should fix the limitation and offer a better error when targeting a repeated field.
The biggest risk would be for an action to now target the wrong reference. I’ve spent a lot of time thinking about how this change could lead to that and haven’t come up with anything.
I did discover that the following test leads to a StackOverflow now whereas it just would have failed the parenting test before. That's what happens when a ref with a predicate is expanded using itself as context (and it's always been that way as far as I can tell). Hopefully the exception means we hear about it if someone tries to do it so I don't think it's so bad.
Do we need any specific form for testing your changes? If so, please attach one.
See tests.
Does this change require updates to documentation? If so, please file an issue here and include the link below.
no.