Compare commits
4 Commits
1ee19b4b7f
...
aaeb8d3650
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aaeb8d3650 | ||
|
|
e082a39596 | ||
|
|
e399f6c6f8 | ||
|
|
8453b1fc8f |
111
init.lua
111
init.lua
@@ -246,6 +246,117 @@ function M.run_tests(ctx)
|
||||
local list = maps.list()
|
||||
engine.test.equals(#list, 2, "maps.list returns 2 registered maps")
|
||||
|
||||
-- ---------- v0.4.0: Write APIs — set_cell_gid ----------
|
||||
-- Build a fresh v2 map for write tests (separate from earlier load-based tests).
|
||||
-- maps.create only handles the v1 path (requires tilemap_table); use maps.load
|
||||
-- with a fixture file for the v2 path instead.
|
||||
local write_id = maps.load("maps/write_test.map.json")
|
||||
maps.set_current(write_id)
|
||||
|
||||
-- Happy path
|
||||
local gid_painted = maps.encode_gid(0, 1, 0)
|
||||
maps.set_cell_gid("surface", 1, 2, gid_painted)
|
||||
engine.test.equals(maps.cell_gid("surface", 1, 2), gid_painted,
|
||||
"set_cell_gid writes the cell that cell_gid reads back")
|
||||
|
||||
-- Bounds-error: x >= w
|
||||
local ok1, err1 = pcall(function() maps.set_cell_gid("surface", 4, 0, gid_painted) end)
|
||||
engine.test.assert(not ok1, "set_cell_gid rejects x out of bounds")
|
||||
engine.test.assert(err1 and err1:find("bounds"), "set_cell_gid bounds-error mentions 'bounds'")
|
||||
|
||||
-- Bounds-error: negative coord
|
||||
local ok2 = pcall(function() maps.set_cell_gid("surface", -1, 0, gid_painted) end)
|
||||
engine.test.assert(not ok2, "set_cell_gid rejects negative x")
|
||||
|
||||
-- Unknown-layer error
|
||||
local ok3, err3 = pcall(function() maps.set_cell_gid("bogus_layer", 0, 0, gid_painted) end)
|
||||
engine.test.assert(not ok3, "set_cell_gid rejects unknown layer")
|
||||
engine.test.assert(err3 and err3:find("layer"), "unknown-layer error mentions 'layer'")
|
||||
|
||||
-- On-demand layer allocation
|
||||
engine.test.assert(maps.cell_gid("wall", 0, 0) == 0,
|
||||
"wall layer empty before any write")
|
||||
maps.set_cell_gid("wall", 2, 2, gid_painted)
|
||||
engine.test.equals(maps.cell_gid("wall", 2, 2), gid_painted,
|
||||
"set_cell_gid auto-allocates the wall layer")
|
||||
engine.test.equals(maps.cell_gid("wall", 0, 0), 0,
|
||||
"auto-allocated layer initialised to all-zero except the written cell")
|
||||
|
||||
-- ---------- v0.4.0: set_roof ----------
|
||||
-- Roof should be nil before any write. No direct cell_roof reader exists yet
|
||||
-- (out of scope for v0.4.0). Verify behaviourally via JSON round-trip in Task 3.
|
||||
|
||||
-- Happy path: set roof cells, no assertion on read since no public reader
|
||||
maps.set_roof(1, 1, 1)
|
||||
maps.set_roof(1, 1, 0) -- toggle back
|
||||
maps.set_roof(2, 2, 1) -- leave this one set for Task 3's round-trip test
|
||||
|
||||
-- Value validation
|
||||
local ok_v, err_v = pcall(function() maps.set_roof(0, 0, 2) end)
|
||||
engine.test.assert(not ok_v, "set_roof rejects value=2")
|
||||
engine.test.assert(err_v and err_v:find("0.*1"), "set_roof error mentions 0 or 1")
|
||||
|
||||
-- Bounds rejection
|
||||
local ok_b = pcall(function() maps.set_roof(4, 0, 1) end)
|
||||
engine.test.assert(not ok_b, "set_roof rejects x out of bounds")
|
||||
|
||||
-- ---------- v0.4.0: save_to_disk ----------
|
||||
-- Map state from Task 1+2: surface(1,2) = gid_painted, wall(2,2) = gid_painted,
|
||||
-- roof(2,2) = 1. Save and re-load to verify round-trip.
|
||||
|
||||
-- Re-establish deterministic state (defensive — earlier asserts may have toggled).
|
||||
maps.set_cell_gid("surface", 1, 2, gid_painted)
|
||||
maps.set_cell_gid("wall", 2, 2, gid_painted)
|
||||
maps.set_roof(2, 2, 1)
|
||||
|
||||
-- Pick a temp path. Use TEMP env var for Windows compatibility; fall back to
|
||||
-- os.tmpname() on POSIX (where it returns a writable path).
|
||||
local tmp_dir = os.getenv("TEMP") or os.getenv("TMP") or "/tmp"
|
||||
-- Unique suffix via os.clock() + os.time() to avoid collisions.
|
||||
local tmp_suffix = string.format("sporel_maps_test_%d_%d", os.time(), math.floor(os.clock() * 1e6) % 1000000)
|
||||
local out_path = tmp_dir .. "/" .. tmp_suffix .. "_1.json"
|
||||
local out_path_2 = tmp_dir .. "/" .. tmp_suffix .. "_2.json"
|
||||
local rl_path = tmp_dir .. "/" .. tmp_suffix .. "_rl.json"
|
||||
maps.save_to_disk("write_test", out_path)
|
||||
|
||||
-- Re-read raw bytes for byte-determinism test
|
||||
local f1 = io.open(out_path, "r")
|
||||
engine.test.assert(f1 ~= nil, "save_to_disk wrote a readable file")
|
||||
local bytes_1 = f1:read("*a")
|
||||
f1:close()
|
||||
|
||||
-- Save a second time; bytes must match exactly
|
||||
maps.save_to_disk("write_test", out_path_2)
|
||||
local f2 = io.open(out_path_2, "r")
|
||||
local bytes_2 = f2:read("*a")
|
||||
f2:close()
|
||||
engine.test.equals(bytes_1, bytes_2,
|
||||
"save_to_disk is byte-deterministic across calls")
|
||||
|
||||
-- Verify JSON has expected keys
|
||||
engine.test.assert(bytes_1:find('"schema_version"') ~= nil, "saved file has schema_version key")
|
||||
engine.test.assert(bytes_1:find('"surface"') ~= nil, "saved file has surface key")
|
||||
engine.test.assert(bytes_1:find('"wall"') ~= nil, "saved file has wall key (auto-allocated)")
|
||||
engine.test.assert(bytes_1:find('"roof"') ~= nil, "saved file has roof key (set in Task 2)")
|
||||
|
||||
-- Re-load (with patched id to avoid registry collision).
|
||||
-- engine.asset.load_json only accepts relative (sandboxed) paths, so write
|
||||
-- the round-trip file into the maps-test lib's own maps/ directory where
|
||||
-- the asset resolver can find it by relative path.
|
||||
local lib_dir = engine.module.dir_of("lib-core.maps-test")
|
||||
local rewritten = bytes_1:gsub('"id"%s*:%s*"write_test"', '"id":"write_test_reloaded"')
|
||||
local abs_rl_path = lib_dir .. "/maps/write_test_reloaded.map.json"
|
||||
local rf = io.open(abs_rl_path, "w"); rf:write(rewritten); rf:close()
|
||||
maps.load("maps/write_test_reloaded.map.json")
|
||||
|
||||
engine.test.equals(maps.cell_gid("surface", 1, 2, "write_test_reloaded"), gid_painted,
|
||||
"save round-trip preserves surface cell")
|
||||
engine.test.equals(maps.cell_gid("wall", 2, 2, "write_test_reloaded"), gid_painted,
|
||||
"save round-trip preserves wall cell")
|
||||
|
||||
-- Cleanup
|
||||
os.remove(out_path); os.remove(out_path_2); os.remove(abs_rl_path)
|
||||
|
||||
engine.exit(engine.test.failures())
|
||||
end
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"id": "lib-core.maps-test",
|
||||
"role": "test",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"api_min": "0.1",
|
||||
"deps": [
|
||||
{"id": "lib-core.maps", "version": "0.3.0"}
|
||||
{"id": "lib-core.maps", "version": "0.4.0"}
|
||||
]
|
||||
}
|
||||
|
||||
16
maps/write_test.map.json
Normal file
16
maps/write_test.map.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schema_version": 2,
|
||||
"id": "write_test",
|
||||
"size": { "w": 4, "h": 4 },
|
||||
"atlases": ["demo_tilemap"],
|
||||
"layers": {
|
||||
"surface": {
|
||||
"tiles": [
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user