Skip to content

Commit 1196573

Browse files
committed
Accurate machine output assertions
1 parent 9762ab9 commit 1196573

File tree

3 files changed

+131
-86
lines changed

3 files changed

+131
-86
lines changed

technic/spec/fixtures/technic.lua

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,40 @@ fixture("mesecons")
1919
fixture("digilines")
2020
fixture("pipeworks")
2121
fixture("technic_worldgen")
22+
23+
spec_utility = {}
24+
25+
-- Calculate expected amount of items produced by base machines within completed network cycles
26+
function spec_utility.base_machine_output_calculator(RUN_CYCLES)
27+
return function (machine_speed, recipe_time, output_amount)
28+
-- Total amount not necessarily divisible by per cycle output
29+
local partial = math.floor(RUN_CYCLES * (output_amount * machine_speed / recipe_time))
30+
-- Maximum amount divisible by per cycle output (amount clamped to full cycles)
31+
return math.floor(partial / output_amount) * output_amount
32+
end
33+
end
34+
35+
-- Helper function to execute multiple globalsteps
36+
function spec_utility.run_globalsteps(times, dtime)
37+
-- By default, run once with dtime = 1 second instead of every 0.1 seconds
38+
for i=1, times or 1 do
39+
mineunit:execute_globalstep(dtime or 1)
40+
end
41+
end
42+
43+
-- Helper function to place itemstack into machine inventory, default listname = src
44+
function spec_utility.place_itemstack(pos, itemstack, listname)
45+
local meta = core.get_meta(pos)
46+
local inv = meta:get_inventory()
47+
if not inv:room_for_item(listname or "src", itemstack) then
48+
inv:set_stack(listname or "src", 1, ItemStack(nil))
49+
end
50+
inv:add_item(listname or "src", itemstack)
51+
end
52+
53+
-- Get itemstack in inventory for inspection without removing it, default listname = dst
54+
function spec_utility.get_itemstack(pos, listname, index)
55+
local meta = core.get_meta(pos)
56+
local inv = meta:get_inventory()
57+
return inv:get_stack(listname or "dst", index or 1)
58+
end

