Core: add unit tests and more documentation for numeric options (#2926)

* Core: add unit tests for the numeric options

* document using a collection and the hashing quirk

* add another example for the footgun

---------

Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
This commit is contained in:
Aaron Wagener 2024-06-05 17:17:52 -05:00 committed by GitHub
parent 04ec2f3893
commit be03dca774
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 85 additions and 1 deletions

View File

@ -132,7 +132,8 @@ or if I need a boolean object, such as in my slot_data I can access it as:
start_with_sword = bool(self.options.starting_sword.value) start_with_sword = bool(self.options.starting_sword.value)
``` ```
All numeric options (i.e. Toggle, Choice, Range) can be compared to integers, strings that match their attributes, All numeric options (i.e. Toggle, Choice, Range) can be compared to integers, strings that match their attributes,
strings that match the option attributes after "option_" is stripped, and the attributes themselves. strings that match the option attributes after "option_" is stripped, and the attributes themselves. The option can
also be checked to see if it exists within a collection, but this will fail for a set of strings due to hashing.
```python ```python
# options.py # options.py
class Logic(Choice): class Logic(Choice):
@ -144,6 +145,12 @@ class Logic(Choice):
alias_extra_hard = 2 alias_extra_hard = 2
crazy = 4 # won't be listed as an option and only exists as an attribute on the class crazy = 4 # won't be listed as an option and only exists as an attribute on the class
class Weapon(Choice):
option_none = 0
option_sword = 1
option_bow = 2
option_hammer = 3
# __init__.py # __init__.py
from .options import Logic from .options import Logic
@ -157,6 +164,16 @@ elif self.options.logic == Logic.option_extreme:
do_extreme_things() do_extreme_things()
elif self.options.logic == "crazy": elif self.options.logic == "crazy":
do_insane_things() do_insane_things()
# check if the current option is in a collection of integers using the class attributes
if self.options.weapon in {Weapon.option_bow, Weapon.option_sword}:
do_stuff()
# in order to make a set of strings work, we have to compare against current_key
elif self.options.weapon.current_key in {"none", "hammer"}:
do_something_else()
# though it's usually better to just use a tuple instead
elif self.options.weapon in ("none", "hammer"):
do_something_else()
``` ```
## Generic Option Classes ## Generic Option Classes
These options are generically available to every game automatically, but can be overridden for slightly different These options are generically available to every game automatically, but can be overridden for slightly different

0
test/options/__init__.py Normal file
View File

View File

@ -0,0 +1,67 @@
import unittest
from Options import Choice, DefaultOnToggle, Toggle
class TestNumericOptions(unittest.TestCase):
def test_numeric_option(self) -> None:
"""Tests the initialization and equivalency comparisons of the base Numeric Option class."""
class TestChoice(Choice):
option_zero = 0
option_one = 1
option_two = 2
alias_three = 1
non_option_attr = 2
class TestToggle(Toggle):
pass
class TestDefaultOnToggle(DefaultOnToggle):
pass
with self.subTest("choice"):
choice_option_default = TestChoice.from_any(TestChoice.default)
choice_option_string = TestChoice.from_any("one")
choice_option_int = TestChoice.from_any(2)
choice_option_alias = TestChoice.from_any("three")
choice_option_attr = TestChoice.from_any(TestChoice.option_two)
self.assertEqual(choice_option_default, TestChoice.option_zero,
"assigning default didn't match default value")
self.assertEqual(choice_option_string, "one")
self.assertEqual(choice_option_int, 2)
self.assertEqual(choice_option_alias, TestChoice.alias_three)
self.assertEqual(choice_option_attr, TestChoice.non_option_attr)
self.assertRaises(KeyError, TestChoice.from_any, "four")
self.assertIn(choice_option_int, [1, 2, 3])
self.assertIn(choice_option_int, {2})
self.assertIn(choice_option_int, (2,))
self.assertIn(choice_option_string, ["one", "two", "three"])
# this fails since the hash is derived from the value
self.assertNotIn(choice_option_string, {"one"})
self.assertIn(choice_option_string, ("one",))
with self.subTest("toggle"):
toggle_default = TestToggle.from_any(TestToggle.default)
toggle_string = TestToggle.from_any("false")
toggle_int = TestToggle.from_any(0)
toggle_alias = TestToggle.from_any("off")
self.assertFalse(toggle_default)
self.assertFalse(toggle_string)
self.assertFalse(toggle_int)
self.assertFalse(toggle_alias)
with self.subTest("on toggle"):
toggle_default = TestDefaultOnToggle.from_any(TestDefaultOnToggle.default)
toggle_string = TestDefaultOnToggle.from_any("true")
toggle_int = TestDefaultOnToggle.from_any(1)
toggle_alias = TestDefaultOnToggle.from_any("on")
self.assertTrue(toggle_default)
self.assertTrue(toggle_string)
self.assertTrue(toggle_int)
self.assertTrue(toggle_alias)