Ruined
This commit is contained in:
+89
-16
@@ -33,9 +33,9 @@ local function reset()
|
||||
auth=auth+1; assert(q==p and player:is_player() and action=="use"); return allowed
|
||||
end}
|
||||
end
|
||||
local inv={room_for_item=function(_,list,item) assert(list=="main" and item=="hearth:berries 2"); return room end,
|
||||
local inv={room_for_item=function(_,list,item) assert(list=="main" and (item=="hearth:berries 2" or item=="hearth:berries 3")); return room end,
|
||||
add_item=function(_,list,item)
|
||||
assert(list=="main" and item=="hearth:berries 2"); added=added+2-leftover
|
||||
assert(list=="main" and (item=="hearth:berries 2" or item=="hearth:berries 3")); added=added+tonumber(item:match("(%d+)$"))-leftover
|
||||
return {get_count=function() return leftover end}
|
||||
end}
|
||||
local player={is_player=function() return true end,get_inventory=function() return inv end}
|
||||
@@ -56,12 +56,12 @@ local function register()
|
||||
B.register_nodes(function(id,def) assert(not defs["hearth:"..id],id); defs["hearth:"..id]=def end)
|
||||
end
|
||||
local function bush(id) world[key(p)]={name="hearth:"..(id or "bilberry")} end
|
||||
test("exactly eighty disjoint real taxa in eight ordered groups of ten",function()
|
||||
assert(#B.groups==8 and #B.catalogue==80 and #B.list()==80)
|
||||
test("exactly one hundred disjoint real taxa in eight uneven groups",function()
|
||||
assert(#B.groups==8 and #B.catalogue==100 and #B.list()==100)
|
||||
assert(table.concat(B.groups,",")=="trees,shrubs,grasses,herbs,ferns_mosses,fungi,aquatic,lichens")
|
||||
local ids,latin={},{},{}
|
||||
for _,g in ipairs(B.groups) do
|
||||
assert(#B.list(g)==10,g)
|
||||
assert(#B.list(g)==({trees=13,shrubs=14,grasses=10,herbs=22,ferns_mosses=11,fungi=10,aquatic=10,lichens=10})[g],g)
|
||||
for _,r in ipairs(B.list(g)) do
|
||||
assert(not ids[r.id] and not latin[r.latin]); ids[r.id]=true; latin[r.latin]=true
|
||||
assert(r.common~="" and r.latin:match("^[A-Z][a-z]+ [a-z%-]+$"),r.latin)
|
||||
@@ -69,6 +69,21 @@ test("exactly eighty disjoint real taxa in eight ordered groups of ten",function
|
||||
end
|
||||
end
|
||||
end)
|
||||
test("twenty expansion identities match the lifecycle contract with nitrogen and flower seasons",function()
|
||||
local L=dofile(target:gsub("[^/\\]+$","lifecycle.lua"))
|
||||
local ids={"dandelion","daisy","red_clover","birdsfoot_trefoil","ribwort_plantain","selfheal","knapweed",
|
||||
"oxeye_daisy","field_scabious","teasel","cow_parsley","garlic_mustard","honeysuckle","ivy","gorse","broom",
|
||||
"crab_apple","wild_cherry","field_maple","holly_fern"}
|
||||
assert(#ids==20)
|
||||
for _,id in ipairs(ids) do
|
||||
local r=B.get(id); local p=L.plant(id)
|
||||
assert(r and p and r.latin==p.latin and r.group==p.group and not r.food,id)
|
||||
end
|
||||
for _,id in ipairs({"red_clover","birdsfoot_trefoil","gorse","broom"}) do assert(B.nitrogen(id,0)==1) end
|
||||
assert(B.pollinator("ivy","Autumn") and not B.pollinator("ivy","Spring"))
|
||||
assert(B.pollinator("gorse","Winter") and not B.pollinator("ribwort_plantain","Summer"))
|
||||
assert(B.seeding("garlic_mustard","Summer") and not B.seeding("garlic_mustard","Spring"))
|
||||
end)
|
||||
test("legacy IDs map exactly without counting generic bushes or patches",function()
|
||||
local expected={oak="Quercus robur",birch="Betula pendula",pine="Pinus sylvestris",willow="Salix alba",
|
||||
alder="Alnus glutinosa",clover="Trifolium repens",nettle="Urtica dioica",heather="Calluna vulgaris",
|
||||
@@ -94,7 +109,7 @@ test("catalogue snapshots and getters cannot alter internal policy",function()
|
||||
assert(B.get("oak").latin=="Quercus robur" and not B.has_tag("oak","pollinator"))
|
||||
assert(B.get("oak").niche.light[1]==4)
|
||||
end)
|
||||
test("all eighty species have a passing season niche vector",function()
|
||||
test("all one hundred species have a passing season niche vector",function()
|
||||
for _,r in ipairs(B.list()) do assert(B.suitable(r.id,habitat(r.id),next(r.seasons)),r.id) end
|
||||
end)
|
||||
test("each niche dimension rejects out-of-window values for all species",function()
|
||||
@@ -213,7 +228,7 @@ test("nitrogen is capped and fungi transfer only an existing positive budget",fu
|
||||
assert(B.resin("spruce") and B.resin("pine_log") and not B.resin("oak"))
|
||||
assert(writes==0)
|
||||
end)
|
||||
test("register exactly sixty-two missing understory nodes, never legacy or trees",function()
|
||||
test("register exactly seventy-nine missing understory nodes, never legacy or trees",function()
|
||||
register(); local count=0
|
||||
for name,def in pairs(defs) do
|
||||
count=count+1; local r=B.get(name)
|
||||
@@ -222,7 +237,7 @@ test("register exactly sixty-two missing understory nodes, never legacy or trees
|
||||
assert(def.description==r.common.." ("..r.latin..")")
|
||||
assert(not def.walkable and not def.buildable_to and def.groups.hearth_ecosystem==1)
|
||||
end
|
||||
assert(count==62); register(); local again=0; for _ in pairs(defs) do again=again+1 end; assert(again==count)
|
||||
assert(count==79); register(); local again=0; for _ in pairs(defs) do again=again+1 end; assert(again==count)
|
||||
end)
|
||||
test("existing registered definitions are preserved and construction stays late-bound",function()
|
||||
local marker={description="external owner"}; defs["hearth:bilberry"]=marker
|
||||
@@ -253,17 +268,19 @@ test("harvest checks permission before metadata or inventory and returns at most
|
||||
bush(); allowed=false; local ok,reason=B.harvest(p,player)
|
||||
assert(not ok and reason=="denied" and auth==1 and writes==0 and added==0)
|
||||
allowed=true; ok,reason=B.harvest(p,player)
|
||||
assert(ok and reason==2 and added==2 and tonumber(fields[key(p)].botany_ready_at)==time+86400)
|
||||
assert(ok and reason==2 and added==2 and tonumber(fields[key(p)].botany_ready_at)==time+365.2425*86400)
|
||||
end)
|
||||
test("cooldown has no catchup and survives a new module instance",function()
|
||||
bush(); assert(B.harvest(p,player)); assert(not B.harvest(p,player) and added==2)
|
||||
policies={} -- a fresh factory may reinstall the same seasonal policy
|
||||
B=factory(H,A); assert(not B.harvest(p,player)); time=time+86400*30
|
||||
assert(not B.harvest(p,player) and added==2)
|
||||
time=time+86400*400
|
||||
assert(B.harvest(p,player) and added==4); assert(not B.harvest(p,player) and added==4)
|
||||
end)
|
||||
test("full inventory does not consume stock or start cooldown",function()
|
||||
bush(); room=false; local ok,reason=B.harvest(p,player)
|
||||
assert(not ok and reason=="inventory" and writes==0 and added==0)
|
||||
assert(not ok and reason=="inventory" and fields[key(p)].botany_ready_at=="" and added==0)
|
||||
room=true; leftover=2; assert(not B.harvest(p,player) and fields[key(p)].botany_ready_at=="")
|
||||
leftover=1; ok,reason=B.harvest(p,player); assert(ok and reason==1 and added==1)
|
||||
assert(not B.harvest(p,player))
|
||||
@@ -296,11 +313,11 @@ test("rightclick returns item stack and reentrant inventory cannot duplicate",fu
|
||||
local stack={}; assert(defs["hearth:bilberry"].on_rightclick(p,{},player,stack)==stack)
|
||||
inv.add_item=original; assert(added==2)
|
||||
end)
|
||||
test("the actual position selector can return each of all eighty exact node IDs",function()
|
||||
test("the actual position selector can return each of all hundred exact node IDs",function()
|
||||
for index,r in ipairs(B.list()) do
|
||||
local h=habitat(r.id); h.include_trees=true
|
||||
local x=0
|
||||
while (x*17+7)%80~=index-1 do x=x+1; assert(x<80) end
|
||||
while (x*17+7)%100~=index-1 do x=x+1; assert(x<100) end
|
||||
local k,selected=B.choose({x=x,y=1,z=0},h,next(r.seasons))
|
||||
assert(k==r.node:sub(8) and selected.id==r.id,r.id)
|
||||
assert(B.suitable(k,h,next(r.seasons)))
|
||||
@@ -317,7 +334,7 @@ test("submerged candidates work as separate air-cell stands, never as liquid nod
|
||||
assert(not def.buildable_to and not def.walkable and def.drawtype=="plantlike")
|
||||
end
|
||||
end)
|
||||
test("all sixty-two new understory policies match actual activity and dormant art",function()
|
||||
test("all seventy-nine new understory policies match actual activity and dormant art",function()
|
||||
local count=0
|
||||
for _,r in ipairs(B.list()) do
|
||||
local policy=policies[r.id]
|
||||
@@ -335,7 +352,7 @@ test("all sixty-two new understory policies match actual activity and dormant ar
|
||||
end
|
||||
end
|
||||
end
|
||||
assert(count==62)
|
||||
assert(count==79)
|
||||
policies.holly.active.Winter=false; assert(B.active("holly","Winter"))
|
||||
assert(next(policies.juniper.definitions)==nil and next(policies.holly.definitions)==nil)
|
||||
end)
|
||||
@@ -354,7 +371,7 @@ test("harvest samples one validated epoch before climate and uses the same coold
|
||||
return {season="Summer"}
|
||||
end
|
||||
assert(B.harvest(p,player) and clock_reads==1 and climate_calls==1)
|
||||
assert(tonumber(fields[key(p)].botany_ready_at)==1782043200+86400)
|
||||
assert(tonumber(fields[key(p)].botany_ready_at)==1782043200+365.2425*86400)
|
||||
end)
|
||||
test("only exact owned seasonal aliases harvest in an active fruit season",function()
|
||||
bush("bilberry_winter"); season="Winter"
|
||||
@@ -375,6 +392,62 @@ test("southern berry seasons use the solar model at the validated epoch",functio
|
||||
bush(); time=1782043200
|
||||
local ok,reason=B.harvest(p,player); assert(not ok and reason=="season" and writes==0)
|
||||
time=1797854400; assert(B.harvest(p,player) and added==2)
|
||||
assert(tonumber(fields[key(p)].botany_ready_at)==time+86400)
|
||||
assert(tonumber(fields[key(p)].botany_ready_at)==time+365.2425*86400)
|
||||
end)
|
||||
test("shared annual fruit readiness rejects an animal debit and has no daily refill",function()
|
||||
bush(); local m=A.get_meta(p)
|
||||
m:set_string("botany_ready_at",tostring(time+365.2425*86400))
|
||||
assert(not B.harvest(p,player) and added==0)
|
||||
time=time+86400; assert(not B.harvest(p,player))
|
||||
time=time+(365.2425-1)*86400; assert(B.harvest(p,player) and added==2)
|
||||
end)
|
||||
test("one unexpired pollination credit adds only one berry and is spent once",function()
|
||||
bush(); local m=A.get_meta(p)
|
||||
m:set_string("succ_pollinated_until",tostring(time+86400))
|
||||
local ok,n=B.harvest(p,player); assert(ok and n==3 and added==3)
|
||||
assert(m:get_string("succ_pollinated_until")=="0")
|
||||
assert(not B.harvest(p,player) and added==3)
|
||||
time=time+365.2425*86400; ok,n=B.harvest(p,player)
|
||||
assert(ok and n==2 and added==5)
|
||||
end)
|
||||
test("expired pollination is not a bonus and invalid credits fail closed",function()
|
||||
bush(); local m=A.get_meta(p)
|
||||
for _,v in ipairs({"broken","-1",tostring(time+86401),"inf"}) do
|
||||
m:set_string("succ_pollinated_until",v)
|
||||
local before=writes; assert(not B.harvest(p,player) and added==0 and writes==before)
|
||||
end
|
||||
m:set_string("succ_pollinated_until",tostring(time))
|
||||
local ok,n=B.harvest(p,player); assert(ok and n==2 and added==2)
|
||||
end)
|
||||
test("empty fruit cannot be manufactured by fresh pollination",function()
|
||||
bush(); local m=A.get_meta(p)
|
||||
m:set_string("botany_ready_at",tostring(time+86400))
|
||||
m:set_string("succ_pollinated_until",tostring(time+86400))
|
||||
local before=writes; assert(not B.harvest(p,player) and writes==before and added==0)
|
||||
assert(tonumber(m:get_string("succ_pollinated_until"))==time+86400)
|
||||
end)
|
||||
test("inventory rejection restores fruit and credit; partial delivery spends both",function()
|
||||
bush(); local m=A.get_meta(p); local pollen=tostring(time+86400)
|
||||
m:set_string("succ_pollinated_until",pollen)
|
||||
room=false; assert(not B.harvest(p,player))
|
||||
assert(m:get_string("botany_ready_at")=="" and m:get_string("succ_pollinated_until")==pollen)
|
||||
room=true; leftover=3; assert(not B.harvest(p,player))
|
||||
assert(m:get_string("botany_ready_at")=="" and m:get_string("succ_pollinated_until")==pollen)
|
||||
leftover=2; local ok,n=B.harvest(p,player); assert(ok and n==1 and added==1)
|
||||
assert(m:get_string("succ_pollinated_until")=="0" and not B.harvest(p,player))
|
||||
end)
|
||||
test("both inventory callbacks observe reserved fruit and pollination credit",function()
|
||||
bush(); local m=A.get_meta(p); m:set_string("succ_pollinated_until",tostring(time+86400))
|
||||
local old_room,old_add=inv.room_for_item,inv.add_item
|
||||
local function check()
|
||||
assert(not B.harvest(p,player))
|
||||
assert(m:get_string("succ_pollinated_until")=="0")
|
||||
end
|
||||
inv.room_for_item=function(...) check(); return old_room(...) end
|
||||
inv.add_item=function(...) check(); return old_add(...) end
|
||||
local ok,n=B.harvest(p,player)
|
||||
inv.room_for_item,inv.add_item=old_room,old_add
|
||||
assert(ok and n==3 and added==3)
|
||||
end)
|
||||
assert(passed==44,"Unexpected focused botany integration count")
|
||||
print("BOTANY_SPEC_PASS "..passed)
|
||||
|
||||
Reference in New Issue
Block a user