Ruined
This commit is contained in:
+176
-13
@@ -13,7 +13,7 @@ local items = {
|
||||
["hearth:log"] = {description="Timber log"}, ["hearth:stone"] = {description="Weathered stone"},
|
||||
["hearth:alluvium"] = {description="Alluvium"},
|
||||
}
|
||||
local species = {"oak", "birch", "pine", "willow", "alder", "beech", "aspen", "rowan", "hazel", "spruce"}
|
||||
local species = {"oak", "birch", "pine", "willow", "alder", "beech", "aspen", "rowan", "hazel", "spruce", "crab_apple", "wild_cherry", "field_maple"}
|
||||
local rocks = {"granite", "basalt", "limestone", "slate", "sandstone"}
|
||||
for _, s in ipairs(species) do
|
||||
items["hearth:"..s.."_log"] = {description=s.." log"}
|
||||
@@ -61,6 +61,11 @@ function core.show_formspec(name, form, spec) screens[#screens+1]={name=name,for
|
||||
hearth = {sessions={alice={}}, model={location=function() end}}
|
||||
dofile(target)
|
||||
local player={get_player_name=function() return "alice" end}
|
||||
local player_metadata={}
|
||||
function player:get_meta()
|
||||
return {get_string=function(_,key) return player_metadata[key] or "" end,
|
||||
set_string=function(_,key,value) player_metadata[key]=value end}
|
||||
end
|
||||
function player:get_pos() return {x=10,y=4,z=-2} end
|
||||
function player:set_inventory_formspec(spec) self.inventory_spec=spec end
|
||||
local hud = {}
|
||||
@@ -264,14 +269,16 @@ test("ecosystem command and guide button only read one habitat and status snapsh
|
||||
end,step=forbidden,forage=forbidden,deposit=forbidden}
|
||||
hearth.wildlife={status=function()
|
||||
snapshots=snapshots+1
|
||||
return {hare=3,deer=2,fox=1,total=6,global_cap=32,local_cap=6,player_cap=6}
|
||||
return {hare=3,deer=2,fox=1,total=6,global_cap=32,local_cap=6,player_cap=6,
|
||||
recruitment={attempts=8,successes=2,last_reason="admitted"}}
|
||||
end}
|
||||
assert(commands.ecosystem.func("alice"))
|
||||
assert(reads==1 and snapshots==1 and latest().form=="hearth:ecosystem")
|
||||
for _,text in ipairs({"Natural grass cover: 3", "Flower-support cover: 2", "Shrub / fern / aquatic / tree cover: 4",
|
||||
"Moisture: 65%", "Hares: 3", "Deer: 2", "Foxes: 1", "Active total: 6 / 32 globally",
|
||||
"not a local census", "Loaded sample", "No terrain is loaded", "Ground: Alluvium",
|
||||
"Pollinator-support plants: 7", "Nutrient reserve: 2 / 8", "pine and spruce stay evergreen", "deciduous canopy thins"}) do
|
||||
"Pollinator-support plants: 7", "Nutrient reserve: 2 / 8", "pine and spruce stay evergreen", "deciduous canopy thins",
|
||||
"Admissions: 2 / 8 attempts", "Latest outcome: admitted"}) do
|
||||
assert(latest().spec:find(text,1,true),text)
|
||||
end
|
||||
registered.fields(player,"hearth:guide",{ecosystem_survey=true})
|
||||
@@ -323,14 +330,14 @@ end)
|
||||
-- Actual catalogue factory/methods, not an invented list of test species.
|
||||
local botany_path = target:match("^(.*[/\\])") or ""
|
||||
local actual_botany = dofile(botany_path .. "botany.lua")(hearth,{})
|
||||
test("actual botanical catalogue displays eighty species in eight ten-row pages", function()
|
||||
test("actual botanical catalogue displays one hundred species in ten ten-row pages and eight uneven groups", function()
|
||||
hearth.botany=actual_botany
|
||||
local records, groups = actual_botany.list(), {}
|
||||
assert(#records==80)
|
||||
for page=1,8 do
|
||||
assert(#records==100)
|
||||
for page=1,10 do
|
||||
hearth.botanical_guide(player,"",page)
|
||||
local spec,rows=latest().spec,0
|
||||
assert(spec:find("Page "..page.." / 8 / 80 matches",1,true))
|
||||
assert(spec:find("Page "..page.." / 10 / 100 matches",1,true))
|
||||
for _ in spec:gmatch("Habitat:") do rows=rows+1 end
|
||||
assert(rows==10,"each page must contain ten species rows")
|
||||
for i=(page-1)*10+1,page*10 do
|
||||
@@ -339,7 +346,8 @@ test("actual botanical catalogue displays eighty species in eight ten-row pages"
|
||||
assert(spec:find("Active seasons:",1,true) and spec:find("Roles / conditional policy or descriptors:",1,true))
|
||||
end
|
||||
end
|
||||
local count=0; for _,n in pairs(groups) do assert(n==10); count=count+1 end; assert(count==8)
|
||||
local sizes={trees=13,shrubs=14,grasses=10,herbs=22,ferns_mosses=11,fungi=10,aquatic=10,lichens=10}
|
||||
local count=0; for g,n in pairs(groups) do assert(n==sizes[g]); count=count+1 end; assert(count==8)
|
||||
hearth.guide(player,6)
|
||||
for _,r in ipairs(records) do assert(latest().spec:find(core.formspec_escape(r.common.." ("..r.latin..")"),1,true),r.id) end
|
||||
end)
|
||||
@@ -376,7 +384,7 @@ test("botanical query escaping literal search and finite pagination bounds", fun
|
||||
hearth.botanical_guide(player,"\n\tlichen",-math.huge)
|
||||
assert(hearth.sessions.alice.botany_query==" lichen" and hearth.sessions.alice.botany_page==1)
|
||||
for _,p in ipairs({0/0,-8,"bad",0}) do hearth.botanical_guide(player,"",p); assert(hearth.sessions.alice.botany_page==1) end
|
||||
hearth.botanical_guide(player,"",math.huge); assert(hearth.sessions.alice.botany_page==8)
|
||||
hearth.botanical_guide(player,"",math.huge); assert(hearth.sessions.alice.botany_page==10)
|
||||
local record=actual_botany.list()[1]; record.common=query
|
||||
hearth.botany={list=function() return {record} end}
|
||||
hearth.botanical_guide(player,"",1)
|
||||
@@ -487,7 +495,7 @@ test("HUD accepts legacy mocks without optional hotbar image setters", function(
|
||||
assert(hearth.sessions.alice.hud.needs)
|
||||
player.hud_set_hotbar_image,player.hud_set_hotbar_selected_image=image,selected
|
||||
end)
|
||||
assert(total==38,"The original 38 recipe/journal checks must remain intact")
|
||||
assert(total==41,"The original checks plus three new tree recipe searches must remain intact")
|
||||
test("inspect command uses exact species and rejects absent session unknown and URL input",function()
|
||||
hearth.botany=actual_botany
|
||||
hearth.wiki_articles=dofile(sibling.."wiki_articles.lua")
|
||||
@@ -501,9 +509,9 @@ test("inspect command uses exact species and rejects absent session unknown and
|
||||
end)
|
||||
test("botanical article selection uses trusted current-page numeric rows only",function()
|
||||
hearth.botanical_guide(player,"",2)
|
||||
assert(latest().spec:find("tooltip[species_choice;Species article]",1,true))
|
||||
assert(latest().spec:find("tooltip[species_choice;Species article;#181825;#cdd6f4]",1,true))
|
||||
registered.fields(player,"hearth:botany",{species_choice="2",species_article=true,id="oak"})
|
||||
assert(latest().form=="hearth:species" and hearth.sessions.alice.species_reader.id=="blackberry")
|
||||
assert(latest().form=="hearth:species" and hearth.sessions.alice.species_reader.id==actual_botany.list()[12].id)
|
||||
for _,v in ipairs({"oak","0","11","2.5","1e0","999",{},string.rep("1",1000)}) do
|
||||
hearth.botanical_guide(player,"",2); local n=#screens
|
||||
registered.fields(player,"hearth:botany",{species_choice=v,species_article=true})
|
||||
@@ -566,5 +574,160 @@ test("inventory appearance entry opens only the requesting player's creator", fu
|
||||
hearth.character = nil
|
||||
registered.fields(player,"",{character_creator=true}); assert(called == 1)
|
||||
end)
|
||||
assert(total==44,"Unexpected recipe/journal/character integration count")
|
||||
assert(total==47,"Unexpected recipe/journal/character integration count")
|
||||
test("inventory and journal tooltips contain escaped text, never an invalid third argument",function()
|
||||
local specs={}
|
||||
hearth.inventory(player); specs[#specs+1]=player.inventory_spec
|
||||
local text="Preview woodland clothing and features. Cosmetic only; Save / Apply to keep changes."
|
||||
assert(player.inventory_spec:find("tooltip[character_creator;"..core.formspec_escape(text)..";#181825;#cdd6f4]",1,true))
|
||||
hearth.guide(player,6); specs[#specs+1]=latest().spec
|
||||
hearth.recipes(player,"",1); specs[#specs+1]=latest().spec
|
||||
hearth.location_form(player); specs[#specs+1]=latest().spec
|
||||
hearth.botanical_guide(player,"",1); specs[#specs+1]=latest().spec
|
||||
hearth.ecosystem(player); specs[#specs+1]=latest().spec
|
||||
local n=0
|
||||
for _,spec in ipairs(specs) do for body in spec:gmatch("tooltip%[(.-)%]") do
|
||||
local clean=body:gsub("\\.",""); local _,separators=clean:gsub(";","")
|
||||
assert(separators==1 or separators==3,"invalid tooltip arity: "..body); n=n+1
|
||||
end end
|
||||
assert(n>=10)
|
||||
end)
|
||||
test("survey loops actual counts for all 23 animals without changing the world",function()
|
||||
hearth.lifecycle=dofile(sibling.."lifecycle.lua")
|
||||
hearth.fauna=dofile(sibling.."fauna.lua")(hearth,{})
|
||||
local counts={}; for i,r in ipairs(hearth.fauna.list()) do counts[r.id]=i end
|
||||
local calls=0
|
||||
hearth.wildlife={status=function() calls=calls+1; return {counts=counts,total=64,global_cap=64,local_cap=12,player_cap=16} end}
|
||||
hearth.ecosystem(player); assert(calls==1)
|
||||
for id,n in pairs(counts) do
|
||||
local title=({hare="Hares",deer="Deer",fox="Foxes"})[id] or id:gsub("_"," ")
|
||||
assert(latest().spec:find(title..": "..n,1,true),id)
|
||||
end
|
||||
assert(latest().spec:find("Calendar age includes unloaded time",1,true))
|
||||
end)
|
||||
test("actual fauna guide shows all identities sources and conservative lifecycle status read-only",function()
|
||||
assert(commands.fauna.func("alice",""))
|
||||
local records=hearth.fauna.list()
|
||||
assert(#records==23 and latest().form=="hearth:fauna")
|
||||
for page=1,5 do
|
||||
hearth.fauna_guide(player,"",page)
|
||||
assert(latest().spec:find("Page "..page.." / 5 / 23 matches",1,true))
|
||||
for i=(page-1)*5+1,math.min(#records,page*5) do
|
||||
local r=records[i]
|
||||
assert(latest().spec:find(core.formspec_escape(r.source_url),1,true),r.id)
|
||||
assert(latest().spec:find(core.formspec_escape(r.latin or "UNKNOWN species identity (legacy deer)"),1,true))
|
||||
end
|
||||
assert(latest().spec:find("automatic breeding disabled",1,true))
|
||||
assert(latest().spec:find("no lifespan-endpoint death",1,true))
|
||||
end
|
||||
hearth.fauna_guide(player,"rabbit",1)
|
||||
assert(latest().spec:find("Maturity: UNKNOWN",1,true))
|
||||
hearth.fauna_guide(player,"bank_vole",1)
|
||||
assert(latest().spec:find(core.formspec_escape("42-56 real days [source_reported]"),1,true))
|
||||
assert(not commands.fauna.func("offline",""))
|
||||
end)
|
||||
test("fauna search pagination routing and escaping stay bounded and session-owned",function()
|
||||
local query="];button[0,0;1,1;attack;Injected]"
|
||||
hearth.fauna_guide(player,query,0/0)
|
||||
assert(latest().spec:find(core.formspec_escape(query),1,true) and not latest().spec:find(";attack;Injected]",1,true))
|
||||
assert(latest().spec:find("No animal matches",1,true))
|
||||
hearth.fauna_guide(player,string.rep("x",80),1); assert(#hearth.sessions.alice.fauna_query==48)
|
||||
hearth.fauna_guide(player,"",math.huge); assert(hearth.sessions.alice.fauna_page==5)
|
||||
registered.fields(player,"hearth:guide",{fauna_index=true}); assert(hearth.sessions.alice.fauna_page==1)
|
||||
registered.fields(player,"hearth:fauna",{next=true}); assert(hearth.sessions.alice.fauna_page==2)
|
||||
registered.fields(player,"hearth:fauna",{previous=true}); assert(hearth.sessions.alice.fauna_page==1)
|
||||
registered.fields(player,"hearth:fauna",{search=true,query="Lutra lutra"}); assert(latest().spec:find("otter",1,true))
|
||||
registered.fields(player,"hearth:fauna",{botany_index=true}); assert(latest().form=="hearth:botany")
|
||||
registered.fields(player,"hearth:botany",{fauna_index=true}); assert(latest().form=="hearth:fauna")
|
||||
registered.fields(player,"hearth:fauna",{field_notes=true}); assert(latest().form=="hearth:guide")
|
||||
registered.fields(player,"hearth:ecosystem",{fauna_index=true}); assert(latest().form=="hearth:fauna")
|
||||
local original=hearth.fauna
|
||||
local r=original.list()[1]; r.common=query; r.source_url=query
|
||||
hearth.fauna={list=function() return {r} end}; hearth.fauna_guide(player,"",1)
|
||||
assert(latest().spec:find(core.formspec_escape(query),1,true) and not latest().spec:find(";attack;Injected]",1,true))
|
||||
hearth.fauna=nil; hearth.fauna_guide(player,"",1); assert(latest().spec:find("catalogue unavailable",1,true))
|
||||
hearth.fauna=original
|
||||
local session,n=hearth.sessions.alice,#screens; hearth.sessions.alice=nil
|
||||
assert(not commands.fauna.func("alice","")); hearth.fauna_guide(player,"",1)
|
||||
registered.fields(player,"hearth:fauna",{next=true}); assert(#screens==n)
|
||||
hearth.sessions.alice=session
|
||||
end)
|
||||
test("fauna species selection and live inspection show bounded read-only species details",function()
|
||||
local records=hearth.fauna.list(); local before=hearth.wildlife.status()
|
||||
hearth.fauna_guide(player,"",1)
|
||||
assert(latest().spec:find("species_choice;hare,deer,fox,rabbit,red_squirrel",1,true))
|
||||
registered.fields(player,"hearth:fauna",{species_choice="3",species_details=true})
|
||||
assert(latest().form=="hearth:fauna_detail" and latest().spec:find("Vulpes vulpes",1,true))
|
||||
assert(latest().spec:find("Modeled prey:",1,true) and latest().spec:find("Winter rest policy:",1,true))
|
||||
registered.fields(player,"hearth:fauna_detail",{fauna_index=true})
|
||||
assert(latest().form=="hearth:fauna" and hearth.sessions.alice.fauna_page==1)
|
||||
local now=os.time()
|
||||
assert(hearth.inspect_fauna(player,"hare",{born_at=now-500*86400,origin="born",foodreserve=.42,
|
||||
resident=true,observation="rest"}))
|
||||
local spec=latest().spec
|
||||
for _,text in ipairs({"Lepus europaeus","Lifecycle: mature","model years","real calendar days",
|
||||
"Coarse modeled food reserve (policy, not biology): 42%","Current animation observation: resting",
|
||||
"persistent registered resident","Modeled diet: browse","Activity / sleep policy: night / solar_night",
|
||||
"Winter rest policy:","Modeled behavior:","Modeled prey:","Reproduction: enabled only within the coarse model",
|
||||
"Active loaded animals of this species:"}) do
|
||||
assert(spec:find(core.formspec_escape(text),1,true),text)
|
||||
end
|
||||
local after=hearth.wildlife.status()
|
||||
assert(after.total==before.total and after.counts.hare==before.counts.hare,"panel reads status without game changes")
|
||||
local original_get=hearth.fauna.get; local injection="];button[0,0;1,1;attack;Injected]"
|
||||
hearth.fauna.get=function(id)
|
||||
local r=original_get(id)
|
||||
if id=="hare" then r.common=injection; r.latin=injection; r.source_url=injection end
|
||||
return r
|
||||
end
|
||||
hearth.inspect_fauna(player,"hare",nil)
|
||||
assert(latest().spec:find(core.formspec_escape(injection),1,true) and not latest().spec:find(";attack;Injected]",1,true))
|
||||
hearth.fauna.get=original_get
|
||||
local session,count=hearth.sessions.alice,#screens; hearth.sessions.alice=nil
|
||||
assert(not hearth.inspect_fauna(player,"hare",nil) and #screens==count)
|
||||
hearth.sessions.alice=session
|
||||
local impostor={get_player_name=function() return "alice" end}
|
||||
assert(not hearth.inspect_fauna(impostor,"hare",nil) and #screens==count)
|
||||
assert(not hearth.inspect_fauna(player,"hare",setmetatable({},{})) and #screens==count)
|
||||
assert(not hearth.inspect_fauna(player,"unknown",nil) and #screens==count)
|
||||
assert(#records==23)
|
||||
end)
|
||||
test("wildlife encounters add canonical per-player field-journal entries; catalogue browsing does not",function()
|
||||
local key="hearth:fauna_observations_v1"
|
||||
player_metadata[key]=""
|
||||
hearth.fauna_guide(player,"",1)
|
||||
assert(latest().spec:find("0 / 23 species recorded",1,true))
|
||||
hearth.inspect_fauna(player,"hare",{born_at=os.time()-86400,origin="established",foodreserve=.5,
|
||||
resident=true,observation="awake"})
|
||||
assert(player_metadata[key]=="hare")
|
||||
assert(latest().spec:find("Field journal: first recorded encounter",1,true))
|
||||
hearth.inspect_fauna(player,"fox",{born_at=os.time()-86400,origin="established",foodreserve=.5,
|
||||
resident=true,observation="awake"})
|
||||
assert(player_metadata[key]=="fox,hare","journal storage is canonical and sorted")
|
||||
hearth.inspect_fauna(player,"hare",{born_at=os.time()-86400,origin="established",foodreserve=.5,
|
||||
resident=true,observation="awake"})
|
||||
assert(latest().spec:find("already recorded",1,true))
|
||||
hearth.inspect_fauna(player,"deer",nil)
|
||||
assert(player_metadata[key]=="fox,hare","catalogue profile selection is not a sighting")
|
||||
hearth.fauna_guide(player,"",1)
|
||||
assert(latest().spec:find("2 / 23 species recorded",1,true))
|
||||
assert(latest().spec:find("recorded encounter",1,true))
|
||||
player_metadata[key]="hare,unknown"
|
||||
assert(hearth.inspect_fauna(player,"deer",{born_at=os.time()-86400,origin="established",foodreserve=.5,
|
||||
resident=true,observation="awake"}))
|
||||
assert(player_metadata[key]=="hare,unknown","malformed journal data fails closed without overwriting")
|
||||
player_metadata[key]=nil
|
||||
end)
|
||||
test("calendar guidance never promises accelerated saplings daily berries or complete biology",function()
|
||||
hearth.recipes(player,"Renewal",1)
|
||||
for _,s in ipairs({"365.2425 days","no 24-hour refill","at most one berry","one real year","UNKNOWN"}) do
|
||||
assert(latest().spec:find(s,1,true),s)
|
||||
end
|
||||
hearth.guide(player,6)
|
||||
for _,s in ipairs({"100 named species","23 animal identities","eight uneven","real years to decades","fungi do not accelerate growth","disable breeding"}) do
|
||||
assert(latest().spec:find(s,1,true),s)
|
||||
end
|
||||
assert(not latest().spec:find("eight categories of ten",1,true))
|
||||
end)
|
||||
assert(total==54,"Unexpected focused integration count")
|
||||
print("PASS "..total.." recipe discovery tests")
|
||||
|
||||
Reference in New Issue
Block a user