mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-11-25 22:41:39 +02:00
Add player settings for corpse pings + tests.
This commit is contained in:
@@ -3,6 +3,18 @@ local Global = require 'utils.global'
|
|||||||
local Task = require 'utils.task'
|
local Task = require 'utils.task'
|
||||||
local Token = require 'utils.token'
|
local Token = require 'utils.token'
|
||||||
local Utils = require 'utils.core'
|
local Utils = require 'utils.core'
|
||||||
|
local Settings = require 'utils.redmew_settings'
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local ping_own_death_name = 'corpse_util.ping_own_death'
|
||||||
|
local ping_other_death_name = 'corpse_util.ping_other_death'
|
||||||
|
|
||||||
|
Public.ping_own_death_name = ping_own_death_name
|
||||||
|
Public.ping_other_death_name = ping_other_death_name
|
||||||
|
|
||||||
|
Settings.register(ping_own_death_name, Settings.types.boolean, true, 'corpse_util.ping_own_death')
|
||||||
|
Settings.register(ping_other_death_name, Settings.types.boolean, false, 'corpse_util.ping_other_death')
|
||||||
|
|
||||||
local player_corpses = {}
|
local player_corpses = {}
|
||||||
|
|
||||||
@@ -49,13 +61,26 @@ local function player_died(event)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
player.force.print({
|
if Settings.get(player_index, ping_own_death_name) then
|
||||||
'corpse_util.marked_tag',
|
player.print({
|
||||||
|
'corpse_util.own_corpse_location',
|
||||||
|
string.format('%.1f', position.x),
|
||||||
|
string.format('%.1f', position.y),
|
||||||
|
player.surface.name
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, other_player in pairs(player.force.players) do
|
||||||
|
if other_player ~= player and Settings.get(other_player.index, ping_other_death_name) then
|
||||||
|
other_player.print({
|
||||||
|
'corpse_util.other_corpse_location',
|
||||||
player.name,
|
player.name,
|
||||||
string.format('%.1f', position.x),
|
string.format('%.1f', position.x),
|
||||||
string.format('%.1f', position.y),
|
string.format('%.1f', position.y),
|
||||||
player.surface.name
|
player.surface.name
|
||||||
})
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
player_corpses[player_index * 0x100000000 + tick] = tag
|
player_corpses[player_index * 0x100000000 + tick] = tag
|
||||||
end
|
end
|
||||||
@@ -144,3 +169,11 @@ Event.add(defines.events.on_player_died, player_died)
|
|||||||
Event.add(defines.events.on_character_corpse_expired, corpse_expired)
|
Event.add(defines.events.on_character_corpse_expired, corpse_expired)
|
||||||
Event.add(defines.events.on_pre_player_mined_item, mined_entity)
|
Event.add(defines.events.on_pre_player_mined_item, mined_entity)
|
||||||
Event.add(defines.events.on_gui_opened, on_gui_opened)
|
Event.add(defines.events.on_gui_opened, on_gui_opened)
|
||||||
|
|
||||||
|
function Public.clear()
|
||||||
|
table.clear_table(player_corpses)
|
||||||
|
end
|
||||||
|
|
||||||
|
Public._player_died = player_died
|
||||||
|
|
||||||
|
return Public
|
||||||
|
|||||||
235
features/corpse_util_tests.lua
Normal file
235
features/corpse_util_tests.lua
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
local Declare = require 'utils.test.declare'
|
||||||
|
local EventFactory = require 'utils.test.event_factory'
|
||||||
|
local Assert = require 'utils.test.assert'
|
||||||
|
local Helper = require 'utils.test.helper'
|
||||||
|
local Settings = require 'utils.redmew_settings'
|
||||||
|
local CorpseUtil = require 'features.corpse_util'
|
||||||
|
|
||||||
|
local function test_teardown(context)
|
||||||
|
context:add_teardown(CorpseUtil.clear)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function declare_test(name, func)
|
||||||
|
local function test_func(context)
|
||||||
|
test_teardown(context)
|
||||||
|
func(context)
|
||||||
|
end
|
||||||
|
|
||||||
|
Declare.test(name, test_func)
|
||||||
|
end
|
||||||
|
|
||||||
|
Declare.module({'features', 'corpse_util'}, function()
|
||||||
|
local teardown
|
||||||
|
|
||||||
|
Declare.module_startup(function(context)
|
||||||
|
teardown = Helper.startup_test_surface(context)
|
||||||
|
|
||||||
|
-- wait for surface to be charted, needed before a tag can be created.
|
||||||
|
context:next(function()
|
||||||
|
local player = context.player
|
||||||
|
Helper.wait_for_chunk_to_be_charted(context, player.force, player.surface, {0, 0})
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
Declare.module_teardown(function()
|
||||||
|
teardown()
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function change_settings_for_test(context, key, value)
|
||||||
|
local player_index = context.player.index
|
||||||
|
|
||||||
|
local current_value = Settings.get(player_index, key)
|
||||||
|
Settings.set(player_index, key, value)
|
||||||
|
|
||||||
|
context:add_teardown(function()
|
||||||
|
Settings.set(player_index, key, current_value)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function fake_death(player)
|
||||||
|
local surface = player.surface
|
||||||
|
local position = player.position
|
||||||
|
|
||||||
|
local entity = surface.create_entity {
|
||||||
|
name = 'character-corpse',
|
||||||
|
position = position,
|
||||||
|
player_index = player.index
|
||||||
|
}
|
||||||
|
|
||||||
|
if not entity or not entity.valid then
|
||||||
|
error('no corpse')
|
||||||
|
end
|
||||||
|
|
||||||
|
return EventFactory.on_player_died(player.index)
|
||||||
|
end
|
||||||
|
|
||||||
|
declare_test('ping player corpse location when died', function(context)
|
||||||
|
-- Arrange.
|
||||||
|
local player = context.player
|
||||||
|
|
||||||
|
local actual_text
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, player, 'print', function(text)
|
||||||
|
actual_text = text
|
||||||
|
end)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, game, 'get_player', function()
|
||||||
|
return player
|
||||||
|
end)
|
||||||
|
|
||||||
|
local event = fake_death(player)
|
||||||
|
|
||||||
|
-- Act.
|
||||||
|
CorpseUtil._player_died(event)
|
||||||
|
|
||||||
|
-- Assert.
|
||||||
|
local expected = {'corpse_util.own_corpse_location', '0.0', '0.0', player.surface.name}
|
||||||
|
Assert.table_equal(expected, actual_text)
|
||||||
|
end)
|
||||||
|
|
||||||
|
declare_test('ping other player corpse location when other player died', function(context)
|
||||||
|
-- Arrange.
|
||||||
|
local player = context.player
|
||||||
|
local force = player.force
|
||||||
|
|
||||||
|
local actual_text
|
||||||
|
|
||||||
|
local second_player = {
|
||||||
|
index = 2,
|
||||||
|
valid = true,
|
||||||
|
name = 'second_player',
|
||||||
|
surface = player.surface,
|
||||||
|
force = force,
|
||||||
|
print = function()
|
||||||
|
end,
|
||||||
|
position = EventFactory.position({1, 1})
|
||||||
|
}
|
||||||
|
|
||||||
|
change_settings_for_test(context, CorpseUtil.ping_other_death_name, true)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, game, 'get_player', function(index)
|
||||||
|
if index == player.index then
|
||||||
|
return player
|
||||||
|
end
|
||||||
|
|
||||||
|
if index == second_player.index then
|
||||||
|
return second_player
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, force, 'players', {player, second_player})
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, player, 'print', function(text)
|
||||||
|
actual_text = text
|
||||||
|
end)
|
||||||
|
|
||||||
|
local event = fake_death(second_player)
|
||||||
|
|
||||||
|
-- Act.
|
||||||
|
CorpseUtil._player_died(event)
|
||||||
|
|
||||||
|
-- Assert.
|
||||||
|
local expected = {'corpse_util.other_corpse_location', second_player.name, '1.0', '1.0', player.surface.name}
|
||||||
|
Assert.table_equal(expected, actual_text)
|
||||||
|
end)
|
||||||
|
|
||||||
|
declare_test('do not ping player corpse location when died and setting disabled', function(context)
|
||||||
|
-- Arrange.
|
||||||
|
local player = context.player
|
||||||
|
change_settings_for_test(context, CorpseUtil.ping_own_death_name, false)
|
||||||
|
|
||||||
|
local actual_text
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, player, 'print', function(text)
|
||||||
|
actual_text = text
|
||||||
|
end)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, game, 'get_player', function()
|
||||||
|
return player
|
||||||
|
end)
|
||||||
|
|
||||||
|
local event = fake_death(player)
|
||||||
|
|
||||||
|
-- Act.
|
||||||
|
CorpseUtil._player_died(event)
|
||||||
|
|
||||||
|
-- Assert.
|
||||||
|
Assert.is_nil(actual_text)
|
||||||
|
end)
|
||||||
|
|
||||||
|
declare_test('do not ping other player corpse location when other player died and settings disabled',
|
||||||
|
function(context)
|
||||||
|
-- Arrange.
|
||||||
|
local player = context.player
|
||||||
|
local force = player.force
|
||||||
|
|
||||||
|
local actual_text
|
||||||
|
|
||||||
|
local second_player = {
|
||||||
|
index = 2,
|
||||||
|
valid = true,
|
||||||
|
name = 'second_player',
|
||||||
|
surface = player.surface,
|
||||||
|
force = force,
|
||||||
|
print = function()
|
||||||
|
end,
|
||||||
|
position = EventFactory.position({1, 1})
|
||||||
|
}
|
||||||
|
|
||||||
|
change_settings_for_test(context, CorpseUtil.ping_other_death_name, false)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, game, 'get_player', function(index)
|
||||||
|
if index == player.index then
|
||||||
|
return player
|
||||||
|
end
|
||||||
|
|
||||||
|
if index == second_player.index then
|
||||||
|
return second_player
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, force, 'players', {player, second_player})
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, player, 'print', function(text)
|
||||||
|
actual_text = text
|
||||||
|
end)
|
||||||
|
|
||||||
|
local event = fake_death(second_player)
|
||||||
|
|
||||||
|
-- Act.
|
||||||
|
CorpseUtil._player_died(event)
|
||||||
|
|
||||||
|
-- Assert.
|
||||||
|
Assert.is_nil(actual_text)
|
||||||
|
end)
|
||||||
|
|
||||||
|
declare_test('do not ping other player corpse location for self', function(context)
|
||||||
|
-- Arrange.
|
||||||
|
local player = context.player
|
||||||
|
local force = player.force
|
||||||
|
|
||||||
|
local actual_text
|
||||||
|
|
||||||
|
change_settings_for_test(context, CorpseUtil.ping_own_death_name, false)
|
||||||
|
change_settings_for_test(context, CorpseUtil.ping_other_death_name, true)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, game, 'get_player', function()
|
||||||
|
return player
|
||||||
|
end)
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, player, 'force', force)
|
||||||
|
Helper.modify_lua_object(context, force, 'players', {player})
|
||||||
|
|
||||||
|
Helper.modify_lua_object(context, player, 'print', function(text)
|
||||||
|
actual_text = text
|
||||||
|
end)
|
||||||
|
|
||||||
|
local event = fake_death(player)
|
||||||
|
|
||||||
|
-- Act.
|
||||||
|
CorpseUtil._player_died(event)
|
||||||
|
|
||||||
|
-- Assert.
|
||||||
|
Assert.is_nil(actual_text)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
@@ -179,4 +179,7 @@ instructions=Select a brush tile to replace [item=refined-concrete] and [item=re
|
|||||||
no_place_landfill=Coloured concrete can not be placed on landfill tiles.
|
no_place_landfill=Coloured concrete can not be placed on landfill tiles.
|
||||||
|
|
||||||
[corpse_util]
|
[corpse_util]
|
||||||
marked_tag=__1__'s corpse has been marked on the map at [gps=__2__,__3__,__4__]
|
ping_own_death=Ping the location when you die.
|
||||||
|
ping_other_death=Ping the location when other players die.
|
||||||
|
own_corpse_location=[color=red][Corpse][/color] Your corpse is located at [gps=__1__,__2__,__3__]
|
||||||
|
other_corpse_location=[Color=red][Corpse][/Color] __1__'s corpse is located at [gps=__2__,__3__,__4__]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
local table = require 'utils.table'
|
||||||
local error = error
|
local error = error
|
||||||
local concat = table.concat
|
local concat = table.concat
|
||||||
|
|
||||||
@@ -25,6 +26,28 @@ function Public.equal(a, b, optional_message)
|
|||||||
error(message, 2)
|
error(message, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Public.is_nil(value, optional_message)
|
||||||
|
if value == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local message = {tostring(value), ' was not nil'}
|
||||||
|
if optional_message then
|
||||||
|
message[#message + 1] = ' - '
|
||||||
|
message[#message + 1] = optional_message
|
||||||
|
end
|
||||||
|
|
||||||
|
message = concat(message)
|
||||||
|
error(message, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Public.table_equal(a, b)
|
||||||
|
-- Todo write own table equal
|
||||||
|
if not table.equals(a, b) then
|
||||||
|
error('tables not equal', 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Public.is_true(condition, optional_message)
|
function Public.is_true(condition, optional_message)
|
||||||
if not condition then
|
if not condition then
|
||||||
error(optional_message or 'condition was not true', 2)
|
error(optional_message or 'condition was not true', 2)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ local Public = {}
|
|||||||
Public.__index = Public
|
Public.__index = Public
|
||||||
|
|
||||||
function Public.new(player)
|
function Public.new(player)
|
||||||
return setmetatable({player = player, _steps = {}}, Public)
|
return setmetatable({player = player, _steps = {}, _teardowns = {}}, Public)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Public.timeout(self, delay, func)
|
function Public.timeout(self, delay, func)
|
||||||
@@ -15,4 +15,15 @@ function Public.next(self, func)
|
|||||||
return self:timeout(1, func)
|
return self:timeout(1, func)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Public.wait(self, delay)
|
||||||
|
return self:timeout(delay, function()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Public.add_teardown(self, func)
|
||||||
|
local teardowns = self._teardowns
|
||||||
|
teardowns[#teardowns + 1] = func
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
return Public
|
return Public
|
||||||
|
|||||||
@@ -57,18 +57,20 @@ function Public.on_player_deconstructed_area(player_index, surface, area, item)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Public.do_player_deconstruct_area(cursor, player, area, optional_skip_fog_of_war)
|
function Public.do_player_deconstruct_area(cursor, player, area, optional_skip_fog_of_war)
|
||||||
cursor.deconstruct_area(
|
cursor.deconstruct_area({
|
||||||
{
|
|
||||||
surface = player.surface,
|
surface = player.surface,
|
||||||
force = player.force,
|
force = player.force,
|
||||||
area = area,
|
area = area,
|
||||||
by_player = player,
|
by_player = player,
|
||||||
skip_fog_of_war = optional_skip_fog_of_war
|
skip_fog_of_war = optional_skip_fog_of_war
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
local event = Public.on_player_deconstructed_area(player.index, player.surface, area, cursor.name)
|
local event = Public.on_player_deconstructed_area(player.index, player.surface, area, cursor.name)
|
||||||
Public.raise(event)
|
Public.raise(event)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Public.on_player_died(player_index)
|
||||||
|
return {name = defines.events.on_player_died, tick = game.tick, player_index = player_index, cause = nils}
|
||||||
|
end
|
||||||
|
|
||||||
return Public
|
return Public
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ local Public = {}
|
|||||||
|
|
||||||
local surface_count = 0
|
local surface_count = 0
|
||||||
|
|
||||||
Global.register(
|
Global.register({surface_count = surface_count}, function(tbl)
|
||||||
{surface_count = surface_count},
|
|
||||||
function(tbl)
|
|
||||||
surface_count = tbl.surface_count
|
surface_count = tbl.surface_count
|
||||||
end
|
end)
|
||||||
)
|
|
||||||
|
|
||||||
local function get_surface_name()
|
local function get_surface_name()
|
||||||
surface_count = surface_count + 1
|
surface_count = surface_count + 1
|
||||||
@@ -17,62 +14,21 @@ local function get_surface_name()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local autoplace_settings = {
|
local autoplace_settings = {
|
||||||
tile = {
|
tile = {treat_missing_as_default = false, settings = {['grass-1'] = {frequency = 1, size = 1, richness = 1}}}
|
||||||
treat_missing_as_default = false,
|
|
||||||
settings = {
|
|
||||||
['grass-1'] = {frequency = 1, size = 1, richness = 1}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local autoplace_controls = {
|
local autoplace_controls = {
|
||||||
trees = {
|
trees = {frequency = 1, richness = 1, size = 0},
|
||||||
frequency = 1,
|
['enemy-base'] = {frequency = 1, richness = 1, size = 0},
|
||||||
richness = 1,
|
coal = {frequency = 1, richness = 1, size = 0},
|
||||||
size = 0
|
['copper-ore'] = {frequency = 1, richness = 1, size = 0},
|
||||||
},
|
['crude-oil'] = {frequency = 1, richness = 1, size = 0},
|
||||||
['enemy-base'] = {
|
['iron-ore'] = {frequency = 1, richness = 1, size = 0},
|
||||||
frequency = 1,
|
stone = {frequency = 1, richness = 1, size = 0},
|
||||||
richness = 1,
|
['uranium-ore'] = {frequency = 1, richness = 1, size = 0}
|
||||||
size = 0
|
|
||||||
},
|
|
||||||
coal = {
|
|
||||||
frequency = 1,
|
|
||||||
richness = 1,
|
|
||||||
size = 0
|
|
||||||
},
|
|
||||||
['copper-ore'] = {
|
|
||||||
frequency = 1,
|
|
||||||
richness = 1,
|
|
||||||
size = 0
|
|
||||||
},
|
|
||||||
['crude-oil'] = {
|
|
||||||
frequency = 1,
|
|
||||||
richness = 1,
|
|
||||||
size = 0
|
|
||||||
},
|
|
||||||
['iron-ore'] = {
|
|
||||||
frequency = 1,
|
|
||||||
richness = 1,
|
|
||||||
size = 0
|
|
||||||
},
|
|
||||||
stone = {
|
|
||||||
frequency = 1,
|
|
||||||
richness = 1,
|
|
||||||
size = 0
|
|
||||||
},
|
|
||||||
['uranium-ore'] = {
|
|
||||||
frequency = 1,
|
|
||||||
richness = 1,
|
|
||||||
size = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local cliff_settings = {
|
local cliff_settings = {cliff_elevation_0 = 1024, cliff_elevation_interval = 10, name = 'cliff'}
|
||||||
cliff_elevation_0 = 1024,
|
|
||||||
cliff_elevation_interval = 10,
|
|
||||||
name = 'cliff'
|
|
||||||
}
|
|
||||||
|
|
||||||
function Public.startup_test_surface(context, options)
|
function Public.startup_test_surface(context, options)
|
||||||
options = options or {}
|
options = options or {}
|
||||||
@@ -84,23 +40,19 @@ function Public.startup_test_surface(context, options)
|
|||||||
local old_position = player.position
|
local old_position = player.position
|
||||||
local old_character = player.character
|
local old_character = player.character
|
||||||
|
|
||||||
local surface =
|
local surface = game.create_surface(name, {
|
||||||
game.create_surface(
|
|
||||||
name,
|
|
||||||
{
|
|
||||||
width = area.x or area[1],
|
width = area.x or area[1],
|
||||||
height = area.y or area[2],
|
height = area.y or area[2],
|
||||||
autoplace_settings = autoplace_settings,
|
autoplace_settings = autoplace_settings,
|
||||||
autoplace_controls = autoplace_controls,
|
autoplace_controls = autoplace_controls,
|
||||||
cliff_settings = cliff_settings
|
cliff_settings = cliff_settings
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
surface.request_to_generate_chunks({0, 0}, 32)
|
surface.request_to_generate_chunks({0, 0}, 32)
|
||||||
surface.force_generate_chunk_requests()
|
surface.force_generate_chunk_requests()
|
||||||
|
player.force.chart_all(surface)
|
||||||
|
|
||||||
context:next(
|
context:next(function()
|
||||||
function()
|
|
||||||
for k, v in pairs(surface.find_entities()) do
|
for k, v in pairs(surface.find_entities()) do
|
||||||
v.destroy()
|
v.destroy()
|
||||||
end
|
end
|
||||||
@@ -110,8 +62,7 @@ function Public.startup_test_surface(context, options)
|
|||||||
player.character = nil
|
player.character = nil
|
||||||
player.teleport({0, 0}, surface)
|
player.teleport({0, 0}, surface)
|
||||||
player.create_character()
|
player.create_character()
|
||||||
end
|
end)
|
||||||
)
|
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
player.character = nil
|
player.character = nil
|
||||||
@@ -125,4 +76,26 @@ function Public.startup_test_surface(context, options)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Public.wait_for_chunk_to_be_charted(context, force, surface, chunk_position, next)
|
||||||
|
if not force.is_chunk_charted(surface, chunk_position) then
|
||||||
|
context:next(function()
|
||||||
|
Public.wait_for_chunk_to_be_charted(context, force, surface, chunk_position)
|
||||||
|
end)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if next then
|
||||||
|
context:next(next)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Public.modify_lua_object(context, object, key, value)
|
||||||
|
local old_value = object[key]
|
||||||
|
rawset(object, key, value)
|
||||||
|
|
||||||
|
context:add_teardown(function()
|
||||||
|
rawset(object, key, old_value)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
return Public
|
return Public
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ local pcall = pcall
|
|||||||
|
|
||||||
local Public = {}
|
local Public = {}
|
||||||
|
|
||||||
Public.events = {
|
Public.events = {tests_run_finished = Event.generate_event_name('test_run_finished')}
|
||||||
tests_run_finished = Event.generate_event_name('test_run_finished')
|
|
||||||
}
|
|
||||||
|
|
||||||
local run_runnables_token
|
local run_runnables_token
|
||||||
|
|
||||||
@@ -67,6 +65,10 @@ local function print_hook_error(hook)
|
|||||||
hook.context.player.print(table.concat {'Failed ', hook.name, " hook -':", tostring(hook.error)}, {r = 1})
|
hook.context.player.print(table.concat {'Failed ', hook.name, " hook -':", tostring(hook.error)}, {r = 1})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function print_teardown_error(context, name, error_message)
|
||||||
|
context.player.print(table.concat {'Failed ', name, " teardown -':", error_message}, {r = 1})
|
||||||
|
end
|
||||||
|
|
||||||
local function record_hook_error_in_module(hook)
|
local function record_hook_error_in_module(hook)
|
||||||
if hook.name == 'startup' then
|
if hook.name == 'startup' then
|
||||||
hook.module.startup_error = hook.error
|
hook.module.startup_error = hook.error
|
||||||
@@ -86,6 +88,32 @@ local function do_termination(data)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function run_teardown(teardown, errors)
|
||||||
|
local success, error_message = pcall(teardown)
|
||||||
|
|
||||||
|
if not success then
|
||||||
|
errors[#errors + 1] = error_message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function do_teardowns(context, name)
|
||||||
|
local teardowns = context._teardowns
|
||||||
|
local errors = {}
|
||||||
|
|
||||||
|
for i = 1, #teardowns do
|
||||||
|
run_teardown(teardowns[i], errors)
|
||||||
|
end
|
||||||
|
|
||||||
|
if #errors > 0 then
|
||||||
|
local error_message = table.concat(errors, '\n')
|
||||||
|
print_teardown_error(context, name, error_message)
|
||||||
|
|
||||||
|
return error_message
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
local function run_hook(hook)
|
local function run_hook(hook)
|
||||||
local context = hook.context
|
local context = hook.context
|
||||||
local steps = context._steps
|
local steps = context._steps
|
||||||
@@ -104,14 +132,22 @@ local function run_hook(hook)
|
|||||||
hook.error = return_value
|
hook.error = return_value
|
||||||
print_hook_error(hook)
|
print_hook_error(hook)
|
||||||
record_hook_error_in_module(hook)
|
record_hook_error_in_module(hook)
|
||||||
|
do_teardowns(context, hook.name)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if current_step == #steps then
|
if current_step ~= #steps then
|
||||||
return true
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
local error_message = do_teardowns(context, hook.name)
|
||||||
|
if error_message then
|
||||||
|
hook.error = error_message
|
||||||
|
record_hook_error_in_module(hook)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function do_hook(hook, data)
|
local function do_hook(hook, data)
|
||||||
@@ -152,18 +188,26 @@ local function run_test(test)
|
|||||||
print_error(context.player, test.name, return_value)
|
print_error(context.player, test.name, return_value)
|
||||||
test.passed = false
|
test.passed = false
|
||||||
test.error = return_value
|
test.error = return_value
|
||||||
|
do_teardowns(context, test.name)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if current_step ~= #steps then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local error_message = do_teardowns(context, test.name)
|
||||||
|
if error_message then
|
||||||
|
test.passed = false
|
||||||
|
test.error = error_message
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if current_step == #steps then
|
|
||||||
print_success(context.player, test.name)
|
print_success(context.player, test.name)
|
||||||
test.passed = true
|
test.passed = true
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local function do_test(test, data)
|
local function do_test(test, data)
|
||||||
local success = run_test(test)
|
local success = run_test(test)
|
||||||
|
|
||||||
@@ -219,16 +263,14 @@ end
|
|||||||
|
|
||||||
local function run(runnables, player, options)
|
local function run(runnables, player, options)
|
||||||
options = validate_options(options)
|
options = validate_options(options)
|
||||||
run_runnables(
|
run_runnables({
|
||||||
{
|
|
||||||
runnables = runnables,
|
runnables = runnables,
|
||||||
player = player,
|
player = player,
|
||||||
index = 1,
|
index = 1,
|
||||||
count = 0,
|
count = 0,
|
||||||
fail_count = 0,
|
fail_count = 0,
|
||||||
stop_on_first_error = options.stop_on_first_error
|
stop_on_first_error = options.stop_on_first_error
|
||||||
}
|
})
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Public.run_module(module, player, options)
|
function Public.run_module(module, player, options)
|
||||||
|
|||||||
Reference in New Issue
Block a user