unit test update
This commit is contained in:
@@ -32,47 +32,79 @@
|
||||
/// Intended to be used in the manner of `TEST_FOCUS(/datum/unit_test/math)`
|
||||
#define TEST_FOCUS(test_path) ##test_path { focus = TRUE; }
|
||||
|
||||
/// Constants indicating unit test completion status
|
||||
#define UNIT_TEST_PASSED 0
|
||||
#define UNIT_TEST_FAILED 1
|
||||
#define UNIT_TEST_SKIPPED 2
|
||||
|
||||
#define TEST_DEFAULT 1
|
||||
#define TEST_DEL_WORLD INFINITY
|
||||
|
||||
/// A trait source when adding traits through unit tests
|
||||
#define TRAIT_SOURCE_UNIT_TESTS "unit_tests"
|
||||
|
||||
#include "anchored_mobs.dm"
|
||||
#include "bespoke_id.dm"
|
||||
#include "binary_insert.dm"
|
||||
// #include "bloody_footprints.dm"
|
||||
// #include "breath.dm"
|
||||
// #include "card_mismatch.dm"
|
||||
#include "chain_pull_through_space.dm"
|
||||
// #include "combat.dm"
|
||||
#include "component_tests.dm"
|
||||
// #include "connect_loc.dm"
|
||||
// #include "confusion.dm"
|
||||
// #include "crayons.dm"
|
||||
// #include "create_and_destroy.dm"
|
||||
// #include "designs.dm"
|
||||
// #include "dynamic_ruleset_sanity.dm"
|
||||
// #include "egg_glands.dm"
|
||||
// #include "emoting.dm"
|
||||
// #include "food_edibility_check.dm"
|
||||
// #include "greyscale_config.dm"
|
||||
// #include "heretic_knowledge.dm"
|
||||
// #include "holidays.dm"
|
||||
#include "initialize_sanity.dm"
|
||||
// #include "hydroponics_harvest.dm"
|
||||
// #include "keybinding_init.dm"
|
||||
#include "machine_disassembly.dm"
|
||||
#include "medical_wounds.dm"
|
||||
#include "merge_type.dm"
|
||||
// #include "metabolizing.dm"
|
||||
// #include "ntnetwork_tests.dm"
|
||||
// #include "outfit_sanity.dm"
|
||||
// #include "pills.dm"
|
||||
// #include "plantgrowth_tests.dm"
|
||||
// #include "projectiles.dm"
|
||||
// #include "rcd.dm"
|
||||
#include "reagent_id_typos.dm"
|
||||
// #include "reagent_mod_expose.dm"
|
||||
// #include "reagent_mod_procs.dm"
|
||||
#include "reagent_recipe_collisions.dm"
|
||||
#include "resist.dm"
|
||||
// #include "say.dm"
|
||||
#include "say.dm"
|
||||
// #include "security_officer_distribution.dm"
|
||||
// #include "serving_tray.dm"
|
||||
// #include "siunit.dm"
|
||||
#include "spawn_humans.dm"
|
||||
#include "spawn_mobs.dm"
|
||||
// #include "species_whitelists.dm"
|
||||
// #include "stomach.dm"
|
||||
// #include "strippable.dm"
|
||||
#include "subsystem_init.dm"
|
||||
#include "surgeries.dm"
|
||||
#include "teleporters.dm"
|
||||
#include "tgui_create_message.dm"
|
||||
#include "timer_sanity.dm"
|
||||
#include "unit_test.dm"
|
||||
// #include "wizard.dm"
|
||||
|
||||
/// CIT TESTS
|
||||
#include "character_saving.dm"
|
||||
|
||||
#ifdef REFERENCE_TRACKING //Don't try and parse this file if ref tracking isn't turned on. IE: don't parse ref tracking please mr linter
|
||||
#include "find_reference_sanity.dm"
|
||||
#endif
|
||||
|
||||
#undef TEST_ASSERT
|
||||
#undef TEST_ASSERT_EQUAL
|
||||
#undef TEST_ASSERT_NOTEQUAL
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/unit_test/chain_pull_through_space
|
||||
var/turf/open/space/space_tile
|
||||
var/turf/claimed_tile
|
||||
var/claimed_tile
|
||||
var/mob/living/carbon/human/alice
|
||||
var/mob/living/carbon/human/bob
|
||||
var/mob/living/carbon/human/charlie
|
||||
@@ -9,25 +9,25 @@
|
||||
..()
|
||||
|
||||
// Create a space tile that goes to another z-level
|
||||
claimed_tile = run_loc_bottom_left
|
||||
claimed_tile = run_loc_floor_bottom_left.type
|
||||
|
||||
space_tile = new(locate(run_loc_bottom_left.x, run_loc_bottom_left.y, run_loc_bottom_left.z))
|
||||
space_tile = new(locate(run_loc_floor_bottom_left.x, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
|
||||
space_tile.destination_x = 100
|
||||
space_tile.destination_y = 100
|
||||
space_tile.destination_z = 5
|
||||
|
||||
// Create our list of humans, all adjacent to one another
|
||||
alice = new(locate(run_loc_bottom_left.x + 2, run_loc_bottom_left.y, run_loc_bottom_left.z))
|
||||
alice = new(locate(run_loc_floor_bottom_left.x + 2, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
|
||||
alice.name = "Alice"
|
||||
|
||||
bob = new(locate(run_loc_bottom_left.x + 3, run_loc_bottom_left.y, run_loc_bottom_left.z))
|
||||
bob = new(locate(run_loc_floor_bottom_left.x + 3, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
|
||||
bob.name = "Bob"
|
||||
|
||||
charlie = new(locate(run_loc_bottom_left.x + 4, run_loc_bottom_left.y, run_loc_bottom_left.z))
|
||||
charlie = new(locate(run_loc_floor_bottom_left.x + 4, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
|
||||
charlie.name = "Charlie"
|
||||
|
||||
/datum/unit_test/chain_pull_through_space/Destroy()
|
||||
space_tile.copyTurf(claimed_tile)
|
||||
space_tile.ChangeTurf(claimed_tile)
|
||||
qdel(alice)
|
||||
qdel(bob)
|
||||
qdel(charlie)
|
||||
@@ -40,14 +40,14 @@
|
||||
bob.start_pulling(charlie)
|
||||
|
||||
// Walk normally to the left, make sure we're still a chain
|
||||
alice.Move(locate(run_loc_bottom_left.x + 1, run_loc_bottom_left.y, run_loc_bottom_left.z))
|
||||
if (bob.x != run_loc_bottom_left.x + 2)
|
||||
alice.Move(locate(run_loc_floor_bottom_left.x + 1, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
|
||||
if (bob.x != run_loc_floor_bottom_left.x + 2)
|
||||
return Fail("During normal move, Bob was not at the correct x ([bob.x])")
|
||||
if (charlie.x != run_loc_bottom_left.x + 3)
|
||||
if (charlie.x != run_loc_floor_bottom_left.x + 3)
|
||||
return Fail("During normal move, Charlie was not at the correct x ([charlie.x])")
|
||||
|
||||
// We're going through the space turf now that should teleport us
|
||||
alice.Move(run_loc_bottom_left)
|
||||
alice.Move(run_loc_floor_bottom_left)
|
||||
if (alice.z != space_tile.destination_z)
|
||||
return Fail("Alice did not teleport to the destination z-level. Current location: ([alice.x], [alice.y], [alice.z])")
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
///Used to test the completeness of the reference finder proc.
|
||||
/datum/unit_test/find_reference_sanity
|
||||
|
||||
/atom/movable/ref_holder
|
||||
var/atom/movable/ref_test/test
|
||||
var/list/test_list = list()
|
||||
var/list/test_assoc_list = list()
|
||||
|
||||
/atom/movable/ref_holder/Destroy()
|
||||
test = null
|
||||
test_list.Cut()
|
||||
test_assoc_list.Cut()
|
||||
return ..()
|
||||
|
||||
/atom/movable/ref_test
|
||||
var/atom/movable/ref_test/self_ref
|
||||
|
||||
/atom/movable/ref_test/Destroy(force)
|
||||
self_ref = null
|
||||
return ..()
|
||||
|
||||
/datum/unit_test/find_reference_sanity/Run()
|
||||
var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test)
|
||||
var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder)
|
||||
SSgarbage.should_save_refs = TRUE
|
||||
|
||||
//Sanity check
|
||||
victim.DoSearchVar(testbed, "Sanity Check", search_time = 1) //We increment search time to get around an optimization
|
||||
TEST_ASSERT(!victim.found_refs.len, "The ref-tracking tool found a ref where none existed")
|
||||
SSgarbage.should_save_refs = FALSE
|
||||
|
||||
/datum/unit_test/find_reference_baseline/Run()
|
||||
var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test)
|
||||
var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder)
|
||||
SSgarbage.should_save_refs = TRUE
|
||||
|
||||
//Set up for the first round of tests
|
||||
testbed.test = victim
|
||||
testbed.test_list += victim
|
||||
testbed.test_assoc_list["baseline"] = victim
|
||||
|
||||
victim.DoSearchVar(testbed, "First Run", search_time = 2)
|
||||
|
||||
TEST_ASSERT(victim.found_refs["test"], "The ref-tracking tool failed to find a regular value")
|
||||
TEST_ASSERT(victim.found_refs[testbed.test_list], "The ref-tracking tool failed to find a list entry")
|
||||
TEST_ASSERT(victim.found_refs[testbed.test_assoc_list], "The ref-tracking tool failed to find an assoc list value")
|
||||
SSgarbage.should_save_refs = FALSE
|
||||
|
||||
/datum/unit_test/find_reference_exotic/Run()
|
||||
var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test)
|
||||
var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder)
|
||||
SSgarbage.should_save_refs = TRUE
|
||||
|
||||
//Second round, bit harder this time
|
||||
testbed.overlays += victim
|
||||
testbed.vis_contents += victim
|
||||
testbed.test_assoc_list[victim] = TRUE
|
||||
|
||||
victim.DoSearchVar(testbed, "Second Run", search_time = 3)
|
||||
|
||||
//This is another sanity check
|
||||
TEST_ASSERT(!victim.found_refs[testbed.overlays], "The ref-tracking tool found an overlays entry? That shouldn't be possible")
|
||||
TEST_ASSERT(victim.found_refs[testbed.vis_contents], "The ref-tracking tool failed to find a vis_contents entry")
|
||||
TEST_ASSERT(victim.found_refs[testbed.test_assoc_list], "The ref-tracking tool failed to find an assoc list key")
|
||||
SSgarbage.should_save_refs = FALSE
|
||||
|
||||
/datum/unit_test/find_reference_esoteric/Run()
|
||||
var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test)
|
||||
var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder)
|
||||
SSgarbage.should_save_refs = TRUE
|
||||
|
||||
//Let's get a bit esoteric
|
||||
victim.self_ref = victim
|
||||
var/list/to_find = list(victim)
|
||||
testbed.test_list += list(to_find)
|
||||
var/list/to_find_assoc = list(victim)
|
||||
testbed.test_assoc_list["Nesting"] = to_find_assoc
|
||||
|
||||
victim.DoSearchVar(victim, "Third Run Self", search_time = 4)
|
||||
victim.DoSearchVar(testbed, "Third Run Testbed", search_time = 4)
|
||||
TEST_ASSERT(victim.found_refs["self_ref"], "The ref-tracking tool failed to find a self reference")
|
||||
TEST_ASSERT(victim.found_refs[to_find], "The ref-tracking tool failed to find a nested list entry")
|
||||
TEST_ASSERT(victim.found_refs[to_find_assoc], "The ref-tracking tool failed to find a nested assoc list entry")
|
||||
SSgarbage.should_save_refs = FALSE
|
||||
|
||||
/datum/unit_test/find_reference_null_key_entry/Run()
|
||||
var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test)
|
||||
var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder)
|
||||
SSgarbage.should_save_refs = TRUE
|
||||
|
||||
//Calm before the storm
|
||||
testbed.test_assoc_list = list(null = victim)
|
||||
|
||||
victim.DoSearchVar(testbed, "Fourth Run", search_time = 5)
|
||||
TEST_ASSERT(testbed.test_assoc_list, "The ref-tracking tool failed to find a null key'd assoc list entry")
|
||||
|
||||
/datum/unit_test/find_reference_assoc_investigation/Run()
|
||||
var/atom/movable/ref_test/victim = allocate(/atom/movable/ref_test)
|
||||
var/atom/movable/ref_holder/testbed = allocate(/atom/movable/ref_holder)
|
||||
SSgarbage.should_save_refs = TRUE
|
||||
|
||||
//Let's do some more complex assoc list investigation
|
||||
var/list/to_find_in_key = list(victim)
|
||||
testbed.test_assoc_list[to_find_in_key] = list("memes")
|
||||
var/list/to_find_null_assoc_nested = list(victim)
|
||||
testbed.test_assoc_list[null] = to_find_null_assoc_nested
|
||||
|
||||
victim.DoSearchVar(testbed, "Fifth Run", search_time = 6)
|
||||
TEST_ASSERT(victim.found_refs[to_find_in_key], "The ref-tracking tool failed to find a nested assoc list key")
|
||||
TEST_ASSERT(victim.found_refs[to_find_null_assoc_nested], "The ref-tracking tool failed to find a null key'd nested assoc list entry")
|
||||
SSgarbage.should_save_refs = FALSE
|
||||
@@ -1,11 +0,0 @@
|
||||
/datum/unit_test/initialize_sanity/Run()
|
||||
if(length(SSatoms.BadInitializeCalls))
|
||||
Fail("Bad Initialize() calls detected. Please read logs.")
|
||||
var/list/init_failures_to_text = list(
|
||||
"[BAD_INIT_QDEL_BEFORE]" = "Qdeleted Before Initialized",
|
||||
"[BAD_INIT_DIDNT_INIT]" = "Did Not Initialize",
|
||||
"[BAD_INIT_SLEPT]" = "Initialize() Slept",
|
||||
"[BAD_INIT_NO_HINT]" = "No Initialize() Hint Returned",
|
||||
)
|
||||
for(var/failure in SSatoms.BadInitializeCalls)
|
||||
log_world("[failure]: [init_failures_to_text["[SSatoms.BadInitializeCalls[failure]]"]]") // You like stacked brackets?
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/unit_test/spawn_humans/Run()
|
||||
var/locs = block(run_loc_bottom_left, run_loc_top_right)
|
||||
var/locs = block(run_loc_floor_bottom_left, run_loc_floor_top_right)
|
||||
|
||||
for(var/I in 1 to 5)
|
||||
new /mob/living/carbon/human(pick(locs))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
///Unit test that spawns all mobs that can be spawned by golden slimes
|
||||
/datum/unit_test/spawn_mobs
|
||||
|
||||
/datum/unit_test/spawn_mobs/Run()
|
||||
for(var/_animal in typesof(/mob/living/simple_animal))
|
||||
var/mob/living/simple_animal/animal = _animal
|
||||
if (initial(animal.gold_core_spawnable) == HOSTILE_SPAWN || initial(animal.gold_core_spawnable) == FRIENDLY_SPAWN)
|
||||
allocate(_animal)
|
||||
@@ -0,0 +1,28 @@
|
||||
/// Test that `TGUI_CREATE_MESSAGE` is correctly implemented
|
||||
/datum/unit_test/tgui_create_message
|
||||
|
||||
/datum/unit_test/tgui_create_message/Run()
|
||||
var/type = "something/here"
|
||||
var/list/payload = list(
|
||||
"name" = "Terry McTider",
|
||||
"heads_caved" = 100,
|
||||
"accomplishments" = list(
|
||||
"nothing",
|
||||
"literally nothing",
|
||||
list(
|
||||
"something" = "just kidding",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
var/message = TGUI_CREATE_MESSAGE(type, payload)
|
||||
|
||||
// Ensure consistent output to compare by performing a round-trip.
|
||||
var/output = json_encode(json_decode(url_decode(message)))
|
||||
|
||||
var/expected = json_encode(list(
|
||||
"type" = type,
|
||||
"payload" = payload,
|
||||
))
|
||||
|
||||
TEST_ASSERT_EQUAL(expected, output, "TGUI_CREATE_MESSAGE didn't round trip properly")
|
||||
@@ -7,7 +7,7 @@ Call Fail() to fail the test (You should specify a reason)
|
||||
|
||||
You may use /New() and /Destroy() for setup/teardown respectively
|
||||
|
||||
You can use the run_loc_bottom_left and run_loc_top_right to get turfs for testing
|
||||
You can use the run_loc_floor_bottom_left and run_loc_floor_top_right to get turfs for testing
|
||||
|
||||
*/
|
||||
|
||||
@@ -19,39 +19,46 @@ GLOBAL_VAR(test_log)
|
||||
//Bit of metadata for the future maybe
|
||||
var/list/procs_tested
|
||||
|
||||
/// The bottom left turf of the testing zone
|
||||
var/turf/run_loc_bottom_left
|
||||
|
||||
/// The top right turf of the testing zone
|
||||
var/turf/run_loc_top_right
|
||||
|
||||
/// The type of turf to allocate for the testing zone
|
||||
var/test_turf_type = /turf/open/floor/plasteel
|
||||
/// The bottom left floor turf of the testing zone
|
||||
var/turf/run_loc_floor_bottom_left
|
||||
|
||||
/// The top right floor turf of the testing zone
|
||||
var/turf/run_loc_floor_top_right
|
||||
///The priority of the test, the larger it is the later it fires
|
||||
var/priority = TEST_DEFAULT
|
||||
//internal shit
|
||||
var/focus = FALSE
|
||||
var/succeeded = TRUE
|
||||
var/list/allocated
|
||||
var/list/fail_reasons
|
||||
|
||||
var/static/datum/turf_reservation/turf_reservation
|
||||
var/static/datum/turf_reservation/reservation
|
||||
|
||||
/proc/cmp_unit_test_priority(datum/unit_test/a, datum/unit_test/b)
|
||||
return initial(a.priority) - initial(b.priority)
|
||||
|
||||
/datum/unit_test/New()
|
||||
if (isnull(turf_reservation))
|
||||
turf_reservation = SSmapping.RequestBlockReservation(5, 5)
|
||||
if (isnull(reservation))
|
||||
reservation = SSmapping.RequestBlockReservation(5, 5)
|
||||
|
||||
for (var/turf/reserved_turf in turf_reservation.reserved_turfs)
|
||||
reserved_turf.ChangeTurf(test_turf_type)
|
||||
for (var/turf/reserved_turf in reservation.reserved_turfs)
|
||||
reserved_turf.ChangeTurf(/turf/open/floor/plasteel)
|
||||
|
||||
allocated = new
|
||||
run_loc_bottom_left = locate(turf_reservation.bottom_left_coords[1], turf_reservation.bottom_left_coords[2], turf_reservation.bottom_left_coords[3])
|
||||
run_loc_top_right = locate(turf_reservation.top_right_coords[1], turf_reservation.top_right_coords[2], turf_reservation.top_right_coords[3])
|
||||
run_loc_floor_bottom_left = locate(reservation.bottom_left_coords[1], reservation.bottom_left_coords[2], reservation.bottom_left_coords[3])
|
||||
run_loc_floor_top_right = locate(reservation.top_right_coords[1], reservation.top_right_coords[2], reservation.top_right_coords[3])
|
||||
|
||||
TEST_ASSERT(isfloorturf(run_loc_floor_bottom_left), "run_loc_floor_bottom_left was not a floor ([run_loc_floor_bottom_left])")
|
||||
TEST_ASSERT(isfloorturf(run_loc_floor_top_right), "run_loc_floor_top_right was not a floor ([run_loc_floor_top_right])")
|
||||
|
||||
/datum/unit_test/Destroy()
|
||||
//clear the test area
|
||||
for(var/atom/movable/AM in block(run_loc_bottom_left, run_loc_top_right))
|
||||
qdel(AM)
|
||||
QDEL_LIST(allocated)
|
||||
// clear the test area
|
||||
for (var/turf/turf in block(locate(1, 1, run_loc_floor_bottom_left.z), locate(world.maxx, world.maxy, run_loc_floor_bottom_left.z)))
|
||||
for (var/content in turf.contents)
|
||||
if (istype(content, /obj/effect/landmark))
|
||||
continue
|
||||
qdel(content)
|
||||
return ..()
|
||||
|
||||
/datum/unit_test/proc/Run()
|
||||
@@ -70,44 +77,63 @@ GLOBAL_VAR(test_log)
|
||||
/datum/unit_test/proc/allocate(type, ...)
|
||||
var/list/arguments = args.Copy(2)
|
||||
if (!arguments.len)
|
||||
arguments = list(run_loc_bottom_left)
|
||||
arguments = list(run_loc_floor_bottom_left)
|
||||
else if (arguments[1] == null)
|
||||
arguments[1] = run_loc_bottom_left
|
||||
arguments[1] = run_loc_floor_bottom_left
|
||||
var/instance = new type(arglist(arguments))
|
||||
allocated += instance
|
||||
return instance
|
||||
|
||||
/proc/RunUnitTest(test_path, list/test_results)
|
||||
var/datum/unit_test/test = new test_path
|
||||
|
||||
GLOB.current_test = test
|
||||
var/duration = REALTIMEOFDAY
|
||||
|
||||
test.Run()
|
||||
|
||||
duration = REALTIMEOFDAY - duration
|
||||
GLOB.current_test = null
|
||||
GLOB.failed_any_test |= !test.succeeded
|
||||
|
||||
var/list/log_entry = list("[test.succeeded ? "PASS" : "FAIL"]: [test_path] [duration / 10]s")
|
||||
var/list/fail_reasons = test.fail_reasons
|
||||
|
||||
for(var/J in 1 to LAZYLEN(fail_reasons))
|
||||
log_entry += "\tREASON #[J]: [fail_reasons[J]]"
|
||||
var/message = log_entry.Join("\n")
|
||||
log_test(message)
|
||||
|
||||
test_results[test_path] = list("status" = test.succeeded ? UNIT_TEST_PASSED : UNIT_TEST_FAILED, "message" = message, "name" = test_path)
|
||||
|
||||
qdel(test)
|
||||
|
||||
/proc/RunUnitTests()
|
||||
CHECK_TICK
|
||||
|
||||
var/tests_to_run = subtypesof(/datum/unit_test)
|
||||
var/list/tests_to_run = subtypesof(/datum/unit_test)
|
||||
for (var/_test_to_run in tests_to_run)
|
||||
var/datum/unit_test/test_to_run = _test_to_run
|
||||
if (initial(test_to_run.focus))
|
||||
tests_to_run = list(test_to_run)
|
||||
break
|
||||
|
||||
for(var/I in tests_to_run)
|
||||
var/datum/unit_test/test = new I
|
||||
tests_to_run = sortTim(tests_to_run, /proc/cmp_unit_test_priority)
|
||||
|
||||
GLOB.current_test = test
|
||||
var/duration = REALTIMEOFDAY
|
||||
var/list/test_results = list()
|
||||
|
||||
test.Run()
|
||||
for(var/unit_path in tests_to_run)
|
||||
CHECK_TICK //We check tick first because the unit test we run last may be so expensive that checking tick will lock up this loop forever
|
||||
RunUnitTest(unit_path, test_results)
|
||||
|
||||
duration = REALTIMEOFDAY - duration
|
||||
GLOB.current_test = null
|
||||
GLOB.failed_any_test |= !test.succeeded
|
||||
|
||||
var/list/log_entry = list("[test.succeeded ? "PASS" : "FAIL"]: [I] [duration / 10]s")
|
||||
var/list/fail_reasons = test.fail_reasons
|
||||
|
||||
qdel(test)
|
||||
|
||||
for(var/J in 1 to LAZYLEN(fail_reasons))
|
||||
log_entry += "\tREASON #[J]: [fail_reasons[J]]"
|
||||
log_test(log_entry.Join("\n"))
|
||||
|
||||
CHECK_TICK
|
||||
var/file_name = "data/unit_tests.json"
|
||||
fdel(file_name)
|
||||
file(file_name) << json_encode(test_results)
|
||||
|
||||
SSticker.force_ending = TRUE
|
||||
//We have to call this manually because del_text can preceed us, and SSticker doesn't fire in the post game
|
||||
SSticker.standard_reboot()
|
||||
|
||||
// /datum/map_template/unit_tests
|
||||
// name = "Unit Tests Zone"
|
||||
// mappath = "_maps/templates/unit_tests.dmm"
|
||||
|
||||
Reference in New Issue
Block a user