technic/spec/hv_network_spec.lua

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ describe("HV machine network", function()
1818
mineunit:execute_globalstep(60)
1919
world.set_default_node("air")
2020

21+
-- Execute multiple globalsteps: run_network(times = 1, dtime = 1)
22+
local run_network = spec_utility.run_globalsteps
23+
24+
-- Place itemstack into inventory slot 1: place_itemstack(pos, itemstack, listname = "src")
25+
local place_itemstack = spec_utility.place_itemstack
26+
27+
-- Get itemstack for inspection without removing it: get_itemstack(pos, listname = "dst", index = 1)
28+
local get_itemstack = spec_utility.get_itemstack
29+
30+
-- Execute this many 1 second glopbalstep cycles for each RE machine
31+
local RUN_CYCLES = 4
32+
-- Function to calculate amount of items produced by base machines within completed network cycles
33+
-- usage: base_machine_expected_amount(machine_speed, recipe_time, output_amount)
34+
local base_machine_expected_amount = spec_utility.base_machine_output_calculator(RUN_CYCLES)
35+
2136
local machines = {
2237
"technic:hv_generator",
2338
"technic:hv_battery_box0",
@@ -29,45 +44,23 @@ describe("HV machine network", function()
2944
"technic:hv_solar_array",
3045
}
3146

47+
local function reset_machine(pos)
48+
world.place_node(pos, machines[pos.x], player)
49+
end
50+
3251
world.clear()
3352
world.place_node({x=0,y=51,z=0}, "technic:switching_station", player)
3453
for x = 0, 10 do
3554
world.place_node({x=x,y=50,z=0}, "technic:hv_cable", player)
3655
end
37-
for x, name in ipairs(machines) do
38-
world.place_node({x=x,y=51,z=0}, name, player)
39-
end
40-
41-
-- Helper function to execute netowork
42-
local function run_network(times)
43-
times = times or 1
44-
for i=1, times do
45-
-- Globalstep every second instead of every 0.1 seconds
46-
mineunit:execute_globalstep(1)
47-
end
48-
end
49-
50-
-- Helper function to place itemstack into machine inventory
51-
local function place_itemstack(pos, itemstack, listname)
52-
local meta = minetest.get_meta(pos)
53-
local inv = meta:get_inventory()
54-
if not inv:room_for_item(listname or "src", itemstack) then
55-
inv:set_stack(listname or "src", 1, ItemStack(nil))
56-
end
57-
inv:add_item(listname or "src", itemstack)
58-
end
59-
60-
-- Get itemstack in inventory for inspection without removing it
61-
local function get_itemstack(pos, listname, index)
62-
local meta = minetest.get_meta(pos)
63-
local inv = meta:get_inventory()
64-
return inv:get_stack(listname or "dst", index or 1)
56+
for x = 1, #machines do
57+
reset_machine({x=x,y=51,z=0})
6558
end
6659

6760
it("executes network", function()
6861
spy.on(technic, "network_run")
69-
run_network(60)
70-
assert.spy(technic.network_run).called(60)
62+
run_network(4)
63+
assert.spy(technic.network_run).called(4)
7164
local id = technic.pos2network({x=0,y=50,z=0})
7265
assert.not_nil(technic.networks[id])
7366
assert.gt(technic.networks[id].supply, 0)
@@ -95,48 +88,61 @@ describe("HV machine network", function()
9588

9689
it("smelts ores", function()
9790
local machine_pos = {x=3,y=51,z=0}
91+
reset_machine(machine_pos)
9892
place_itemstack(machine_pos, "technic:lead_lump 99")
99-
run_network(50)
100-
-- Check results, at least 10 items processed and results in correct stuff
93+
-- Extra cycle: powers up the machine but wont produce anything
94+
run_network(RUN_CYCLES + 1)
95+
-- Check results
10196
local stack = get_itemstack(machine_pos)
102-
assert.gt(stack:get_count(), 9)
10397
assert.equals(stack:get_name(), "technic:lead_ingot")
98+
-- Expected amount of items produced: machine speed, recipe time, items per cycle
99+
assert.equals(base_machine_expected_amount(12, 3, 1), stack:get_count())
104100
end)
105101

106102
it("grinds ores", function()
107103
local machine_pos = {x=4,y=51,z=0}
104+
reset_machine(machine_pos)
108105
place_itemstack(machine_pos, "technic:lead_lump 99")
109-
run_network(50)
110-
-- Check results, at least 10 items processed and results in correct stuff
106+
-- Extra cycle: powers up the machine but wont produce anything
107+
run_network(RUN_CYCLES + 1)
108+
-- Check results
111109
local stack = get_itemstack(machine_pos)
112-
assert.gt(stack:get_count(), 9)
113110
assert.equals(stack:get_name(), "technic:lead_dust")
111+
-- Expected amount of items produced: machine speed, recipe time, items per cycle
112+
assert.equals(base_machine_expected_amount(5, 3, 2), stack:get_count())
114113
end)
115114

116115
it("accepts battery upgrades", function()
117116
local machine_pos = {x=4,y=51,z=0}
118-
mineunit:clear_InvRef(machine_pos)
117+
reset_machine(machine_pos)
119118
place_itemstack(machine_pos, "technic:battery 1", "upgrade1")
120119
place_itemstack(machine_pos, "technic:battery 1", "upgrade2")
121120
place_itemstack(machine_pos, "technic:lead_lump 99")
122-
run_network(6)
123-
-- Check results, at least 2 items processed and results in correct stuff
121+
-- Extra cycle: powers up the machine but wont produce anything
122+
run_network(RUN_CYCLES + 1)
123+
-- Check results
124124
local stack = get_itemstack(machine_pos)
125-
assert.gt(stack:get_count(), 2)
126125
assert.equals(stack:get_name(), "technic:lead_dust")
126+
-- Expected amount of items produced: machine speed, recipe time, items per cycle
127+
assert.equals(base_machine_expected_amount(5, 3, 2), stack:get_count())
127128
end)
128129

129130
it("accepts control logic upgrades", function()
130131
local machine_pos = {x=4,y=51,z=0}
131-
mineunit:clear_InvRef(machine_pos)
132+
reset_machine(machine_pos)
132133
place_itemstack(machine_pos, "technic:control_logic_unit 1", "upgrade1")
133134
place_itemstack(machine_pos, "technic:control_logic_unit 1", "upgrade2")
134135
place_itemstack(machine_pos, "technic:lead_lump 99")
135-
run_network(6)
136-
-- Check results, at least 2 items processed and results in correct stuff
136+
-- Extra cycle: powers up the machine but wont produce anything
137+
run_network(RUN_CYCLES + 1)
138+
-- Check results
137139
local stack = get_itemstack(machine_pos)
138-
assert.gt(stack:get_count(), 1)
139140
assert.equals(stack:get_name(), "technic:lead_dust")
141+
-- Expected amount of items produced: machine speed, recipe time, items per cycle
142+
-- Minus items sent away by CLUs: single item per cycle except first cycle which only produces
143+
local expected_amount = base_machine_expected_amount(5, 3, 2) - RUN_CYCLES + 1
144+
assert.equals(expected_amount, stack:get_count())
145+
-- Pipeworks isn't loaded and tubes are handled with no-op functions, sent items are lost
140146
end)
141147

142148
end)

technic/spec/lv_network_spec.lua

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ describe("LV machine network", function()
1818
mineunit:execute_globalstep(60)
1919
world.set_default_node("air")
2020

21+
-- Execute multiple globalsteps: run_network(times = 1, dtime = 1)
22+
local run_network = spec_utility.run_globalsteps
23+
24+
-- Place itemstack into inventory slot 1: place_itemstack(pos, itemstack, listname = "src")
25+
local place_itemstack = spec_utility.place_itemstack
26+
27+
-- Get itemstack for inspection without removing it: get_itemstack(pos, listname = "dst", index = 1)
28+
local get_itemstack = spec_utility.get_itemstack
29+
30+
-- Execute this many 1 second glopbalstep cycles for each RE machine
31+
local RUN_CYCLES = 4
32+
-- Function to calculate amount of items produced by base machines within completed network cycles
33+
-- usage: base_machine_expected_amount(machine_speed, recipe_time, output_amount)
34+
local base_machine_expected_amount = spec_utility.base_machine_output_calculator(RUN_CYCLES)
35+
2136
local machines = {
2237
"technic:lv_battery_box0",
2338
"technic:lv_electric_furnace",
@@ -34,21 +49,25 @@ describe("LV machine network", function()
3449
"technic:lv_solar_array",
3550
}
3651

52+
local function reset_machine(pos)
53+
world.place_node(pos, machines[pos.x], player)
54+
end
55+
3756
world.clear()
3857
world.place_node({x=0,y=51,z=0}, "technic:switching_station", player)
3958
for x = 0, 15 do
4059
world.place_node({x=x,y=50,z=0}, "technic:lv_cable", player)
4160
end
4261
for x, name in ipairs(machines) do
43-
world.place_node({x=x,y=51,z=0}, name, player)
62+
reset_machine({x=x,y=51,z=0})
4463
end
4564

4665
-- Helper to destroy nodes in test world returning list of removed nodes indexed by coordinates
4766
local function remove_nodes(nodes)
4867
local removed = {}
4968
for x = 0, 15 do
5069
local pos = {x=x,y=51,z=0}
51-
local node = minetest.get_node(pos)
70+
local node = core.get_node(pos)
5271
if nodes[node.name] then
5372
removed[pos] = node
5473
world.remove_node(pos)
@@ -64,36 +83,10 @@ describe("LV machine network", function()
6483
end
6584
end
6685

67-
-- Helper function to execute netowork
68-
local function run_network(times)
69-
times = times or 1
70-
for i=1, times do
71-
-- Globalstep every second instead of every 0.1 seconds
72-
mineunit:execute_globalstep(1)
73-
end
74-
end
75-
76-
-- Helper function to place itemstack into machine inventory
77-
local function place_itemstack(pos, itemstack, listname)
78-
local meta = minetest.get_meta(pos)
79-
local inv = meta:get_inventory()
80-
if not inv:room_for_item(listname or "src", itemstack) then
81-
inv:set_stack(listname or "src", 1, ItemStack(nil))
82-
end
83-
inv:add_item(listname or "src", itemstack)
84-
end
85-
86-
-- Get itemstack in inventory for inspection without removing it
87-
local function get_itemstack(pos, listname, index)
88-
local meta = minetest.get_meta(pos)
89-
local inv = meta:get_inventory()
90-
return inv:get_stack(listname or "dst", index or 1)
91-
end
92-
9386
it("executes network", function()
9487
spy.on(technic, "network_run")
95-
run_network(60)
96-
assert.spy(technic.network_run).called(60)
88+
run_network(4)
89+
assert.spy(technic.network_run).called(4)
9790
local id = technic.pos2network({x=0,y=50,z=0})
9891
assert.not_nil(technic.networks[id])
9992
assert.gt(technic.networks[id].supply, 0)
@@ -121,32 +114,41 @@ describe("LV machine network", function()
121114

122115
it("smelts ores", function()
123116
local machine_pos = {x=2,y=51,z=0}
117+
reset_machine(machine_pos)
124118
place_itemstack(machine_pos, "technic:lead_lump 99")
125-
run_network(60)
126-
-- Check results, at least 10 items processed and results in correct stuff
119+
-- Extra cycle: powers up the machine but wont produce anything
120+
run_network(RUN_CYCLES + 1)
121+
-- Check results
127122
local stack = get_itemstack(machine_pos)
128-
assert.gt(stack:get_count(), 10)
129123
assert.equals(stack:get_name(), "technic:lead_ingot")
124+
-- Expected amount of items produced: machine speed, recipe time, items per cycle
125+
assert.equals(base_machine_expected_amount(2, 3, 1), stack:get_count())
130126
end)
131127

132128
it("grinds ores", function()
133129
local machine_pos = {x=4,y=51,z=0}
130+
reset_machine(machine_pos)
134131
place_itemstack(machine_pos, "technic:lead_lump 99")
135-
run_network(60)
136-
-- Check results, at least 10 items processed and results in correct stuff
132+
-- Extra cycle: powers up the machine but wont produce anything
133+
run_network(RUN_CYCLES + 1)
134+
-- Check results
137135
local stack = get_itemstack(machine_pos)
138-
assert.gt(stack:get_count(), 10)
139136
assert.equals(stack:get_name(), "technic:lead_dust")
137+
-- Expected amount of items produced: machine speed, recipe time, items per cycle
138+
assert.equals(base_machine_expected_amount(1, 3, 2), stack:get_count())
140139
end)
141140

142141
it("comperess sand", function()
143142
local machine_pos = {x=6,y=51,z=0}
143+
reset_machine(machine_pos)
144144
place_itemstack(machine_pos, "default:sand 99")
145-
run_network(60)
146-
-- Check results, at least 10 items processed and results in correct stuff
145+
-- Extra cycle: powers up the machine but wont produce anything
146+
run_network(RUN_CYCLES + 1)
147+
-- Check results
147148
local stack = get_itemstack(machine_pos)
148-
assert.gt(stack:get_count(), 10)
149149
assert.equals(stack:get_name(), "default:sandstone")
150+
-- Expected amount of items produced: machine speed, recipe time, items per cycle
151+
assert.equals(base_machine_expected_amount(1, 4, 1), stack:get_count())
150152
end)
151153

152154
it("cuts power when generators disappear", function()
@@ -163,15 +165,15 @@ describe("LV machine network", function()
163165
}
164166
local restore = remove_nodes(generators)
165167

166-
-- Verify that network power is down immediately
168+
-- Verify that network gets immediately powered down
167169
local net = technic.networks[id]
168-
run_network(1)
170+
run_network()
169171
assert.equal(net.supply, 0)
170172

171173
-- Get current battery charge for network and execute few more cycles
172174
local battery_charge = net.battery_charge
173175
assert.gt(net.battery_charge, 1000)
174-
run_network(60)
176+
run_network(RUN_CYCLES)
175177

176178
-- Verify that significant battery charge was used and network still does not generate energy
177179
assert.lt(net.battery_charge, battery_charge / 2)

0 commit comments

Comments
 (0)