clone

an offline sliding-block puzzle game in gleam and lustre, with an endless ladder of puzzles ranked by search

main
klot.ski / test / klotski / store_test.gleam
store_test.gleam 2.0K
1import gleam/option.{Some}2import gleeunit/should3import klotski/store45/// The envelope is the whole point of the format: a schema version to migrate6/// against and a monotonic counter rather than a wall clock, so a later sync can7/// merge by "which write came after" without trusting two devices to agree on8/// the time. None of that is worth anything if the payload does not survive the9/// round trip.10pub fn a_save_survives_the_round_trip_test() {11 let #(save, _) =12 store.record(13 save: store.fresh(),14 family_id: "classic",15 rung: 1,16 optimal: 14,17 steps: 14,18 ms: 4742,19 score: 1.9,20 detours: 0,21 worst_detour: 0,22 now: 1_786_078_332,23 today: "2026-08-07",24 )25 let restored = store.decode(store.encode(save))2627 restored.totals |> should.equal(save.totals)28 restored.days |> should.equal(save.days)29 restored.log |> should.equal(save.log)30 // The ladder only advances on a first clear, so a cleared rung 1 leaves the31 // family sitting on rung 2.32 store.record_for(restored, "classic").rung |> should.equal(2)33 store.record_for(restored, "classic").best |> should.equal([#(1, 14)])34}3536pub fn a_corrupt_save_is_a_fresh_one_test() {37 store.decode("not json at all") |> should.equal(store.fresh())38 store.decode("") |> should.equal(store.fresh())39}4041/// A streak survives a gap of one day, because "yesterday" should still count42/// while today is still going. Two days is a break.43pub fn a_streak_survives_one_day_and_not_two_test() {44 let start =45 store.stamp_day(store.Days(option.None, option.None, 0, 0), "2026-08-05")46 start.streak |> should.equal(1)4748 let next = store.stamp_day(start, "2026-08-06")49 next.streak |> should.equal(2)50 next.best |> should.equal(2)5152 // Same day again changes nothing.53 store.stamp_day(next, "2026-08-06").streak |> should.equal(2)5455 let broken = store.stamp_day(next, "2026-08-08")56 broken.streak |> should.equal(1)57 // The best is kept even once the run is over.58 broken.best |> should.equal(2)59 broken.first |> should.equal(Some("2026-08-05"))60}