test: de-duplication + malformed-locale assertions
§19 verifies sources={c, c} is de-duplicated (have=1, not 2).
§20 verifies {sink=c} without sources raises a loud-error
attributing crafting + sources.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
73
init.lua
73
init.lua
@@ -1,5 +1,7 @@
|
||||
-- lib-core.crafting-test — Phase C.1
|
||||
-- 12 assertions: 5 registry (define_recipe + list + get) + 7 discovery/match/craft.
|
||||
-- lib-core.crafting-test — Phase C.1 + D.0
|
||||
-- 20 assertions: 12 base (registry + discovery/match/craft), 6 locale-API
|
||||
-- (Form-2 happy + greedy-drain + aggregate + Loud-Errors), 2 silent-fail
|
||||
-- regressions (duplicate-sources de-dup + malformed-locale loud-error).
|
||||
-- Pattern follows P.2.4 Test-Module-Pattern; TAP output via engine.test.*
|
||||
|
||||
local composition = require("lib-core.composition")
|
||||
@@ -531,6 +533,73 @@ function M.run_tests(ctx)
|
||||
and string.find(err18, "sink") ~= nil
|
||||
and string.find(err18, "nil") ~= nil,
|
||||
"18. Loud-Error: locale.sink=nil → error mentions 'crafting', 'sink', 'nil'")
|
||||
|
||||
-- ================================================================
|
||||
-- §19: Duplicate sources are de-duplicated.
|
||||
-- Single container with 1 rock; pass {c, c} as sources.
|
||||
-- count_by_template must NOT double-count → can_craft for a
|
||||
-- recipe needing 2 rocks reports have=1 (not 2).
|
||||
-- ================================================================
|
||||
local c_19 = setup_container{
|
||||
{ template = "craft_test.rock", count = 1 },
|
||||
}
|
||||
composition.define_template{
|
||||
id = "craft_test.rock_pile_19",
|
||||
properties = {
|
||||
stack_mode = "individual",
|
||||
sprite_path = "sprites/pile.png",
|
||||
position = {x = 0, y = 0},
|
||||
},
|
||||
tags = {"renderable", "item"},
|
||||
}
|
||||
crafting.define_recipe{
|
||||
id = "r2rocks_19",
|
||||
inputs = { { template = "craft_test.rock", count = 2 } },
|
||||
output = { template = "craft_test.rock_pile_19", count = 1 },
|
||||
}
|
||||
local cc19 = crafting.can_craft("r2rocks_19",
|
||||
{ sources = {c_19, c_19}, sink = c_19 }, {})
|
||||
local missing_match_19 = false
|
||||
if cc19.missing then
|
||||
for _, m in ipairs(cc19.missing) do
|
||||
if m.template == "craft_test.rock"
|
||||
and m.needed == 2 and m.have == 1 then
|
||||
missing_match_19 = true; break
|
||||
end
|
||||
end
|
||||
end
|
||||
T.assert(cc19.ok == false and cc19.error == "missing_inputs"
|
||||
and missing_match_19,
|
||||
"19. Duplicate sources de-duplicated: sources={c,c} with 1 rock reports have=1 (not 2)")
|
||||
|
||||
-- ================================================================
|
||||
-- §20: Loud-Error — Form-2 table without sources field.
|
||||
-- Caller typo passes {sink=c} without sources. resolve_locale
|
||||
-- must loud-error attributing crafting + sources, not silently
|
||||
-- fall through to the Form-1 bw-compat shim (which would then
|
||||
-- crash deep inside inventory-list).
|
||||
-- ================================================================
|
||||
local c_20 = setup_container{}
|
||||
composition.define_template{
|
||||
id = "craft_test.x_20",
|
||||
properties = {
|
||||
stack_mode = "individual",
|
||||
sprite_path = "sprites/x.png",
|
||||
position = {x = 0, y = 0},
|
||||
},
|
||||
tags = {"renderable", "item"},
|
||||
}
|
||||
crafting.define_recipe{
|
||||
id = "rp_20",
|
||||
inputs = { { template = "craft_test.rock", count = 1 } },
|
||||
output = { template = "craft_test.x_20", count = 1 },
|
||||
}
|
||||
local malformed_20 = { sink = c_20 }
|
||||
local ok20, err20 = pcall(crafting.craft, "rp_20", malformed_20, {})
|
||||
T.assert(not ok20 and type(err20) == "string"
|
||||
and string.find(err20, "crafting") ~= nil
|
||||
and string.find(err20, "sources") ~= nil,
|
||||
"20. Loud-Error: locale table without 'sources' field → error mentions 'crafting' and 'sources'")
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Reference in New Issue
Block a user