Skip to content

Commit

Permalink
#106 added tests for key action and few fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
bomzheg committed Nov 15, 2024
1 parent 99d317d commit 7d83494
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 20 deletions.
13 changes: 13 additions & 0 deletions shvatka/core/models/dto/action/decisions.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import logging
from dataclasses import dataclass
from typing import Literal, Sequence, overload

from shvatka.common.log_utils import obfuscate_sensitive
from shvatka.core.models.dto.action.interface import DecisionType, Decision

logger = logging.getLogger(__name__)


@dataclass
class NotImplementedActionDecision(Decision):
Expand Down Expand Up @@ -36,6 +40,15 @@ def get_significant(self) -> "Decisions":
def get_implemented(self) -> "Decisions":
return self.get_all_except(DecisionType.NOT_IMPLEMENTED)

def get_exactly_one(self, level_id: str = "unknown") -> Decision:
if len(self.decisions) != 1:
logger.warning(
"in level %s there is more than one duplicate correct key decision %s",
level_id,
obfuscate_sensitive(self.decisions),
)
return self.decisions[0]

def get_all(self, *type_: type) -> "Decisions":
return Decisions([d for d in self.decisions if isinstance(d, type_)])

Expand Down
19 changes: 5 additions & 14 deletions shvatka/core/models/dto/scn/level.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from datetime import timedelta
from typing import overload

from shvatka.common.log_utils import obfuscate_sensitive
from shvatka.core.utils import exceptions
from .hint_part import AnyHint
from .time_hint import TimeHint, EnumeratedTimeHint
Expand All @@ -18,6 +17,7 @@
KeyDecision,
KeyBonusCondition,
NotImplementedActionDecision,
BonusKeyDecision,
)
from shvatka.core.models.dto.action.keys import (
SHKey,
Expand Down Expand Up @@ -216,27 +216,18 @@ def check(self, action: Action, state: StateHolder) -> Decision:
if not implemented:
return NotImplementedActionDecision()
if isinstance(action, TypedKeyAction):
if bonuses := implemented.get_all(BonusKeyDecision):
return bonuses.get_exactly_one(self.id)
key_decisions = implemented.get_all(KeyDecision, WrongKeyDecision)
if not key_decisions:
return NotImplementedActionDecision()
if not key_decisions.get_significant():
assert all(d.type == DecisionType.NO_ACTION for d in key_decisions)
if duplicate_correct := key_decisions.get_all(KeyDecision):
if len(duplicate_correct) != 1:
logger.warning(
"more than one duplicate correct key decision %s",
obfuscate_sensitive(duplicate_correct),
)
return duplicate_correct[0]
return duplicate_correct.get_exactly_one(self.id)
return key_decisions[0]
significant_key_decisions = key_decisions.get_significant()
if len(significant_key_decisions) != 1:
logger.warning(
"More than one significant key decision. "
"Will used first but it's not clear %s",
obfuscate_sensitive(significant_key_decisions),
)
return significant_key_decisions[0]
return significant_key_decisions.get_exactly_one(self.id)
else:
return NotImplementedActionDecision()

Expand Down
54 changes: 48 additions & 6 deletions tests/unit/domain/level_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,26 @@ def level_one_key(hints: scn.HintsList) -> scn.LevelScenario:
return scn.LevelScenario(
id="test1",
time_hints=hints,
conditions=scn.Conditions([action.KeyWinCondition({"SH123"})]),
conditions=scn.Conditions(
[
action.KeyWinCondition({"SH123"}),
action.KeyBonusCondition({action.BonusKey(text="SHB1", bonus_minutes=1)}),
]
),
)


@pytest.fixture
def level_three_keys(hints: scn.HintsList) -> scn.LevelScenario:
return scn.LevelScenario(
id="test2",
time_hints=hints,
conditions=scn.Conditions([
action.KeyWinCondition({"SH123", "SH321", "СХ123"})
]),
conditions=scn.Conditions(
[
action.KeyWinCondition({"SH123", "SH321", "СХ123"}),
action.KeyBonusCondition({action.BonusKey(text="SHB1", bonus_minutes=1)}),
]
),
)


Expand Down Expand Up @@ -72,6 +81,35 @@ def test_duplicate_wrong_level_single_key(level_one_key: scn.LevelScenario):
assert decision.type == action.DecisionType.NO_ACTION
assert decision.duplicate


def test_bonus_level_single_key(level_one_key: scn.LevelScenario):
decision = level_one_key.check(
action.TypedKeyAction("SHB1"), action.InMemoryStateHolder(set(), {"SHWRONG"})
)

assert isinstance(decision, action.BonusKeyDecision)
assert decision.key.text == "SHB1"
assert decision.key.bonus_minutes == 1
assert decision.key_text == "SHB1"
assert decision.key_type == enums.KeyType.bonus
assert decision.type == action.DecisionType.BONUS_TIME
assert not decision.duplicate


def test_duplicate_bonus_level_single_key(level_one_key: scn.LevelScenario):
decision = level_one_key.check(
action.TypedKeyAction("SHB1"), action.InMemoryStateHolder(set(), {"SHWRONG", "SHB1"})
)

assert isinstance(decision, action.BonusKeyDecision)
assert decision.key.text == "SHB1"
assert decision.key.bonus_minutes == 1
assert decision.key_text == "SHB1"
assert decision.key_type == enums.KeyType.bonus
assert decision.type == action.DecisionType.BONUS_TIME
assert decision.duplicate


def test_second_key_of_three(level_three_keys: scn.LevelScenario):
decision = level_three_keys.check(
action.TypedKeyAction("SH123"), action.InMemoryStateHolder({"SH321"}, {"SH321"})
Expand All @@ -85,9 +123,11 @@ def test_second_key_of_three(level_three_keys: scn.LevelScenario):
assert not decision.is_level_up()
assert not decision.duplicate


def test_duplicate_second_key_of_three(level_three_keys: scn.LevelScenario):
decision = level_three_keys.check(
action.TypedKeyAction("SH123"), action.InMemoryStateHolder({"SH321", "SH123"}, {"SH321", "SH123"})
action.TypedKeyAction("SH123"),
action.InMemoryStateHolder({"SH321", "SH123"}, {"SH321", "SH123"}),
)

assert isinstance(decision, action.KeyDecision)
Expand All @@ -98,9 +138,11 @@ def test_duplicate_second_key_of_three(level_three_keys: scn.LevelScenario):
assert not decision.is_level_up()
assert decision.duplicate


def test_third_key_of_three(level_three_keys: scn.LevelScenario):
decision = level_three_keys.check(
action.TypedKeyAction("SH123"), action.InMemoryStateHolder({"SH321", "СХ123"}, {"SH321", "СХ123"})
action.TypedKeyAction("SH123"),
action.InMemoryStateHolder({"SH321", "СХ123"}, {"SH321", "СХ123"}),
)

assert isinstance(decision, action.KeyDecision)
Expand Down

0 comments on commit 7d83494

Please sign in to comment.