Skip to content
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

Show repeat in hierarchy view even if first instance has no relevant content #4762

Merged
merged 10 commits into from
Oct 6, 2021

Conversation

dimwight
Copy link
Contributor

@dimwight dimwight commented Jul 30, 2021

Closes #4570
Blocked on #4570 discussion

What has been done to verify that this works as intended?

Tested manually and with new test added to FormHierarchyTest (empty_first_repeat is a placeholder name, help needed for a suitable final one).

Why is this the best possible solution? Were any other approaches considered?

Trivial fix to ensure that

  • repeats appear in hierarchy even if first is empty
  • relevant repeats are nonetheless listed correctly

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?

Shows no regression when tested before and after with testDebug and connectedDebugAndroidTest.

Do we need any specific form for testing your changes? If so, please attach one.

The issue contains example forms.

Does this change require updates to documentation? If so, please file an issue here and include the link below.

No, behaviour is now as expected.

Before submitting this PR, please make sure you have:

  • run ./gradlew checkAll and confirmed all checks still pass OR confirm CircleCI build passes and run ./gradlew connectedDebugAndroidTest locally.
  • verified that any code or assets from external sources are properly credited in comments and/or in the about file.
  • verified that any new UI elements use theme colors. UI Components Style guidelines

@dimwight
Copy link
Contributor Author

Once again test_app seems not to like me for no obvious reason.

@dimwight
Copy link
Contributor Author

dimwight commented Sep 3, 2021

Definitely awaiting review, does this reopen it? (Seems not)

@seadowg seadowg reopened this Sep 3, 2021
@seadowg seadowg marked this pull request as ready for review September 3, 2021 09:04
@seadowg seadowg self-requested a review September 3, 2021 09:04
@seadowg
Copy link
Member

seadowg commented Sep 3, 2021

@dimwight I've reopened and marked ready for review. When something is ready, you can just hit the "Ready for review" button above the test/quality checks, so we know you're not still working on it.

@dimwight
Copy link
Contributor Author

dimwight commented Sep 3, 2021

"Ready for review" button above the test/quality checks

Doesn't seem to appear for me, maybe because of failed check which I can't see how to resolve.

