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

Tests: test that collect and remove have expected behaviour. #2062

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

Berserker66
Copy link
Member

What is this fixing or adding?

test that collect and remove have expected behaviour

How was this tested?

test

If this makes graphical changes, please attach screenshots.

test/general/TestItems.py Outdated Show resolved Hide resolved
@ThePhar ThePhar added is: enhancement Issues requesting new features or pull requests implementing new features. is: refactor/cleanup Improvements to code/output readability or organizization. affects: core Issues/PRs that touch core and may need additional validation. labels Jul 31, 2023
@el-u
Copy link
Collaborator

el-u commented Sep 15, 2023

Please consider reviewing #2093 as well for some progress on a related topic.

Out of scope feature request removed.

test/general/TestItems.py Outdated Show resolved Hide resolved
# Non-Advancement should not modify state.
base_state = multiworld.state.prog_items.copy()
multiworld.state.collect(item)
self.assertEqual(base_state, multiworld.state.prog_items)
Copy link
Collaborator

@el-u el-u Sep 15, 2023

Choose a reason for hiding this comment

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

Seems like the variable base_state could be removed and empty_prog_items be used instead (once the bug on the line below has been fixed.)

Out of scope feature request removed.

test/general/TestItems.py Outdated Show resolved Hide resolved
test/general/TestItems.py Outdated Show resolved Hide resolved
@el-u
Copy link
Collaborator

el-u commented Sep 16, 2023

I am not sure what to do about the remaining Python 3.8 failures of Link's Awakening and The Messenger. The collect->remove test fails, not because the code of #2093 is incorrect, but because the testing mechanic (equality tests of Counter objects) is simply not adequate before Python 3.10. Maybe the collect->remove portion of the test could be gated for Python >= 3.10 only.

Out of scope feature request removed.

test/general/TestItems.py Outdated Show resolved Hide resolved
@agilbert1412 agilbert1412 added the waiting-on: author Issue/PR is waiting for feedback or changes from its author. label Feb 11, 2024
qwint added a commit to qwint/Archipelago that referenced this pull request Jul 19, 2024
@NewSoupVi
Copy link
Member

NewSoupVi commented Jul 31, 2024

Yacht Dice and Tunic are doing stuff like this

    def collect(self, state: CollectionState, item: Item) -> bool:
        change = super().collect(state, item)
        if change and ...:
            state.prog_items[self.player]["stale"] = 1
        return change

    def remove(self, state: CollectionState, item: Item) -> bool:
        change = super().remove(state, item)
        if change and ...:
            state.prog_items[self.player]["stale"] = 1
        return change

to track the staleness of some custom state.

This unit test would break that.
I believe this to be a perfectly valid use case.

It actually works out for Yacht Dice (because in Yacht Dice's case, the fake prog item is called state_is_fresh and is set to 0 instead of being state_is_stale and being set to 1)
The new Tunic changes would fail this unit test.

What Tunic does is it lazily calculates and caches the accessibility of its areas by a specific metric and then marks them as "succeeded" (2), "failed" (1) or "unchecked" (0), as key-value pairs on state.prog_items (key = area name, value = unchecked/failed/succeeded).

A collect causes all "failed" areas to go back to "unchecked", but leaves "succeeded" areas as "succeeded" (cause gaining an item can never fail a previously successful check).
A remove causes all "succeeded" areas to go back to "unchecked", but leaves "failed" as "failed" (cause losing an item can't make something succeed that previously failed).

This means that collect -> remove could leave a lot of areas as "failed" (1) that were previously "unchecked" (0). Which is correct. Information was literally gained about the accessibility of areas, that is fine to persist through the remove.

@Berserker66
Copy link
Member Author

This unit test would break that. I believe this to be a perfectly valid use case.

I believe it's not, and is why CollectionState extending exists.

@Exempt-Medic Exempt-Medic added waiting-on: peer-review Issue/PR has not been reviewed by enough people yet. and removed waiting-on: author Issue/PR is waiting for feedback or changes from its author. labels Jul 31, 2024
Copy link
Collaborator

@qwint qwint left a comment

Choose a reason for hiding this comment

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

for a simple test that can catch mistakes this is perfect, code makes sense and has already caught multiple mistakes when I have used it,

That being said it is not the end all be all of testing collect/remove because any complex collect/remove that changes depending on what the current state is, will not be fully tested because state will always be empty (or fail the test) for each new item.
I don't think this is a reason not to merge as-is, but we should be aware that some issues (like HK's split cloak issues, see #1844) may not be caught with just this test

multiworld.state.collect(item)
self.assertEqual(base_state, multiworld.state.prog_items)

multiworld.state.prog_items = empty_prog_items
Copy link
Collaborator

Choose a reason for hiding this comment

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

per discussion in ap-core-dev, this line is setting by reference and causing errors to go unnoticed

a couple of things seem to work, that I don't have much of an opinion on which is better

  • deepcopy when copying prog_items
  • copying CollectionState instead and using that state's prog_items when comparing
  • copy a new CollectionState for each item_name and using that state's collect() instead of copying the state back to multiworld each loop

@Exempt-Medic Exempt-Medic added the waiting-on: author Issue/PR is waiting for feedback or changes from its author. label Aug 19, 2024
@NewSoupVi
Copy link
Member

Ftr, I was just made aware that this PR includes a test that non-progression doesn't change state

Wanted to make you aware of an alternative PR that just straight up asserts this
Core: CollectionState - Never pick up non-advancements #3786

@qwint
Copy link
Collaborator

qwint commented Jan 12, 2025

Opened #4468 that handles the issue I still have with the PR, the other approaches I outlined in my last comment are still valid, but I implemented the approach that made the most sense to me

@qwint qwint removed the waiting-on: author Issue/PR is waiting for feedback or changes from its author. label Jan 13, 2025
@qwint
Copy link
Collaborator

qwint commented Jan 13, 2025

FYI test failures are appropriate and handled by #4433

@Exempt-Medic Exempt-Medic added waiting-on: core-review Issue/PR has been peer-reviewed and is ready to be merged or needs input from a core maintainer. and removed waiting-on: peer-review Issue/PR has not been reviewed by enough people yet. labels Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects: core Issues/PRs that touch core and may need additional validation. is: enhancement Issues requesting new features or pull requests implementing new features. is: refactor/cleanup Improvements to code/output readability or organizization. waiting-on: core-review Issue/PR has been peer-reviewed and is ready to be merged or needs input from a core maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants