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:
parent
04ec2f3893
commit
be03dca774
|
@ -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,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)
|
Loading…
Reference in New Issue