123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- #!/usr/bin/env python3
- """
- This file tests src.get_roll.
- Three main parts are tested:
- general form, injection, and failure detection.
- """
- import unittest
- from src.gen_roll import get_roll
- from src.config import DICE, HITS, FAILS
- class TestRoll(unittest.TestCase):
- """Unittest Testcase for src.get_roll"""
- # neutral are all dice results minux the results of HITS and FAILS
- NEUTRAL_RES = set(DICE) - set(HITS) - set(FAILS)
- NEUTRAL_RES = list(NEUTRAL_RES)
- NON_FAILS = NEUTRAL_RES + HITS
- # general form
- def test_normal_length(self):
- """Tests if the result length is equal to the amount passed."""
- len_roll_result = len(get_roll(3)["result"])
- self.assertEqual(len_roll_result, 3, "amount of dice throws should be equal to results")
- def test_available_keys(self):
- """Tests if different amount roll dicts have all the necessary key"""
- keys = ["result", "hits", "fails", "isFailure"]
- rolls = [get_roll(1), get_roll(2), get_roll(3)]
- for roll in rolls:
- has_all_keys = True
- for key in keys:
- if not key in roll:
- has_all_keys = False
- self.assertTrue(has_all_keys,
- f"roll dict with length {len(roll['result'])} should have all keys")
- # injection tests
- def test_injection(self):
- """Tests if the injection is the same in the output"""
- if len(DICE) < 2:
- print("Unable to test injection ordering, since too few elements exist")
- return
- injections = _get_ordered_injection(DICE, [0,1,2,3])
- for injection in injections:
- roll = get_roll(len(injection), injection)
- self.assertEqual(roll["result"], injection,
- f"injection {injection} should be the same in the roll result")
- def test_injection_fill(self):
- """Tests if an underfull injection gets filled up by random numbers"""
- injections = _get_ordered_injection(DICE, [0,1,2])
- amount = 4
- for injection in injections:
- roll = get_roll(amount, injection)
- self.assertEqual(amount, len(roll["result"]),
- f"injected roll result {injection} length should be equal to amount")
- def test_injection_overlong(self):
- """Tests if an overlong injection will be cut off"""
- injection = _get_ordered_injection(DICE, [5])[0]
- amount = 4
- roll = get_roll(amount, injection)
- self.assertEqual(roll["result"], injection[:amount],
- "injected overlong roll should be equal after being cut off to the result")
- def test_injection_fill_placement(self):
- """Tests if a injected underfull injection is correctly placed"""
- injections = _get_ordered_injection(DICE, [0,1,2])
- amount = 4
- for injection in injections:
- roll = get_roll(amount, injection)
- res = roll["result"][:len(injection)]
- self.assertEqual(res, injection,
- "beginning of result should be equal to underlong injection")
- # failure tests
- def test_failure_detection(self):
- """Tests if failures are detected correctly.
- Failures are if half (rounded up) or more are failure rolls (here: 1)."""
- fail = FAILS[0]
- non_fail = self.NON_FAILS[0]
- if len(FAILS) < 1 and len(self.NON_FAILS) < 1:
- print("Not able to test failure detection with no failures or no neutral results/hits")
- return
- # test fail
- roll = get_roll(1, [fail])
- self.assertTrue(roll["isFailure"],
- "single roll with result {fail} should be a failure according to config")
- # test non fail
- for res in self.NON_FAILS:
- roll = get_roll(1, [res])
- self.assertFalse(roll["isFailure"],
- f"single roll with result {res} should not be a failure according to config")
- # test uneven
- for res in [[fail,non_fail,non_fail], [non_fail]*3]:
- roll = get_roll(3, res)
- self.assertFalse(roll["isFailure"],
- f"tripple roll with result {res} should not be a failure")
- for res in [[fail]*3, [fail,fail,non_fail]]:
- roll = get_roll(3, res)
- self.assertTrue(roll["isFailure"],
- f"tripple roll with result {res} should be a failure")
- # test uneven
- for res in [[fail,fail,non_fail,non_fail], [non_fail]*4]:
- roll = get_roll(4, res)
- self.assertFalse(roll["isFailure"],
- f"quad roll with result {res} should not be a failure")
- for res in [[fail]*4, [fail,fail,fail,non_fail]]:
- roll = get_roll(4, res)
- self.assertTrue(roll["isFailure"],
- f"quad roll with result {res} should be a failure")
- # TODO: test DICE, HITS and FAILS with different kinds of data types
- # problem: how to change config dynamically/load dynamically?
- # at the moment it tests from the current config only
- ### helpers ####
- def _get_ordered_injection(dice: list, lens: list) -> list:
- """Return a list of lists, which have a unique element at the second position,
- eg an amount of 4 with dice = [0,1]:
- [0,1,0,0]
- """
- if len(dice) < 2:
- raise Exception("At least two dice entries required.")
- injections = []
- # create injection
- for lst_len in lens:
- if lst_len < 1:
- injections.append([])
- else:
- injections.append([dice[0]])
- if lst_len > 1:
- injections[-1].append(dice[1])
- lst_len -= 2 # two numbers were added already
- while lst_len > 0:
- injections[-1].append(dice[0])
- lst_len -= 1
- return injections
- if __name__ == '__main__':
- unittest.main()
|