local failures = 0 local function expect(condition, message) if not condition then failures = failures + 1 io.stderr:write("FAIL: " .. message .. "\n") end end local activeModIds = {} getActivatedMods = function() return { contains = function(_, modId) return activeModIds[modId] == true end } end local function vehicle(fullName, modelScale) return { getScript = function() return { getFullName = function() return fullName end, getModelScale = function() return modelScale end } end } end local classifierPath = "42.20/media/lua/shared/TowBar/VehicleCompatibility.lua" local loaded, loadError = pcall(dofile, classifierPath) expect(loaded, "dual-mode classifier must load from " .. classifierPath .. ": " .. tostring(loadError)) local Compatibility = TowBarMod and TowBarMod.Compatibility expect(Compatibility ~= nil, "classifier must expose TowBarMod.Compatibility") expect(Compatibility and type(Compatibility.isKi5Vehicle) == "function", "classifier must expose isKi5Vehicle(vehicle)") if Compatibility and type(Compatibility.isKi5Vehicle) == "function" then local function isKi5(fullName, modelScale) return Compatibility.isKi5Vehicle(vehicle(fullName, modelScale)) end -- Positive contracts use exact mod IDs and exact script full names verified -- from the locally installed KI5 workshop items. activeModIds = { ["91range"] = true } expect(isKi5("Base.91range", 0.01), "active KI5 Range Rover must use KI5 mode") activeModIds = { ["87toyotaCorolla"] = true } expect(isKi5("Base.87toyotaCorollaAE92levin", 1.75), "active KI5 Corolla must use KI5 mode regardless of model scale") activeModIds = { ["76chevyKseries"] = true } expect(isKi5("Base.76chevyK30CCwrecker", 1.75), "active KI5 Chevrolet variant must use KI5 mode") -- Exact identity is intentional. Scale, name fragments, attachment shape, -- and an active mod ID by itself must never capture another vehicle. activeModIds = {} expect(not isKi5("Base.91range", 0.01), "a KI5-looking script without its exact active mod must use legacy mode") activeModIds = { ["91range"] = true } expect(not isKi5("Base.91rangeBurnt", 0.01), "a suffixed KI5 lookalike must use legacy mode") expect(not isKi5("Base.CarNormal", 0.01), "vanilla must not be classified by KI5-like model scale") expect(not isKi5("Base.SmallCar", 1.75), "vanilla must not be classified by legacy vanilla model scale") expect(not isKi5("Base.Chevalier_Rhino_TowTruck", 0.01), "a non-KI5 tow-truck mod must use legacy mode") activeModIds = { ["91range-copy"] = true } expect(not isKi5("Base.91range", 0.01), "a prefix or suffix match on mod ID must not enable KI5 mode") expect(not Compatibility.isKi5Vehicle(nil), "nil vehicle must safely use legacy mode") expect(not Compatibility.isKi5Vehicle({ getScript = function() return nil end }), "vehicle without a script must safely use legacy mode") end if failures > 0 then os.exit(1) end print("PASS: exact KI5 dual-mode classifier")