feat(course): audit fixes and twelve extensions (Modules 7b, 12, 13)

Audit pass:
- Frame rule counts frames since the last move, so every step lasts
  exactly movesEvery(score) frames, also right after a speed-up
- clampTime + MAX_GAP_MS: a hidden tab no longer replays the whole gap
- Pong Restart keeps held keys
- Fact corrections (mulberry32 output coverage, Haskell IO, uniform)
- New fixture cases from a mutation analysis

Extensions (all three tracks, shared fixtures, course text):
- Turn queue (Exercise 10.6), persisted high score (10.7),
  replay viewer (10.8), play() end-to-end helper (9.5)
- Optional State (4.7) and optional Module 7b, stack-safe IO
- Module 12, property-based testing with generators, shrinking,
  invariants and a model-based oracle
- Module 13, Conway's Life with a Click event
- JS type checking via jsconfig, JSDoc and types.d.ts
- Maintainer tools: scripts/mutate.mjs, scripts/typecheck-js.sh,
  Playwright end-to-end suite (e2e/, scripts/e2e.sh)

Docs: docs/contract.md is the canonical contract; specs and build log
under docs/superpowers.

Verified: JS 728, Scala 689, F# 691 unit tests; stubs and progression
M01-M13 and M07b; 176 end-to-end tests on Chromium and WebKit.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Fable 5.2 committed 2026-11-11 12:05:29 +01:00
1 parent 876f5aabb1
commit edd57f0148
253 files changed
+21753 -503

No files matched your search

