module Snake.Tests.M10Extensions open Expecto open Snake open Snake.Model open Snake.IO open Snake.Stream open Snake.Tests.Fixtures open Snake.Tests.M09Helpers let private frameTimes = [ 25L; 50L; 75L; 100L; 125L; 150L; 175L; 200L ] [] let tests = testList "M10 Extensions" [ yield! fixtureTests "m10-update" "update" (fun c -> Expect.equal (Game.update (gameState (arg 0 c)) (action (arg 1 c))) (gameState (expected c)) "update") yield! fixtureTests "m10-moves-every" "movesEvery" (fun c -> Expect.equal (Game.movesEvery (num (arg 0 c))) (num (expected c)) "movesEvery") yield! fixtureTests "m10-input" "keyToAction" (fun c -> Expect.equal (Input.keyToAction (str (arg 0 c))) (opt action (expected c)) "keyToAction") testCase "the animation clock runs every 25 ms" (fun () -> Expect.equal App.FRAME_MS 25L "FRAME_MS") testCase "speedActions turns the clock into Frame actions every 25 ms" (fun () -> Expect.equal (Stream.run (List.map Time frameTimes) App.speedActions) (List.replicate 8 Frame) "actions") testCase "speedActions still turns keys into actions, including pause and restart" (fun () -> Expect.equal (Stream.run [ KeyDown " "; KeyDown "r"; KeyDown "ArrowUp" ] App.speedActions) [ TogglePause; Restart; Turn Up ] "actions") testCase "main (seed 42) draws a moved snake after eight 25 ms frames" (fun () -> let traced = IO.trace 42u (App.main ()) Expect.equal traced.Ops [ RandomSeed ] "ops" let first, afterFirst = Stream.step (Time 0L) traced.Result Expect.equal (drawn (List.head first)) (View.view (Spawn.newGame 42u)) "first drawing" let drawings = Stream.run (List.map Time frameTimes) afterFirst Expect.equal (List.length drawings) 8 "eight drawings" let start = Spawn.newGame 42u let moved = { start with Snake = start.Snake |> List.map (fun p -> { p with X = p.X + 1 }) Frame = 8 } Expect.equal (drawn drawings[7]) (View.view moved) "moved snake") ]