Files
Bubberstation/code/modules/unit_tests/unit_test.dm
SkyratBot 71efaf0d7a [MIRROR] Put unit tests in a box, fixes sporradic gun test failure (#3896)
* Put unit tests in a box, fixes sporradic gun test failure (#57408)

* Initial commit

* Fix removing old objects

* Remove define

* TGM

* Put unit tests in a box, fixes sporradic gun test failure

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
2021-03-05 14:06:09 +00:00

128 lines
3.6 KiB
Plaintext

/*
Usage:
Override /Run() to run your test code
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_floor_bottom_left and run_loc_floor_top_right to get turfs for testing
*/
GLOBAL_DATUM(current_test, /datum/unit_test)
GLOBAL_VAR_INIT(failed_any_test, FALSE)
GLOBAL_VAR(test_log)
/datum/unit_test
//Bit of metadata for the future maybe
var/list/procs_tested
/// 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
//internal shit
var/focus = FALSE
var/succeeded = TRUE
var/list/allocated
var/list/fail_reasons
var/static/datum/space_level/reservation
/datum/unit_test/New()
if (isnull(reservation))
var/datum/map_template/unit_tests/template = new
reservation = template.load_new_z()
allocated = new
run_loc_floor_bottom_left = get_turf(locate(/obj/effect/landmark/unit_test_bottom_left) in GLOB.landmarks_list)
run_loc_floor_top_right = get_turf(locate(/obj/effect/landmark/unit_test_top_right) in GLOB.landmarks_list)
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()
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 (iseffect(content))
continue
qdel(content)
return ..()
/datum/unit_test/proc/Run()
Fail("Run() called parent or not implemented")
/datum/unit_test/proc/Fail(reason = "No reason")
succeeded = FALSE
if(!istext(reason))
reason = "FORMATTED: [reason != null ? reason : "NULL"]"
LAZYADD(fail_reasons, reason)
/// Allocates an instance of the provided type, and places it somewhere in an available loc
/// Instances allocated through this proc will be destroyed when the test is over
/datum/unit_test/proc/allocate(type, ...)
var/list/arguments = args.Copy(2)
if (!arguments.len)
arguments = list(run_loc_floor_bottom_left)
else if (arguments[1] == null)
arguments[1] = run_loc_floor_bottom_left
var/instance = new type(arglist(arguments))
allocated += instance
return instance
/proc/RunUnitTests()
CHECK_TICK
var/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
var/list/test_results = list()
for(var/I in tests_to_run)
var/datum/unit_test/test = new I
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"]: [I] [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[I] = list("status" = test.succeeded ? UNIT_TEST_PASSED : UNIT_TEST_FAILED, "message" = message, "name" = I)
qdel(test)
CHECK_TICK
var/file_name = "data/unit_tests.json"
fdel(file_name)
file(file_name) << json_encode(test_results)
SSticker.force_ending = TRUE
/datum/map_template/unit_tests
name = "Unit Tests Zone"
mappath = "_maps/templates/unit_tests.dmm"