From 27b7ea8486a7944803efb2eff953a037d39a314e Mon Sep 17 00:00:00 2001 From: Daniel McCoy Stephenson Date: Sat, 3 Oct 2026 02:42:49 -0600 Subject: [PATCH] Test the journal, its calendar and the count page The journal was 17% covered and winter.calendar and Galley.sum had no test of their own. These characterise what each page says today: the descriptor's counts, registry order and trail markers, the leads that drop away as facts are found, the calendar rows that appear as the ice, the storm and the dark flight become known, and the count's arithmetic short, closed and with the manifest. Co-Authored-By: Claude Opus 5.5 --- tests/test_journal.py | 163 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 tests/test_journal.py diff --git a/tests/test_journal.py b/tests/test_journal.py new file mode 100644 index 0000000..ba1f560 --- /dev/null +++ b/tests/test_journal.py @@ -0,0 +1,163 @@ +from conftest import FakeGame, ScriptedUI + +from overwinter import endings, facts, flags, premise, winter +from overwinter.scenes.galley import Galley +from overwinter.scenes.journal import Journal +from overwinter.state import ( + AKSEL_STATION, + DARK_FLIGHT_DAY, + ICE_SAFE_DAY, + MANIFEST_FOOD, + PLANE_DAY, + STORM_DAYS, +) + + +def journal(script=()): + game = FakeGame(ScriptedUI(list(script))) + game.scenes = {"galley": Galley(game)} + return game, Journal(game) + + +def calendarDays(state): + return [day for day, _ in winter.calendar(state)] + + +def test_the_descriptor_counts_what_is_known_and_how_far_along_the_trail(): + game, page = journal() + game.state.day = 3 + game.learn(facts.THE_STORE) + game.learn(facts.THE_ICE) + assert page.descriptor() == ( + "Day 3. 2 of %d things known; 1 of %d on the trail of the count." + % (len(facts.FACTS), len(facts.TRAIL)) + ) + + +def test_nothing_known_is_said_plainly_and_leads_nowhere(): + _, page = journal() + assert page.knownText() == "Nothing yet." + assert page.leadsText() == "" + + +def test_what_you_know_is_in_registry_order_with_the_day_and_the_trail_marked(): + game, page = journal() + game.state.day = 6 + game.learn(facts.THE_ICE) + game.state.day = 2 + game.learn(facts.THE_STORE) + text = page.knownText() + store, ice = facts.title(facts.THE_STORE), facts.title(facts.THE_ICE) + assert text.index(store) < text.index(ice) + assert "* %s - day 2\n %s" % (store, facts.text(facts.THE_STORE)) in text + assert "- %s - day 6\n %s" % (ice, facts.text(facts.THE_ICE)) in text + assert text.endswith("(* marks the trail of the count.)") + + +def test_leads_list_where_to_look_and_drop_what_has_been_found(): + game, page = journal() + game.learn(facts.THE_STORE) + text = page.leadsText() + assert text.startswith("\n\nThere's more to learn:\n") + for _, line in facts.leads(facts.THE_STORE): + assert "? " + line in text + game.learn(facts.THE_MANIFEST) + text = page.leadsText() + assert dict(facts.leads(facts.THE_STORE))[facts.THE_MANIFEST] not in text + for _, line in facts.leads(facts.THE_MANIFEST): + assert "? " + line in text + + +def test_the_calendar_starts_with_only_the_plane(): + game, page = journal() + assert calendarDays(game.state) == [PLANE_DAY] + assert page.calendarText() == ( + "Day 20 The plane. Light enough on the strip; the Otter comes." + ) + + +def test_the_calendar_learns_the_ice_by_hearing_or_living_it(): + game, _ = journal() + game.learn(facts.THE_ICE) + assert calendarDays(game.state) == [ICE_SAFE_DAY, PLANE_DAY] + game, _ = journal() + game.state.day = ICE_SAFE_DAY + assert calendarDays(game.state) == [ICE_SAFE_DAY, PLANE_DAY] + + +def test_the_storm_is_on_the_calendar_once_it_has_come(): + game, _ = journal() + game.state.day = STORM_DAYS[0] - 1 + assert STORM_DAYS[0] not in calendarDays(game.state) + game.state.day = STORM_DAYS[0] + assert calendarDays(game.state) == [ICE_SAFE_DAY, STORM_DAYS[0], PLANE_DAY] + + +def test_the_dark_flight_is_listed_only_while_it_is_coming(): + game, page = journal() + game.state.flags[flags.DOV_REPORTED] = True + assert DARK_FLIGHT_DAY in calendarDays(game.state) + assert "Day 12 Base sends the plane in the dark." in page.calendarText() + game.state.ending = facts.THE_DARK_FLIGHT + assert DARK_FLIGHT_DAY not in calendarDays(game.state) + + +def test_the_count_says_how_short_the_sum_is(): + game, _ = journal() + game.learn(facts.THE_STORE) + assert game.scenes["galley"].sum() == ( + "60 rations on the shelf.\n" + "4 people eating, at full rations: 4 rations a day.\n" + "15 days of food. 19 days until the plane.\n" + "The sum is 4 days short." + ) + + +def test_the_count_with_aksel_on_half_rations_closes_and_names_the_manifest(): + game, _ = journal() + state = game.state + state.day = 10 + state.food = 30 + state.akselAt = AKSEL_STATION + state.flags[flags.HALF_RATIONS] = True + game.learn(facts.THE_MANIFEST) + total = game.scenes["galley"].sum() + assert "5 people eating, at half rations: 3 rations a day." in total + assert "10 days of food. 10 days until the plane." in total + assert "The sum closes, with 0 days over." in total + assert ( + "The manifest says %d rations were landed: 21 days at four. " + "24 rations are not in this store." % MANIFEST_FOOD + ) in total + + +def test_the_menu_offers_the_count_once_counted_and_the_last_page_once_over(): + game, page = journal(["Close the journal"]) + assert page.run() == "bunks" + labels = game.ui.menus[-1][1] + assert "The count" not in labels + assert "The last page" not in labels + + game, page = journal(["The count", "The last page", "Close the journal"]) + game.learn(facts.THE_STORE) + game.state.ending = facts.FIVE_OUT + assert page.run() == "journal" + assert game.ui.saw("60 rations on the shelf.") + assert page.run() == "journal" + assert game.ui.dialogues[-1] == endings.text(game.state) + assert page.run() == "epilogue" + assert game.state.location == "epilogue" + + +def test_each_page_of_the_journal_shows_its_own_text(): + game, page = journal( + ["What is happening to you", "What you know", "The winter, as you know it"] + ) + game.learn(facts.THE_STORE) + page.run() + page.run() + page.run() + premisePage, knownPage, calendarPage = game.ui.dialogues + assert premisePage == premise.text(game.state) + assert knownPage == page.knownText() + page.leadsText() + assert calendarPage == page.calendarText()