+4 -2
View File
@@ -29,7 +29,8 @@
"seed": 7,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -60,7 +61,8 @@
"seed": 4294967295,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
}
]
+48 -24
View File
@@ -27,7 +27,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -53,7 +54,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -82,7 +84,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -108,7 +111,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -140,7 +144,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -169,7 +174,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -201,7 +207,8 @@
"seed": 1,
"score": 4,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -231,7 +238,8 @@
"seed": 1,
"score": 5,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -260,7 +268,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -286,7 +295,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -315,7 +325,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -341,7 +352,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -378,7 +390,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -412,7 +425,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -445,7 +459,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -475,7 +490,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -511,7 +527,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -544,7 +561,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -573,7 +591,8 @@
"seed": 1,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -599,7 +618,8 @@
"seed": 1,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -628,7 +648,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -654,7 +675,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -683,7 +705,8 @@
"seed": 1,
"score": 0,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -709,7 +732,8 @@
"seed": 1,
"score": 0,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
}
}
]
+14 -7
View File
@@ -27,7 +27,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"x": 0,
@@ -62,7 +63,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"x": 19,
@@ -97,7 +99,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"x": -1,
@@ -132,7 +135,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"x": 0,
@@ -167,7 +171,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"x": 20,
@@ -202,7 +207,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"x": 5,
@@ -237,7 +243,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"x": 10,
+32 -16
View File
@@ -27,7 +27,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
"Up"
],
@@ -54,7 +55,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -83,7 +85,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
"Right"
],
@@ -110,7 +113,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -139,7 +143,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
"Left"
],
@@ -166,7 +171,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -195,7 +201,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
"Down"
],
@@ -222,7 +229,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -251,7 +259,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
"Left"
],
@@ -278,7 +287,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -307,7 +317,8 @@
"seed": 1,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
},
"Up"
],
@@ -334,7 +345,8 @@
"seed": 1,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -363,7 +375,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
},
"Up"
],
@@ -390,7 +403,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -419,7 +433,8 @@
"seed": 1,
"score": 0,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
},
"Up"
],
@@ -446,7 +461,8 @@
"seed": 1,
"score": 0,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
}
}
]
+10 -5
View File
@@ -19,7 +19,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -67,7 +68,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -115,7 +117,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -158,7 +161,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -218,7 +222,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": []
+4 -2
View File
@@ -32,7 +32,8 @@
"seed": 1831565813,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -66,7 +67,8 @@
"seed": 1831565855,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
}
]
+32 -16
View File
@@ -23,7 +23,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -48,7 +49,8 @@
"seed": 1831565813,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -73,7 +75,8 @@
"seed": 1,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -98,7 +101,8 @@
"seed": 1831565814,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -135,7 +139,8 @@
"seed": 7,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -172,7 +177,8 @@
"seed": 1831565820,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -213,7 +219,8 @@
"seed": 5,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -251,7 +258,8 @@
"seed": 5,
"score": 0,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -279,7 +287,8 @@
"seed": 5,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -304,7 +313,8 @@
"seed": 5,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -329,7 +339,8 @@
"seed": 5,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -351,7 +362,8 @@
"seed": 5,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -376,7 +388,8 @@
"seed": 5,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -398,7 +411,8 @@
"seed": 5,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -423,7 +437,8 @@
"seed": 5,
"score": 0,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -445,7 +460,8 @@
"seed": 5,
"score": 0,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
}
}
]
+80 -8
View File
@@ -22,7 +22,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -47,7 +48,8 @@
"seed": 1831565813,
"score": 1,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -71,7 +73,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -92,7 +95,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -116,7 +120,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -137,7 +142,8 @@
"seed": 0,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -161,7 +167,8 @@
"seed": 0,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": {
@@ -182,7 +189,72 @@
"seed": 0,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
"name": "eating-the-last-free-cell-wins",
"args": [
{
"width": 2,
"height": 2,
"snake": [
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 1
},
{
"x": 1,
"y": 1
}
],
"dir": "Up",
"nextDir": "Right",
"apple": {
"x": 1,
"y": 0
},
"seed": 7,
"score": 2,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": {
"width": 2,
"height": 2,
"snake": [
{
"x": 1,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 1
},
{
"x": 1,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": null,
"seed": 7,
"score": 3,
"status": "Won",
"frame": 0,
"queued": null
}
}
]
+14 -7
View File
@@ -22,7 +22,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
[]
],
@@ -45,7 +46,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
]
},
@@ -70,7 +72,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
[
{
@@ -104,7 +107,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"width": 3,
@@ -124,7 +128,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"width": 3,
@@ -144,7 +149,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"width": 3,
@@ -164,7 +170,8 @@
"seed": 0,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
]
}
+8 -4
View File
@@ -30,7 +30,8 @@
"seed": 1831565855,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
[
{
@@ -103,7 +104,8 @@
"seed": 3663131668,
"score": 1,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -135,7 +137,8 @@
"seed": 1831565855,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
[]
],
@@ -165,7 +168,8 @@
"seed": 1831565855,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
}
]
+28 -14
View File
@@ -22,7 +22,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"tag": "Tick"
@@ -46,7 +47,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -70,7 +72,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"tag": "Tick"
@@ -98,7 +101,8 @@
"seed": 1831565813,
"score": 1,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -122,7 +126,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"tag": "Tick"
@@ -146,7 +151,8 @@
"seed": 0,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -170,7 +176,8 @@
"seed": 0,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
},
{
"tag": "Tick"
@@ -194,7 +201,8 @@
"seed": 0,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -218,7 +226,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"tag": "Turn",
@@ -243,7 +252,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -267,7 +277,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
},
{
"tag": "Turn",
@@ -292,7 +303,8 @@
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
},
{
@@ -316,7 +328,8 @@
"seed": 0,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
},
{
"tag": "Turn",
@@ -341,7 +354,8 @@
"seed": 0,
"score": 0,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
}
]
+10 -5
View File
@@ -26,7 +26,8 @@
"seed": 0,
"score": 5,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -95,7 +96,8 @@
"seed": 0,
"score": 5,
"status": "Playing",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -159,7 +161,8 @@
"seed": 0,
"score": 5,
"status": "Paused",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -250,7 +253,8 @@
"seed": 1,
"score": 0,
"status": "GameOver",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
@@ -337,7 +341,8 @@
"seed": 0,
"score": 5,
"status": "Won",
"frame": 0
"frame": 0,
"queued": null
}
],
"expected": [
+694
View File
@@ -0,0 +1,694 @@
{
"function": "play",
"cases": [
{
"name": "seed-42-eats-three-apples-with-no-stored-best",
"args": [
42,
[
{
"tag": "KeyDown",
"key": "ArrowUp"
},
{
"tag": "Time",
"t": 200
},
{
"tag": "KeyDown",
"key": "ArrowLeft"
},
{
"tag": "Time",
"t": 450
},
{
"tag": "Time",
"t": 700
},
{
"tag": "Time",
"t": 950
},
{
"tag": "Time",
"t": 1200
},
{
"tag": "Time",
"t": 1450
},
{
"tag": "Time",
"t": 1700
},
{
"tag": "Time",
"t": 1950
},
{
"tag": "Time",
"t": 2000
},
{
"tag": "KeyDown",
"key": "ArrowUp"
},
{
"tag": "Time",
"t": 2250
},
{
"tag": "Time",
"t": 2500
},
{
"tag": "Time",
"t": 2750
},
{
"tag": "Time",
"t": 2800
},
{
"tag": "KeyDown",
"key": "ArrowRight"
},
{
"tag": "Time",
"t": 3050
},
{
"tag": "Time",
"t": 3300
},
{
"tag": "Time",
"t": 3550
},
{
"tag": "Time",
"t": 3800
},
{
"tag": "Time",
"t": 4050
},
{
"tag": "Time",
"t": 4300
},
{
"tag": "Time",
"t": 4550
},
{
"tag": "Time",
"t": 4800
},
{
"tag": "Time",
"t": 5050
},
{
"tag": "Time",
"t": 5300
},
{
"tag": "Time",
"t": 5400
},
{
"tag": "KeyDown",
"key": "ArrowUp"
},
{
"tag": "Time",
"t": 5650
},
{
"tag": "Time",
"t": 5900
},
{
"tag": "Time",
"t": 6150
},
{
"tag": "Time",
"t": 6200
}
],
0
],
"expected": [
{
"tag": "Rect",
"x": 0,
"y": 0,
"w": 400,
"h": 400,
"color": "#111111"
},
{
"tag": "Rect",
"x": 21,
"y": 161,
"w": 18,
"h": 18,
"color": "#e53935"
},
{
"tag": "Rect",
"x": 281,
"y": 21,
"w": 18,
"h": 18,
"color": "#7cb342"
},
{
"tag": "Rect",
"x": 281,
"y": 41,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 281,
"y": 61,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 281,
"y": 81,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 281,
"y": 101,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 261,
"y": 101,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Text",
"x": 6,
"y": 18,
"text": "Score: 3",
"color": "#ffffff",
"size": 16,
"align": "left"
},
{
"tag": "Text",
"x": 394,
"y": 18,
"text": "Best: 3",
"color": "#ffffff",
"size": 16,
"align": "right"
}
]
},
{
"name": "seed-7-beats-a-stored-best-of-2-and-hits-the-wall",
"args": [
7,
[
{
"tag": "Time",
"t": 250
},
{
"tag": "Time",
"t": 500
},
{
"tag": "Time",
"t": 750
},
{
"tag": "Time",
"t": 1000
},
{
"tag": "Time",
"t": 1250
},
{
"tag": "Time",
"t": 1500
},
{
"tag": "Time",
"t": 1750
},
{
"tag": "Time",
"t": 1800
},
{
"tag": "KeyDown",
"key": "ArrowDown"
},
{
"tag": "Time",
"t": 2050
},
{
"tag": "Time",
"t": 2200
},
{
"tag": "KeyDown",
"key": "ArrowLeft"
},
{
"tag": "Time",
"t": 2450
},
{
"tag": "Time",
"t": 2700
},
{
"tag": "Time",
"t": 2950
},
{
"tag": "Time",
"t": 3200
},
{
"tag": "KeyDown",
"key": "ArrowDown"
},
{
"tag": "Time",
"t": 3450
},
{
"tag": "Time",
"t": 3700
},
{
"tag": "Time",
"t": 3950
},
{
"tag": "Time",
"t": 4200
},
{
"tag": "KeyDown",
"key": "ArrowLeft"
},
{
"tag": "Time",
"t": 4375
},
{
"tag": "KeyDown",
"key": "ArrowUp"
},
{
"tag": "Time",
"t": 4625
},
{
"tag": "Time",
"t": 4875
},
{
"tag": "Time",
"t": 5125
},
{
"tag": "Time",
"t": 5375
},
{
"tag": "Time",
"t": 5600
},
{
"tag": "KeyDown",
"key": "ArrowRight"
},
{
"tag": "Time",
"t": 5850
},
{
"tag": "Time",
"t": 6100
},
{
"tag": "Time",
"t": 6350
},
{
"tag": "Time",
"t": 6600
},
{
"tag": "Time",
"t": 6825
}
],
2
],
"expected": [
{
"tag": "Rect",
"x": 0,
"y": 0,
"w": 400,
"h": 400,
"color": "#111111"
},
{
"tag": "Rect",
"x": 321,
"y": 81,
"w": 18,
"h": 18,
"color": "#e53935"
},
{
"tag": "Rect",
"x": 381,
"y": 201,
"w": 18,
"h": 18,
"color": "#7cb342"
},
{
"tag": "Rect",
"x": 361,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 341,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 321,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 301,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 281,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 261,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Text",
"x": 6,
"y": 18,
"text": "Score: 4",
"color": "#ffffff",
"size": 16,
"align": "left"
},
{
"tag": "Text",
"x": 200,
"y": 200,
"text": "Game Over",
"color": "#ffffff",
"size": 32,
"align": "center"
},
{
"tag": "Text",
"x": 200,
"y": 230,
"text": "Press R to restart",
"color": "#ffffff",
"size": 16,
"align": "center"
},
{
"tag": "Text",
"x": 394,
"y": 18,
"text": "Best: 4",
"color": "#ffffff",
"size": 16,
"align": "right"
}
]
},
{
"name": "seed-42-restart-after-game-over-keeps-the-best",
"args": [
42,
[
{
"tag": "KeyDown",
"key": "ArrowUp"
},
{
"tag": "Time",
"t": 200
},
{
"tag": "KeyDown",
"key": "ArrowLeft"
},
{
"tag": "Time",
"t": 450
},
{
"tag": "Time",
"t": 700
},
{
"tag": "Time",
"t": 950
},
{
"tag": "Time",
"t": 1200
},
{
"tag": "Time",
"t": 1450
},
{
"tag": "Time",
"t": 1700
},
{
"tag": "Time",
"t": 1950
},
{
"tag": "Time",
"t": 2000
},
{
"tag": "KeyDown",
"key": "ArrowUp"
},
{
"tag": "Time",
"t": 2250
},
{
"tag": "Time",
"t": 2500
},
{
"tag": "Time",
"t": 2750
},
{
"tag": "Time",
"t": 2800
},
{
"tag": "KeyDown",
"key": "ArrowRight"
},
{
"tag": "Time",
"t": 3050
},
{
"tag": "Time",
"t": 3300
},
{
"tag": "Time",
"t": 3550
},
{
"tag": "Time",
"t": 3800
},
{
"tag": "Time",
"t": 4050
},
{
"tag": "Time",
"t": 4300
},
{
"tag": "Time",
"t": 4550
},
{
"tag": "Time",
"t": 4800
},
{
"tag": "Time",
"t": 5050
},
{
"tag": "Time",
"t": 5300
},
{
"tag": "Time",
"t": 5550
},
{
"tag": "Time",
"t": 5800
},
{
"tag": "Time",
"t": 6050
},
{
"tag": "Time",
"t": 6300
},
{
"tag": "Time",
"t": 6550
},
{
"tag": "Time",
"t": 6600
},
{
"tag": "KeyDown",
"key": "r"
}
],
0
],
"expected": [
{
"tag": "Rect",
"x": 0,
"y": 0,
"w": 400,
"h": 400,
"color": "#111111"
},
{
"tag": "Rect",
"x": 261,
"y": 61,
"w": 18,
"h": 18,
"color": "#e53935"
},
{
"tag": "Rect",
"x": 201,
"y": 201,
"w": 18,
"h": 18,
"color": "#7cb342"
},
{
"tag": "Rect",
"x": 181,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Rect",
"x": 161,
"y": 201,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Text",
"x": 6,
"y": 18,
"text": "Score: 0",
"color": "#ffffff",
"size": 16,
"align": "left"
},
{
"tag": "Text",
"x": 394,
"y": 18,
"text": "Best: 2",
"color": "#ffffff",
"size": 16,
"align": "right"
}
]
}
]
}
+756
View File
@@ -0,0 +1,756 @@
{
"function": "sessionUpdate",
"cases": [
{
"name": "a-step-without-eating-keeps-the-best",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 2,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 5,
"improved": false
},
{
"tag": "Tick"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 2,
"y": 1
},
{
"x": 1,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 2,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 5,
"improved": false
}
},
{
"name": "the-first-apple-with-no-record-is-an-improvement",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 5,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 0,
"improved": false
},
{
"tag": "Tick"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 2,
"y": 1
},
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 1831565818,
"score": 1,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 1,
"improved": true
}
},
{
"name": "eating-past-the-record-raises-the-best",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 5,
"score": 5,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 5,
"improved": false
},
{
"tag": "Tick"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 2,
"y": 1
},
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 1831565818,
"score": 6,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 6,
"improved": true
}
},
{
"name": "eating-below-the-record-keeps-the-best",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 5,
"score": 1,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 5,
"improved": false
},
{
"tag": "Tick"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 2,
"y": 1
},
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 1831565818,
"score": 2,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 5,
"improved": false
}
},
{
"name": "equalling-the-record-is-not-an-improvement",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 5,
"score": 4,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 5,
"improved": false
},
{
"tag": "Tick"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 2,
"y": 1
},
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 1831565818,
"score": 5,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 5,
"improved": false
}
},
{
"name": "the-next-action-clears-improved",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 6,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 6,
"improved": true
},
{
"tag": "Turn",
"dir": "Up"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Up",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 6,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 6,
"improved": false
}
},
{
"name": "a-frame-that-steps-and-eats-raises-the-best",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 5,
"score": 3,
"status": "Playing",
"frame": 6,
"queued": null
},
"best": 3,
"improved": false
},
{
"tag": "Frame"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 2,
"y": 1
},
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 1831565818,
"score": 4,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 4,
"improved": true
}
},
{
"name": "a-frame-that-only-counts-keeps-the-best-and-clears-improved",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 3,
"status": "Playing",
"frame": 1,
"queued": null
},
"best": 3,
"improved": true
},
{
"tag": "Frame"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 3,
"status": "Playing",
"frame": 2,
"queued": null
},
"best": 3,
"improved": false
}
},
{
"name": "game-over-keeps-the-best",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 3,
"y": 1
},
{
"x": 2,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 4,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 4,
"improved": false
},
{
"tag": "Tick"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 3,
"y": 1
},
{
"x": 2,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 4,
"status": "GameOver",
"frame": 0,
"queued": null
},
"best": 4,
"improved": false
}
},
{
"name": "restart-keeps-the-best",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 6,
"status": "GameOver",
"frame": 0,
"queued": null
},
"best": 6,
"improved": false
},
{
"tag": "Restart"
}
],
"expected": {
"game": {
"width": 20,
"height": 20,
"snake": [
{
"x": 10,
"y": 10
},
{
"x": 9,
"y": 10
},
{
"x": 8,
"y": 10
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 11,
"y": 9
},
"seed": 1831565818,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 6,
"improved": false
}
},
{
"name": "pausing-keeps-the-best",
"args": [
{
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 2,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 9,
"improved": true
},
{
"tag": "TogglePause"
}
],
"expected": {
"game": {
"width": 4,
"height": 3,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 3,
"y": 0
},
"seed": 5,
"score": 2,
"status": "Paused",
"frame": 0,
"queued": null
},
"best": 9,
"improved": false
}
}
]
}
+281
View File
@@ -0,0 +1,281 @@
{
"function": "sessionView",
"cases": [
{
"name": "playing-adds-the-best-at-the-top-right",
"args": [
{
"game": {
"width": 3,
"height": 2,
"snake": [
{
"x": 1,
"y": 0
},
{
"x": 0,
"y": 0
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 0,
"score": 5,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 12,
"improved": false
}
],
"expected": [
{
"tag": "Rect",
"x": 0,
"y": 0,
"w": 60,
"h": 40,
"color": "#111111"
},
{
"tag": "Rect",
"x": 41,
"y": 21,
"w": 18,
"h": 18,
"color": "#e53935"
},
{
"tag": "Rect",
"x": 21,
"y": 1,
"w": 18,
"h": 18,
"color": "#7cb342"
},
{
"tag": "Rect",
"x": 1,
"y": 1,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Text",
"x": 6,
"y": 18,
"text": "Score: 5",
"color": "#ffffff",
"size": 16,
"align": "left"
},
{
"tag": "Text",
"x": 54,
"y": 18,
"text": "Best: 12",
"color": "#ffffff",
"size": 16,
"align": "right"
}
]
},
{
"name": "a-best-of-zero-is-shown-too",
"args": [
{
"game": {
"width": 3,
"height": 2,
"snake": [
{
"x": 1,
"y": 0
},
{
"x": 0,
"y": 0
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
},
"best": 0,
"improved": false
}
],
"expected": [
{
"tag": "Rect",
"x": 0,
"y": 0,
"w": 60,
"h": 40,
"color": "#111111"
},
{
"tag": "Rect",
"x": 41,
"y": 21,
"w": 18,
"h": 18,
"color": "#e53935"
},
{
"tag": "Rect",
"x": 21,
"y": 1,
"w": 18,
"h": 18,
"color": "#7cb342"
},
{
"tag": "Rect",
"x": 1,
"y": 1,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Text",
"x": 6,
"y": 18,
"text": "Score: 0",
"color": "#ffffff",
"size": 16,
"align": "left"
},
{
"tag": "Text",
"x": 54,
"y": 18,
"text": "Best: 0",
"color": "#ffffff",
"size": 16,
"align": "right"
}
]
},
{
"name": "game-over-shows-the-banner-and-then-the-best",
"args": [
{
"game": {
"width": 3,
"height": 2,
"snake": [
{
"x": 1,
"y": 0
},
{
"x": 0,
"y": 0
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 1
},
"seed": 0,
"score": 5,
"status": "GameOver",
"frame": 0,
"queued": null
},
"best": 7,
"improved": true
}
],
"expected": [
{
"tag": "Rect",
"x": 0,
"y": 0,
"w": 60,
"h": 40,
"color": "#111111"
},
{
"tag": "Rect",
"x": 41,
"y": 21,
"w": 18,
"h": 18,
"color": "#e53935"
},
{
"tag": "Rect",
"x": 21,
"y": 1,
"w": 18,
"h": 18,
"color": "#7cb342"
},
{
"tag": "Rect",
"x": 1,
"y": 1,
"w": 18,
"h": 18,
"color": "#43a047"
},
{
"tag": "Text",
"x": 6,
"y": 18,
"text": "Score: 5",
"color": "#ffffff",
"size": 16,
"align": "left"
},
{
"tag": "Text",
"x": 30,
"y": 20,
"text": "Game Over",
"color": "#ffffff",
"size": 32,
"align": "center"
},
{
"tag": "Text",
"x": 30,
"y": 50,
"text": "Press R to restart",
"color": "#ffffff",
"size": 16,
"align": "center"
},
{
"tag": "Text",
"x": 54,
"y": 18,
"text": "Best: 7",
"color": "#ffffff",
"size": 16,
"align": "right"
}
]
}
]
}
+1266 -54
View File
File diff suppressed because it is too large. Load diff
+19
View File
@@ -0,0 +1,19 @@
{
"function": "viewerKey",
"cases": [
{"name":"ArrowRight-is-next","args":["ArrowRight"],"expected":{"tag":"Next"}},
{"name":"d-is-next","args":["d"],"expected":{"tag":"Next"}},
{"name":"D-is-next","args":["D"],"expected":{"tag":"Next"}},
{"name":"ArrowLeft-is-prev","args":["ArrowLeft"],"expected":{"tag":"Prev"}},
{"name":"a-is-prev","args":["a"],"expected":{"tag":"Prev"}},
{"name":"A-is-prev","args":["A"],"expected":{"tag":"Prev"}},
{"name":"Home-is-first","args":["Home"],"expected":{"tag":"First"}},
{"name":"End-is-last","args":["End"],"expected":{"tag":"Last"}},
{"name":"space-toggles-play","args":[" "],"expected":{"tag":"TogglePlay"}},
{"name":"ArrowUp-is-not-bound","args":["ArrowUp"],"expected":null},
{"name":"r-is-not-bound","args":["r"],"expected":null},
{"name":"constructor-is-not-bound","args":["constructor"],"expected":null},
{"name":"toString-is-not-bound","args":["toString"],"expected":null},
{"name":"empty-string-is-not-bound","args":[""],"expected":null}
]
}
+23
View File
@@ -0,0 +1,23 @@
{
"function": "viewerUpdate",
"cases": [
{"name":"next-moves-one-frame-forward","args":[{"index":3,"last":10,"playing":false},{"tag":"Next"}],"expected":{"index":4,"last":10,"playing":false}},
{"name":"next-at-the-last-frame-stays","args":[{"index":10,"last":10,"playing":false},{"tag":"Next"}],"expected":{"index":10,"last":10,"playing":false}},
{"name":"prev-moves-one-frame-back","args":[{"index":3,"last":10,"playing":false},{"tag":"Prev"}],"expected":{"index":2,"last":10,"playing":false}},
{"name":"prev-at-the-first-frame-stays","args":[{"index":0,"last":10,"playing":false},{"tag":"Prev"}],"expected":{"index":0,"last":10,"playing":false}},
{"name":"first-goes-to-frame-zero","args":[{"index":7,"last":10,"playing":false},{"tag":"First"}],"expected":{"index":0,"last":10,"playing":false}},
{"name":"last-goes-to-the-last-frame","args":[{"index":2,"last":10,"playing":false},{"tag":"Last"}],"expected":{"index":10,"last":10,"playing":false}},
{"name":"toggle-play-starts-autoplay","args":[{"index":4,"last":10,"playing":false},{"tag":"TogglePlay"}],"expected":{"index":4,"last":10,"playing":true}},
{"name":"toggle-play-stops-autoplay","args":[{"index":4,"last":10,"playing":true},{"tag":"TogglePlay"}],"expected":{"index":4,"last":10,"playing":false}},
{"name":"toggle-play-at-the-end-starts-again-from-the-first-frame","args":[{"index":10,"last":10,"playing":false},{"tag":"TogglePlay"}],"expected":{"index":0,"last":10,"playing":true}},
{"name":"beat-while-playing-moves-one-frame-forward","args":[{"index":4,"last":10,"playing":true},{"tag":"Beat"}],"expected":{"index":5,"last":10,"playing":true}},
{"name":"beat-while-not-playing-is-ignored","args":[{"index":4,"last":10,"playing":false},{"tag":"Beat"}],"expected":{"index":4,"last":10,"playing":false}},
{"name":"beat-that-reaches-the-last-frame-stops-autoplay","args":[{"index":9,"last":10,"playing":true},{"tag":"Beat"}],"expected":{"index":10,"last":10,"playing":false}},
{"name":"next-while-playing-keeps-playing","args":[{"index":4,"last":10,"playing":true},{"tag":"Next"}],"expected":{"index":5,"last":10,"playing":true}},
{"name":"prev-while-playing-keeps-playing","args":[{"index":4,"last":10,"playing":true},{"tag":"Prev"}],"expected":{"index":3,"last":10,"playing":true}},
{"name":"last-while-playing-stops-autoplay","args":[{"index":4,"last":10,"playing":true},{"tag":"Last"}],"expected":{"index":10,"last":10,"playing":false}},
{"name":"first-while-playing-keeps-playing","args":[{"index":4,"last":10,"playing":true},{"tag":"First"}],"expected":{"index":0,"last":10,"playing":true}},
{"name":"a-recording-with-no-actions-cannot-play","args":[{"index":0,"last":0,"playing":false},{"tag":"TogglePlay"}],"expected":{"index":0,"last":0,"playing":false}},
{"name":"a-recording-with-no-actions-stays-at-frame-zero","args":[{"index":0,"last":0,"playing":false},{"tag":"Next"}],"expected":{"index":0,"last":0,"playing":false}}
]
}
+8
View File
@@ -0,0 +1,8 @@
{
"function": "viewerView",
"cases": [
{"name":"first-frame-not-playing","args":[[{"width":20,"height":20,"snake":[{"x":10,"y":10},{"x":9,"y":10},{"x":8,"y":10}],"dir":"Right","nextDir":"Right","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null},{"width":20,"height":20,"snake":[{"x":11,"y":10},{"x":10,"y":10},{"x":9,"y":10}],"dir":"Right","nextDir":"Right","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null},{"width":20,"height":20,"snake":[{"x":11,"y":10},{"x":10,"y":10},{"x":9,"y":10}],"dir":"Right","nextDir":"Up","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null}],{"index":0,"last":2,"playing":false}],"expected":[{"tag":"Rect","x":0,"y":0,"w":400,"h":400,"color":"#111111"},{"tag":"Rect","x":21,"y":181,"w":18,"h":18,"color":"#e53935"},{"tag":"Rect","x":201,"y":201,"w":18,"h":18,"color":"#7cb342"},{"tag":"Rect","x":181,"y":201,"w":18,"h":18,"color":"#43a047"},{"tag":"Rect","x":161,"y":201,"w":18,"h":18,"color":"#43a047"},{"tag":"Text","x":6,"y":18,"text":"Score: 0","color":"#ffffff","size":16,"align":"left"},{"tag":"Text","x":394,"y":18,"text":"step 0 / 2","color":"#ffffff","size":16,"align":"right"},{"tag":"Text","x":200,"y":392,"text":"Left/Right: step Home/End: jump Space: play","color":"#aaaaaa","size":12,"align":"center"}]},
{"name":"middle-frame-while-playing","args":[[{"width":20,"height":20,"snake":[{"x":10,"y":10},{"x":9,"y":10},{"x":8,"y":10}],"dir":"Right","nextDir":"Right","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null},{"width":20,"height":20,"snake":[{"x":11,"y":10},{"x":10,"y":10},{"x":9,"y":10}],"dir":"Right","nextDir":"Right","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null},{"width":20,"height":20,"snake":[{"x":11,"y":10},{"x":10,"y":10},{"x":9,"y":10}],"dir":"Right","nextDir":"Up","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null}],{"index":1,"last":2,"playing":true}],"expected":[{"tag":"Rect","x":0,"y":0,"w":400,"h":400,"color":"#111111"},{"tag":"Rect","x":21,"y":181,"w":18,"h":18,"color":"#e53935"},{"tag":"Rect","x":221,"y":201,"w":18,"h":18,"color":"#7cb342"},{"tag":"Rect","x":201,"y":201,"w":18,"h":18,"color":"#43a047"},{"tag":"Rect","x":181,"y":201,"w":18,"h":18,"color":"#43a047"},{"tag":"Text","x":6,"y":18,"text":"Score: 0","color":"#ffffff","size":16,"align":"left"},{"tag":"Text","x":394,"y":18,"text":"step 1 / 2","color":"#ffffff","size":16,"align":"right"},{"tag":"Text","x":200,"y":392,"text":"Space: pause","color":"#aaaaaa","size":12,"align":"center"}]},
{"name":"last-frame","args":[[{"width":20,"height":20,"snake":[{"x":10,"y":10},{"x":9,"y":10},{"x":8,"y":10}],"dir":"Right","nextDir":"Right","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null},{"width":20,"height":20,"snake":[{"x":11,"y":10},{"x":10,"y":10},{"x":9,"y":10}],"dir":"Right","nextDir":"Right","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null},{"width":20,"height":20,"snake":[{"x":11,"y":10},{"x":10,"y":10},{"x":9,"y":10}],"dir":"Right","nextDir":"Up","apple":{"x":1,"y":9},"seed":1831565855,"score":0,"status":"Playing","frame":0,"queued":null}],{"index":2,"last":2,"playing":false}],"expected":[{"tag":"Rect","x":0,"y":0,"w":400,"h":400,"color":"#111111"},{"tag":"Rect","x":21,"y":181,"w":18,"h":18,"color":"#e53935"},{"tag":"Rect","x":221,"y":201,"w":18,"h":18,"color":"#7cb342"},{"tag":"Rect","x":201,"y":201,"w":18,"h":18,"color":"#43a047"},{"tag":"Rect","x":181,"y":201,"w":18,"h":18,"color":"#43a047"},{"tag":"Text","x":6,"y":18,"text":"Score: 0","color":"#ffffff","size":16,"align":"left"},{"tag":"Text","x":394,"y":18,"text":"step 2 / 2","color":"#ffffff","size":16,"align":"right"},{"tag":"Text","x":200,"y":392,"text":"Left/Right: step Home/End: jump Space: play","color":"#aaaaaa","size":12,"align":"center"}]}
]
}
+326 -2
View File
@@ -2156,8 +2156,8 @@
"player": 21,
"cpu": 21,
"held": {
"up": false,
"down": false
"up": true,
"down": true
},
"score": {
"player": 0,
@@ -2331,6 +2331,330 @@
"seed": 0,
"frame": 0
}
},
{
"name": "player-paddle-catches-the-ball-at-its-first-row",
"args": [
{
"ball": {
"x": 3,
"y": 19
},
"vel": {
"dx": -1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 0
},
{
"tag": "Frame"
}
],
"expected": {
"ball": {
"x": 3,
"y": 20
},
"vel": {
"dx": 1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 1
}
},
{
"name": "ball-may-enter-the-top-row",
"args": [
{
"ball": {
"x": 40,
"y": 1
},
"vel": {
"dx": 1,
"dy": -1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 0
},
{
"tag": "Frame"
}
],
"expected": {
"ball": {
"x": 41,
"y": 0
},
"vel": {
"dx": 1,
"dy": -1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 1
}
},
{
"name": "ball-may-enter-the-bottom-row",
"args": [
{
"ball": {
"x": 40,
"y": 48
},
"vel": {
"dx": 1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 0
},
{
"tag": "Frame"
}
],
"expected": {
"ball": {
"x": 41,
"y": 49
},
"vel": {
"dx": 1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 1
}
},
{
"name": "ball-in-column-zero-is-still-in-play",
"args": [
{
"ball": {
"x": 1,
"y": 40
},
"vel": {
"dx": -1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 0
},
{
"tag": "Frame"
}
],
"expected": {
"ball": {
"x": 0,
"y": 41
},
"vel": {
"dx": -1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 1
}
},
{
"name": "ball-in-the-last-column-is-still-in-play",
"args": [
{
"ball": {
"x": 78,
"y": 40
},
"vel": {
"dx": 1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 0
},
{
"tag": "Frame"
}
],
"expected": {
"ball": {
"x": 79,
"y": 41
},
"vel": {
"dx": 1,
"dy": 1
},
"player": 20,
"cpu": 21,
"held": {
"up": false,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 1
}
},
{
"name": "restart-keeps-the-held-keys",
"args": [
{
"ball": {
"x": 3,
"y": 24
},
"vel": {
"dx": -1,
"dy": 1
},
"player": 3,
"cpu": 21,
"held": {
"up": true,
"down": false
},
"score": {
"player": 1,
"cpu": 4
},
"status": "Playing",
"seed": 0,
"frame": 250
},
{
"tag": "Restart"
}
],
"expected": {
"ball": {
"x": 40,
"y": 25
},
"vel": {
"dx": 1,
"dy": 1
},
"player": 21,
"cpu": 21,
"held": {
"up": true,
"down": false
},
"score": {
"player": 0,
"cpu": 0
},
"status": "Playing",
"seed": 0,
"frame": 0
}
}
]
}
+756
View File
@@ -0,0 +1,756 @@
{
"function": "violations",
"cases": [
{
"name": "a-sane-state-has-no-violations",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": []
},
{
"name": "no-apple-is-fine",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": null,
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": []
},
{
"name": "a-pending-perpendicular-turn-is-fine",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Up",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": []
},
{
"name": "a-one-cell-snake-is-fine",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 0,
"y": 0
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": []
},
{
"name": "a-game-over-state-can-be-sane",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 4,
"y": 2
},
{
"x": 3,
"y": 2
},
{
"x": 2,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "GameOver",
"frame": 0,
"queued": null
}
],
"expected": []
},
{
"name": "empty-snake",
"args": [
{
"width": 5,
"height": 5,
"snake": [],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-not-empty"
]
},
{
"name": "head-off-the-right-edge",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 5,
"y": 2
},
{
"x": 4,
"y": 2
},
{
"x": 3,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-in-bounds"
]
},
{
"name": "tail-above-the-board",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 1,
"y": 1
},
{
"x": 1,
"y": 0
},
{
"x": 1,
"y": -1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-in-bounds"
]
},
{
"name": "head-on-its-own-body",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 2,
"y": 3
},
{
"x": 1,
"y": 3
},
{
"x": 1,
"y": 2
},
{
"x": 2,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-no-overlap"
]
},
{
"name": "snake-with-a-gap",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 3,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-connected"
]
},
{
"name": "snake-with-a-diagonal-step",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 1
},
{
"x": 0,
"y": 1
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-connected"
]
},
{
"name": "apple-outside-the-board",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 5,
"y": 0
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"apple-in-bounds"
]
},
{
"name": "apple-on-the-head",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 2,
"y": 2
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"apple-not-on-snake"
]
},
{
"name": "apple-on-the-tail",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 0,
"y": 2
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"apple-not-on-snake"
]
},
{
"name": "pending-turn-straight-back",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Left",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"turn-not-reversed"
]
},
{
"name": "pending-turn-straight-back-vertical",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Up",
"nextDir": "Down",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"turn-not-reversed"
]
},
{
"name": "several-violations-are-listed-in-order",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 5,
"y": 2
},
{
"x": 3,
"y": 2
},
{
"x": 3,
"y": 2
}
],
"dir": "Right",
"nextDir": "Left",
"apple": {
"x": 3,
"y": 2
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-in-bounds",
"snake-no-overlap",
"snake-connected",
"apple-not-on-snake",
"turn-not-reversed"
]
},
{
"name": "doubled-cell-counts-as-overlap-and-as-disconnected",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 2,
"y": 2
}
],
"dir": "Right",
"nextDir": "Right",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": null
}
],
"expected": [
"snake-no-overlap",
"snake-connected"
]
},
{
"name": "a-queued-turn-is-fine",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Up",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": "Left"
}
],
"expected": []
},
{
"name": "queued-turn-straight-back-from-the-pending-turn",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Up",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": "Down"
}
],
"expected": [
"queued-not-reversed"
]
},
{
"name": "reversed-pending-turn-and-reversed-queue-are-both-listed",
"args": [
{
"width": 5,
"height": 5,
"snake": [
{
"x": 2,
"y": 2
},
{
"x": 1,
"y": 2
},
{
"x": 0,
"y": 2
}
],
"dir": "Right",
"nextDir": "Left",
"apple": {
"x": 4,
"y": 4
},
"seed": 0,
"score": 0,
"status": "Playing",
"frame": 0,
"queued": "Right"
}
],
"expected": [
"turn-not-reversed",
"queued-not-reversed"
]
}
]
}
+15
View File
@@ -0,0 +1,15 @@
{
"function": "lifeClick",
"cases": [
{"name":"the-top-left-pixel-is-cell-0-0","args":[0,0],"expected":{"tag":"Toggle","cell":{"x":0,"y":0}}},
{"name":"the-last-pixel-of-the-first-cell","args":[15,15],"expected":{"tag":"Toggle","cell":{"x":0,"y":0}}},
{"name":"the-next-pixel-is-the-next-cell","args":[16,0],"expected":{"tag":"Toggle","cell":{"x":1,"y":0}}},
{"name":"the-row-below","args":[3,16],"expected":{"tag":"Toggle","cell":{"x":0,"y":1}}},
{"name":"a-pixel-in-the-middle","args":[100,250],"expected":{"tag":"Toggle","cell":{"x":6,"y":15}}},
{"name":"the-bottom-right-pixel-of-the-board","args":[639,479],"expected":{"tag":"Toggle","cell":{"x":39,"y":29}}},
{"name":"right-of-the-board-is-nothing","args":[640,10],"expected":null},
{"name":"the-status-strip-under-the-board-is-nothing","args":[10,480],"expected":null},
{"name":"left-of-the-board-is-nothing","args":[-1,10],"expected":null},
{"name":"above-the-board-is-nothing","args":[10,-1],"expected":null}
]
}
+17
View File
@@ -0,0 +1,17 @@
{
"function": "lifeKey",
"cases": [
{"name":"space-toggles-pause","args":[" "],"expected":{"tag":"TogglePause"}},
{"name":"n-steps","args":["n"],"expected":{"tag":"Step"}},
{"name":"N-steps","args":["N"],"expected":{"tag":"Step"}},
{"name":"c-clears","args":["c"],"expected":{"tag":"Clear"}},
{"name":"C-clears","args":["C"],"expected":{"tag":"Clear"}},
{"name":"r-randomizes","args":["r"],"expected":{"tag":"Randomize"}},
{"name":"R-randomizes","args":["R"],"expected":{"tag":"Randomize"}},
{"name":"ArrowUp-is-not-bound","args":["ArrowUp"],"expected":null},
{"name":"Enter-is-not-bound","args":["Enter"],"expected":null},
{"name":"constructor-is-not-bound","args":["constructor"],"expected":null},
{"name":"toString-is-not-bound","args":["toString"],"expected":null},
{"name":"empty-string-is-not-bound","args":[""],"expected":null}
]
}
+20
View File
@@ -0,0 +1,20 @@
{
"function": "lifeStep",
"cases": [
{"name":"an-empty-board-stays-empty","args":[[]],"expected":[]},
{"name":"a-lonely-cell-dies","args":[[{"x":5,"y":5}]],"expected":[]},
{"name":"two-cells-die-of-loneliness","args":[[{"x":5,"y":5},{"x":6,"y":5}]],"expected":[]},
{"name":"a-block-is-stable","args":[[{"x":5,"y":5},{"x":6,"y":5},{"x":5,"y":6},{"x":6,"y":6}]],"expected":[{"x":5,"y":5},{"x":6,"y":5},{"x":5,"y":6},{"x":6,"y":6}]},
{"name":"a-horizontal-blinker-turns-vertical","args":[[{"x":4,"y":5},{"x":5,"y":5},{"x":6,"y":5}]],"expected":[{"x":5,"y":4},{"x":5,"y":5},{"x":5,"y":6}]},
{"name":"a-vertical-blinker-turns-horizontal","args":[[{"x":5,"y":4},{"x":5,"y":5},{"x":5,"y":6}]],"expected":[{"x":4,"y":5},{"x":5,"y":5},{"x":6,"y":5}]},
{"name":"three-cells-in-an-l-give-birth-to-a-block","args":[[{"x":5,"y":5},{"x":6,"y":5},{"x":5,"y":6}]],"expected":[{"x":5,"y":5},{"x":6,"y":5},{"x":5,"y":6},{"x":6,"y":6}]},
{"name":"a-cell-with-four-neighbours-dies-of-overcrowding","args":[[{"x":5,"y":4},{"x":4,"y":5},{"x":5,"y":5},{"x":6,"y":5},{"x":5,"y":6}]],"expected":[{"x":4,"y":4},{"x":5,"y":4},{"x":6,"y":4},{"x":4,"y":5},{"x":6,"y":5},{"x":4,"y":6},{"x":5,"y":6},{"x":6,"y":6}]},
{"name":"a-glider-moves-and-the-result-is-sorted-row-major","args":[[{"x":1,"y":0},{"x":2,"y":1},{"x":0,"y":2},{"x":1,"y":2},{"x":2,"y":2}]],"expected":[{"x":0,"y":1},{"x":2,"y":1},{"x":1,"y":2},{"x":2,"y":2},{"x":1,"y":3}]},
{"name":"a-block-in-the-corner-is-stable","args":[[{"x":0,"y":0},{"x":1,"y":0},{"x":0,"y":1},{"x":1,"y":1}]],"expected":[{"x":0,"y":0},{"x":1,"y":0},{"x":0,"y":1},{"x":1,"y":1}]},
{"name":"a-block-in-the-far-corner-is-stable","args":[[{"x":38,"y":28},{"x":39,"y":28},{"x":38,"y":29},{"x":39,"y":29}]],"expected":[{"x":38,"y":28},{"x":39,"y":28},{"x":38,"y":29},{"x":39,"y":29}]},
{"name":"a-blinker-on-the-top-edge-cannot-grow-beyond-it","args":[[{"x":4,"y":0},{"x":5,"y":0},{"x":6,"y":0}]],"expected":[{"x":5,"y":0},{"x":5,"y":1}]},
{"name":"a-blinker-on-the-right-edge-does-not-wrap-to-the-left-edge","args":[[{"x":39,"y":9},{"x":39,"y":10},{"x":39,"y":11}]],"expected":[{"x":38,"y":10},{"x":39,"y":10}]},
{"name":"cells-on-opposite-edges-are-not-neighbours","args":[[{"x":39,"y":9},{"x":0,"y":10},{"x":39,"y":10},{"x":39,"y":11}]],"expected":[{"x":38,"y":10},{"x":39,"y":10}]},
{"name":"a-blinker-on-the-bottom-edge-cannot-grow-beyond-it","args":[[{"x":10,"y":29},{"x":11,"y":29},{"x":12,"y":29}]],"expected":[{"x":11,"y":28},{"x":11,"y":29}]}
]
}
File diff suppressed because it is too large. Load diff
+8
View File
@@ -0,0 +1,8 @@
{
"function": "lifeView",
"cases": [
{"name":"a-new-world-is-an-empty-paused-board","args":[{"cells":[],"running":false,"seed":42,"generation":0}],"expected":[{"tag":"Rect","x":0,"y":0,"w":640,"h":480,"color":"#111111"},{"tag":"Rect","x":0,"y":480,"w":640,"h":24,"color":"#222222"},{"tag":"Text","x":6,"y":497,"text":"Generation 0","color":"#ffffff","size":14,"align":"left"},{"tag":"Text","x":634,"y":497,"text":"Paused: Space runs, N steps","color":"#ffffff","size":14,"align":"right"}]},
{"name":"live-cells-in-row-major-order-while-running","args":[{"cells":[{"x":0,"y":0},{"x":5,"y":5},{"x":39,"y":29}],"running":true,"seed":1,"generation":17}],"expected":[{"tag":"Rect","x":0,"y":0,"w":640,"h":480,"color":"#111111"},{"tag":"Rect","x":1,"y":1,"w":14,"h":14,"color":"#7cb342"},{"tag":"Rect","x":81,"y":81,"w":14,"h":14,"color":"#7cb342"},{"tag":"Rect","x":625,"y":465,"w":14,"h":14,"color":"#7cb342"},{"tag":"Rect","x":0,"y":480,"w":640,"h":24,"color":"#222222"},{"tag":"Text","x":6,"y":497,"text":"Generation 17","color":"#ffffff","size":14,"align":"left"},{"tag":"Text","x":634,"y":497,"text":"Running: Space pauses","color":"#ffffff","size":14,"align":"right"}]},
{"name":"paused-after-some-generations","args":[{"cells":[{"x":4,"y":5},{"x":5,"y":5},{"x":6,"y":5}],"running":false,"seed":1,"generation":4}],"expected":[{"tag":"Rect","x":0,"y":0,"w":640,"h":480,"color":"#111111"},{"tag":"Rect","x":65,"y":81,"w":14,"h":14,"color":"#7cb342"},{"tag":"Rect","x":81,"y":81,"w":14,"h":14,"color":"#7cb342"},{"tag":"Rect","x":97,"y":81,"w":14,"h":14,"color":"#7cb342"},{"tag":"Rect","x":0,"y":480,"w":640,"h":24,"color":"#222222"},{"tag":"Text","x":6,"y":497,"text":"Generation 4","color":"#ffffff","size":14,"align":"left"},{"tag":"Text","x":634,"y":497,"text":"Paused: Space runs, N steps","color":"#ffffff","size":14,"align":"right"}]}
]
}
+231
View File
@@ -0,0 +1,231 @@
{
"seed": 1,
"actions": [
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Down"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Left"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Down"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Down"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Left"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Down"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Left"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Left"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Down"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Left"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Down"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Left"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Right"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Down"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Left"},
{"tag":"Tick"},
{"tag":"Turn","dir":"Up"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"},
{"tag":"Tick"}
]
}