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

RecycleGridLayout : Fix layout when number of widgets match number of columns #7262

Merged
merged 15 commits into from Dec 15, 2020

Conversation

gottadiveintopython
Copy link
Member

@gottadiveintopython gottadiveintopython commented Dec 12, 2020

Maintainer merge checklist

  • Title is descriptive/clear for inclusion in release notes.
  • Applied a Component: xxx label.
  • Applied the api-deprecation or api-break label.
  • Applied the release-highlight label to be highlighted in release notes.
  • Added to the milestone version it was merged into.
  • Unittests are included in PR.
  • Properly documented, including versionadded, versionchanged as needed.

fixes #7255

I put "WIP" in the title because I feel like there is a better implemetation.

@gottadiveintopython gottadiveintopython changed the title fix layout calculation on RecycleGridLayout (WIP) fix layout calculation on RecycleGridLayout Dec 12, 2020
@tshirtman
Copy link
Member

tshirtman commented Dec 12, 2020

The parametrised test seems to repeat the implementation, i think it's better to be less smart in such cases and be explicit about tho expected result, each parameter could be a tuple of (input, exptected_output) instead.

Edit: i think it's a situation where a few lines of comments explaining the loogic of the implementation would be fine, up to you.

@matham
Copy link
Member

matham commented Dec 13, 2020

The parametrised test seems to repeat the implementation, i think it's better to be less smart in such cases and be explicit about tho expected result, each parameter could be a tuple of (input, exptected_output) instead.

Agree. But also, this is not testing the implementation directly, but rather an analog of the implementation. So if one changes the implementation, the test would not be helpful anymore. So it's better to test the actual implementation and use hard-coded input/output values as @tshirtman suggested.

@matham
Copy link
Member

matham commented Dec 13, 2020

I think I wasn't clear enough with what I was trying to say, but could you test an actual gridlayout widget? Beause this basically tests that the current implementation is current. But if someone changes the gridlayout in the future, the test will not test that.

@gottadiveintopython
Copy link
Member Author

@tshirtman Ah sorry for my explanation being not enough. There is a situation where we cannot just sort the view indices in ascending order as the latest commit shows.

@matham No, you were clear enough. I pushed the latest commit before I read your comment.

it's better to test the actual implementation

OK, so is it ok to create a new function that implements that specific part, and use it in the unittests? or I better to use compute_visible_views() itself in the unittests somehow?

@gottadiveintopython
Copy link
Member Author

gottadiveintopython commented Dec 13, 2020

When I implemented the 'orientation', I left the original code as possible in order to avoid introducing new bugs. But maybe this compute_visible_views() should be re-written entirely (if I come up with good implementation) to avoid this complicated unittests.

@matham
Copy link
Member

matham commented Dec 13, 2020

Yeah, I'd say to call compute_visible_views directly and ensure the it returns them in the correct order.

Or even better, create a actual recyclegridlayout (and normal gridlayout) and set the data/children, run do_layout or whatever is required to do the layout, and then check that the children widgets are at the expected positions. But compute_visible_views is enough if you don't want to do that.

@matham
Copy link
Member

matham commented Dec 13, 2020

But maybe this compute_visible_views() should be re-written entirely (if I come up with good implementation) to avoid this complicated unittests.

Ultimately, it'd be nice if we can test that the widgets are laid out correctly, irrespective of the implementation. So I'm not sure if that would help.

@matham
Copy link
Member

matham commented Dec 13, 2020

Perfect. Just one more thing, it's probably better if you use the clock fixture rather than the raw clock.

@gottadiveintopython
Copy link
Member Author

gottadiveintopython commented Dec 13, 2020

Test_layout.compute_layout() is not a test case, which means it cannot use any fixture directly, which means I have to do something like this:

class Test_layout:
    def compute_layout(self, *, clock):
        ...
    def test_case1(self, kivy_clock, ...):
       self.compute_layout(..., clock=kivy_clock)
    def test_case2(self, kivy_clock, ...):
       self.compute_layout(..., clock=kivy_clock)

This is not desirable, isn't it?

@matham
Copy link
Member

matham commented Dec 13, 2020

This is not desirable, isn't it?

I think that's fine!? It's just more verbose, but I don't really see another way that is not hacky.

@matham matham added this to the 2.1.0 milestone Dec 13, 2020
@matham matham added the Component: Widgets kivy/uix, style.kv label Dec 13, 2020
@matham matham changed the title (WIP) fix layout calculation on RecycleGridLayout RecycleGridLayout : Fix layout when number of widgets match number of columns Dec 13, 2020
@gottadiveintopython
Copy link
Member Author

gottadiveintopython commented Dec 14, 2020

@matham OK, how about the following fixture? Do you think it's a good idea?

# kivy/tests/fixtures.py
@pytest.fixture(scope='module')
def module_scope_kivy_clock():
    # same as kivy_clock


# kivy/tests/test_uix_recyclegridlayout.py
global_kivy_clock = None

@pytest.fixture(scope='module', autouse=True)
def acquire_kivy_clock(module_scope_kivy_clock):
    global global_kivy_clock
    global_kivy_clock = module_scope_kivy_clock
    yield module_scope_kivy_clock
    global_kivy_clock = None

class Test_layout:
    def compute_layout(...):
         global_kivy_clock.tick()

I myself am not sure this is good or not.

(Also, don't merge the PR yet.)

@gottadiveintopython
Copy link
Member Author

TestLayout_all_the_data_is_visible might be unnecessary if TestLayout_only_a_part_of_the_data_is_visible exists.

@matham
Copy link
Member

matham commented Dec 14, 2020

OK, how about the following fixture?

I think the way it is currently is better. It's simpler even if more verbose, which is not really a big deal.

TestLayout_all_the_data_is_visible might be unnecessary if TestLayout_only_a_part_of_the_data_is_visible exists.

Extra tests have never hurt anyone 😄

matham
matham previously approved these changes Dec 14, 2020
@matham
Copy link
Member

matham commented Dec 14, 2020

Feel free to merge if you're happy with it.

@gottadiveintopython
Copy link
Member Author

@matham I think the pr is mergable now. I'd appreciate if you approve it again :)

@matham matham merged commit 00399f7 into kivy:master Dec 15, 2020
@gottadiveintopython gottadiveintopython deleted the fix_RecycleGridLayout branch March 12, 2021 05:32
hamlet4401 pushed a commit to tytgatlieven/kivy that referenced this pull request Jul 3, 2021
… columns (kivy#7262)

* fix 'RecycleGridLayout.compute_visible_views()'

* add more unittests

* test the actual layout not the internal code

* reduce the test code

* add more test cases

* edit comment

* re-write the GridLayout's unittests

* test the situation where only a part of the data is visible

* use 'kivy_clock' fixture instead of raw Clock

* make 'compute_visible_views()' readable

* might improve performance

* refactor the unittests

* test the situations where view widgets are L-shaped rather than rectangle-shaped

* revert an unnecessary change

* avoid unnecessary list creation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Widgets kivy/uix, style.kv
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RecycleGridLayout not able to render viewclass when number of columns is equal to the length of data
3 participants