Add some tests for charging and using tools Fix tool spec, mod loading was updated Tests using air as default node
454 lines
15 KiB
Lua
454 lines
15 KiB
Lua
require("mineunit")
|
|
--[[
|
|
Technic tool regression tests.
|
|
Execute mineunit at technic source directory.
|
|
--]]
|
|
|
|
-- Load complete technic mod
|
|
fixture("technic")
|
|
sourcefile("init")
|
|
|
|
local RUN_TECHNIC_ADDONS_CHAINSAWMK3_TESTS = false
|
|
|
|
describe("Technic power tool", function()
|
|
|
|
if RUN_TECHNIC_ADDONS_CHAINSAWMK3_TESTS then
|
|
-- Load technic_addons mod
|
|
mineunit:set_modpath("technic_addons", "../../technic_addons")
|
|
mineunit:set_current_modname("technic_addons")
|
|
sourcefile("../../technic_addons/init")
|
|
mineunit:restore_current_modname()
|
|
end
|
|
|
|
world.set_default_node("air")
|
|
|
|
-- HV battery box and some HV solar arrays for charging
|
|
local BB_Charge_POS = {x=0,y=51,z=0}
|
|
local BB_Discharge_POS = {x=0,y=51,z=2}
|
|
world.layout({
|
|
-- Network with generators for charging tools in battery box
|
|
{BB_Charge_POS, "technic:hv_battery_box0"},
|
|
{{x=1,y=51,z=0}, "technic:switching_station"},
|
|
{{{x=2,y=51,z=0},{x=10,y=51,z=0}}, "technic:solar_array_hv"},
|
|
{{{x=0,y=50,z=0},{x=10,y=50,z=0}}, "technic:hv_cable"},
|
|
-- Network without generators for discharging tools in battery box
|
|
{BB_Discharge_POS, "technic:hv_battery_box0"},
|
|
{{x=1,y=51,z=2}, "technic:switching_station"},
|
|
{{{x=0,y=50,z=2},{x=1,y=50,z=2}}, "technic:hv_cable"},
|
|
})
|
|
|
|
-- Some helpers to make stack access simpler
|
|
local player = Player("SX")
|
|
local charge_inv = minetest.get_meta(BB_Charge_POS):get_inventory()
|
|
local discharge_inv = minetest.get_meta(BB_Discharge_POS):get_inventory()
|
|
local function set_charge_stack(stack) charge_inv:set_stack("src", 1, stack) end
|
|
local function get_charge_stack() return charge_inv:get_stack("src", 1) end
|
|
local function set_discharge_stack(stack) discharge_inv:set_stack("src", 1, stack) end
|
|
local function get_discharge_stack() return discharge_inv:get_stack("src", 1) end
|
|
local function set_player_stack(stack) return player:get_inventory():set_stack("main", 1, stack) end
|
|
local function get_player_stack() return player:get_inventory():get_stack("main", 1) end
|
|
|
|
-- Execute on mods loaded callbacks to finish loading.
|
|
mineunit:mods_loaded()
|
|
-- Tell mods that 1 minute passed already to execute all weird minetest.after hacks.
|
|
mineunit:execute_globalstep(60)
|
|
|
|
describe("API", function()
|
|
|
|
setup(function()
|
|
set_charge_stack(ItemStack())
|
|
set_discharge_stack(ItemStack())
|
|
mineunit:set_current_modname("mymod")
|
|
mineunit:execute_on_joinplayer(player)
|
|
end)
|
|
|
|
teardown(function()
|
|
mineunit:execute_on_leaveplayer(player)
|
|
mineunit:restore_current_modname()
|
|
end)
|
|
|
|
local use_RE_charge_result
|
|
|
|
it("technic.register_power_tool works", function()
|
|
technic.register_power_tool("mymod:powertool", {
|
|
description = "My Mod Power Tool",
|
|
inventory_image = "mymod_powertool.png",
|
|
max_charge = 1234,
|
|
on_use = function(itemstack, player, pointed_thing)
|
|
use_RE_charge_result = technic.use_RE_charge(itemstack, 123)
|
|
return itemstack
|
|
end,
|
|
})
|
|
local itemdef = minetest.registered_items["mymod:powertool"]
|
|
assert.is_hashed(itemdef)
|
|
assert.is_function(itemdef.on_use)
|
|
assert.is_function(itemdef.on_refill)
|
|
assert.equals("technic_RE_charge", itemdef.wear_represents)
|
|
assert.is_number(itemdef.technic_max_charge)
|
|
assert.gt(itemdef.technic_max_charge, 0)
|
|
end)
|
|
|
|
it("technic.use_RE_charge works (zero charge)", function()
|
|
set_player_stack("mymod:powertool")
|
|
spy.on(technic, "use_RE_charge")
|
|
player:do_use(player:get_pos())
|
|
assert.spy(technic.use_RE_charge).called(1)
|
|
assert.equals("boolean", type(use_RE_charge_result))
|
|
assert.is_false(use_RE_charge_result)
|
|
end)
|
|
|
|
it("technic.get_RE_charge works (zero charge)", function()
|
|
assert.equals(0, technic.get_RE_charge(ItemStack("mymod:powertool")))
|
|
end)
|
|
|
|
it("technic.set_RE_charge works (zero charge -> 123)", function()
|
|
local stack = ItemStack("mymod:powertool")
|
|
technic.set_RE_charge(stack, 123)
|
|
assert.equals(123, technic.get_RE_charge(stack))
|
|
end)
|
|
|
|
it("technic.use_RE_charge works (minimum charge)", function()
|
|
-- Add partially charged tool to player inventory
|
|
local stack = ItemStack("mymod:powertool")
|
|
technic.set_RE_charge(stack, 123)
|
|
set_player_stack(stack)
|
|
|
|
-- Use tool and verify results
|
|
spy.on(technic, "use_RE_charge")
|
|
player:do_use(player:get_pos())
|
|
assert.spy(technic.use_RE_charge).called(1)
|
|
assert.equals("boolean", type(use_RE_charge_result))
|
|
assert.is_true(use_RE_charge_result)
|
|
assert.equals(0, technic.get_RE_charge(get_player_stack()))
|
|
end)
|
|
|
|
it("technic.use_RE_charge works (minimum charge + 1)", function()
|
|
-- Add partially charged tool to player inventory
|
|
local stack = ItemStack("mymod:powertool")
|
|
technic.set_RE_charge(stack, 124)
|
|
set_player_stack(stack)
|
|
-- Use tool and verify results
|
|
player:do_use(player:get_pos())
|
|
assert.equals(1, technic.get_RE_charge(get_player_stack()))
|
|
end)
|
|
|
|
end)
|
|
|
|
describe("charging and discharging extreme ratios", function()
|
|
|
|
local function register_test_tool(name, charge_per_use, max_charge)
|
|
technic.register_power_tool("mymod:"..name, {
|
|
description = name,
|
|
inventory_image = "mymod_powertool.png",
|
|
max_charge = max_charge,
|
|
on_use = function(itemstack, player, pointed_thing)
|
|
technic.use_RE_charge(itemstack, charge_per_use)
|
|
return itemstack
|
|
end,
|
|
})
|
|
end
|
|
|
|
setup(function()
|
|
set_charge_stack(ItemStack())
|
|
set_discharge_stack(ItemStack())
|
|
mineunit:set_current_modname("mymod")
|
|
register_test_tool("t1_1", 1, 1)
|
|
register_test_tool("t1_2", 1, 2)
|
|
register_test_tool("t1_10001", 1, 10001)
|
|
register_test_tool("t1_65535", 1, 65535)
|
|
register_test_tool("t1_65536", 1, 65536)
|
|
register_test_tool("t100_6553500", 1, 6553500)
|
|
register_test_tool("t100_6553600", 1, 6553600)
|
|
register_test_tool("t2_3", 2, 3)
|
|
mineunit:restore_current_modname()
|
|
mineunit:execute_on_joinplayer(player)
|
|
end)
|
|
|
|
teardown(function()
|
|
mineunit:execute_on_leaveplayer(player)
|
|
end)
|
|
|
|
-- Very basic tests for few simple and straightforward max_charge values
|
|
-- Add tool to battery box and test charging, 10kEU / cycle
|
|
|
|
it("t1_1 can be charged", function()
|
|
set_charge_stack(ItemStack("mymod:t1_1"))
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
mineunit:execute_globalstep(1)
|
|
assert.equals(1, technic.get_RE_charge(get_charge_stack()))
|
|
end)
|
|
|
|
it("t1_2 can be charged", function()
|
|
-- Add tool to battery box
|
|
set_charge_stack(ItemStack("mymod:t1_2"))
|
|
-- Test charging, 10kEU / cycle
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
mineunit:execute_globalstep(1)
|
|
assert.equals(2, technic.get_RE_charge(get_charge_stack()))
|
|
end)
|
|
|
|
it("t1_10001 can be charged", function()
|
|
-- Add tool to battery box
|
|
set_charge_stack(ItemStack("mymod:t1_10001"))
|
|
-- Test charging, 10kEU / cycle
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
mineunit:execute_globalstep(1)
|
|
assert.equals(10000, technic.get_RE_charge(get_charge_stack()))
|
|
mineunit:execute_globalstep(1)
|
|
assert.equals(10001, technic.get_RE_charge(get_charge_stack()))
|
|
end)
|
|
|
|
it("t1_65535 can be charged", function()
|
|
-- Add tool to battery box
|
|
set_charge_stack(ItemStack("mymod:t1_65535"))
|
|
-- Test charging, 10kEU / cycle
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
for i=1,6 do mineunit:execute_globalstep(1) end
|
|
assert.equals(60000, technic.get_RE_charge(get_charge_stack()))
|
|
mineunit:execute_globalstep(1)
|
|
assert.equals(65535, technic.get_RE_charge(get_charge_stack()))
|
|
end)
|
|
|
|
it("t1_65536 can be charged", function()
|
|
-- Add tool to battery box
|
|
set_charge_stack(ItemStack("mymod:t1_65536"))
|
|
-- Test charging, 10kEU / cycle
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
for i=1,6 do mineunit:execute_globalstep(1) end
|
|
assert.equals(60000, technic.get_RE_charge(get_charge_stack()))
|
|
mineunit:execute_globalstep(1)
|
|
assert.equals(65536, technic.get_RE_charge(get_charge_stack()))
|
|
end)
|
|
|
|
it("t100_6553500 can be charged", function()
|
|
-- Add tool to battery box
|
|
set_charge_stack(ItemStack("mymod:t100_6553500"))
|
|
-- Test charging, 10kEU / cycle
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
for i=1,6 do mineunit:execute_globalstep(1) end
|
|
assert.equals(60000, technic.get_RE_charge(get_charge_stack()))
|
|
mineunit:execute_globalstep(1)
|
|
assert.equals(70000, technic.get_RE_charge(get_charge_stack()))
|
|
end)
|
|
|
|
it("t100_6553600 can be charged", function()
|
|
-- Add tool to battery box
|
|
set_charge_stack(ItemStack("mymod:t100_6553600"))
|
|
-- Test charging, 10kEU / cycle
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
for i=1,7 do mineunit:execute_globalstep(1) end
|
|
-- This tool already has small charge error and it is acceptable as long as error stays small
|
|
-- Charge value must be 69999-70001 after 7 charge cycles
|
|
assert.lt(69998, technic.get_RE_charge(get_charge_stack()))
|
|
assert.gt(70002, technic.get_RE_charge(get_charge_stack()))
|
|
end)
|
|
|
|
it("t100_6553600 can be used", function()
|
|
-- Add tool to battery box
|
|
local stack = ItemStack("mymod:t100_6553600")
|
|
technic.set_RE_charge(stack, 700)
|
|
set_player_stack(stack)
|
|
-- Test using, 100 / cycle
|
|
for i=1,6 do player:do_use({x=0, y=0, z=0}) end
|
|
assert.equals(100, technic.get_RE_charge(get_player_stack()))
|
|
player:do_use({x=0, y=0, z=0})
|
|
assert.equals(0, technic.get_RE_charge(get_player_stack()))
|
|
end)
|
|
|
|
end)
|
|
|
|
describe("Flashlight", function()
|
|
|
|
local itemname = "technic:flashlight"
|
|
local itemdef = minetest.registered_items[itemname]
|
|
|
|
setup(function()
|
|
set_charge_stack(ItemStack())
|
|
set_discharge_stack(ItemStack())
|
|
mineunit:execute_on_joinplayer(player)
|
|
end)
|
|
|
|
teardown(function()
|
|
mineunit:execute_on_leaveplayer(player)
|
|
end)
|
|
|
|
it("is registered", function()
|
|
assert.is_hashed(itemdef)
|
|
assert.is_function(itemdef.on_refill)
|
|
assert.equals("technic_RE_charge", itemdef.wear_represents)
|
|
assert.is_number(itemdef.technic_max_charge)
|
|
assert.gt(itemdef.technic_max_charge, 0)
|
|
end)
|
|
|
|
it("charge is used", function()
|
|
-- Get fully charged item
|
|
local stack = ItemStack(itemname)
|
|
technic.set_RE_charge(stack, itemdef.technic_max_charge)
|
|
set_player_stack(stack)
|
|
|
|
-- Use item, flashlight charge is used every globalstep and there's no on_use definition
|
|
spy.on(technic, "use_RE_charge")
|
|
for i=1, 100 do
|
|
mineunit:execute_globalstep(1)
|
|
end
|
|
assert.spy(technic.use_RE_charge).called(100)
|
|
|
|
-- Check that item charge was actually used and error is acceptable
|
|
local charge_used = itemdef.technic_max_charge - technic.get_RE_charge(get_player_stack())
|
|
local exact_use = 2 * 100 -- 2 per cycle / 100 cycles
|
|
assert.lt(0.9, charge_used / exact_use)
|
|
assert.gt(1.1, charge_used / exact_use)
|
|
end)
|
|
|
|
end)
|
|
|
|
describe("Multimeter", function()
|
|
|
|
local itemname = "technic:multimeter"
|
|
local itemdef = minetest.registered_items[itemname]
|
|
|
|
setup(function()
|
|
set_charge_stack(ItemStack())
|
|
set_discharge_stack(ItemStack())
|
|
mineunit:execute_on_joinplayer(player)
|
|
player:get_inventory():set_stack("main", 1, itemname)
|
|
end)
|
|
|
|
teardown(function()
|
|
mineunit:execute_on_leaveplayer(player)
|
|
end)
|
|
|
|
it("is registered", function()
|
|
assert.is_hashed(itemdef)
|
|
assert.is_function(itemdef.on_use)
|
|
assert.is_function(itemdef.on_refill)
|
|
assert.equals("technic_RE_charge", itemdef.wear_represents)
|
|
assert.is_number(itemdef.technic_max_charge)
|
|
assert.gt(itemdef.technic_max_charge, 0)
|
|
end)
|
|
|
|
it("new item can be used", function()
|
|
spy.on(itemdef, "on_use")
|
|
player:do_use({x=0, y=0, z=0})
|
|
assert.spy(itemdef.on_use).called(1)
|
|
end)
|
|
|
|
it("has zero charge", function()
|
|
local stack = player:get_wielded_item()
|
|
assert.is_ItemStack(stack)
|
|
assert.is_false(stack:is_empty())
|
|
assert.equals(0, technic.get_RE_charge(stack))
|
|
end)
|
|
|
|
it("can be charged", function()
|
|
-- Put item from player inventory to battery box src inventory
|
|
player:do_metadata_inventory_put(BB_Charge_POS, "src", 1)
|
|
|
|
-- Verify that item charge is empty and charge in battery box for 30 seconds
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
for i=0, 30 do
|
|
mineunit:execute_globalstep(1)
|
|
end
|
|
|
|
-- Take item from battery box and check charge / wear values
|
|
player:do_metadata_inventory_take(BB_Charge_POS, "src", 1)
|
|
assert.gt(itemdef.technic_max_charge, 0)
|
|
assert.equals(itemdef.technic_max_charge, technic.get_RE_charge(get_player_stack()))
|
|
end)
|
|
|
|
it("charge is used", function()
|
|
spy.on(itemdef, "on_use")
|
|
player:set_pos(vector.add(BB_Charge_POS, {x=0,y=1,z=0}))
|
|
player:do_use(BB_Charge_POS)
|
|
assert.spy(itemdef.on_use).called(1)
|
|
|
|
-- Check that item charge was actually used and is not zero
|
|
local charge = technic.get_RE_charge(get_player_stack())
|
|
assert.is_number(charge)
|
|
assert.gt(charge, 0)
|
|
assert.lt(charge, itemdef.technic_max_charge)
|
|
end)
|
|
|
|
end)
|
|
|
|
describe("technic_addons:chainsawmk3", function()
|
|
|
|
-- Not running technic_addons:chainsawmk3 tests, this tools is just example of
|
|
-- actually available mod where max_charge vs use ratio goes over safe limits.
|
|
if not RUN_TECHNIC_ADDONS_CHAINSAWMK3_TESTS then return end
|
|
|
|
local itemname = "technic_addons:chainsawmk3"
|
|
local itemdef = minetest.registered_items[itemname]
|
|
|
|
setup(function()
|
|
world.add_layout({
|
|
-- Some wood for chainsaw
|
|
{{{x=-10,y=0,z=-10},{x=10,y=10,z=10}}, "default:wood"},
|
|
})
|
|
set_charge_stack(ItemStack())
|
|
set_discharge_stack(ItemStack())
|
|
mineunit:execute_on_joinplayer(player)
|
|
set_player_stack(itemname)
|
|
end)
|
|
|
|
teardown(function()
|
|
mineunit:execute_on_leaveplayer(player)
|
|
end)
|
|
|
|
it("is registered", function()
|
|
assert.is_hashed(itemdef)
|
|
assert.is_function(itemdef.on_use)
|
|
assert.is_function(itemdef.on_refill)
|
|
assert.equals("technic_RE_charge", itemdef.wear_represents)
|
|
assert.is_number(itemdef.technic_max_charge)
|
|
assert.gt(itemdef.technic_max_charge, 0)
|
|
end)
|
|
|
|
it("new item can be used", function()
|
|
spy.on(itemdef, "on_use")
|
|
player:do_use({x=0, y=0, z=0})
|
|
assert.spy(itemdef.on_use).called(1)
|
|
end)
|
|
|
|
it("has zero charge", function()
|
|
local stack = player:get_wielded_item()
|
|
assert.is_ItemStack(stack)
|
|
assert.is_false(stack:is_empty())
|
|
assert.equals(0, technic.get_RE_charge(stack))
|
|
end)
|
|
|
|
it("can be charged", function()
|
|
-- Put item from player inventory to battery box src inventory
|
|
player:do_metadata_inventory_put(BB_Charge_POS, "src", 1)
|
|
|
|
-- Verify that item charge is empty and charge in battery box for 30 seconds
|
|
assert.equals(0, technic.get_RE_charge(get_charge_stack()))
|
|
for i=0, math.ceil(itemdef.technic_max_charge / 10000) do
|
|
mineunit:execute_globalstep(1)
|
|
end
|
|
|
|
-- Take item from battery box and check charge / wear values
|
|
player:do_metadata_inventory_take(BB_Charge_POS, "src", 1)
|
|
assert.gt(itemdef.technic_max_charge, 0)
|
|
assert.equals(itemdef.technic_max_charge, technic.get_RE_charge(get_player_stack()))
|
|
end)
|
|
|
|
it("charge is used", function()
|
|
spy.on(itemdef, "on_use")
|
|
player:set_pos({x=0,y=1,z=0})
|
|
player:do_use(player:get_pos())
|
|
assert.spy(itemdef.on_use).called(1)
|
|
|
|
-- Check that item charge was actually used and is not zero
|
|
local charge_used = itemdef.technic_max_charge - technic.get_RE_charge(get_player_stack())
|
|
local accurate_use = 21 * 21 * 11 * 10 -- Area times use per node
|
|
local acceptable_error = accurate_use * 0.0001
|
|
assert.gt(accurate_use + acceptable_error, charge_used)
|
|
assert.lt(accurate_use - acceptable_error, charge_used)
|
|
assert.equals(accurate_use, charge_used)
|
|
end)
|
|
|
|
end)
|
|
|
|
end)
|