Oops, seem to have closed it again. :(

@dimwight dimwight closed this Sep 3, 2021
@seadowg seadowg reopened this Sep 3, 2021
@seadowg
Copy link
Member

seadowg commented Sep 6, 2021

Blocking this on making sure we fully understand the issue (I don't).

@seadowg seadowg added the blocked label Sep 6, 2021
@dimwight
Copy link
Contributor Author

dimwight commented Sep 6, 2021

fully understand the issue

Would it help if I spelled out in detail what I think is going on? (I certainly had some difficulty getting my head round it.)

@seadowg
Copy link
Member

seadowg commented Sep 6, 2021

Would it help if I spelled out in detail what I think is going on? (I certainly had some difficulty getting my head round it.)

Yes that'd be great! Happy to dive in, but if you've already got a good idea of what's happening, it'd be great to hear.

@dimwight
Copy link
Contributor Author

Hi @seadowg, an overview as promised of the issue and my proposed resolution.

In FormHierarchyActivity, when refreshView hits EVENT_REPEAT it is ready to add a HierarchyElement for one of two cases.

  • A (the default) if the repeat is the first in its group, display the group details; or
  • B (set by shouldShowRepeatGroupPicker()) display the repeat in a picker view.

Before proceeding either way, refreshView checks if the repeat is empty. If it is,

  • in case A, the current logic assumes that if the first repeat in a group is empty, any subsequent repeats will be as well so the whole group should be skipped.
  • in case B it should clearly skip the empty repeat which has no content to display or edit.

Issue #4570 arises from the corner case of A where repeats derive from a multiple select. Even if the first repeat is empty, some of those following will not be - the group should definitely be displayed.

For this PR the existing logic is refined such that the first repeat is never skipped even when empty, so its group is always displayed. The unlikely case that all repeats in a group are empty simply results in a harmless (and maybe expressive) empty picker.

@dimwight
Copy link
Contributor Author

I've also updated the PR as follows.

  • In FormHierarchyActivity, refreshView has been lightly reworked to make the logic clearer.
  • In FormHierarchyTest, empty_first_repeat (just a placeholder for a more descriptive name) has been extended to check inside the group picker.
  • In empty_first_repeat.xml the choice list has been truncated to simplify debugging.

@seadowg
Copy link
Member

seadowg commented Sep 22, 2021

in case A, the current logic assumes that if the first repeat in a group is empty, any subsequent repeats will be as well so the whole group should be skipped.

What do you mean by "empty" here? No relevant questions?

Issue #4570 arises from the corner case of A where repeats derive from a multiple select. Even if the first repeat is empty, some of those following will not be - the group should definitely be displayed.

This is the part I'm having trouble understanding. Why does the example form in #4570 (and in this PR) cause that issue? I'm probably missing something obvious, but I couldn't see why selecting 'beans' would result in different behaviour from selecting other vegetables. Is there maybe a simpler/smaller form that could illustrate the problem?

@dimwight
Copy link
Contributor Author

Hi @seadowg, I'm sorry you're finding this issue hard to disentangle, it's trivial on the face of it but quite subtle.

With a bit of luck you'll find my latest commit of some help. In essence it recapitulates my own investigations and proposed fix, by adding to FormHierarchyActivity a temporary enum Scenarios4570 and associated class constant SCENARIO_4570.

The four members of Scenarios4570 encapsulate the possible permutations of two flags.

Flag testWithBeans

(Where 'beans' is shorthand for 'first repeat with content because first item in select multiple was checked; so that FormEntryModel regards its FormIndex, other things being equal, as relevant')

This is tested in FormHierarchyTest in the method now renamed to showsRepeatsWhenFirstIsEmpty (hitherto with the placeholder name 'empty_first_repeat'). It defines which of two forms to open: empty_first_repeat.xml to test the issue as defined in #4570 , or empty_first_repeat_beans.xml (somehat confusingly named) for scenarios expecting a non-empty first repeat. The only difference between the two is at L10 between <veg_type>2 3 5</veg_type> and <veg_type>1 2 3 5</veg_type>.

Based on the state of testWithBeans the test then adjusts its expectations of what FormHierarchyTest should display given the form chosen.

Incidentally, I use the term 'empty' in preference to 'non-relevant' because it describes the repeat so neatly ie in XML <veg_repeat/> as opposed to a 'non-empty' repeat such as:

    <veg_repeat>
        <veg_group>
            <veg_name>Beans</veg_name>
           <veg_often />
        </veg_group>
    </veg_repeat>

Flag restoreOldLogic

This is tested in FormHierarchyActivity at L624, and when set negates the effect of my proposed fix.

By setting the values() index for SCENARIO_4570 you can test all permutations of the two flags, with the following results:

  1. WITH_BEANS_OLD_LOGIC will obviously pass as its first repeat will be non-empty
  2. WITHOUT_BEANS_OLD_LOGIC won't pass because of its empty first repeat - the issue as raised by @lognaturel in Repeat is not shown in hierarchy view if first instance has no relevant content #4570
  3. WITH_BEANS_NEW_LOGIC will pass as before
  4. WITHOUT_BEANS_NEW_LOGIC will also pass despite having an empty first repeat

You can observe all this happening by stepping through the relevant code. In FormHierarchyActivity you will note the importance of testing shouldShowRepeatGroupPicker to ensure that repeat items appear in a picker.

Once again rather a long explanation, I hope it helps.

@dimwight
Copy link
Contributor Author

And to explicitly answer your other questions as well:

...why selecting 'beans' would result in different behaviour from selecting other vegetables.

Beans is special because it's the first item in the veg_type choices; if it's not selected the first repeat is empty. And it's the first repeat that triggers the Frequencies repeat header in the hierarchy view: under the existing logic it doesn't if empty and therefore non-relevant (hence the issue), with my fix it always does.

Finally

Is there maybe a simpler/smaller form that could illustrate the problem?

I do think this is the minimal form to demonstrate the issue.

Copy link
Member

@seadowg seadowg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per our discussion on Slack, next steps are:

  1. Remove the SCENARIO_4570 debug code
  2. Use the simpler form (posted in the issue) for the test rather than the veg form

@dimwight
Copy link
Contributor Author

1. Remove the `SCENARIO_4570` debug code 

Done in 'Removed debug code'

2. Use the simpler form ... for the test rather than the veg form

Done in 'Updated test with simpler form'.

Also checked that the test fails appropriately when in FormHierarchyActivity at L609ff the code is tweaked to

boolean asOldCode = true;
if (isEmpty && asOldCode ||
        // For #4570
        (!isFirst || forPicker)) {
    break;
}

@dimwight
Copy link
Contributor Author

And then test_app failed code that passed when previously committed!

Copy link
Member

@seadowg seadowg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for wrapping your head around this and then explaining it to me. There are a couple of tweaks I'd like to see, and I've also thought about a slightly different implementation that'd be good to discuss.

@@ -30,6 +30,7 @@
.around(new CopyFormRule("formHierarchy2.xml", null))
.around(new CopyFormRule("formHierarchy3.xml", null))
.around(new CopyFormRule("repeat_group_new.xml", null))
.around(new CopyFormRule("Empty First Repeat.xml", null))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note to myself to rework this test file to remove CopyFormRule before merging this. I won't make you slog through that @dimwight.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a good thing as my code here is pure copy and paste, I've no idea as to how it works.

@seadowg
Copy link
Member

seadowg commented Oct 4, 2021

@dimwight is this ready for another review? You can request that with the 🔃 icon next to my name in "Reviewers".

@dimwight dimwight requested a review from seadowg October 4, 2021 09:51
}

@Test
public void empty_first_repeat() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need both tests now. As far as I can see showRepeatsPickerWhenFirstRepeatIsEmpty() enforces the correct code on its own.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely, I only put the earlier one back as a check.

@dimwight dimwight requested a review from seadowg October 4, 2021 14:03
Copy link
Member

@seadowg seadowg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to do a little work to rewrite a test file here in a newer style, but this is ready for QA I think! I think testing repeats in general, especially with relevance would be good in addition to testing the issue at hand.

@dimwight
Copy link
Contributor Author

dimwight commented Oct 4, 2021

Excellent, thanks @seadowg for your help!

@lognaturel lognaturel changed the title Resolves #4570 Repeat is not shown in hierarchy view… Show repeat in hierarchy view even if first instance has no relevant content Oct 6, 2021
@kkrawczyk123
Copy link
Contributor

Tested with success!
Tested on Androids: 5.1 and 11.

Verified cases:

  • confirmed that the original issue has been fixed (both forms attached in issue)
  • regression checks on other forms with repeats: add, remove group, jump to hierarchy, nested repeats, edit group, screen rotation

@mmarciniak90
Copy link
Contributor

Successfully tested on Android versions: 8.1, 9.0, 10.0

@seadowg seadowg merged commit 6977acd into getodk:master Oct 6, 2021
@lognaturel
Copy link
Member

Thank you for taking the time to work through all that, @dimwight and @seadowg! That is a very nice improvement.

@dimwight dimwight deleted the 4570-PR branch July 8, 2023 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Repeat is not shown in hierarchy view if first instance has no relevant content
5 participants