Files
fs25-adsmartpickup/tests/test_adFieldModel.lua
T
masterdraco cf7a2a51e5 feat(marker): sideriver — mål hvor riven lægger skåret, forskyd læssevognen tilsvarende (v1.24.0.0)
Brugerkrav 25/9: alle river-typer skal virke. Nedlægningsområdet (runtime-felt eller riverens XML) måles
i traktorens ramme mens riven arbejder; læssevognen på rivens kursus får CP-toolOffsetX = egen -
skårets forskydning og får sin værdi tilbage når den slippes.
2026-09-25 23:35:42 +02:00

138 lines
7.8 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- Kør: luajit tests/test_adFieldModel.lua (fra repo-roden)
dofile("FS25_ADSmartPickup/adFieldModel.lua")
local M = ADFieldModel
local failures = 0
local function check(name, actual, expected)
if actual == expected then print("OK " .. name) else
failures = failures + 1
print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual)))
end
end
-- M1: ny mark = venter, manuel ensilage uden riv
local f = M.newField(109)
check("M1 stage", f.stage, "idle")
check("M1 mode", f.plan.mode, "manual")
check("M1 product", f.plan.product, "silage")
check("M1 rake", f.plan.rake, false)
-- M2: klar ved >= 90 %
check("M2 89 % ikke klar", M.onReadiness(f, 0.89).stage, "idle")
local ready = M.onReadiness(f, 0.9)
check("M2 90 % klar", ready.stage, "ready")
check("M2 immutabel", f.stage, "idle")
-- M3: klar mark slået af spilleren -> tilbage til venter
check("M3 slået manuelt", M.onReadiness(ready, 0.3).stage, "idle")
check("M3 lidt under 90 % forbliver klar", M.onReadiness(ready, 0.8).stage, "ready")
-- M4: trin pr. plan
check("M4 ensilage", table.concat(M.workStages({product = "silage"}), ","), "mowing,collecting")
check("M4 ensilage m. riv", table.concat(M.workStages({product = "silage", rake = true}), ","), "mowing,raking,collecting")
check("M4 hø", table.concat(M.workStages({product = "hay", rake = false}), ","), "mowing,tedding,collecting")
check("M4 hø m. riv", table.concat(M.workStages({product = "hay", rake = true}), ","), "mowing,tedding,raking,collecting")
-- M5: start: auto starter selv, manuel kun på forespørgsel
check("M5 manuel starter ikke", M.shouldStart(ready), false)
local auto = M.onReadiness(M.newField(5), 1)
auto.plan.mode = "auto"
check("M5 auto starter", M.shouldStart(auto), true)
local requested = M.newField(6); requested.stage = "ready"; requested.startRequested = true
check("M5 Start nu", M.shouldStart(requested), true)
local started = M.start(ready)
check("M5 start -> slås", started.stage, "mowing")
check("M5 start rydder forespørgsel", started.startRequested, false)
local oldMow = M.with(ready, {mowVehicleId = "old"})
check("M5 start glemmer gammel slåmaskine", M.start(oldMow).mowVehicleId, nil)
-- M6: videre gennem trinene; færdig mark bliver klar igen når den er vokset
local hay = M.start(M.onReadiness(M.newField(7), 1)); hay.plan.product = "hay"
hay = M.advance(hay); check("M6 hø -> vendes", hay.stage, "tedding")
hay = M.advance(hay); check("M6 -> samles op", hay.stage, "collecting")
hay = M.advance(hay); check("M6 -> færdig", hay.stage, "done")
check("M6 færdig forbliver ved lav andel", M.onReadiness(hay, 0.1).stage, "done")
check("M6 færdig -> klar når vokset", M.onReadiness(hay, 0.95).stage, "ready")
check("M6 arbejdende mark ignorerer andel", M.onReadiness(started, 0).stage, "mowing")
check("M6 isWorking", M.isWorking(started), true)
check("M6 stop -> klar", M.stop(started).stage, "ready")
-- M7: roller, maks sæt, bredde
check("M7 rolle slå", M.roleFor("mowing"), "mower")
check("M7 rolle saml", M.roleFor("collecting"), "collector")
check("M7 rolle klar = ingen", M.roleFor("ready"), nil)
check("M7 maks læssevogne", M.maxRigs("collecting"), 2)
check("M7 maks slå", M.maxRigs("mowing"), 1)
local okWide, whyWide = M.checkWidth("mower", 60, nil)
check("M7 over 50 m", okWide, false); check("M7 grund", whyWide, "tooWide")
check("M7 40,8 m slå ok", (M.checkWidth("mower", 40.8, nil)), true)
local okNarrow, whyNarrow, args = M.checkWidth("collector", 20, 40.8)
check("M7 for smal", okNarrow, false); check("M7 grund smal", whyNarrow, "tooNarrow"); check("M7 args", args[2], 40.8)
check("M7 lige bred ok (tolerance)", (M.checkWidth("collector", 40.76, 40.8)), true)
check("M7 ukendt slåbredde ok", (M.checkWidth("tedder", 10, nil)), true)
-- wantsRig: kun arbejdende trin, under maks, efter pause
check("M7 wantsRig slå", M.wantsRig(started, 0, 0), "mower")
check("M7 wantsRig fuld", M.wantsRig(started, 1, 0), nil)
local paused = M.start(M.onReadiness(M.newField(8), 1)); paused.retryAt = 1000
check("M7 wantsRig i pause", M.wantsRig(paused, 0, 500), nil)
check("M7 wantsRig efter pause", M.wantsRig(paused, 0, 1000), "mower")
check("M7 wantsRig klar = nil", M.wantsRig(ready, 0, 0), nil)
-- M8: gem/indlæs bevarer trin, plan og slåbredde
local saved = M.advance(M.start(M.onReadiness(M.newField(109), 1))); saved.mowWidth = 40.8; saved.mowVehicleId = "vehicleBigM"
saved.plan = {mode = "auto", product = "hay", rake = true, storeBuildingIds = {"b12", "b7"}}
local back = M.fromRecord(M.toRecord(saved))
check("M8 id", back.id, 109)
check("M8 stage", back.stage, saved.stage)
check("M8 mode", back.plan.mode, "auto")
check("M8 product", back.plan.product, "hay")
check("M8 rake", back.plan.rake, true)
check("M8 lager", table.concat(back.plan.storeBuildingIds, " "), "b12 b7")
check("M8 slåbredde", back.mowWidth, 40.8)
check("M8 slåmaskine", back.mowVehicleId, "vehicleBigM")
check("M8 ingen slåmaskine", M.fromRecord({id = 4, stage = "idle"}).mowVehicleId, nil)
check("M8 ukendt trin -> venter", M.fromRecord({id = 3, stage = "bogus"}).stage, "idle")
-- M9: with() kopierer og fletter planen
local base = M.start(M.onReadiness(M.newField(1), 1))
local noted = M.with(base, {reason = {text = "x"}, retryAt = 5, plan = {product = "hay"}})
check("M9 grund", noted.reason.text, "x"); check("M9 pause", noted.retryAt, 5)
check("M9 plan flettet", noted.plan.product, "hay"); check("M9 mode bevaret", noted.plan.mode, "manual")
check("M9 trin bevaret", noted.stage, "mowing"); check("M9 original urørt", base.plan.product, "silage")
-- M10: Start nu på en mark der ikke er helt klar -> klar; arbejdende mark røres ikke
check("M10 venter -> klar", M.forceReady(M.newField(2)).stage, "ready")
check("M10 arbejdende uændret", M.forceReady(base).stage, "mowing")
-- M11: krævet bredde og kursus-kilde pr. rolle (smalle standardmaskiner, 25/9)
local cut = M.with(M.newField(3), {mowWidth = 40.8})
check("M11 vender kræver ingen bredde", M.requiredWidth(cut, "tedder"), nil)
check("M11 river kræver ingen bredde", M.requiredWidth(cut, "rake"), nil)
check("M11 læssevogn uden riv = slåbredde", M.requiredWidth(cut, "collector"), 40.8)
local raked = M.with(cut, {plan = {rake = true}})
check("M11 læssevogn efter riv = ingen krav", M.requiredWidth(raked, "collector"), nil)
check("M11 vender eget kursus", M.courseSource(cut, "tedder"), nil)
check("M11 river eget kursus", M.courseSource(raked, "rake"), nil)
check("M11 læssevogn uden riv -> slåkursus", M.courseSource(cut, "collector"), "mower")
check("M11 læssevogn efter riv -> rivekursus", M.courseSource(raked, "collector"), "rake")
check("M11 slåmaskine eget kursus", M.courseSource(cut, "mower"), nil)
-- gem/indlæs rivemaskine
local withRake = M.with(raked, {rakeVehicleId = "vehicleRake"})
check("M11 rivemaskine gemt", M.fromRecord(M.toRecord(withRake)).rakeVehicleId, "vehicleRake")
check("M11 start glemmer rivemaskine", M.start(M.with(M.onReadiness(M.newField(9), 1), {rakeVehicleId = "x"})).rakeVehicleId, nil)
-- M12: sideriver — læssevognens CP-forskydning = egen forskydning − skårets forskydning (venstre positiv),
-- holdt inden for Courseplays ±10 m; skårets forskydning gemmes pr. mark
check("M12 midterrive", M.collectorOffset(0, 0), 0)
check("M12 skår 3 m til venstre", M.collectorOffset(0, 3), -3)
check("M12 vogn med egen forskydning", M.collectorOffset(0.5, -2), 2.5)
check("M12 holdes inden for 10 m", M.collectorOffset(0, 14), -10)
check("M12 ukendt skår -> egen forskydning", M.collectorOffset(0.4, nil), 0.4)
local side = M.with(M.newField(11), {windrowOffset = 3.2})
check("M12 skår gemt", M.fromRecord(M.toRecord(side)).windrowOffset, 3.2)
check("M12 intet skår gemt", M.fromRecord(M.toRecord(M.newField(12))).windrowOffset, nil)
check("M12 start glemmer skår", M.start(M.with(M.onReadiness(M.newField(13), 1), {windrowOffset = 1})).windrowOffset, nil)
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)