aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGene Pasquet <dev@etenil.net>2026-04-17 16:52:41 +0100
committerGene Pasquet <dev@etenil.net>2026-04-17 16:52:41 +0100
commita02b892e2ad1e1605ff942c63afdd618daa48be4 (patch)
tree7ccd9278a0cdc7fd2f156b0b4710f6ac00acab27
parent8251c85a4a588504d38a2fad05e4b0fe1cdccb9d (diff)
Migrate tests to the test egg
-rw-r--r--Makefile13
-rw-r--r--downstroke.egg1
-rw-r--r--tests/animation-test.scm49
-rw-r--r--tests/assets-test.scm13
-rw-r--r--tests/engine-test.scm69
-rw-r--r--tests/entity-test.scm75
-rw-r--r--tests/input-test.scm57
-rw-r--r--tests/physics-test.scm241
-rw-r--r--tests/prefabs-test.scm71
-rw-r--r--tests/renderer-test.scm43
-rw-r--r--tests/scene-loader-test.scm13
-rw-r--r--tests/tilemap-test.scm91
-rw-r--r--tests/tween-test.scm85
-rw-r--r--tests/world-test.scm113
14 files changed, 479 insertions, 455 deletions
diff --git a/Makefile b/Makefile
index f550c31..f196633 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,7 @@ bin/%.o: %.scm | bin
csc -c -J -unit downstroke-$* $*.scm -o bin/$*.o -I bin
@if [ -f downstroke-$*.import.scm ]; then mv downstroke-$*.import.scm bin/; fi
-.PHONY: clean test engine demos
+.PHONY: clean test engine demos filter
clean:
rm -rf bin downstroke/
@@ -59,6 +59,17 @@ test:
@csi -s tests/scene-loader-test.scm
@csi -s tests/tween-test.scm
+# Run a single test file with optional name/group filtering (pytest -k style).
+# make filter FILE=tests/physics-test.scm # whole file
+# make filter FILE=tests/physics-test.scm K=gravity # tests matching regex
+# make filter FILE=tests/physics-test.scm G=apply # groups matching regex
+# Note: combining K/G with TEST_QUIET=1 hits a known bug in the `test` egg
+# (modulo error in summary timing), so this target intentionally doesn't
+# expose Q. Use `TEST_QUIET=1 csi -s <file>` directly when you want quiet.
+filter:
+ @if [ -z "$(FILE)" ]; then echo "usage: make filter FILE=<test.scm> [K=name-regex] [G=group-regex]"; exit 2; fi
+ @$(if $(K),TEST_FILTER='$(K)') $(if $(G),TEST_GROUP_FILTER='$(G)') csi -s $(FILE)
+
demos: engine $(DEMO_BINS)
bin/demo-%: demo/%.scm $(OBJECT_FILES) | bin
diff --git a/downstroke.egg b/downstroke.egg
index 516eed3..c069e85 100644
--- a/downstroke.egg
+++ b/downstroke.egg
@@ -4,6 +4,7 @@
(license "BSD-2-Clause")
(category games)
(dependencies sdl2 sdl2-image sdl2-ttf expat defstruct srfi-1 srfi-13 srfi-69 srfi-197 matchable simple-logger list-utils)
+ (test-dependencies test)
(components
(extension downstroke-entity
(source "entity.scm"))
diff --git a/tests/animation-test.scm b/tests/animation-test.scm
index aae829a..adf534f 100644
--- a/tests/animation-test.scm
+++ b/tests/animation-test.scm
@@ -1,4 +1,4 @@
-(import srfi-64
+(import test
(only (list-utils alist) plist->alist))
(include "entity.scm")
(include "tilemap.scm")
@@ -14,59 +14,60 @@
(test-group "frame->tile-id"
(test-group "tile IDs only"
- (test-equal "first frame, frames (0)" 0 (frame->tile-id '(0) 0))
- (test-equal "wraps around" 0 (frame->tile-id '(0 1) 2))
- (test-equal "frame 1 of (27 28)" 28 (frame->tile-id '(27 28) 1)))
+ (test "first frame, frames (0)" 0 (frame->tile-id '(0) 0))
+ (test "wraps around" 0 (frame->tile-id '(0 1) 2))
+ (test "frame 1 of (27 28)" 28 (frame->tile-id '(27 28) 1)))
(test-group "tile IDs and durations"
- (test-equal "first frame, frames (0)" 0 (frame->tile-id '((0 10)) 0))
- (test-equal "wraps around" 0 (frame->tile-id '((0 10) (1 10)) 2))
- (test-equal "frame 1 of (27 28)" 28 (frame->tile-id '((27 10) (28 10)) 1))))
+ (test "first frame, frames (0)" 0 (frame->tile-id '((0 10)) 0))
+ (test "wraps around" 0 (frame->tile-id '((0 10) (1 10)) 2))
+ (test "frame 1 of (27 28)" 28 (frame->tile-id '((27 10) (28 10)) 1))))
(test-group "frame->duration"
- (test-equal "first frame, frames (0)" 100 (frame->duration '((0 100)) 0))
- (test-equal "wraps around" 100 (frame->duration '((0 100) (1 200)) 2))
- (test-equal "frame 1 of (27 28)" 200 (frame->duration '((27 100) (28 200)) 1))
+ (test "first frame, frames (0)" 100 (frame->duration '((0 100)) 0))
+ (test "wraps around" 100 (frame->duration '((0 100) (1 200)) 2))
+ (test "frame 1 of (27 28)" 200 (frame->duration '((27 100) (28 200)) 1))
)
(test-group "set-animation"
(let ((e (entity #:type 'player #:anim-name 'idle #:anim-frame 5 #:anim-tick 8)))
- (test-equal "no-op if already active" e (set-animation e 'idle))
+ (test "no-op if already active" e (set-animation e 'idle))
(let ((switched (set-animation e 'walk)))
- (test-equal "switches anim-name" 'walk (entity-ref switched #:anim-name))
- (test-equal "resets frame" 0 (entity-ref switched #:anim-frame))
- (test-equal "resets tick" 0 (entity-ref switched #:anim-tick)))))
+ (test "switches anim-name" 'walk (entity-ref switched #:anim-name))
+ (test "resets frame" 0 (entity-ref switched #:anim-frame))
+ (test "resets tick" 0 (entity-ref switched #:anim-tick)))))
(test-group "animate-entity"
(test-group "Single frames"
(let* ((anims (list (anim #:name 'walk #:frames '(2 3) #:duration 4)))
(e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 0))
(stepped (animate-entity e anims)))
- (test-equal "increments tick" 1 (entity-ref stepped #:anim-tick))
- (test-equal "sets tile-id on first tick" 2 (entity-ref stepped #:tile-id)))
+ (test "increments tick" 1 (entity-ref stepped #:anim-tick))
+ (test "sets tile-id on first tick" 2 (entity-ref stepped #:tile-id)))
(let* ((anims (list (anim #:name 'walk #:frames '(0 1) #:duration 2)))
(e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 1))
(advanced (animate-entity e anims)))
- (test-equal "advances frame when tick reaches duration" 1 (entity-ref advanced #:anim-frame))
- (test-equal "resets tick on frame advance" 0 (entity-ref advanced #:anim-tick))))
+ (test "advances frame when tick reaches duration" 1 (entity-ref advanced #:anim-frame))
+ (test "resets tick on frame advance" 0 (entity-ref advanced #:anim-tick))))
(test-group "Frames with duration"
(let* ((anims (list (anim #:name 'walk #:frames '((0 10) (1 20)) #:duration 4)))
(e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 9))
(stepped (animate-entity e anims)))
- (test-equal "ticks resets on frame switch" 0 (entity-ref stepped #:anim-tick))
- (test-equal "sets tile-id on 10th tick" 1 (entity-ref stepped #:tile-id))
- (test-equal "sets duration to frame duration" 20 (entity-ref stepped #:duration))))
+ (test "ticks resets on frame switch" 0 (entity-ref stepped #:anim-tick))
+ (test "sets tile-id on 10th tick" 1 (entity-ref stepped #:tile-id))
+ (test "sets duration to frame duration" 20 (entity-ref stepped #:duration))))
(test-group "Empty"
(let* ((e (entity #:type 'player)))
- (test-equal "unchanged entity without anim-name" e (animate-entity e '())))))
+ (test "unchanged entity without anim-name" e (animate-entity e '())))))
(test-group "animation pipeline"
(test-group "animated entity"
(let* ((anims (list (anim #:name 'walk #:frames '(2 3) #:duration 4)))
(e (entity #:type 'player #:anim-name 'walk #:anim-frame 0 #:anim-tick 0 #:animations anims))
(stepped-entity (apply-animation #f e 10)))
- (test-equal "Updated animated entity" 1 (entity-ref stepped-entity #:anim-tick)))
+ (test "Updated animated entity" 1 (entity-ref stepped-entity #:anim-tick)))
(let* ((e (entity #:type 'static))
(stepped-entity (apply-animation #f e 10)))
- (test-equal "unchanged static entity" #f (entity-ref stepped-entity #:anim-tick)))))
+ (test "unchanged static entity" #f (entity-ref stepped-entity #:anim-tick)))))
(test-end "animation")
+(test-exit)
diff --git a/tests/assets-test.scm b/tests/assets-test.scm
index c7b26f0..348cea0 100644
--- a/tests/assets-test.scm
+++ b/tests/assets-test.scm
@@ -1,4 +1,4 @@
-(import srfi-64)
+(import test)
(include "assets.scm")
(import downstroke-assets)
@@ -11,26 +11,27 @@
(test-group "asset-set! and asset-ref"
(let ((reg (make-asset-registry)))
- (test-equal "missing key returns #f"
+ (test "missing key returns #f"
#f
(asset-ref reg 'missing))
(asset-set! reg 'my-tilemap "data")
- (test-equal "stored value is retrievable"
+ (test "stored value is retrievable"
"data"
(asset-ref reg 'my-tilemap))
(asset-set! reg 'my-tilemap "updated")
- (test-equal "overwrite replaces value"
+ (test "overwrite replaces value"
"updated"
(asset-ref reg 'my-tilemap))
(asset-set! reg 'other 42)
- (test-equal "multiple keys coexist"
+ (test "multiple keys coexist"
"updated"
(asset-ref reg 'my-tilemap))
- (test-equal "second key retrievable"
+ (test "second key retrievable"
42
(asset-ref reg 'other))))
(test-end "assets")
+(test-exit)
diff --git a/tests/engine-test.scm b/tests/engine-test.scm
index aa44964..40a02ad 100644
--- a/tests/engine-test.scm
+++ b/tests/engine-test.scm
@@ -1,4 +1,4 @@
-(import scheme (chicken base) (chicken keyword) srfi-64 defstruct (srfi 69))
+(import scheme (chicken base) (chicken keyword) test defstruct (srfi 69))
;; --- Mocks ---
@@ -149,61 +149,61 @@
(test-group "make-game defaults"
(let ((g (make-game)))
- (test-equal "default title"
+ (test "default title"
"Downstroke Game"
(game-title g))
- (test-equal "default width"
+ (test "default width"
640
(game-width g))
- (test-equal "default height"
+ (test "default height"
480
(game-height g))
- (test-equal "default frame-delay"
+ (test "default frame-delay"
16
(game-frame-delay g))
- (test-equal "scene starts as #f"
+ (test "scene starts as #f"
#f
(game-scene g))
- (test-equal "window starts as #f"
+ (test "window starts as #f"
#f
(game-window g))
- (test-equal "renderer starts as #f"
+ (test "renderer starts as #f"
#f
(game-renderer g))
(test-assert "assets registry is created"
(game-assets g))
(test-assert "input state is created"
(game-input g))
- (test-equal "debug? defaults to #f"
+ (test "debug? defaults to #f"
#f
(game-debug? g))
- (test-equal "scale defaults to 1"
+ (test "scale defaults to 1"
1
(game-scale g))))
(test-group "make-game with keyword args"
(let ((g (make-game title: "My Game" width: 320 height: 240 frame-delay: 33)))
- (test-equal "custom title" "My Game" (game-title g))
- (test-equal "custom width" 320 (game-width g))
- (test-equal "custom height" 240 (game-height g))
- (test-equal "custom frame-delay" 33 (game-frame-delay g))))
+ (test "custom title" "My Game" (game-title g))
+ (test "custom width" 320 (game-width g))
+ (test "custom height" 240 (game-height g))
+ (test "custom frame-delay" 33 (game-frame-delay g))))
(test-group "make-game debug? keyword"
- (test-equal "debug? defaults to #f"
+ (test "debug? defaults to #f"
#f
(game-debug? (make-game)))
- (test-equal "debug? can be set to #t"
+ (test "debug? can be set to #t"
#t
(game-debug? (make-game debug?: #t))))
(test-group "make-game scale keyword"
- (test-equal "scale defaults to 1"
+ (test "scale defaults to 1"
1
(game-scale (make-game)))
- (test-equal "scale can be set to 2"
+ (test "scale can be set to 2"
2
(game-scale (make-game scale: 2)))
- (test-equal "scale can be set to 3"
+ (test "scale can be set to 3"
3
(game-scale (make-game scale: 3)))
(import (chicken condition))
@@ -222,24 +222,24 @@
(test-group "game-asset and game-asset-set!"
(let ((g (make-game)))
- (test-equal "missing key returns #f"
+ (test "missing key returns #f"
#f
(game-asset g 'no-such-asset))
(game-asset-set! g 'my-font 'font-object)
- (test-equal "stored asset is retrievable"
+ (test "stored asset is retrievable"
'font-object
(game-asset g 'my-font))
(game-asset-set! g 'my-font 'updated-font)
- (test-equal "overwrite replaces asset"
+ (test "overwrite replaces asset"
'updated-font
(game-asset g 'my-font))))
(test-group "make-game hooks default to #f"
(let ((g (make-game)))
- (test-equal "preload-hook is #f" #f (game-preload-hook g))
- (test-equal "create-hook is #f" #f (game-create-hook g))
- (test-equal "update-hook is #f" #f (game-update-hook g))
- (test-equal "render-hook is #f" #f (game-render-hook g))))
+ (test "preload-hook is #f" #f (game-preload-hook g))
+ (test "create-hook is #f" #f (game-create-hook g))
+ (test "update-hook is #f" #f (game-update-hook g))
+ (test "render-hook is #f" #f (game-render-hook g))))
(test-group "make-game accepts hook lambdas"
(let* ((called #f)
@@ -258,7 +258,7 @@
background: #f))
(g (make-game)))
(game-scene-set! g scene)
- (test-equal "returns scene camera"
+ (test "returns scene camera"
cam
(game-camera g))))
@@ -270,8 +270,8 @@
(test-assert "state has update hook" (state-hook s #:update))
(test-assert "state has render hook" (state-hook s #:render)))
(let ((s (make-game-state)))
- (test-equal "default state hooks are #f" #f (state-hook s #:create))
- (test-equal "default state update is #f" #f (state-hook s #:update))))
+ (test "default state hooks are #f" #f (state-hook s #:create))
+ (test "default state update is #f" #f (state-hook s #:update))))
(test-group "game-add-state! and game-start-state!"
(let* ((created? #f)
@@ -279,18 +279,18 @@
(state (make-game-state
create: (lambda (g) (set! created? #t)))))
(game-add-state! game 'play state)
- (test-equal "active-state defaults to #f" #f (game-active-state game))
+ (test "active-state defaults to #f" #f (game-active-state game))
(game-start-state! game 'play)
- (test-equal "active-state set after start" 'play (game-active-state game))
+ (test "active-state set after start" 'play (game-active-state game))
(test-assert "create hook called on start" created?)))
(test-group "game states defaults"
(let ((game (make-game)))
(test-assert "states is a hash-table" (hash-table? (game-states game)))
- (test-equal "active-state defaults to #f" #f (game-active-state game))))
+ (test "active-state defaults to #f" #f (game-active-state game))))
(test-group "scene engine-update"
- (test-equal "scene engine-update defaults to #f"
+ (test "scene engine-update defaults to #f"
#f
(scene-engine-update (make-scene entities: '() tilemap: #f camera-target: #f)))
(let* ((my-eu (lambda (game dt) #t))
@@ -298,8 +298,9 @@
(test-assert "custom engine-update stored on scene"
(procedure? (scene-engine-update s))))
(let ((s (make-scene entities: '() tilemap: #f camera-target: #f engine-update: 'none)))
- (test-equal "engine-update: 'none disables pipeline"
+ (test "engine-update: 'none disables pipeline"
'none
(scene-engine-update s))))
(test-end "engine")
+(test-exit)
diff --git a/tests/entity-test.scm b/tests/entity-test.scm
index d686acf..d56e115 100644
--- a/tests/entity-test.scm
+++ b/tests/entity-test.scm
@@ -1,4 +1,4 @@
-(import srfi-64)
+(import test)
(include "entity.scm")
(import downstroke-entity)
@@ -11,25 +11,25 @@
(#:y . 200)
(#:width . 16)
(#:height . 16))))
- (test-equal "retrieves type" 'player (entity-ref entity #:type))
- (test-equal "retrieves x" 100 (entity-ref entity #:x))
- (test-equal "retrieves y" 200 (entity-ref entity #:y))
- (test-equal "retrieves width" 16 (entity-ref entity #:width))
- (test-equal "retrieves height" 16 (entity-ref entity #:height)))
+ (test "retrieves type" 'player (entity-ref entity #:type))
+ (test "retrieves x" 100 (entity-ref entity #:x))
+ (test "retrieves y" 200 (entity-ref entity #:y))
+ (test "retrieves width" 16 (entity-ref entity #:width))
+ (test "retrieves height" 16 (entity-ref entity #:height)))
;; Test with default value
(let ((entity '((#:type . player))))
- (test-equal "returns default for missing key"
+ (test "returns default for missing key"
99
(entity-ref entity #:x 99))
- (test-equal "returns #f as default if not specified"
+ (test "returns #f as default if not specified"
#f
(entity-ref entity #:missing-key))))
;; Test: entity-ref with procedure as default
(test-group "entity-ref-with-procedure-default"
(let ((entity '((#:type . player))))
- (test-equal "calls procedure default when key missing"
+ (test "calls procedure default when key missing"
42
(entity-ref entity #:x (lambda () 42)))))
@@ -37,20 +37,20 @@
(test-group "make-entity"
(let ((player (make-entity 50 75 16 16)))
(test-assert "returns a list" (list? player))
- (test-equal "has correct x" 50 (entity-ref player #:x))
- (test-equal "has correct y" 75 (entity-ref player #:y))
- (test-equal "has correct width" 16 (entity-ref player #:width))
- (test-equal "has correct height" 16 (entity-ref player #:height))))
+ (test "has correct x" 50 (entity-ref player #:x))
+ (test "has correct y" 75 (entity-ref player #:y))
+ (test "has correct width" 16 (entity-ref player #:width))
+ (test "has correct height" 16 (entity-ref player #:height))))
;; Test: entity-type extracts type from entity
(test-group "entity-type"
(let ((player '((#:type . player) (#:x . 100)))
(enemy '((#:type . enemy) (#:x . 200))))
- (test-equal "extracts player type" 'player (entity-type player))
- (test-equal "extracts enemy type" 'enemy (entity-type enemy)))
+ (test "extracts player type" 'player (entity-type player))
+ (test "extracts enemy type" 'enemy (entity-type enemy)))
(let ((no-type '((#:x . 100) (#:y . 200))))
- (test-equal "returns #f for entity without type"
+ (test "returns #f for entity without type"
#f
(entity-type no-type))))
@@ -64,49 +64,49 @@
(#:health . 50)
(#:speed . 2.5)
(#:ai-state . patrol))))
- (test-equal "retrieves numeric property" 50 (entity-ref entity #:health))
- (test-equal "retrieves float property" 2.5 (entity-ref entity #:speed))
- (test-equal "retrieves symbol property" 'patrol (entity-ref entity #:ai-state))))
+ (test "retrieves numeric property" 50 (entity-ref entity #:health))
+ (test "retrieves float property" 2.5 (entity-ref entity #:speed))
+ (test "retrieves symbol property" 'patrol (entity-ref entity #:ai-state))))
;; Test: entity-set updates entity properties
(test-group "entity-set"
(test-group "existing key is replaced"
(let ((e (entity-set '((#:x . 10) (#:y . 20)) #:x 15)))
- (test-equal "value updated" 15 (entity-ref e #:x))
- (test-equal "other key untouched" 20 (entity-ref e #:y))
+ (test "value updated" 15 (entity-ref e #:x))
+ (test "other key untouched" 20 (entity-ref e #:y))
;; alist length stays at 2 (one pair removed, one added) — not 3.
- (test-equal "no duplicate key: list length unchanged" 2 (length e))))
+ (test "no duplicate key: list length unchanged" 2 (length e))))
(test-group "new key is added"
(let ((e (entity-set '((#:x . 10)) #:vx 3)))
- (test-equal "new key present" 3 (entity-ref e #:vx))
- (test-equal "existing key untouched" 10 (entity-ref e #:x))
- (test-equal "list grows by one pair" 2 (length e)))))
+ (test "new key present" 3 (entity-ref e #:vx))
+ (test "existing key untouched" 10 (entity-ref e #:x))
+ (test "list grows by one pair" 2 (length e)))))
(test-group "entity-set-many"
(test-group "Set multiple entities with cons"
(let ((e (entity-set-many '((#:x . 10) (#:y . 20))
'((#:x . 15) (#:y . 25)))))
- (test-equal "value x updated" 15 (entity-ref e #:x))
- (test-equal "value y updated" 25 (entity-ref e #:y)))))
+ (test "value x updated" 15 (entity-ref e #:x))
+ (test "value y updated" 25 (entity-ref e #:y)))))
;; Test: entity-update applies transformations
(test-group "entity-update"
(test-group "transform existing value"
(let ((e (entity-update '((#:x . 10) (#:y . 20)) #:x (lambda (v) (+ v 5)))))
- (test-equal "#:x is 15" 15 (entity-ref e #:x))
- (test-equal "#:y is 20" 20 (entity-ref e #:y))))
+ (test "#:x is 15" 15 (entity-ref e #:x))
+ (test "#:y is 20" 20 (entity-ref e #:y))))
(test-group "missing key uses default"
(let ((e (entity-update '((#:x . 10)) #:health (lambda (v) (+ v 1)) 0)))
- (test-equal "#:health is 1" 1 (entity-ref e #:health))))
+ (test "#:health is 1" 1 (entity-ref e #:health))))
(test-group "missing key without default"
(let ((e (entity-update '((#:x . 10)) #:z (lambda (v) v))))
- (test-equal "#:z is #f" #f (entity-ref e #:z))))
+ (test "#:z is #f" #f (entity-ref e #:z))))
(test-group "no duplicate keys"
(let ((e (entity-update '((#:x . 10) (#:y . 20)) #:x (lambda (v) (* v 2)))))
- (test-equal "length is 2" 2 (length e)))))
+ (test "length is 2" 2 (length e)))))
(test-group "entity-skips-pipeline?"
(test-assert "absent skip list"
@@ -123,9 +123,9 @@
(test-group "define-pipeline"
(let ((e '((#:type . t) (#:x . 0))))
- (test-equal "runs body" 42 (entity-ref (fixture-pipeline #f e 0) #:x)))
+ (test "runs body" 42 (entity-ref (fixture-pipeline #f e 0) #:x)))
(let ((e '((#:type . t) (#:x . 0) (#:skip-pipelines . (fixture-skip)))))
- (test-equal "skipped" 0 (entity-ref (fixture-pipeline #f e 0) #:x))))
+ (test "skipped" 0 (entity-ref (fixture-pipeline #f e 0) #:x))))
(define-pipeline (guarded-pipeline guarded-skip) (scene_ ent _dt)
guard: (entity-ref ent #:active? #f)
@@ -133,13 +133,14 @@
(test-group "define-pipeline with guard:"
(let ((e '((#:type . t) (#:x . 0) (#:active? . #t))))
- (test-equal "runs body when guard passes" 99
+ (test "runs body when guard passes" 99
(entity-ref (guarded-pipeline #f e 0) #:x)))
(let ((e '((#:type . t) (#:x . 0))))
- (test-equal "returns entity unchanged when guard fails" 0
+ (test "returns entity unchanged when guard fails" 0
(entity-ref (guarded-pipeline #f e 0) #:x)))
(let ((e '((#:type . t) (#:x . 0) (#:active? . #t) (#:skip-pipelines . (guarded-skip)))))
- (test-equal "skip-pipelines takes precedence over guard" 0
+ (test "skip-pipelines takes precedence over guard" 0
(entity-ref (guarded-pipeline #f e 0) #:x))))
(test-end "entity")
+(test-exit)
diff --git a/tests/input-test.scm b/tests/input-test.scm
index bbc5599..50395d8 100644
--- a/tests/input-test.scm
+++ b/tests/input-test.scm
@@ -7,7 +7,7 @@
(only srfi-197 chain)
(prefix sdl2 sdl2:)
simple-logger
- srfi-64
+ test
defstruct)
;; Load entity first (input imports it)
@@ -35,20 +35,20 @@
(test-assert "has previous field" (list? (input-state-previous state)))
;; All actions should be initialized to #f
- (test-equal "up action is false" #f (input-held? state 'up))
- (test-equal "down action is false" #f (input-held? state 'down))
- (test-equal "left action is false" #f (input-held? state 'left))
- (test-equal "right action is false" #f (input-held? state 'right))
- (test-equal "a action is false" #f (input-held? state 'a))
- (test-equal "b action is false" #f (input-held? state 'b))
- (test-equal "start action is false" #f (input-held? state 'start))
- (test-equal "quit action is false" #f (input-held? state 'quit))))
+ (test "up action is false" #f (input-held? state 'up))
+ (test "down action is false" #f (input-held? state 'down))
+ (test "left action is false" #f (input-held? state 'left))
+ (test "right action is false" #f (input-held? state 'right))
+ (test "a action is false" #f (input-held? state 'a))
+ (test "b action is false" #f (input-held? state 'b))
+ (test "start action is false" #f (input-held? state 'start))
+ (test "quit action is false" #f (input-held? state 'quit))))
;; Test: input-held? query
(test-group "input-held?"
(let ((state (create-input-state *default-input-config*)))
- (test-equal "returns false for unheld action" #f (input-held? state 'up))
- (test-equal "returns false for unknown action" #f (input-held? state 'unknown))))
+ (test "returns false for unheld action" #f (input-held? state 'up))
+ (test "returns false for unknown action" #f (input-held? state 'unknown))))
;; Test: input-pressed? detection
(test-group "input-pressed?"
@@ -59,7 +59,7 @@
(input-state-current state1))))
;; In state1, up is not pressed
- (test-equal "not pressed in initial state" #f (input-pressed? state1 'up))
+ (test "not pressed in initial state" #f (input-pressed? state1 'up))
;; In state2, up is held but was not held before -> pressed
(test-assert "pressed when current=#t and previous=#f"
@@ -77,14 +77,14 @@
(cons (cons 'up #f) (input-state-current state1))
(cons (cons 'up #t) (input-state-current state1)))))
- (test-equal "not released when held" #f (input-released? state-held 'up))
+ (test "not released when held" #f (input-released? state-held 'up))
(test-assert "released when current=#f and previous=#t"
(input-released? state-released 'up))))
;; Test: input-any-pressed?
(test-group "input-any-pressed?"
(let ((state1 (create-input-state *default-input-config*)))
- (test-equal "no actions pressed in initial state"
+ (test "no actions pressed in initial state"
#f
(input-any-pressed? state1 *default-input-config*))))
@@ -109,7 +109,7 @@
(input-state-current state1))))
;; Verify transition from not-held to held = pressed
- (test-equal "up not held in state1" #f (input-held? state1 'up))
+ (test "up not held in state1" #f (input-held? state1 'up))
(test-assert "up held in state2" (input-held? state2 'up))
(test-assert "up pressed in state2" (input-pressed? state2 'up))
@@ -118,7 +118,7 @@
(input-state-current state2)
(input-state-current state2))))
(test-assert "up still held in state3" (input-held? state3 'up))
- (test-equal "up not pressed in state3 (already was pressed)"
+ (test "up not pressed in state3 (already was pressed)"
#f
(input-pressed? state3 'up)))))
@@ -132,40 +132,40 @@
(test-group "no input-map: entity unchanged"
(let* ((e (entity #:type 'player #:x 5 #:y 10))
(out (apply-input-to-entity e (lambda (a) #f))))
- (test-equal "entity returned as-is" e out)))
+ (test "entity returned as-is" e (begin out))))
(test-group "no actions held: velocity is zero"
(let* ((e (make-physics-entity))
(out (apply-input-to-entity e (lambda (a) #f))))
- (test-equal "vx is 0" 0 (entity-ref out #:vx))
- (test-equal "vy is 0" 0 (entity-ref out #:vy))))
+ (test "vx is 0" 0 (entity-ref out #:vx))
+ (test "vy is 0" 0 (entity-ref out #:vy))))
(test-group "right held: vx=2 vy=0"
(let* ((e (make-physics-entity))
(out (apply-input-to-entity e (lambda (a) (eq? a 'right)))))
- (test-equal "vx is 2" 2 (entity-ref out #:vx))
- (test-equal "vy is 0" 0 (entity-ref out #:vy))))
+ (test "vx is 2" 2 (entity-ref out #:vx))
+ (test "vy is 0" 0 (entity-ref out #:vy))))
(test-group "right+down held: vx=2 vy unchanged"
(let* ((e (make-physics-entity))
(out (apply-input-to-entity e (lambda (a) (memv a '(right down))))))
- (test-equal "vx is 2" 2 (entity-ref out #:vx))
- (test-equal "vy is unchanged (input handler does not set vy)" 0 (entity-ref out #:vy))))
+ (test "vx is 2" 2 (entity-ref out #:vx))
+ (test "vy is unchanged (input handler does not set vy)" 0 (entity-ref out #:vy))))
(test-group "right held: facing set to 1"
(let* ((e (make-physics-entity))
(out (apply-input-to-entity e (lambda (a) (eq? a 'right)))))
- (test-equal "facing is 1" 1 (entity-ref out #:facing 0))))
+ (test "facing is 1" 1 (entity-ref out #:facing 0))))
(test-group "left held: facing set to -1"
(let* ((e (make-physics-entity))
(out (apply-input-to-entity e (lambda (a) (eq? a 'left)))))
- (test-equal "facing is -1" -1 (entity-ref out #:facing 0))))
+ (test "facing is -1" -1 (entity-ref out #:facing 0))))
(test-group "no key held: facing retains previous value"
(let* ((e (entity-set (make-physics-entity) #:facing 1))
(out (apply-input-to-entity e (lambda (a) #f))))
- (test-equal "facing stays 1 when vx=0" 1 (entity-ref out #:facing 0)))))
+ (test "facing stays 1 when vx=0" 1 (entity-ref out #:facing 0)))))
(test-group "custom-input-config"
(let* ((cfg (make-input-config
@@ -178,7 +178,8 @@
deadzone: 8000))
(state (create-input-state cfg)))
(test-assert "custom config creates valid state" (input-state? state))
- (test-equal "jump is false" #f (input-held? state 'jump))
- (test-equal "shoot is false" #f (input-held? state 'shoot))))
+ (test "jump is false" #f (input-held? state 'jump))
+ (test "shoot is false" #f (input-held? state 'shoot))))
(test-end "input-module")
+(test-exit)
diff --git a/tests/physics-test.scm b/tests/physics-test.scm
index 4ab4b17..76b480c 100644
--- a/tests/physics-test.scm
+++ b/tests/physics-test.scm
@@ -3,7 +3,7 @@
(chicken base)
(chicken keyword)
defstruct
- srfi-64
+ test
(only srfi-1 every member make-list fold iota))
;; Create a mock tilemap module to avoid SDL dependency
@@ -92,102 +92,102 @@
(test-group "gravity? true, vy starts at 0"
(let* ((e (entity #:type 'rock #:x 0 #:y 0 #:vx 0 #:vy 0 #:gravity? #t))
(result (apply-gravity #f e 0)))
- (test-equal "vy increased by gravity" *gravity* (entity-ref result #:vy))
- (test-equal "x unchanged" 0 (entity-ref result #:x))
- (test-equal "y unchanged" 0 (entity-ref result #:y))
- (test-equal "vx unchanged" 0 (entity-ref result #:vx))))
+ (test "vy increased by gravity" *gravity* (entity-ref result #:vy))
+ (test "x unchanged" 0 (entity-ref result #:x))
+ (test "y unchanged" 0 (entity-ref result #:y))
+ (test "vx unchanged" 0 (entity-ref result #:vx))))
(test-group "gravity? true, vy already has value"
(let* ((e (entity #:type 'rock #:x 0 #:y 0 #:vx 0 #:vy 3 #:gravity? #t))
(result (apply-gravity #f e 0)))
- (test-equal "vy increased by gravity" 4 (entity-ref result #:vy))))
+ (test "vy increased by gravity" 4 (entity-ref result #:vy))))
(test-group "gravity? false"
(let* ((e (entity #:type 'static #:x 0 #:y 0 #:vx 0 #:vy 0 #:gravity? #f))
(result (apply-gravity #f e 0)))
- (test-equal "vy unchanged" 0 (entity-ref result #:vy))))
+ (test "vy unchanged" 0 (entity-ref result #:vy))))
(test-group "no gravity? field at all"
(let* ((e (entity #:type 'static #:x 5 #:y 5))
(result (apply-gravity #f e 0)))
- (test-equal "entity unchanged" e result))))
+ (test "entity unchanged" e (begin result)))))
(test-group "apply-velocity-x"
(test-group "basic horizontal movement"
(let* ((e (entity #:type 'rock #:x 10 #:y 20 #:vx 5 #:vy -2))
(result (apply-velocity-x #f e 0)))
- (test-equal "x moved by vx" 15 (entity-ref result #:x))
- (test-equal "y unchanged" 20 (entity-ref result #:y))
- (test-equal "vy unchanged" -2 (entity-ref result #:vy))))
+ (test "x moved by vx" 15 (entity-ref result #:x))
+ (test "y unchanged" 20 (entity-ref result #:y))
+ (test "vy unchanged" -2 (entity-ref result #:vy))))
(test-group "zero vx"
(let* ((e (entity #:type 'rock #:x 10 #:y 20 #:vx 0 #:vy 3))
(result (apply-velocity-x #f e 0)))
- (test-equal "x unchanged" 10 (entity-ref result #:x))
- (test-equal "y unchanged" 20 (entity-ref result #:y)))))
+ (test "x unchanged" 10 (entity-ref result #:x))
+ (test "y unchanged" 20 (entity-ref result #:y)))))
(test-group "apply-velocity-y"
(test-group "basic vertical movement"
(let* ((e (entity #:type 'rock #:x 10 #:y 20 #:vx 3 #:vy -5))
(result (apply-velocity-y #f e 0)))
- (test-equal "x unchanged" 10 (entity-ref result #:x))
- (test-equal "y moved by vy" 15 (entity-ref result #:y))
- (test-equal "vx unchanged" 3 (entity-ref result #:vx))))
+ (test "x unchanged" 10 (entity-ref result #:x))
+ (test "y moved by vy" 15 (entity-ref result #:y))
+ (test "vx unchanged" 3 (entity-ref result #:vx))))
(test-group "zero vy"
(let* ((e (entity #:type 'rock #:x 10 #:y 20 #:vx 3 #:vy 0))
(result (apply-velocity-y #f e 0)))
- (test-equal "x unchanged" 10 (entity-ref result #:x))
- (test-equal "y unchanged" 20 (entity-ref result #:y)))))
+ (test "x unchanged" 10 (entity-ref result #:x))
+ (test "y unchanged" 20 (entity-ref result #:y)))))
(test-group "apply-velocity"
(test-group "basic movement"
(let* ((e (entity #:type 'rock #:x 10 #:y 20 #:vx 3 #:vy -2))
(result (apply-velocity e)))
- (test-equal "x moved by vx" 13 (entity-ref result #:x))
- (test-equal "y moved by vy" 18 (entity-ref result #:y))))
+ (test "x moved by vx" 13 (entity-ref result #:x))
+ (test "y moved by vy" 18 (entity-ref result #:y))))
(test-group "zero velocity"
(let* ((e (entity #:type 'rock #:x 10 #:y 20 #:vx 0 #:vy 0))
(result (apply-velocity e)))
- (test-equal "x unchanged" 10 (entity-ref result #:x))
- (test-equal "y unchanged" 20 (entity-ref result #:y))))
+ (test "x unchanged" 10 (entity-ref result #:x))
+ (test "y unchanged" 20 (entity-ref result #:y))))
(test-group "no velocity fields (defaults to 0)"
(let* ((e (entity #:type 'static #:x 5 #:y 5))
(result (apply-velocity e)))
- (test-equal "x unchanged" 5 (entity-ref result #:x))
- (test-equal "y unchanged" 5 (entity-ref result #:y)))))
+ (test "x unchanged" 5 (entity-ref result #:x))
+ (test "y unchanged" 5 (entity-ref result #:y)))))
(test-group "build-cell-list"
(test-group "single cell"
(let ((cells (build-cell-list 5 5 3 3)))
- (test-equal "one cell" 1 (length cells))
- (test-equal "cell is pair" '(5 . 3) (car cells))))
+ (test "one cell" 1 (length cells))
+ (test "cell is pair" '(5 . 3) (car cells))))
(test-group "two columns one row"
(let ((cells (build-cell-list 11 12 22 22)))
- (test-equal "two cells" 2 (length cells))
+ (test "two cells" 2 (length cells))
(test-assert "all cells are pairs" (every pair? cells))
(test-assert "contains (11 . 22)" (member '(11 . 22) cells))
(test-assert "contains (12 . 22)" (member '(12 . 22) cells))))
(test-group "one column two rows"
(let ((cells (build-cell-list 5 5 2 3)))
- (test-equal "two cells" 2 (length cells))
+ (test "two cells" 2 (length cells))
(test-assert "all cells are pairs" (every pair? cells))
(test-assert "contains (5 . 2)" (member '(5 . 2) cells))
(test-assert "contains (5 . 3)" (member '(5 . 3) cells))))
(test-group "2x2 grid"
(let ((cells (build-cell-list 0 1 0 1)))
- (test-equal "four cells" 4 (length cells))
+ (test "four cells" 4 (length cells))
(test-assert "all cells are pairs" (every pair? cells))
(test-assert "no #f in list" (not (member #f cells)))))
(test-group "empty when col-start > col-end"
(let ((cells (build-cell-list 5 4 0 0)))
- (test-equal "empty list" '() cells)))
+ (test "empty list" '() (begin cells))))
(test-group "player-like values (x=182 y=352 w=16 h=16 tw=16 th=16)"
(let* ((x 182) (y 352) (w 16) (h 16) (tw 16) (th 16)
@@ -196,11 +196,11 @@
(row-start (inexact->exact (floor (/ y th))))
(row-end (inexact->exact (floor (/ (- (+ y h) 1) th))))
(cells (build-cell-list col-start col-end row-start row-end)))
- (test-equal "col-start" 11 col-start)
- (test-equal "col-end" 12 col-end)
- (test-equal "row-start" 22 row-start)
- (test-equal "row-end" 22 row-end)
- (test-equal "two cells" 2 (length cells))
+ (test "col-start" 11 (begin col-start))
+ (test "col-end" 12 (begin col-end))
+ (test "row-start" 22 (begin row-start))
+ (test "row-end" 22 (begin row-end))
+ (test "two cells" 2 (length cells))
(test-assert "all cells are pairs" (every pair? cells)))))
(test-group "resolve-tile-collisions-x"
@@ -208,100 +208,100 @@
(let* ((tm (make-test-tilemap '((0 0 0) (0 0 0) (0 0 0))))
(e (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16 #:vx 2 #:vy 0)))
(let ((result (resolve-tile-collisions-x (test-scene tilemap: tm) e 0)))
- (test-equal "x unchanged" 0 (entity-ref result #:x))
- (test-equal "vx unchanged" 2 (entity-ref result #:vx)))))
+ (test "x unchanged" 0 (entity-ref result #:x))
+ (test "vx unchanged" 2 (entity-ref result #:vx)))))
(test-group "zero vx: skipped entirely"
(let* ((tm (make-test-tilemap '((0 1 0) (0 0 0) (0 0 0))))
(e (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16 #:vx 0 #:vy 0)))
- (test-equal "entity eq? when vx=0" e (resolve-tile-collisions-x (test-scene tilemap: tm) e 0))))
+ (test "entity eq? when vx=0" e (resolve-tile-collisions-x (test-scene tilemap: tm) e 0))))
(test-group "collision moving right: push left"
;; solid at col=1 (x=16..31); entity at x=20 overlaps it, vx>0
(let* ((tm (make-test-tilemap '((0 0 0) (0 1 0) (0 0 0))))
(e (entity #:type 'player #:x 20 #:y 16 #:width 16 #:height 16 #:vx 5 #:vy 0)))
(let ((result (resolve-tile-collisions-x (test-scene tilemap: tm) e 0)))
- (test-equal "pushed left of solid tile" 0 (entity-ref result #:x))
- (test-equal "vx zeroed" 0 (entity-ref result #:vx)))))
+ (test "pushed left of solid tile" 0 (entity-ref result #:x))
+ (test "vx zeroed" 0 (entity-ref result #:vx)))))
(test-group "collision moving left: push right"
;; solid at col=1 (x=16..31); entity at x=16 overlaps it, vx<0
(let* ((tm (make-test-tilemap '((0 0 0) (0 1 0) (0 0 0))))
(e (entity #:type 'player #:x 16 #:y 16 #:width 16 #:height 16 #:vx -5 #:vy 0)))
(let ((result (resolve-tile-collisions-x (test-scene tilemap: tm) e 0)))
- (test-equal "pushed right of solid tile" 32 (entity-ref result #:x))
- (test-equal "vx zeroed" 0 (entity-ref result #:vx)))))
+ (test "pushed right of solid tile" 32 (entity-ref result #:x))
+ (test "vx zeroed" 0 (entity-ref result #:vx)))))
(test-group "floating-point x position"
;; solid at col=1; entity at x=20.5 (float), vx>0
(let* ((tm (make-test-tilemap '((0 0 0) (0 1 0) (0 0 0))))
(e (entity #:type 'player #:x 20.5 #:y 16 #:width 16 #:height 16 #:vx 2 #:vy 0)))
(let ((result (resolve-tile-collisions-x (test-scene tilemap: tm) e 0)))
- (test-equal "pushed left of solid tile" 0 (entity-ref result #:x))
- (test-equal "vx zeroed" 0 (entity-ref result #:vx)))))
+ (test "pushed left of solid tile" 0 (entity-ref result #:x))
+ (test "vx zeroed" 0 (entity-ref result #:vx)))))
(test-group "entity spanning two columns: both checked"
;; wall at col=3; 20px-wide entity at x=28 spans cols 1 and 2, no collision
(let* ((tm (make-test-tilemap '((0 0 0 1) (0 0 0 1) (0 0 0 1))))
(e (entity #:type 'player #:x 28 #:y 0 #:width 20 #:height 16 #:vx 3 #:vy 0)))
(let ((result (resolve-tile-collisions-x (test-scene tilemap: tm) e 0)))
- (test-equal "no collision yet" 28 (entity-ref result #:x))))
+ (test "no collision yet" 28 (entity-ref result #:x))))
;; entity moved to x=34 now spans cols 2 and 3 (solid), pushed left
(let* ((tm (make-test-tilemap '((0 0 0 1) (0 0 0 1) (0 0 0 1))))
(e (entity #:type 'player #:x 34 #:y 0 #:width 20 #:height 16 #:vx 3 #:vy 0)))
(let ((result (resolve-tile-collisions-x (test-scene tilemap: tm) e 0)))
- (test-equal "pushed left of wall" 28 (entity-ref result #:x))
- (test-equal "vx zeroed" 0 (entity-ref result #:vx))))))
+ (test "pushed left of wall" 28 (entity-ref result #:x))
+ (test "vx zeroed" 0 (entity-ref result #:vx))))))
(test-group "resolve-tile-collisions-y"
(test-group "no collision: entity unchanged"
(let* ((tm (make-test-tilemap '((0 0 0) (0 0 0) (0 0 0))))
(e (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16 #:vx 0 #:vy 2)))
(let ((result (resolve-tile-collisions-y (test-scene tilemap: tm) e 0)))
- (test-equal "y unchanged" 0 (entity-ref result #:y))
- (test-equal "vy unchanged" 2 (entity-ref result #:vy)))))
+ (test "y unchanged" 0 (entity-ref result #:y))
+ (test "vy unchanged" 2 (entity-ref result #:vy)))))
(test-group "zero vy: skipped entirely"
(let* ((tm (make-test-tilemap '((1 0 0) (0 0 0) (0 0 0))))
(e (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16 #:vx 0 #:vy 0)))
- (test-equal "entity eq? when vy=0" e (resolve-tile-collisions-y (test-scene tilemap: tm) e 0))))
+ (test "entity eq? when vy=0" e (resolve-tile-collisions-y (test-scene tilemap: tm) e 0))))
(test-group "collision moving down: push up"
;; solid at row=1 (y=16..31); entity at y=20 overlaps it, vy>0
(let* ((tm (make-test-tilemap '((0 0 0) (1 0 0) (0 0 0))))
(e (entity #:type 'player #:x 0 #:y 20 #:width 16 #:height 16 #:vx 0 #:vy 5)))
(let ((result (resolve-tile-collisions-y (test-scene tilemap: tm) e 0)))
- (test-equal "pushed above solid tile" 0 (entity-ref result #:y))
- (test-equal "vy zeroed" 0 (entity-ref result #:vy)))))
+ (test "pushed above solid tile" 0 (entity-ref result #:y))
+ (test "vy zeroed" 0 (entity-ref result #:vy)))))
(test-group "collision moving up: push down"
;; solid at row=1 (y=16..31); entity at y=16 overlaps it from below, vy<0
(let* ((tm (make-test-tilemap '((0 0 0) (0 1 0) (0 0 0))))
(e (entity #:type 'player #:x 16 #:y 16 #:width 16 #:height 16 #:vx 0 #:vy -5)))
(let ((result (resolve-tile-collisions-y (test-scene tilemap: tm) e 0)))
- (test-equal "pushed below solid tile" 32 (entity-ref result #:y))
- (test-equal "vy zeroed" 0 (entity-ref result #:vy)))))
+ (test "pushed below solid tile" 32 (entity-ref result #:y))
+ (test "vy zeroed" 0 (entity-ref result #:vy)))))
(test-group "floating-point y position"
;; solid at row=1; entity at y=20.5 (float), vy>0
(let* ((tm (make-test-tilemap '((0 0 0) (1 0 0) (0 0 0))))
(e (entity #:type 'player #:x 0 #:y 20.5 #:width 16 #:height 16 #:vx 0 #:vy 3)))
(let ((result (resolve-tile-collisions-y (test-scene tilemap: tm) e 0)))
- (test-equal "pushed above solid tile" 0 (entity-ref result #:y))
- (test-equal "vy zeroed" 0 (entity-ref result #:vy)))))
+ (test "pushed above solid tile" 0 (entity-ref result #:y))
+ (test "vy zeroed" 0 (entity-ref result #:vy)))))
(test-group "entity spanning two rows: both checked"
;; floor at row=3; 20px-tall entity at y=28 spans rows 1 and 2, no collision
(let* ((tm (make-test-tilemap '((0 0 0) (0 0 0) (0 0 0) (1 1 1))))
(e (entity #:type 'player #:x 0 #:y 28 #:width 16 #:height 20 #:vx 0 #:vy 3)))
(let ((result (resolve-tile-collisions-y (test-scene tilemap: tm) e 0)))
- (test-equal "no collision yet" 28 (entity-ref result #:y))))
+ (test "no collision yet" 28 (entity-ref result #:y))))
;; entity at y=34 now spans rows 2 and 3 (solid), pushed up
(let* ((tm (make-test-tilemap '((0 0 0) (0 0 0) (0 0 0) (1 1 1))))
(e (entity #:type 'player #:x 0 #:y 34 #:width 16 #:height 20 #:vx 0 #:vy 3)))
(let ((result (resolve-tile-collisions-y (test-scene tilemap: tm) e 0)))
- (test-equal "pushed above floor" 28 (entity-ref result #:y))
- (test-equal "vy zeroed" 0 (entity-ref result #:vy))))))
+ (test "pushed above floor" 28 (entity-ref result #:y))
+ (test "vy zeroed" 0 (entity-ref result #:vy))))))
(test-group "high-velocity fall: snaps to first solid row, not last"
;; Regression: entity falls fast enough that apply-velocity-y moves it into TWO solid rows.
@@ -311,8 +311,8 @@
(let* ((tm (make-test-tilemap '((0 0 0) (0 0 0) (1 0 0) (1 0 0) (0 0 0))))
(e (entity #:type 'player #:x 0 #:y 34 #:width 16 #:height 16 #:vx 0 #:vy 20)))
(let ((result (resolve-tile-collisions-y (test-scene tilemap: tm) e 0)))
- (test-equal "snapped to first solid row" 16 (entity-ref result #:y))
- (test-equal "vy zeroed" 0 (entity-ref result #:vy)))))
+ (test "snapped to first solid row" 16 (entity-ref result #:y))
+ (test "vy zeroed" 0 (entity-ref result #:vy)))))
;; Integration test: simulate the actual game physics loop
(test-group "multi-frame physics simulation"
@@ -361,8 +361,8 @@
(let* ((a (make-solid 0 0 16 16))
(b (make-solid 100 0 16 16))
(result (resolve-entity-collisions (list a b))))
- (test-equal "a x unchanged" 0 (entity-ref (list-ref result 0) #:x 0))
- (test-equal "b x unchanged" 100 (entity-ref (list-ref result 1) #:x 0))))
+ (test "a x unchanged" 0 (entity-ref (list-ref result 0) #:x 0))
+ (test "b x unchanged" 100 (entity-ref (list-ref result 1) #:x 0))))
(test-group "horizontal overlap: pushed apart on x"
;; a at x=0, b at x=10, both 16x16 → overlap-x = (16+16)/2 - 10 = 6, overlap-y = (16+16)/2 - 0 = 16
@@ -372,8 +372,8 @@
(result (resolve-entity-collisions (list a b)))
(ra (list-ref result 0))
(rb (list-ref result 1)))
- (test-equal "a pushed left by 3" -3 (entity-ref ra #:x 0))
- (test-equal "b pushed right by 3" 13 (entity-ref rb #:x 0))))
+ (test "a pushed left by 3" -3 (entity-ref ra #:x 0))
+ (test "b pushed right by 3" 13 (entity-ref rb #:x 0))))
(test-group "vertical overlap: pushed apart on y"
;; a at y=0, b at y=10, both 16x16 → overlap-x=16, overlap-y=6 → push on y
@@ -382,8 +382,8 @@
(result (resolve-entity-collisions (list a b)))
(ra (list-ref result 0))
(rb (list-ref result 1)))
- (test-equal "a pushed up by 3" -3 (entity-ref ra #:y 0))
- (test-equal "b pushed down by 3" 13 (entity-ref rb #:y 0))))
+ (test "a pushed up by 3" -3 (entity-ref ra #:y 0))
+ (test "b pushed down by 3" 13 (entity-ref rb #:y 0))))
(test-group "immovable: landing uses vertical separation when horizontal overlap is shallower"
;; Without the landing rule, ovx < ovy would pick horizontal separation and shove the
@@ -394,15 +394,15 @@
#:solid? #t #:immovable? #f #:vx 0 #:vy 0))
(result (resolve-entity-collisions (list shelf box)))
(box2 (list-ref result 1)))
- (test-equal "box rests on shelf top (y = shelf_y - height)" 184 (entity-ref box2 #:y 0))
- (test-equal "vy zeroed" 0 (entity-ref box2 #:vy 0))))
+ (test "box rests on shelf top (y = shelf_y - height)" 184 (entity-ref box2 #:y 0))
+ (test "vy zeroed" 0 (entity-ref box2 #:vy 0))))
(test-group "non-solid entity ignored"
(let* ((a (make-solid 0 0 16 16))
(b (entity #:type 'goal #:x 5 #:y 5 #:width 16 #:height 16))
(result (resolve-entity-collisions (list a b))))
- (test-equal "a x unchanged" 0 (entity-ref (list-ref result 0) #:x 0))
- (test-equal "b x unchanged" 5 (entity-ref (list-ref result 1) #:x 0)))))
+ (test "a x unchanged" 0 (entity-ref (list-ref result 0) #:x 0))
+ (test "b x unchanged" 5 (entity-ref (list-ref result 1) #:x 0)))))
;; Tests for detect-on-solid
(test-group "detect-on-solid"
@@ -465,104 +465,104 @@
(test-group "gravity? #t, ay set: consumed into vy and cleared"
(let* ((e (entity #:type 'player #:x 0 #:y 0 #:vy 3 #:ay 5 #:gravity? #t))
(result (apply-acceleration #f e 0)))
- (test-equal "vy += ay" 8 (entity-ref result #:vy 0))
- (test-equal "ay cleared" 0 (entity-ref result #:ay 0))))
+ (test "vy += ay" 8 (entity-ref result #:vy 0))
+ (test "ay cleared" 0 (entity-ref result #:ay 0))))
(test-group "gravity? #t, ay is 0: vy unchanged"
(let* ((e (entity #:type 'player #:x 0 #:y 0 #:vy 3 #:ay 0 #:gravity? #t))
(result (apply-acceleration #f e 0)))
- (test-equal "vy unchanged" 3 (entity-ref result #:vy 0))
- (test-equal "ay still 0" 0 (entity-ref result #:ay 0))))
+ (test "vy unchanged" 3 (entity-ref result #:vy 0))
+ (test "ay still 0" 0 (entity-ref result #:ay 0))))
(test-group "gravity? #f: entity unchanged"
(let* ((e (entity #:type 'player #:x 0 #:y 0 #:vy 3 #:ay 5 #:gravity? #f))
(result (apply-acceleration #f e 0)))
- (test-equal "entity unchanged" e result))))
+ (test "entity unchanged" e (begin result)))))
(test-group "pixel->tile"
- (test-equal "pixel 0 in 16px tile → 0" 0 (pixel->tile 0 16))
- (test-equal "pixel 15 in 16px tile → 0" 0 (pixel->tile 15 16))
- (test-equal "pixel 16 in 16px tile → 1" 1 (pixel->tile 16 16))
- (test-equal "pixel 24 in 16px tile → 1" 1 (pixel->tile 24 16))
- (test-equal "pixel 24.7 in 16px tile → 1" 1 (pixel->tile 24.7 16))
- (test-equal "pixel 32 in 16px tile → 2" 2 (pixel->tile 32 16)))
+ (test "pixel 0 in 16px tile → 0" 0 (pixel->tile 0 16))
+ (test "pixel 15 in 16px tile → 0" 0 (pixel->tile 15 16))
+ (test "pixel 16 in 16px tile → 1" 1 (pixel->tile 16 16))
+ (test "pixel 24 in 16px tile → 1" 1 (pixel->tile 24 16))
+ (test "pixel 24.7 in 16px tile → 1" 1 (pixel->tile 24.7 16))
+ (test "pixel 32 in 16px tile → 2" 2 (pixel->tile 32 16)))
(test-group "entity-tile-cells"
(test-group "entity aligned to one tile"
(let* ((tm (make-test-tilemap '((0 0) (0 0))))
(e (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16))
(cells (entity-tile-cells e tm)))
- (test-equal "one cell" 1 (length cells))
- (test-equal "cell is (0 . 0)" '(0 . 0) (car cells))))
+ (test "one cell" 1 (length cells))
+ (test "cell is (0 . 0)" '(0 . 0) (car cells))))
(test-group "entity spanning 2 cols and 2 rows"
(let* ((tm (make-test-tilemap '((0 0 0) (0 0 0) (0 0 0))))
(e (entity #:type 'player #:x 8 #:y 8 #:width 16 #:height 16))
(cells (entity-tile-cells e tm)))
- (test-equal "four cells" 4 (length cells)))))
+ (test "four cells" 4 (length cells)))))
(test-group "tile-push-pos"
(test-group "moving forward (v>0): snap leading edge to near side of tile"
;; coord=3, tile-size=16, entity-size=16 → 3*16 - 16 = 32
- (test-equal "push pos" 32 (tile-push-pos 1 3 16 16)))
+ (test "push pos" 32 (tile-push-pos 1 3 16 16)))
(test-group "moving backward (v<0): snap trailing edge to far side of tile"
;; coord=3, tile-size=16 → (3+1)*16 = 64
- (test-equal "push pos" 64 (tile-push-pos -1 3 16 16))))
+ (test "push pos" 64 (tile-push-pos -1 3 16 16))))
(test-group "list-set"
- (test-equal "replace first" '(x b c) (list-set '(a b c) 0 'x))
- (test-equal "replace middle" '(a x c) (list-set '(a b c) 1 'x))
- (test-equal "replace last" '(a b x) (list-set '(a b c) 2 'x)))
+ (test "replace first" '(x b c) (list-set '(a b c) 0 'x))
+ (test "replace middle" '(a x c) (list-set '(a b c) 1 'x))
+ (test "replace last" '(a b x) (list-set '(a b c) 2 'x)))
(test-group "index-pairs"
- (test-equal "n=0: empty" '() (index-pairs 0))
- (test-equal "n=1: empty" '() (index-pairs 1))
- (test-equal "n=2: one pair" '((0 . 1)) (index-pairs 2))
+ (test "n=0: empty" '() (index-pairs 0))
+ (test "n=1: empty" '() (index-pairs 1))
+ (test "n=2: one pair" '((0 . 1)) (index-pairs 2))
(test-group "n=3: three pairs"
(let ((pairs (index-pairs 3)))
- (test-equal "count" 3 (length pairs))
+ (test "count" 3 (length pairs))
(test-assert "(0 . 1)" (member '(0 . 1) pairs))
(test-assert "(0 . 2)" (member '(0 . 2) pairs))
(test-assert "(1 . 2)" (member '(1 . 2) pairs)))))
(test-group "axis->dimension"
- (test-equal "#:x → #:width" #:width (axis->dimension #:x))
- (test-equal "#:y → #:height" #:height (axis->dimension #:y)))
+ (test "#:x → #:width" #:width (axis->dimension #:x))
+ (test "#:y → #:height" #:height (axis->dimension #:y)))
(test-group "axis->velocity"
- (test-equal "#:x → #:vx" #:vx (axis->velocity #:x))
- (test-equal "#:y → #:vy" #:vy (axis->velocity #:y)))
+ (test "#:x → #:vx" #:vx (axis->velocity #:x))
+ (test "#:y → #:vy" #:vy (axis->velocity #:y)))
(test-group "push-entity"
(test-group "push right (sign=1): x += overlap/2, vx=1"
(let* ((e (entity #:type 'player #:x 10 #:y 0 #:vx 0 #:vy 0))
(result (push-entity e #:x #:vx 10 6 1)))
- (test-equal "x = 10 + 3" 13 (entity-ref result #:x 0))
- (test-equal "vx = 1" 1 (entity-ref result #:vx 0))))
+ (test "x = 10 + 3" 13 (entity-ref result #:x 0))
+ (test "vx = 1" 1 (entity-ref result #:vx 0))))
(test-group "push left (sign=-1): x -= overlap/2, vx=-1"
(let* ((e (entity #:type 'player #:x 10 #:y 0 #:vx 0 #:vy 0))
(result (push-entity e #:x #:vx 10 6 -1)))
- (test-equal "x = 10 - 3" 7 (entity-ref result #:x 0))
- (test-equal "vx = -1" -1 (entity-ref result #:vx 0)))))
+ (test "x = 10 - 3" 7 (entity-ref result #:x 0))
+ (test "vx = -1" -1 (entity-ref result #:vx 0)))))
(test-group "entity-center-on-axis"
(let ((e (entity #:type 'player #:x 10 #:y 20 #:width 16 #:height 24)))
- (test-equal "center-x = 10 + 8 = 18" 18 (entity-center-on-axis e #:x))
- (test-equal "center-y = 20 + 12 = 32" 32 (entity-center-on-axis e #:y))))
+ (test "center-x = 10 + 8 = 18" 18 (entity-center-on-axis e #:x))
+ (test "center-y = 20 + 12 = 32" 32 (entity-center-on-axis e #:y))))
(test-group "aabb-overlap-on-axis"
(test-group "x overlap: a at x=0 w=16, b at x=10 w=16 → overlap=6"
;; half-sum of widths = 16, center dist = |18 - 8| = 10, overlap = 16 - 10 = 6
(let ((a (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16))
(b (entity #:type 'player #:x 10 #:y 0 #:width 16 #:height 16)))
- (test-equal "x overlap = 6" 6 (aabb-overlap-on-axis #:x a b))))
+ (test "x overlap = 6" 6 (aabb-overlap-on-axis #:x a b))))
(test-group "y overlap: a at y=0 h=16, b at y=10 h=16 → overlap=6"
(let ((a (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16))
(b (entity #:type 'player #:x 0 #:y 10 #:width 16 #:height 16)))
- (test-equal "y overlap = 6" 6 (aabb-overlap-on-axis #:y a b))))
+ (test "y overlap = 6" 6 (aabb-overlap-on-axis #:y a b))))
(test-group "no overlap: negative value"
(let ((a (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16))
@@ -576,10 +576,10 @@
(result (push-along-axis #:x a b 6))
(ra (car result))
(rb (cdr result)))
- (test-equal "a pushed left to -3" -3 (entity-ref ra #:x 0))
- (test-equal "b pushed right to 13" 13 (entity-ref rb #:x 0))
- (test-equal "a vx = -1" -1 (entity-ref ra #:vx 0))
- (test-equal "b vx = 1" 1 (entity-ref rb #:vx 0))))
+ (test "a pushed left to -3" -3 (entity-ref ra #:x 0))
+ (test "b pushed right to 13" 13 (entity-ref rb #:x 0))
+ (test "a vx = -1" -1 (entity-ref ra #:vx 0))
+ (test "b vx = 1" 1 (entity-ref rb #:vx 0))))
(test-group "y axis: a above b, pushed apart"
(let* ((a (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16))
@@ -587,8 +587,8 @@
(result (push-along-axis #:y a b 6))
(ra (car result))
(rb (cdr result)))
- (test-equal "a pushed up to -3" -3 (entity-ref ra #:y 0))
- (test-equal "b pushed down to 13" 13 (entity-ref rb #:y 0)))))
+ (test "a pushed up to -3" -3 (entity-ref ra #:y 0))
+ (test "b pushed down to 13" 13 (entity-ref rb #:y 0)))))
(test-group "push-apart"
(test-group "x overlap smaller: pushes on x axis"
@@ -596,26 +596,26 @@
(let* ((a (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16))
(b (entity #:type 'player #:x 10 #:y 0 #:width 16 #:height 16))
(result (push-apart a b)))
- (test-equal "a pushed left" -3 (entity-ref (car result) #:x 0))
- (test-equal "b pushed right" 13 (entity-ref (cdr result) #:x 0))))
+ (test "a pushed left" -3 (entity-ref (car result) #:x 0))
+ (test "b pushed right" 13 (entity-ref (cdr result) #:x 0))))
(test-group "y overlap smaller: pushes on y axis"
;; a at (0,0), b at (0,10), both 16x16: ovx=16, ovy=6 → push on y
(let* ((a (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16))
(b (entity #:type 'player #:x 0 #:y 10 #:width 16 #:height 16))
(result (push-apart a b)))
- (test-equal "a pushed up" -3 (entity-ref (car result) #:y 0))
- (test-equal "b pushed down" 13 (entity-ref (cdr result) #:y 0)))))
+ (test "a pushed up" -3 (entity-ref (car result) #:y 0))
+ (test "b pushed down" 13 (entity-ref (cdr result) #:y 0)))))
(test-group "skip-pipelines"
(test-group "apply-gravity"
(let* ((e (entity #:type 't #:vy 0 #:gravity? #t #:skip-pipelines '(gravity)))
(r (apply-gravity #f e 0)))
- (test-equal "skipped: vy unchanged" 0 (entity-ref r #:vy))))
+ (test "skipped: vy unchanged" 0 (entity-ref r #:vy))))
(test-group "apply-velocity-x"
(let* ((e (entity #:type 't #:x 10 #:vx 5 #:skip-pipelines '(velocity-x)))
(r (apply-velocity-x #f e 0)))
- (test-equal "skipped: x unchanged" 10 (entity-ref r #:x))))
+ (test "skipped: x unchanged" 10 (entity-ref r #:x))))
(test-group "resolve-pair with entity-collisions skip"
(define (make-solid x y) (entity #:type 'block #:x x #:y y #:width 16 #:height 16 #:solid? #t))
(let* ((a (entity #:type 'ghost #:x 0 #:y 0 #:width 16 #:height 16 #:solid? #t
@@ -660,7 +660,7 @@
(a2 (car r))
(b2 (cdr r)))
(test-assert "result is pair" (pair? r))
- (test-equal "a2 is wall (unchanged x)" 0 (entity-ref a2 #:x))
+ (test "a2 is wall (unchanged x)" 0 (entity-ref a2 #:x))
(test-assert "b2 is box (pushed right)" (> (entity-ref b2 #:x) 8))))
(test-group "box(a) first, wall(b) second"
(let* ((wall (make-static 0 0))
@@ -669,7 +669,7 @@
(a2 (car r))
(b2 (cdr r)))
(test-assert "result is pair" (pair? r))
- (test-equal "b2 is wall (unchanged x)" 0 (entity-ref b2 #:x))
+ (test "b2 is wall (unchanged x)" 0 (entity-ref b2 #:x))
(test-assert "a2 is box (pushed right)" (> (entity-ref a2 #:x) 8))))))
(test-group "aabb-overlap?"
@@ -694,3 +694,4 @@
(aabb-overlap? 0 0 20 20 5 5 10 10))))
(test-end "physics-module")
+(test-exit)
diff --git a/tests/prefabs-test.scm b/tests/prefabs-test.scm
index ab7b5f1..8eaf348 100644
--- a/tests/prefabs-test.scm
+++ b/tests/prefabs-test.scm
@@ -5,7 +5,7 @@
(chicken port)
(chicken pretty-print)
defstruct
- srfi-64)
+ test)
;; Mock downstroke-entity
(module downstroke-entity *
@@ -42,14 +42,14 @@
(test-assert "animated entry exists" (assq 'animated m))
(let ((pb (cdr (assq 'physics-body m))))
- (test-equal "physics-body has #:vx 0" 0 (cadr (memq #:vx pb)))
- (test-equal "physics-body has #:gravity? #t" #t (cadr (memq #:gravity? pb)))
- (test-equal "physics-body has #:on-ground? #f" #f (cadr (memq #:on-ground? pb))))
+ (test "physics-body has #:vx 0" 0 (cadr (memq #:vx pb)))
+ (test "physics-body has #:gravity? #t" #t (cadr (memq #:gravity? pb)))
+ (test "physics-body has #:on-ground? #f" #f (cadr (memq #:on-ground? pb))))
(let ((an (cdr (assq 'animated m))))
- (test-equal "animated has #:anim-tick 0" 0 (cadr (memq #:anim-tick an)))
- (test-equal "animated has #:tile-id 0" 0 (cadr (memq #:tile-id an)))
- (test-equal "animated has #:anim-name idle" 'idle (cadr (memq #:anim-name an))))))
+ (test "animated has #:anim-tick 0" 0 (cadr (memq #:anim-tick an)))
+ (test "animated has #:tile-id 0" 0 (cadr (memq #:tile-id an)))
+ (test "animated has #:anim-name idle" 'idle (cadr (memq #:anim-name an))))))
(test-group "compose-prefab (via load-prefabs with temp file)"
@@ -67,11 +67,11 @@
;; Inline #:vx 99 beats mixin #:vx 5
(let ((e (instantiate-prefab reg 'runner 0 0 16 16)))
(pp e)
- (test-equal "entity should have squashed properties" 7 (length e))
- (test-equal "inline field beats mixin field for same key"
+ (test "entity should have squashed properties" 7 (length e))
+ (test "inline field beats mixin field for same key"
99
(entity-ref e #:vx))
- (test-equal "mixin field present when not overridden"
+ (test "mixin field present when not overridden"
0
(entity-ref e #:vy))))))
@@ -82,7 +82,7 @@
(lambda (reg)
;; m1 listed before m2 → m1's #:key wins
(let ((e (instantiate-prefab reg 'thing 0 0 8 8)))
- (test-equal "earlier mixin wins over later mixin for same key"
+ (test "earlier mixin wins over later mixin for same key"
'first
(entity-ref e #:key))))))
@@ -93,7 +93,7 @@
(lambda (reg)
;; User redefined physics-body → user's version wins
(let ((e (instantiate-prefab reg 'custom-obj 0 0 16 16)))
- (test-equal "user-redefined mixin key overrides engine default"
+ (test "user-redefined mixin key overrides engine default"
77
(entity-ref e #:vx))))))
@@ -120,13 +120,13 @@
(not (instantiate-prefab reg 'unknown 0 0 8 8)))
(let ((e (instantiate-prefab reg 'box 10 20 32 48)))
- (test-equal "instance #:x is set" 10 (entity-ref e #:x))
- (test-equal "instance #:y is set" 20 (entity-ref e #:y))
- (test-equal "instance #:width is set" 32 (entity-ref e #:width))
- (test-equal "instance #:height is set" 48 (entity-ref e #:height))
- (test-equal "prefab field #:type present" 'box (entity-ref e #:type))
- (test-equal "mixin field #:vx present" 0 (entity-ref e #:vx))
- (test-equal "mixin field #:gravity? present" #t (entity-ref e #:gravity?))))))
+ (test "instance #:x is set" 10 (entity-ref e #:x))
+ (test "instance #:y is set" 20 (entity-ref e #:y))
+ (test "instance #:width is set" 32 (entity-ref e #:width))
+ (test "instance #:height is set" 48 (entity-ref e #:height))
+ (test "prefab field #:type present" 'box (entity-ref e #:type))
+ (test "mixin field #:vx present" 0 (entity-ref e #:vx))
+ (test "mixin field #:gravity? present" #t (entity-ref e #:gravity?))))))
(test-group "hooks"
(define (with-hook-registry extra-prefabs user-hooks thunk)
@@ -151,7 +151,7 @@
user-hooks: '()
hook-table: '())))
(let ((e (instantiate-prefab reg 'proc-hooked 0 0 8 8)))
- (test-equal "procedure hook fires and sets #:proc-fired"
+ (test "procedure hook fires and sets #:proc-fired"
#t
(entity-ref e #:proc-fired)))))
@@ -162,7 +162,7 @@
`((my-hook . ,(lambda (e) (entity-set e #:initialized #t))))
(lambda (reg)
(let ((e (instantiate-prefab reg 'hooked 0 0 8 8)))
- (test-equal "user hook sets #:initialized"
+ (test "user hook sets #:initialized"
#t
(entity-ref e #:initialized))))))
@@ -176,7 +176,7 @@
(let ((reg (load-prefabs tmp (engine-mixins)
`((init-npc . ,(lambda (e) (entity-set e #:ai-machine 'from-user-hook)))))))
(let ((e (instantiate-prefab reg 'npc 0 0 16 16)))
- (test-equal "user hook sets #:ai-machine"
+ (test "user hook sets #:ai-machine"
'from-user-hook
(entity-ref e #:ai-machine))))))
@@ -186,7 +186,7 @@
'()
(lambda (reg)
(let ((e (instantiate-prefab reg 'plain 0 0 8 8)))
- (test-equal "no hook: type is plain" 'plain (entity-ref e #:type))))))
+ (test "no hook: type is plain" 'plain (entity-ref e #:type))))))
(test-group "unknown hook symbol raises error"
(test-error
@@ -209,9 +209,9 @@
(display "((mixins) (prefabs (box #:type box #:value 42)))"))))
(reg2 (reload-prefabs! reg1))
(e2 (instantiate-prefab reg2 'box 0 0 8 8)))
- (test-equal "original registry has #:value 1" 1 (entity-ref e1 #:value))
- (test-equal "reloaded registry has #:value 42" 42 (entity-ref e2 #:value))
- (test-equal "original registry unchanged after reload" 1 (entity-ref e1 #:value))))
+ (test "original registry has #:value 1" 1 (entity-ref e1 #:value))
+ (test "reloaded registry has #:value 42" 42 (entity-ref e2 #:value))
+ (test "original registry unchanged after reload" 1 (entity-ref e1 #:value))))
(test-group "group-prefabs"
(define (with-group-prefab-data str thunk)
@@ -229,17 +229,17 @@
(test-assert "instantiate-group-prefab unknown → #f"
(not (instantiate-group-prefab reg 'nope 0 0)))
(let ((lst (instantiate-group-prefab reg 'two-block 100 50)))
- (test-equal "returns list of origin + 2 members" 3 (length lst))
+ (test "returns list of origin + 2 members" 3 (length lst))
(let ((origin (car lst))
(a (cadr lst))
(b (caddr lst)))
- (test-equal "pose-only origin skip-render" #t (entity-ref origin #:skip-render))
- (test-equal "origin group-origin?" #t (entity-ref origin #:group-origin?))
- (test-equal "member a world x" 100 (entity-ref a #:x))
- (test-equal "member b world x" 110 (entity-ref b #:x))
- (test-equal "member a local x" 0 (entity-ref a #:group-local-x))
- (test-equal "member b local x" 10 (entity-ref b #:group-local-x))
- (test-equal "shared group-id" (entity-ref origin #:group-id) (entity-ref a #:group-id))))))
+ (test "pose-only origin skip-render" #t (entity-ref origin #:skip-render))
+ (test "origin group-origin?" #t (entity-ref origin #:group-origin?))
+ (test "member a world x" 100 (entity-ref a #:x))
+ (test "member b world x" 110 (entity-ref b #:x))
+ (test "member a local x" 0 (entity-ref a #:group-local-x))
+ (test "member b local x" 10 (entity-ref b #:group-local-x))
+ (test "shared group-id" (entity-ref origin #:group-id) (entity-ref a #:group-id))))))
(with-group-prefab-data
"((mixins) (prefabs)
@@ -248,8 +248,9 @@
#:parts ((#:local-x 0 #:local-y 0 #:width 4 #:height 4 #:tile-id 1)))))"
(lambda (reg)
(let ((origin (car (instantiate-group-prefab reg 'falling-asm 0 0))))
- (test-equal "physics origin has gravity" #t (entity-ref origin #:gravity?))
+ (test "physics origin has gravity" #t (entity-ref origin #:gravity?))
(test-assert "physics origin has no #:skip-pipelines (pipelines run)"
(eq? 'absent (entity-ref origin #:skip-pipelines 'absent)))))))
(test-end "prefabs")
+(test-exit)
diff --git a/tests/renderer-test.scm b/tests/renderer-test.scm
index 9f6ce55..702a712 100644
--- a/tests/renderer-test.scm
+++ b/tests/renderer-test.scm
@@ -5,7 +5,7 @@
(only srfi-1 fold iota for-each)
srfi-69
defstruct
- srfi-64)
+ test)
;; Mock tilemap module
(module downstroke-tilemap *
@@ -60,42 +60,42 @@
(test-group "entity-screen-coords"
(let* ((cam (make-camera x: 10 y: 20))
(e (entity #:x 50 #:y 80 #:width 16 #:height 16)))
- (test-equal "subtracts camera offset from x"
+ (test "subtracts camera offset from x"
40
(car (entity-screen-coords e cam)))
- (test-equal "subtracts camera offset from y"
+ (test "subtracts camera offset from y"
60
(cadr (entity-screen-coords e cam)))
- (test-equal "preserves width"
+ (test "preserves width"
16
(caddr (entity-screen-coords e cam)))
- (test-equal "preserves height"
+ (test "preserves height"
16
(cadddr (entity-screen-coords e cam))))
(let* ((cam (make-camera x: 0 y: 0))
(e (entity #:x 100.7 #:y 200.3 #:width 16 #:height 16)))
- (test-equal "floors fractional x"
+ (test "floors fractional x"
100
(car (entity-screen-coords e cam)))
- (test-equal "floors fractional y"
+ (test "floors fractional y"
200
(cadr (entity-screen-coords e cam))))
(let* ((cam (make-camera x: 0 y: 0))
(e (entity #:x 0 #:y 0 #:width 32 #:height 32)))
- (test-equal "zero camera, zero position"
+ (test "zero camera, zero position"
'(0 0 32 32)
(entity-screen-coords e cam))))
(test-group "entity-flip"
- (test-equal "facing 1: no flip"
+ (test "facing 1: no flip"
'()
(entity-flip (entity #:facing 1)))
- (test-equal "facing -1: horizontal flip"
+ (test "facing -1: horizontal flip"
'(horizontal)
(entity-flip (entity #:facing -1)))
- (test-equal "no facing key: defaults to no flip"
+ (test "no facing key: defaults to no flip"
'()
(entity-flip (entity #:x 0))))
@@ -135,23 +135,23 @@
(test-group "make-sprite-font*"
(let ((font (make-sprite-font* tile-size: 8 spacing: 1
ranges: (list (list #\A #\C 100)))))
- (test-equal "A maps to 100"
+ (test "A maps to 100"
100
(sprite-font-char->tile-id font #\A))
- (test-equal "B maps to 101"
+ (test "B maps to 101"
101
(sprite-font-char->tile-id font #\B))
- (test-equal "C maps to 102"
+ (test "C maps to 102"
102
(sprite-font-char->tile-id font #\C))))
(test-group "sprite-font-char->tile-id"
(let ((font (make-sprite-font* tile-size: 8 spacing: 1
ranges: (list (list #\A #\Z 100)))))
- (test-equal "returns #f for unmapped char"
+ (test "returns #f for unmapped char"
#f
(sprite-font-char->tile-id font #\1))
- (test-equal "auto-upcase: lowercase a maps to uppercase"
+ (test "auto-upcase: lowercase a maps to uppercase"
100
(sprite-font-char->tile-id font #\a))))
@@ -170,16 +170,16 @@
(test-group "sprite-text-width"
(let ((font (make-sprite-font* tile-size: 8 spacing: 1
ranges: (list (list #\A #\Z 100)))))
- (test-equal "empty string width is 0"
+ (test "empty string width is 0"
0
(sprite-text-width font ""))
- (test-equal "single char width is tile-size"
+ (test "single char width is tile-size"
8
(sprite-text-width font "A"))
- (test-equal "two chars: 2*tile-size + 1*spacing"
+ (test "two chars: 2*tile-size + 1*spacing"
17
(sprite-text-width font "AB"))
- (test-equal "three chars: 3*tile-size + 2*spacing"
+ (test "three chars: 3*tile-size + 2*spacing"
26
(sprite-text-width font "ABC"))))
@@ -303,7 +303,7 @@
(test-assert "render-scene! works with plist entities"
(begin (render-scene! #f scene-ok) #t))
(test-error "render-scene! errors when entity list contains a vector"
- #t (render-scene! #f scene-bad))
+ (render-scene! #f scene-bad))
(test-assert "extracting entity from cell vector fixes the issue"
(let ((scene-fixed (make-scene entities: (list (vector-ref cell 0))
tilemap: tilemap camera: cam
@@ -311,3 +311,4 @@
(begin (render-scene! #f scene-fixed) #t)))))
(test-end "renderer")
+(test-exit)
diff --git a/tests/scene-loader-test.scm b/tests/scene-loader-test.scm
index 88fb544..6e0be9c 100644
--- a/tests/scene-loader-test.scm
+++ b/tests/scene-loader-test.scm
@@ -4,7 +4,7 @@
(chicken keyword)
(only srfi-1 fold filter)
defstruct
- srfi-64)
+ test)
;; Mock tilemap module
(module downstroke-tilemap *
@@ -93,18 +93,18 @@
(list (cons 'player (lambda (x y w h) (entity #:type 'player #:x x #:y y #:width w #:height h)))
(cons 'enemy (lambda (x y w h) (entity #:type 'enemy #:x x #:y y #:width w #:height h)))))
(result (tilemap-objects->entities tm registry)))
- (test-equal "filters #f results: 2 entities from 3 objects"
+ (test "filters #f results: 2 entities from 3 objects"
2 (length result))
- (test-equal "first entity is player"
+ (test "first entity is player"
'player (entity-ref (car result) #:type))
- (test-equal "second entity is enemy"
+ (test "second entity is enemy"
'enemy (entity-ref (cadr result) #:type)))
(let* ((tm-empty (make-tilemap width: 100 height: 100 tilewidth: 16 tileheight: 16
tileset-source: "" tileset: #f layers: '()
objects: '()))
(result (tilemap-objects->entities tm-empty '())))
- (test-equal "empty object list returns empty list"
+ (test "empty object list returns empty list"
0 (length result))))
(test-group "game-load-tilemap! / game-load-tileset! / game-load-font!"
@@ -120,8 +120,9 @@
;; game-load-font! with mock ttf returns a font value
(let* ((game #f) ; mock game (game-asset-set! ignores it in mock)
(font (ttf:open-font "test.ttf" 16)))
- (test-equal "mock font is a list"
+ (test "mock font is a list"
'font
(car font))))
(test-end "scene-loader")
+(test-exit)
diff --git a/tests/tilemap-test.scm b/tests/tilemap-test.scm
index 16629bd..282400f 100644
--- a/tests/tilemap-test.scm
+++ b/tests/tilemap-test.scm
@@ -15,7 +15,7 @@
(prefix sdl2 sdl2:)
(prefix sdl2-image img:)
srfi-69
- srfi-64)
+ test)
;; Load the module source directly
(include "tilemap.scm")
@@ -35,12 +35,12 @@
image-source: "test.png"
image: #f)))
(test-assert "tileset is a record" (tileset? ts))
- (test-equal "tilewidth is set correctly" 16 (tileset-tilewidth ts))
- (test-equal "tileheight is set correctly" 16 (tileset-tileheight ts))
- (test-equal "spacing is set correctly" 1 (tileset-spacing ts))
- (test-equal "tilecount is set correctly" 100 (tileset-tilecount ts))
- (test-equal "columns is set correctly" 10 (tileset-columns ts))
- (test-equal "image-source is set correctly" "test.png" (tileset-image-source ts))))
+ (test "tilewidth is set correctly" 16 (tileset-tilewidth ts))
+ (test "tileheight is set correctly" 16 (tileset-tileheight ts))
+ (test "spacing is set correctly" 1 (tileset-spacing ts))
+ (test "tilecount is set correctly" 100 (tileset-tilecount ts))
+ (test "columns is set correctly" 10 (tileset-columns ts))
+ (test "image-source is set correctly" "test.png" (tileset-image-source ts))))
;; Test: tileset-rows calculation
(test-group "tileset-rows"
@@ -51,7 +51,7 @@
columns: 10
image-source: "test.png"
image: #f)))
- (test-equal "100 tiles / 10 columns = 10 rows"
+ (test "100 tiles / 10 columns = 10 rows"
10
(tileset-rows ts)))
@@ -62,7 +62,7 @@
columns: 10
image-source: "test.png"
image: #f)))
- (test-equal "105 tiles / 10 columns = 11 rows (ceiling)"
+ (test "105 tiles / 10 columns = 11 rows (ceiling)"
11
(tileset-rows ts))))
@@ -79,16 +79,16 @@
(tile11 (tileset-tile ts 11)))
(test-assert "tile1 is a tile record" (tile? tile1))
- (test-equal "tile1 has correct id" 1 (tile-id tile1))
+ (test "tile1 has correct id" 1 (tile-id tile1))
(test-assert "tile1 has a rect" (sdl2:rect? (tile-rect tile1)))
;; First tile should be at (0, 0)
- (test-equal "tile1 x position" 0 (sdl2:rect-x (tile-rect tile1)))
- (test-equal "tile1 y position" 0 (sdl2:rect-y (tile-rect tile1)))
+ (test "tile1 x position" 0 (sdl2:rect-x (tile-rect tile1)))
+ (test "tile1 y position" 0 (sdl2:rect-y (tile-rect tile1)))
;; Tile 11 should be at start of second row (x=0, y=17 with spacing)
- (test-equal "tile11 x position" 0 (sdl2:rect-x (tile-rect tile11)))
- (test-equal "tile11 y position" 17 (sdl2:rect-y (tile-rect tile11)))))
+ (test "tile11 x position" 0 (sdl2:rect-x (tile-rect tile11)))
+ (test "tile11 y position" 17 (sdl2:rect-y (tile-rect tile11)))))
;; Test: layer record creation
(test-group "layer-structure"
@@ -97,10 +97,10 @@
height: 30
map: '())))
(test-assert "layer is a record" (layer? layer))
- (test-equal "name is set correctly" "ground" (layer-name layer))
- (test-equal "width is set correctly" 40 (layer-width layer))
- (test-equal "height is set correctly" 30 (layer-height layer))
- (test-equal "map is empty list" '() (layer-map layer))))
+ (test "name is set correctly" "ground" (layer-name layer))
+ (test "width is set correctly" 40 (layer-width layer))
+ (test "height is set correctly" 30 (layer-height layer))
+ (test "map is empty list" '() (layer-map layer))))
;; Test: object record creation
(test-group "object-structure"
@@ -112,11 +112,11 @@
height: 16
properties: '((text . "hello")))))
(test-assert "object is a record" (object? obj))
- (test-equal "name is set correctly" "player" (object-name obj))
- (test-equal "type is set correctly" "Player" (object-type obj))
- (test-equal "x is set correctly" 100 (object-x obj))
- (test-equal "y is set correctly" 200 (object-y obj))
- (test-equal "properties contain text" "hello" (alist-ref 'text (object-properties obj)))))
+ (test "name is set correctly" "player" (object-name obj))
+ (test "type is set correctly" "Player" (object-type obj))
+ (test "x is set correctly" 100 (object-x obj))
+ (test "y is set correctly" 200 (object-y obj))
+ (test "properties contain text" "hello" (alist-ref 'text (object-properties obj)))))
;; Test: tilemap record creation
(test-group "tilemap-structure"
@@ -129,17 +129,17 @@
layers: '()
objects: '())))
(test-assert "tilemap is a record" (tilemap? tm))
- (test-equal "width is set correctly" 40 (tilemap-width tm))
- (test-equal "height is set correctly" 30 (tilemap-height tm))
- (test-equal "tilewidth is set correctly" 16 (tilemap-tilewidth tm))
- (test-equal "tileheight is set correctly" 16 (tilemap-tileheight tm))))
+ (test "width is set correctly" 40 (tilemap-width tm))
+ (test "height is set correctly" 30 (tilemap-height tm))
+ (test "tilewidth is set correctly" 16 (tilemap-tilewidth tm))
+ (test "tileheight is set correctly" 16 (tilemap-tileheight tm))))
;; Test: tile record creation
(test-group "tile-structure"
(let* ((rect (sdl2:make-rect 0 0 16 16))
(tile (make-tile id: 1 rect: rect)))
(test-assert "tile is a record" (tile? tile))
- (test-equal "id is set correctly" 1 (tile-id tile))
+ (test "id is set correctly" 1 (tile-id tile))
(test-assert "rect is an SDL rect" (sdl2:rect? (tile-rect tile)))))
;; Test: parse-tileset XML parsing
@@ -150,12 +150,12 @@
</tileset>")
(ts (parse-tileset xml)))
(test-assert "returns a tileset" (tileset? ts))
- (test-equal "parses tilewidth" 16 (tileset-tilewidth ts))
- (test-equal "parses tileheight" 16 (tileset-tileheight ts))
- (test-equal "parses spacing" 1 (tileset-spacing ts))
- (test-equal "parses tilecount" 100 (tileset-tilecount ts))
- (test-equal "parses columns" 10 (tileset-columns ts))
- (test-equal "parses image source" "test.png" (tileset-image-source ts))))
+ (test "parses tilewidth" 16 (tileset-tilewidth ts))
+ (test "parses tileheight" 16 (tileset-tileheight ts))
+ (test "parses spacing" 1 (tileset-spacing ts))
+ (test "parses tilecount" 100 (tileset-tilecount ts))
+ (test "parses columns" 10 (tileset-columns ts))
+ (test "parses image source" "test.png" (tileset-image-source ts))))
;; Test: parse-tilemap XML parsing
(test-group "parse-tilemap"
@@ -171,13 +171,13 @@
</map>")
(tm (parse-tilemap xml)))
(test-assert "returns a tilemap" (tilemap? tm))
- (test-equal "parses width" 10 (tilemap-width tm))
- (test-equal "parses height" 10 (tilemap-height tm))
- (test-equal "parses tilewidth" 16 (tilemap-tilewidth tm))
- (test-equal "parses tileheight" 16 (tilemap-tileheight tm))
- (test-equal "parses tileset source" "test.tsx" (tilemap-tileset-source tm))
+ (test "parses width" 10 (tilemap-width tm))
+ (test "parses height" 10 (tilemap-height tm))
+ (test "parses tilewidth" 16 (tilemap-tilewidth tm))
+ (test "parses tileheight" 16 (tilemap-tileheight tm))
+ (test "parses tileset source" "test.tsx" (tilemap-tileset-source tm))
(test-assert "has layers" (not (null? (tilemap-layers tm))))
- (test-equal "first layer name" "ground" (layer-name (car (tilemap-layers tm))))))
+ (test "first layer name" "ground" (layer-name (car (tilemap-layers tm))))))
;; Test: parse-tilemap with objects
(test-group "parse-tilemap-with-objects"
@@ -195,10 +195,11 @@
(tm (parse-tilemap xml)))
(test-assert "has objects" (not (null? (tilemap-objects tm))))
(let ((obj (car (tilemap-objects tm))))
- (test-equal "object name" "player" (object-name obj))
- (test-equal "object type" "Player" (object-type obj))
- (test-equal "object x" 50 (object-x obj))
- (test-equal "object y" 50 (object-y obj))
- (test-equal "object has properties" "5" (alist-ref 'speed (object-properties obj))))))
+ (test "object name" "player" (object-name obj))
+ (test "object type" "Player" (object-type obj))
+ (test "object x" 50 (object-x obj))
+ (test "object y" 50 (object-y obj))
+ (test "object has properties" "5" (alist-ref 'speed (object-properties obj))))))
(test-end "tilemap-module")
+(test-exit)
diff --git a/tests/tween-test.scm b/tests/tween-test.scm
index 962d325..51675b8 100644
--- a/tests/tween-test.scm
+++ b/tests/tween-test.scm
@@ -1,4 +1,4 @@
-(import srfi-64
+(import test
(chicken base))
(include "entity.scm")
(include "tween.scm")
@@ -12,18 +12,18 @@
(test-begin "tween")
(test-group "ease functions"
- (test-equal "linear mid" 0.5 (ease-linear 0.5))
- (test-equal "quad-in mid" 0.25 (ease-quad-in 0.5))
- (test-equal "quad-out mid" 0.75 (ease-quad-out 0.5))
- (test-equal "quad-in-out mid" 0.5 (ease-quad-in-out 0.5))
- (test-equal "cubic-in mid" 0.125 (ease-cubic-in 0.5))
+ (test "linear mid" 0.5 (ease-linear 0.5))
+ (test "quad-in mid" 0.25 (ease-quad-in 0.5))
+ (test "quad-out mid" 0.75 (ease-quad-out 0.5))
+ (test "quad-in-out mid" 0.5 (ease-quad-in-out 0.5))
+ (test "cubic-in mid" 0.125 (ease-cubic-in 0.5))
(test-assert "sine-in-out endpoints"
(and (= 0.0 (ease-sine-in-out 0)) (= 1.0 (ease-sine-in-out 1))))
- (test-equal "expo-in at 0" 0.0 (ease-expo-in 0))
- (test-equal "expo-out at 1" 1.0 (ease-expo-out 1))
- (test-equal "expo-in-out mid" 0.5 (ease-expo-in-out 0.5))
- (test-equal "cubic-in-out mid" 0.5 (ease-cubic-in-out 0.5))
- (test-equal "cubic-out mid" 0.875 (ease-cubic-out 0.5))
+ (test "expo-in at 0" 0.0 (ease-expo-in 0))
+ (test "expo-out at 1" 1.0 (ease-expo-out 1))
+ (test "expo-in-out mid" 0.5 (ease-expo-in-out 0.5))
+ (test "cubic-in-out mid" 0.5 (ease-cubic-in-out 0.5))
+ (test "cubic-out mid" 0.875 (ease-cubic-out 0.5))
(test-assert "cubic-in-out stays in [0,1]"
(let loop ((i 0) (ok #t))
(if (> i 100) ok
@@ -32,11 +32,11 @@
(loop (+ i 1) (and ok (>= v 0) (<= v 1))))))))
(test-group "ease-named"
- (test-equal "quad-in-out proc" ease-quad-in-out (ease-named 'quad-in-out)))
+ (test "quad-in-out proc" ease-quad-in-out (ease-named 'quad-in-out)))
(test-group "ease-resolve"
- (test-equal "symbol" ease-cubic-out (ease-resolve 'cubic-out))
- (test-equal "procedure passthrough" ease-linear (ease-resolve ease-linear)))
+ (test "symbol" ease-cubic-out (ease-resolve 'cubic-out))
+ (test "procedure passthrough" ease-linear (ease-resolve ease-linear)))
(test-group "make-tween / tween-step"
(test-group "linear completes to target"
@@ -44,18 +44,18 @@
(tw (make-tween ent props: '((#:x . 100)) duration: 100 delay: 0 ease: 'linear)))
(receive (tw2 e2) (tween-step tw ent 100)
(test-assert "finished" (tween-finished? tw2))
- (test-equal "x at end" 100.0 (entity-ref e2 #:x))
- (test-equal "y preserved" 10 (entity-ref e2 #:y)))))
+ (test "x at end" 100.0 (entity-ref e2 #:x))
+ (test "y preserved" 10 (entity-ref e2 #:y)))))
(test-group "delay holds props"
(let* ((ent (entity #:type 'a #:x 0))
(tw (make-tween ent props: '((#:x . 50)) duration: 100 delay: 40 ease: 'linear)))
(receive (tw2 e2) (tween-step tw ent 30)
(test-assert "not finished" (not (tween-finished? tw2)))
- (test-equal "x unchanged during delay" 0 (entity-ref e2 #:x))
+ (test "x unchanged during delay" 0 (entity-ref e2 #:x))
(receive (tw3 e3) (tween-step tw2 e2 9)
(test-assert "still in delay at 39ms" (not (tween-finished? tw3)))
- (test-equal "x still 0" 0 (entity-ref e3 #:x))
+ (test "x still 0" 0 (entity-ref e3 #:x))
(receive (_tw4 e4) (tween-step tw3 e3 50)
(test-assert "past delay, moved" (> (entity-ref e4 #:x) 0)))))))
@@ -63,7 +63,7 @@
(let* ((ent (entity #:type 'a #:x 0))
(tw (make-tween ent props: '((#:x . 100)) duration: 100 delay: 0 ease: 'linear)))
(receive (_ e2) (tween-step tw ent 50)
- (test-equal "halfway x" 50.0 (entity-ref e2 #:x)))))
+ (test "halfway x" 50.0 (entity-ref e2 #:x)))))
(test-group "on-complete runs once"
(let ((calls 0))
@@ -71,10 +71,10 @@
(tw (make-tween ent props: '((#:x . 10)) duration: 10 delay: 0 ease: 'linear
on-complete: (lambda (_) (set! calls (+ calls 1))))))
(receive (tw2 e2) (tween-step tw ent 10)
- (test-equal "one call" 1 calls)
+ (test "one call" 1 (begin calls))
(receive (tw3 e3) (tween-step tw2 e2 5)
- (test-equal "still one call" 1 calls)
- (test-equal "entity stable" e3 e2))))))
+ (test "still one call" 1 (begin calls))
+ (test "entity stable" e3 (begin e2)))))))
(test-group "idempotent after finish"
(let* ((ent (entity #:type 'a #:x 0))
@@ -82,7 +82,7 @@
(receive (tw2 e2) (tween-step tw ent 10)
(receive (tw3 e3) (tween-step tw2 e2 999)
(test-assert (tween-finished? tw3))
- (test-equal "x stays" 20.0 (entity-ref e3 #:x)))))))
+ (test "x stays" 20.0 (entity-ref e3 #:x)))))))
(test-group "repeat"
(test-group "repeat: 1 plays twice"
@@ -91,10 +91,10 @@
ease: 'linear repeat: 1)))
(receive (tw2 e2) (tween-step tw ent 100)
(test-assert "not finished after first play" (not (tween-finished? tw2)))
- (test-equal "x at target" 100.0 (entity-ref e2 #:x))
+ (test "x at target" 100.0 (entity-ref e2 #:x))
(receive (tw3 e3) (tween-step tw2 e2 100)
(test-assert "finished after second play" (tween-finished? tw3))
- (test-equal "x at target again" 100.0 (entity-ref e3 #:x))))))
+ (test "x at target again" 100.0 (entity-ref e3 #:x))))))
(test-group "repeat: -1 never finishes"
(let* ((ent (entity #:type 'a #:x 0))
@@ -119,9 +119,9 @@
ease: 'linear repeat: 1
on-complete: (lambda (_) (set! calls (+ calls 1))))))
(receive (tw2 e2) (tween-step tw ent 10)
- (test-equal "no call after first play" 0 calls)
+ (test "no call after first play" 0 (begin calls))
(receive (tw3 e3) (tween-step tw2 e2 10)
- (test-equal "one call after last repeat" 1 calls))))))
+ (test "one call after last repeat" 1 (begin calls)))))))
(test-group "on-complete does not fire with repeat: -1"
(let ((calls 0))
@@ -130,7 +130,7 @@
ease: 'linear repeat: -1
on-complete: (lambda (_) (set! calls (+ calls 1))))))
(let loop ((tw tw) (ent ent) (i 0))
- (if (>= i 5) (test-equal "never called" 0 calls)
+ (if (>= i 5) (test "never called" 0 (begin calls))
(receive (tw2 e2) (tween-step tw ent 10)
(loop tw2 e2 (+ i 1)))))))))
@@ -140,12 +140,12 @@
(tw (make-tween ent props: '((#:x . 100)) duration: 100
ease: 'linear repeat: 1 yoyo?: #t)))
(receive (tw2 e2) (tween-step tw ent 100)
- (test-equal "x at target after forward" 100.0 (entity-ref e2 #:x))
+ (test "x at target after forward" 100.0 (entity-ref e2 #:x))
(receive (tw3 e3) (tween-step tw2 e2 50)
- (test-equal "x halfway back" 50.0 (entity-ref e3 #:x))
+ (test "x halfway back" 50.0 (entity-ref e3 #:x))
(receive (tw4 e4) (tween-step tw3 e3 50)
(test-assert "finished after reverse" (tween-finished? tw4))
- (test-equal "x back to start" 0.0 (entity-ref e4 #:x)))))))
+ (test "x back to start" 0.0 (entity-ref e4 #:x)))))))
(test-group "yoyo: #t with repeat: -1 ping-pongs forever"
(let* ((ent (entity #:type 'a #:x 0))
@@ -153,13 +153,13 @@
ease: 'linear repeat: -1 yoyo?: #t)))
;; Forward
(receive (tw2 e2) (tween-step tw ent 100)
- (test-equal "at target" 100.0 (entity-ref e2 #:x))
+ (test "at target" 100.0 (entity-ref e2 #:x))
;; Reverse
(receive (tw3 e3) (tween-step tw2 e2 100)
- (test-equal "back to start" 0.0 (entity-ref e3 #:x))
+ (test "back to start" 0.0 (entity-ref e3 #:x))
;; Forward again
(receive (tw4 e4) (tween-step tw3 e3 100)
- (test-equal "at target again" 100.0 (entity-ref e4 #:x))
+ (test "at target again" 100.0 (entity-ref e4 #:x))
(test-assert "still active" (tween-active? tw4)))))))
(test-group "yoyo: #f with repeat: 1 replays same direction"
@@ -167,7 +167,7 @@
(tw (make-tween ent props: '((#:x . 100)) duration: 100
ease: 'linear repeat: 1 yoyo?: #f)))
(receive (tw2 e2) (tween-step tw ent 100)
- (test-equal "x at target" 100.0 (entity-ref e2 #:x))
+ (test "x at target" 100.0 (entity-ref e2 #:x))
;; Second play starts from same starts (0→100), but entity is at 100
;; The tween replays 0→100 using original start values
(receive (tw3 e3) (tween-step tw2 e2 50)
@@ -179,7 +179,7 @@
ease: 'linear repeat: 0 yoyo?: #t)))
(receive (tw2 e2) (tween-step tw ent 100)
(test-assert "finishes normally" (tween-finished? tw2))
- (test-equal "x at target" 100.0 (entity-ref e2 #:x))))))
+ (test "x at target" 100.0 (entity-ref e2 #:x))))))
(test-group "step-tweens pipeline"
(test-group "advances #:tween on entity"
@@ -187,7 +187,7 @@
#:tween (make-tween (entity #:x 0) props: '((#:x . 100))
duration: 100 ease: 'linear)))
(e2 (step-tweens #f ent 50)))
- (test-equal "x moved to midpoint" 50.0 (entity-ref e2 #:x))
+ (test "x moved to midpoint" 50.0 (entity-ref e2 #:x))
(test-assert "tween still attached" (entity-ref e2 #:tween #f))))
(test-group "removes #:tween when finished"
@@ -195,20 +195,20 @@
#:tween (make-tween (entity #:x 0) props: '((#:x . 100))
duration: 100 ease: 'linear)))
(e2 (step-tweens #f ent 100)))
- (test-equal "x at target" 100.0 (entity-ref e2 #:x))
- (test-equal "tween removed" #f (entity-ref e2 #:tween #f))))
+ (test "x at target" 100.0 (entity-ref e2 #:x))
+ (test "tween removed" #f (entity-ref e2 #:tween #f))))
(test-group "no-op without #:tween"
(let* ((ent (entity #:type 'a #:x 42))
(e2 (step-tweens #f ent 100)))
- (test-equal "x unchanged" 42 (entity-ref e2 #:x))))
+ (test "x unchanged" 42 (entity-ref e2 #:x))))
(test-group "keeps repeating tween attached"
(let* ((ent (entity #:type 'a #:x 0
#:tween (make-tween (entity #:x 0) props: '((#:x . 100))
duration: 100 ease: 'linear repeat: -1 yoyo?: #t)))
(e2 (step-tweens #f ent 100)))
- (test-equal "x at target" 100.0 (entity-ref e2 #:x))
+ (test "x at target" 100.0 (entity-ref e2 #:x))
(test-assert "tween still attached (repeating)" (entity-ref e2 #:tween #f))))
(test-group "respects #:skip-pipelines"
@@ -217,7 +217,8 @@
#:tween (make-tween (entity #:x 0) props: '((#:x . 100))
duration: 100 ease: 'linear)))
(e2 (step-tweens #f ent 100)))
- (test-equal "x unchanged (skipped)" 0 (entity-ref e2 #:x))
+ (test "x unchanged (skipped)" 0 (entity-ref e2 #:x))
(test-assert "tween still there" (entity-ref e2 #:tween #f)))))
(test-end "tween")
+(test-exit)
diff --git a/tests/world-test.scm b/tests/world-test.scm
index a66103e..8cbe4f2 100644
--- a/tests/world-test.scm
+++ b/tests/world-test.scm
@@ -3,7 +3,7 @@
(chicken base)
(chicken keyword)
defstruct
- srfi-64
+ test
(only srfi-1 every member make-list))
;; Create a mock tilemap module to avoid SDL dependency
@@ -65,10 +65,10 @@
tileset: #f
layers: (list layer1)
objects: '())))
- (test-equal "top-left corner" 1 (tilemap-tile-at tm 0 0))
- (test-equal "top-right corner" 3 (tilemap-tile-at tm 2 0))
- (test-equal "bottom-left corner" 7 (tilemap-tile-at tm 0 2))
- (test-equal "center" 5 (tilemap-tile-at tm 1 1))))
+ (test "top-left corner" 1 (tilemap-tile-at tm 0 0))
+ (test "top-right corner" 3 (tilemap-tile-at tm 2 0))
+ (test "bottom-left corner" 7 (tilemap-tile-at tm 0 2))
+ (test "center" 5 (tilemap-tile-at tm 1 1))))
(test-group "out-of-bounds returns 0"
(let* ((layer1 (make-layer name: "test" width: 3 height: 3
@@ -79,10 +79,10 @@
tileset: #f
layers: (list layer1)
objects: '())))
- (test-equal "negative col" 0 (tilemap-tile-at tm -1 0))
- (test-equal "col beyond width" 0 (tilemap-tile-at tm 3 0))
- (test-equal "negative row" 0 (tilemap-tile-at tm 0 -1))
- (test-equal "row beyond height" 0 (tilemap-tile-at tm 0 3))))
+ (test "negative col" 0 (tilemap-tile-at tm -1 0))
+ (test "col beyond width" 0 (tilemap-tile-at tm 3 0))
+ (test "negative row" 0 (tilemap-tile-at tm 0 -1))
+ (test "row beyond height" 0 (tilemap-tile-at tm 0 3))))
(test-group "zero tiles are skipped to next layer"
(let* ((layer1 (make-layer name: "test1" width: 3 height: 3
@@ -95,23 +95,23 @@
tileset: #f
layers: (list layer1 layer2)
objects: '())))
- (test-equal "skips zero in layer1, finds in layer2"
+ (test "skips zero in layer1, finds in layer2"
5 (tilemap-tile-at tm 1 1)))))
;; Test: scene record creation
(test-group "scene-structure"
(let ((scene (make-scene entities: '() tilemap: #f camera-target: #f)))
(test-assert "scene is a record" (scene? scene))
- (test-equal "entities list is empty" '() (scene-entities scene))
- (test-equal "tilemap is #f" #f (scene-tilemap scene))
- (test-equal "background defaults to #f" #f (scene-background scene))
- (test-equal "tileset defaults to #f" #f (scene-tileset scene)))
+ (test "entities list is empty" '() (scene-entities scene))
+ (test "tilemap is #f" #f (scene-tilemap scene))
+ (test "background defaults to #f" #f (scene-background scene))
+ (test "tileset defaults to #f" #f (scene-tileset scene)))
(let ((s (make-scene entities: '() tilemap: #f camera-target: #f
background: '(40 44 52))))
- (test-equal "background RGB stored" '(40 44 52) (scene-background s)))
+ (test "background RGB stored" '(40 44 52) (scene-background s)))
(let ((s (make-scene entities: '() tilemap: #f camera-target: #f
background: '(1 2 3 200))))
- (test-equal "background RGBA stored" '(1 2 3 200) (scene-background s))))
+ (test "background RGBA stored" '(1 2 3 200) (scene-background s))))
;; Test: scene with entities and tilemap
(test-group "scene-with-data"
@@ -121,13 +121,13 @@
(scene (make-scene entities: (list player enemy)
tilemap: tilemap
camera-target: #f)))
- (test-equal "scene has 2 entities"
+ (test "scene has 2 entities"
2
(length (scene-entities scene)))
- (test-equal "first entity is player"
+ (test "first entity is player"
'player
(entity-type (car (scene-entities scene))))
- (test-equal "tilemap is set correctly"
+ (test "tilemap is set correctly"
"mock-tilemap"
(scene-tilemap scene))))
@@ -137,12 +137,12 @@
(scene (make-scene entities: (list player) tilemap: #f camera-target: #f))
(enemy (entity #:type 'enemy #:x 200 #:y 200)))
- (test-equal "initial entity count" 1 (length (scene-entities scene)))
+ (test "initial entity count" 1 (length (scene-entities scene)))
(let ((scene2 (scene-add-entity scene enemy)))
- (test-equal "original scene unchanged" 1 (length (scene-entities scene)))
- (test-equal "entity count after add" 2 (length (scene-entities scene2)))
- (test-equal "second entity is enemy"
+ (test "original scene unchanged" 1 (length (scene-entities scene)))
+ (test "entity count after add" 2 (length (scene-entities scene2)))
+ (test "second entity is enemy"
'enemy
(entity-type (cadr (scene-entities scene2)))))))
@@ -155,7 +155,7 @@
(scene (scene-add-entity scene e2))
(scene (scene-add-entity scene e3)))
- (test-equal "entities are in order"
+ (test "entities are in order"
'(a b c)
(map entity-type (scene-entities scene)))))
@@ -171,16 +171,16 @@
(entity #:type type #:x (+ x 10) #:y y))))
(scene2 (scene-map-entities scene move-right)))
- (test-equal "original scene unchanged"
+ (test "original scene unchanged"
100
(entity-ref (car (scene-entities scene)) #:x))
- (test-equal "first entity moved right"
+ (test "first entity moved right"
110
(entity-ref (car (scene-entities scene2)) #:x))
- (test-equal "second entity moved right"
+ (test "second entity moved right"
210
(entity-ref (cadr (scene-entities scene2)) #:x))
- (test-equal "y values unchanged"
+ (test "y values unchanged"
100
(entity-ref (car (scene-entities scene2)) #:y))))
@@ -191,8 +191,8 @@
(scene (make-scene entities: (list e1 e2) tilemap: #f camera-target: #f))
(scene2 (scene-map-entities scene (lambda (scene e) e))))
- (test-equal "entity count unchanged" 2 (length (scene-entities scene2)))
- (test-equal "first entity unchanged"
+ (test "entity count unchanged" 2 (length (scene-entities scene2)))
+ (test "first entity unchanged"
100
(entity-ref (car (scene-entities scene2)) #:x))))
@@ -202,7 +202,7 @@
(player (make-entity 10 20 16 16))
(scene (scene-add-entity scene player)))
- (test-equal "entity added" 1 (length (scene-entities scene)))
+ (test "entity added" 1 (length (scene-entities scene)))
(let ((scene (scene-map-entities scene
(lambda (scene e)
@@ -211,15 +211,15 @@
(type (entity-type e)))
(entity #:type type #:x (* x 2) #:y (* y 2)
#:width 16 #:height 16))))))
- (test-equal "entity x doubled" 20 (entity-ref (car (scene-entities scene)) #:x))
- (test-equal "entity y doubled" 40 (entity-ref (car (scene-entities scene)) #:y)))))
+ (test "entity x doubled" 20 (entity-ref (car (scene-entities scene)) #:x))
+ (test "entity y doubled" 40 (entity-ref (car (scene-entities scene)) #:y)))))
;; Test: update-scene for tilemap
(test-group "scene-tilemap-update"
(let* ((scene (make-scene entities: '() tilemap: #f camera-target: #f))
(scene2 (update-scene scene tilemap: "new-tilemap")))
- (test-equal "tilemap initially #f" #f (scene-tilemap scene))
- (test-equal "tilemap updated in new scene" "new-tilemap" (scene-tilemap scene2))))
+ (test "tilemap initially #f" #f (scene-tilemap scene))
+ (test "tilemap updated in new scene" "new-tilemap" (scene-tilemap scene2))))
;; Create a test tilemap for the filter test
(define test-tilemap
@@ -241,9 +241,9 @@
camera-target: #f))
(scene2 (scene-filter-entities scene
(lambda (e) (eq? (entity-ref e #:type #f) 'player)))))
- (test-equal "original scene unchanged" 2 (length (scene-entities scene)))
- (test-equal "keeps matching entities" 1 (length (scene-entities scene2)))
- (test-equal "kept entity is player"
+ (test "original scene unchanged" 2 (length (scene-entities scene)))
+ (test "keeps matching entities" 1 (length (scene-entities scene2)))
+ (test "kept entity is player"
'player
(entity-ref (car (scene-entities scene2)) #:type #f))))
@@ -251,24 +251,24 @@
(let* ((cam (make-camera x: 0 y: 0))
(ent (entity #:type 'player #:x 400 #:y 300 #:width 16 #:height 16))
(cam2 (camera-follow cam ent 600 400)))
- (test-equal "original camera unchanged" 0 (camera-x cam))
- (test-equal "centers camera x on entity" 100 (camera-x cam2))
- (test-equal "centers camera y on entity" 100 (camera-y cam2)))
+ (test "original camera unchanged" 0 (camera-x cam))
+ (test "centers camera x on entity" 100 (camera-x cam2))
+ (test "centers camera y on entity" 100 (camera-y cam2)))
(let* ((cam (make-camera x: 0 y: 0))
(ent (entity #:type 'player #:x 50 #:y 30 #:width 16 #:height 16))
(cam2 (camera-follow cam ent 600 400)))
- (test-equal "clamps camera x to 0 when entity near origin" 0 (camera-x cam2))
- (test-equal "clamps camera y to 0 when entity near origin" 0 (camera-y cam2))))
+ (test "clamps camera x to 0 when entity near origin" 0 (camera-x cam2))
+ (test "clamps camera y to 0 when entity near origin" 0 (camera-y cam2))))
(test-group "scene-find-tagged"
(let* ((p (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16 #:tags '(player)))
(e (entity #:type 'enemy #:x 0 #:y 0 #:width 16 #:height 16 #:tags '(enemy npc)))
(s (make-scene entities: (list p e) tilemap: #f
camera: (make-camera x: 0 y: 0) tileset-texture: #f camera-target: #f)))
- (test-equal "finds entity with matching tag" p (scene-find-tagged s 'player))
- (test-equal "finds enemy by 'enemy tag" e (scene-find-tagged s 'enemy))
- (test-equal "finds entity with second tag in list" e (scene-find-tagged s 'npc))
- (test-equal "returns #f when tag not found" #f (scene-find-tagged s 'boss))))
+ (test "finds entity with matching tag" p (scene-find-tagged s 'player))
+ (test "finds enemy by 'enemy tag" e (scene-find-tagged s 'enemy))
+ (test "finds entity with second tag in list" e (scene-find-tagged s 'npc))
+ (test "returns #f when tag not found" #f (scene-find-tagged s 'boss))))
(test-group "scene-find-all-tagged"
(let* ((p1 (entity #:type 'player #:x 0 #:y 0 #:width 16 #:height 16 #:tags '(player friendly)))
@@ -276,8 +276,8 @@
(e (entity #:type 'enemy #:x 0 #:y 0 #:width 16 #:height 16 #:tags '(enemy)))
(s (make-scene entities: (list p1 p2 e) tilemap: #f
camera: (make-camera x: 0 y: 0) tileset-texture: #f camera-target: #f)))
- (test-equal "returns all friendly entities" 2 (length (scene-find-all-tagged s 'friendly)))
- (test-equal "returns empty list when none match" '() (scene-find-all-tagged s 'boss))))
+ (test "returns all friendly entities" 2 (length (scene-find-all-tagged s 'friendly)))
+ (test "returns empty list when none match" '() (scene-find-all-tagged s 'boss))))
(test-group "sync-groups"
(let* ((gid 'g1)
@@ -289,20 +289,21 @@
#:x 0 #:y 0 #:width 8 #:height 8))
(entities (list origin m1 m2))
(result (sync-groups entities)))
- (test-equal "original list unchanged" 0 (entity-ref (list-ref entities 1) #:x))
- (test-equal "member 1 follows origin" 105 (entity-ref (list-ref result 1) #:x))
- (test-equal "member 1 y" 200 (entity-ref (list-ref result 1) #:y))
- (test-equal "member 2 x" 100 (entity-ref (list-ref result 2) #:x))
- (test-equal "member 2 y" 207 (entity-ref (list-ref result 2) #:y))))
+ (test "original list unchanged" 0 (entity-ref (list-ref entities 1) #:x))
+ (test "member 1 follows origin" 105 (entity-ref (list-ref result 1) #:x))
+ (test "member 1 y" 200 (entity-ref (list-ref result 1) #:y))
+ (test "member 2 x" 100 (entity-ref (list-ref result 2) #:x))
+ (test "member 2 y" 207 (entity-ref (list-ref result 2) #:y))))
(test-group "scene-transform-entities"
(let* ((e1 (entity #:type 'a #:x 1))
(e2 (entity #:type 'b #:x 2))
(scene (make-scene entities: (list e1 e2) tilemap: #f camera-target: #f))
(scene2 (scene-transform-entities scene reverse)))
- (test-equal "transforms entity list" 'b
+ (test "transforms entity list" 'b
(entity-type (car (scene-entities scene2))))
- (test-equal "original scene unchanged" 'a
+ (test "original scene unchanged" 'a
(entity-type (car (scene-entities scene))))))
(test-end "world-module")
+(test-exit)