* fix: use str() instead of .value for realm i18n display Fix bug where user-facing messages displayed raw enum values like "FOUNDATION_ESTABLISHMENT" instead of translated names like "筑基". The Realm and Stage classes already have __str__ methods that return i18n translated text, but several places were incorrectly using .value which returns the raw enum string. Changed files: - src/classes/single_choice.py: item exchange messages - src/classes/kill_and_grab.py: loot messages - src/classes/fortune.py: fortune discovery messages - src/classes/avatar/inventory_mixin.py: purchase error messages Also added unit tests and integration tests to prevent regression. * test: add integration tests for all modified files Add tests covering: - kill_and_grab.py: context string realm display - fortune.py: weapon/auxiliary intro realm display - inventory_mixin.py: can_buy_item error message realm display
139 lines
4.7 KiB
Python
139 lines
4.7 KiB
Python
import pytest
|
|
from src.classes.cultivation import Realm, Stage, CultivationProgress
|
|
|
|
# ================= Realm Tests =================
|
|
def test_realm_comparison():
|
|
assert Realm.Qi_Refinement < Realm.Foundation_Establishment
|
|
assert Realm.Foundation_Establishment < Realm.Core_Formation
|
|
assert Realm.Core_Formation < Realm.Nascent_Soul
|
|
assert Realm.Nascent_Soul > Realm.Qi_Refinement
|
|
|
|
def test_realm_str_returns_translated_text_not_value():
|
|
"""Test that str(Realm) returns i18n translated text, not the raw enum value."""
|
|
# str() should NOT return the uppercase enum value.
|
|
assert str(Realm.Qi_Refinement) != "QI_REFINEMENT"
|
|
assert str(Realm.Foundation_Establishment) != "FOUNDATION_ESTABLISHMENT"
|
|
assert str(Realm.Core_Formation) != "CORE_FORMATION"
|
|
assert str(Realm.Nascent_Soul) != "NASCENT_SOUL"
|
|
|
|
# str() should return non-empty translated text.
|
|
assert len(str(Realm.Qi_Refinement)) > 0
|
|
assert len(str(Realm.Foundation_Establishment)) > 0
|
|
assert len(str(Realm.Core_Formation)) > 0
|
|
assert len(str(Realm.Nascent_Soul)) > 0
|
|
|
|
def test_realm_from_id():
|
|
assert Realm.from_id(1) == Realm.Qi_Refinement
|
|
assert Realm.from_id(4) == Realm.Nascent_Soul
|
|
with pytest.raises(ValueError):
|
|
Realm.from_id(0)
|
|
|
|
# ================= Stage Tests =================
|
|
def test_stage_comparison():
|
|
assert Stage.Early_Stage < Stage.Middle_Stage
|
|
assert Stage.Middle_Stage < Stage.Late_Stage
|
|
|
|
def test_stage_str_returns_translated_text_not_value():
|
|
"""Test that str(Stage) returns i18n translated text, not the raw enum value."""
|
|
# str() should NOT return the uppercase enum value.
|
|
assert str(Stage.Early_Stage) != "EARLY_STAGE"
|
|
assert str(Stage.Middle_Stage) != "MIDDLE_STAGE"
|
|
assert str(Stage.Late_Stage) != "LATE_STAGE"
|
|
|
|
# str() should return non-empty translated text.
|
|
assert len(str(Stage.Early_Stage)) > 0
|
|
assert len(str(Stage.Middle_Stage)) > 0
|
|
assert len(str(Stage.Late_Stage)) > 0
|
|
|
|
# ================= CultivationProgress Tests =================
|
|
def test_cp_initialization():
|
|
cp = CultivationProgress(level=1, exp=0)
|
|
assert cp.realm == Realm.Qi_Refinement
|
|
assert cp.stage == Stage.Early_Stage
|
|
|
|
def test_cp_level_mapping():
|
|
# Level 1-10 -> Early
|
|
assert CultivationProgress(1).stage == Stage.Early_Stage
|
|
assert CultivationProgress(10).stage == Stage.Early_Stage
|
|
|
|
# Level 11-20 -> Middle
|
|
assert CultivationProgress(11).stage == Stage.Middle_Stage
|
|
assert CultivationProgress(20).stage == Stage.Middle_Stage
|
|
|
|
# Level 21-30 -> Late
|
|
assert CultivationProgress(21).stage == Stage.Late_Stage
|
|
assert CultivationProgress(30).stage == Stage.Late_Stage
|
|
|
|
# Level 31 -> Next Realm (Foundation)
|
|
cp = CultivationProgress(31)
|
|
assert cp.realm == Realm.Foundation_Establishment
|
|
assert cp.stage == Stage.Early_Stage
|
|
|
|
def test_cp_bottleneck():
|
|
# Level 30 is end of Qi Refinement (Late Stage)
|
|
# According to code: bottleneck if level % 30 == 0
|
|
cp = CultivationProgress(30)
|
|
assert cp.is_in_bottleneck() is True
|
|
assert cp.can_break_through() is True
|
|
assert cp.can_cultivate() is False
|
|
|
|
cp = CultivationProgress(29)
|
|
assert cp.is_in_bottleneck() is False
|
|
|
|
def test_cp_add_exp_normal():
|
|
cp = CultivationProgress(1, exp=0)
|
|
required = cp.get_exp_required()
|
|
|
|
# Add not enough to level up
|
|
leveled = cp.add_exp(required - 1)
|
|
assert leveled is False
|
|
assert cp.level == 1
|
|
assert cp.exp == required - 1
|
|
|
|
# Add enough to level up
|
|
leveled = cp.add_exp(2) # Total > required
|
|
assert leveled is True
|
|
assert cp.level == 2
|
|
# Exp should be consumed
|
|
assert cp.exp == 1
|
|
|
|
def test_cp_add_exp_stops_at_bottleneck():
|
|
# Start at level 29
|
|
cp = CultivationProgress(29, exp=0)
|
|
req_29 = cp.get_exp_required()
|
|
|
|
# Add enough exp to theoretically go to 31
|
|
# But should stop at 30 (bottleneck)
|
|
# Need exp for 29->30.
|
|
# At 30, it is bottleneck.
|
|
|
|
cp.add_exp(req_29 + 100000)
|
|
|
|
assert cp.level == 30
|
|
assert cp.is_in_bottleneck() is True
|
|
# Exp should accumulate? Logic says:
|
|
# if is_in_bottleneck(): break (inside while loop)
|
|
# So extra exp stays in self.exp
|
|
assert cp.exp >= 100000
|
|
|
|
def test_cp_breakthrough():
|
|
cp = CultivationProgress(30, exp=0)
|
|
cp.break_through()
|
|
assert cp.level == 31
|
|
assert cp.realm == Realm.Foundation_Establishment
|
|
assert cp.is_in_bottleneck() is False
|
|
|
|
def test_cp_serialization():
|
|
cp = CultivationProgress(5, exp=123)
|
|
data = cp.to_dict()
|
|
assert data["level"] == 5
|
|
assert data["exp"] == 123
|
|
|
|
cp_new = CultivationProgress.from_dict(data)
|
|
assert cp_new.level == 5
|
|
assert cp_new.exp == 123
|
|
assert cp_new.realm == Realm.Qi_Refinement
|
|
|
|
|
|
|