stardew-tracker/tests/test_app.py

88 lines
3.5 KiB
Python
Raw Permalink Normal View History

2026-10-04 19:27:36 +01:00
import tempfile
import unittest
from concurrent.futures import ThreadPoolExecutor
2026-10-04 19:27:36 +01:00
from pathlib import Path
import app
class StoreTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.store = app.Store(Path(self.temp.name) / "state.sqlite3")
self.store.initialize()
def tearDown(self):
self.temp.cleanup()
def test_empty_store(self):
self.assertEqual(self.store.snapshot()["checks"], {})
self.assertEqual(self.store.snapshot()["revision"], 0)
def test_shared_check_round_trip(self):
result = self.store.set_check("crop-parsnip", True, "fred")
self.assertEqual(result["revision"], 1)
snapshot = self.store.snapshot()
self.assertTrue(snapshot["checks"]["crop-parsnip"])
self.assertEqual(snapshot["updatedBy"], "fred")
self.store.set_check("crop-parsnip", False, "kayla")
snapshot = self.store.snapshot()
self.assertFalse(snapshot["checks"]["crop-parsnip"])
self.assertEqual(snapshot["revision"], 2)
def test_two_clients_keep_distinct_concurrent_changes(self):
second_client = app.Store(self.store.path)
def write(index):
store = self.store if index % 2 else second_client
store.set_check(f"concurrent-item-{index}", True, f"player-{index % 2}")
with ThreadPoolExecutor(max_workers=2) as pool:
list(pool.map(write, range(20)))
snapshot = self.store.snapshot()
self.assertEqual(snapshot["revision"], 20)
self.assertEqual(len(snapshot["checks"]), 20)
self.assertTrue(all(snapshot["checks"].values()))
def test_planting_round_trip(self):
spring_three = {"year": 1, "season": "spring", "day": 3}
result = self.store.set_planting("crop-parsnip", spring_three, "fred")
self.assertEqual(result["revision"], 1)
self.assertEqual(self.store.snapshot()["plantings"], {"crop-parsnip": spring_three})
self.store.set_planting("crop-parsnip", None, "fred")
snapshot = self.store.snapshot()
self.assertEqual(snapshot["plantings"], {})
self.assertEqual(snapshot["revision"], 2)
def test_undated_planted_checks_migrate_to_plantings(self):
self.store.set_check("planted-crop-parsnip", True, "fred")
self.store.set_check("planted-crop-potato", False, "fred")
self.store.initialize()
snapshot = self.store.snapshot()
self.assertEqual(snapshot["checks"], {})
self.assertEqual(
snapshot["plantings"], {"crop-parsnip": {"year": None, "season": None, "day": None}}
)
self.assertEqual(snapshot["revision"], 3)
def test_game_date_validation(self):
self.assertTrue(app.valid_game_date({"year": 2, "season": "winter", "day": 28}))
self.assertFalse(app.valid_game_date({"year": 1, "season": "spring", "day": 29}))
self.assertFalse(app.valid_game_date({"year": True, "season": "spring", "day": 1}))
self.assertFalse(app.valid_game_date({"year": 1, "season": "monsoon", "day": 1}))
2026-10-04 19:27:36 +01:00
class StaticInteractionTests(unittest.TestCase):
def test_native_checkboxes_cover_each_tickable_row(self):
styles = (Path(__file__).parent.parent / "static" / "styles.css").read_text()
self.assertIn(".today-card > input, .crop-row input, .bundle-item input", styles)
self.assertIn("inset: 0", styles)
self.assertNotIn(".crop-row input, .bundle-item input { position: absolute; opacity: 0; pointer-events: none; }", styles)
2026-10-04 19:27:36 +01:00
if __name__ == "__main__":
unittest.main()