mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Merge branch 'master' of github.com:tgstation/tgstation into upstream-2026-06-23
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
/// *Only* run the test provided within the parentheses
|
||||
/// This is useful for debugging when you want to reduce noise, but should never be pushed
|
||||
/// Intended to be used in the manner of `TEST_FOCUS(/datum/unit_test/math)`
|
||||
#define TEST_FOCUS(test_path) ##test_path { focus = TRUE; }
|
||||
#define TEST_FOCUS(test_path) ##test_path { test_flags = UNIT_TEST_FOCUS; }
|
||||
|
||||
/// Run the test provided within the parentheses run_count times
|
||||
/// Useful for debugging flaky tests that only fail sometimes
|
||||
@@ -67,6 +67,16 @@
|
||||
*/
|
||||
#define TEST_AFTER_CREATE_AND_DESTROY INFINITY
|
||||
|
||||
// Unit test bitflags
|
||||
|
||||
/// If any unit test has this bitflag, only unit tests with UNIT_TEST_FOCUS will run.
|
||||
#define UNIT_TEST_FOCUS (1<<0)
|
||||
/// This unit test only runs on specially designated unit test maps (Should only ever be one).
|
||||
#define UNIT_TEST_DEBUG_MAP_ONLY (1<<1)
|
||||
|
||||
#define UNIT_TEST_BASIC (UNIT_TEST_DEBUG_MAP_ONLY)
|
||||
#define UNIT_TEST_MAP_TEST (NONE)
|
||||
|
||||
/// Change color to red on ANSI terminal output, if enabled with -DANSICOLORS.
|
||||
#ifdef ANSICOLORS
|
||||
#define TEST_OUTPUT_RED(text) "\x1B\x5B1;31m[text]\x1B\x5B0m"
|
||||
@@ -212,6 +222,7 @@
|
||||
#include "keybinding_init.dm"
|
||||
#include "kinetic_crusher.dm"
|
||||
#include "knockoff_component.dm"
|
||||
#include "language_key_conflicts.dm"
|
||||
#include "language_transfer.dm"
|
||||
#include "leash.dm"
|
||||
#include "lesserform.dm"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/// Verifies that an area's perception of their "turfs" is correct, and no other area overlaps with them
|
||||
/// Quite slow, but needed
|
||||
/datum/unit_test/maptest_area_contents
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
priority = TEST_LONGER
|
||||
|
||||
/datum/unit_test/maptest_area_contents/Run()
|
||||
|
||||
@@ -1,51 +1,59 @@
|
||||
/**
|
||||
* This test checks that all expected areas are connected to a starting area
|
||||
* This test checks that all areas are connected to their distribution loops
|
||||
*/
|
||||
/datum/unit_test/atmospherics_sanity
|
||||
// we iterate over all atmospherics devices on the starting networks
|
||||
priority = TEST_LONGER
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
priority = TEST_LONGER // we iterate over all atmospherics devices on the starting networks
|
||||
|
||||
/// List of areas remaining to be checked
|
||||
var/list/area/remaining_areas
|
||||
/// List of areas to start crawling from
|
||||
var/list/area/starting_areas
|
||||
|
||||
/// List of areas already crawled, to prevent needless crawling
|
||||
var/list/area/crawled_areas
|
||||
|
||||
/// List of areas to start crawling from
|
||||
var/list/area/starting_areas
|
||||
/// List of areas remaining to be checked
|
||||
var/list/area/remaining_areas
|
||||
|
||||
/// List of areas that should absolutely not be encountered
|
||||
var/list/area/forbidden_areas
|
||||
|
||||
/// We run this test in parallel, so we need to keep track of how many crawls are running
|
||||
/// This is to prevent stack overflow mostly
|
||||
var/crawls = 0
|
||||
|
||||
/datum/unit_test/atmospherics_sanity/proc/get_areas()
|
||||
/datum/unit_test/atmospherics_sanity/proc/prepare_crawl()
|
||||
starting_areas = list()
|
||||
forbidden_areas = list()
|
||||
crawled_areas = list()
|
||||
remaining_areas = list()
|
||||
|
||||
for(var/obj/effect/landmark/atmospheric_sanity/start_area/start_marker in GLOB.landmarks_list)
|
||||
var/area/starting_area = get_area(start_marker)
|
||||
if(starting_area in starting_areas)
|
||||
TEST_FAIL("Duplicate atmospherics sanity starting marker in '[starting_area]'([starting_area.type]) at ([start_marker.x], [start_marker.y], [start_marker.z])")
|
||||
continue
|
||||
if(starting_area.outdoors)
|
||||
TEST_FAIL("Atmospherics sanity starting marker in outdoors area '[starting_area]'([starting_area.type]) at ([start_marker.x], [start_marker.y], [start_marker.z])")
|
||||
TEST_FAIL("Atmospherics sanity starting marker cannot be in outdoors area '[starting_area]'([starting_area.type]) at ([start_marker.x], [start_marker.y], [start_marker.z])")
|
||||
continue
|
||||
starting_areas |= get_area(start_marker)
|
||||
|
||||
// If there are no starting areas, default to these
|
||||
var/static/list/area/default_starting_areas = list(
|
||||
/area/station/ai/satellite/chamber,
|
||||
/area/station/engineering/atmos,
|
||||
/area/station/medical/virology,
|
||||
/area/station/science/xenobiology,
|
||||
)
|
||||
|
||||
if(!length(starting_areas))
|
||||
log_test("No starting areas found, defaulting...")
|
||||
|
||||
var/list/area/default_starting_areas = list(
|
||||
// These areas have their own air supply
|
||||
/area/station/ai/satellite/chamber,
|
||||
/area/station/medical/virology,
|
||||
/area/station/science/xenobiology,
|
||||
// Otherwise, this should connect to the rest of the station
|
||||
/area/station/engineering/atmos,
|
||||
)
|
||||
|
||||
for(var/area/starting_area as anything in default_starting_areas)
|
||||
var/area/station_area = GLOB.areas_by_type[starting_area]
|
||||
if(!isnull(station_area))
|
||||
starting_areas += station_area
|
||||
|
||||
remaining_areas = list()
|
||||
|
||||
var/atom/mark_all_station_areas_marker = locate(/obj/effect/landmark/atmospheric_sanity/mark_all_station_areas_as_goal) in GLOB.landmarks_list
|
||||
if(!isnull(mark_all_station_areas_marker))
|
||||
@@ -61,59 +69,77 @@
|
||||
if(goal_area.outdoors)
|
||||
TEST_FAIL("Atmospherics sanity goal marker in outdoors area '[goal_area]'([goal_area.type]) at ([goal_marker.x], [goal_marker.y], [goal_marker.z])")
|
||||
continue
|
||||
if(istype(goal_area, /area/space))
|
||||
TEST_FAIL("Atmospherics sanity goal marker in space at ([goal_marker.x], [goal_marker.y], [goal_marker.z])")
|
||||
continue
|
||||
remaining_areas |= get_area(goal_marker)
|
||||
|
||||
if(!length(remaining_areas))
|
||||
log_test("No goal areas found, defaulting...")
|
||||
mark_station_areas_as_goals()
|
||||
else
|
||||
for(var/obj/effect/landmark/atmospheric_sanity/forbidden_area/forbidden_marker in GLOB.landmarks_list)
|
||||
var/area/forbidden_area = get_area(forbidden_marker)
|
||||
if(forbidden_area in remaining_areas)
|
||||
var/obj/effect/landmark/atmospheric_sanity/goal_area/goal_marker = locate() in forbidden_area
|
||||
TEST_FAIL("Area '[forbidden_area]'([forbidden_area.type]) \
|
||||
has a goal marker at ([goal_marker.x], [goal_marker.y], [goal_marker.z]) \
|
||||
and a forbidden marker at ([forbidden_marker.x], ([forbidden_marker.y], ([forbidden_marker.z])")
|
||||
continue
|
||||
if(forbidden_area in forbidden_areas)
|
||||
TEST_FAIL("Area '[forbidden_area]'([forbidden_area.type]) is so forbidden it has a duplicate marker at at ([forbidden_marker.x], ([forbidden_marker.y], ([forbidden_marker.z])")
|
||||
continue
|
||||
|
||||
forbidden_areas |= forbidden_area
|
||||
|
||||
for(var/obj/effect/landmark/atmospheric_sanity/ignore_area/ignore_marker in GLOB.landmarks_list)
|
||||
remaining_areas -= get_area(ignore_marker)
|
||||
|
||||
/datum/unit_test/atmospherics_sanity/proc/mark_station_areas_as_goals()
|
||||
// We don't want to check these areas
|
||||
var/static/list/area/ignored_types = list(
|
||||
// We don't care if we find these
|
||||
var/list/area/ignored_types = list(
|
||||
/area/station/asteroid,
|
||||
/area/station/engineering/supermatter,
|
||||
/area/station/holodeck,
|
||||
/area/station/maintenance,
|
||||
/area/station/science/ordnance/bomb,
|
||||
/area/station/solars,
|
||||
|
||||
// FIXME, burnchamber is usually mapped with a vent in the buffer airlock
|
||||
// which causes us to leak into freezer. These two should be forbidden
|
||||
/area/station/science/ordnance/burnchamber,
|
||||
/area/station/science/ordnance/freezerchamber,
|
||||
/area/station/solars,
|
||||
/area/station/tcommsat/server,
|
||||
/area/station/commons/vacant_room/office, // BUBBER EDIT ADDITION - We often overwrite the vacant room with the NT Rep office, which can lead to incorrect failures
|
||||
)
|
||||
|
||||
for(var/area/ignored as anything in ignored_types)
|
||||
ignored_types |= subtypesof(ignored)
|
||||
|
||||
for(var/area/station/station_area_type as anything in subtypesof(/area/station) - ignored_types)
|
||||
// We should never find these
|
||||
var/list/area/forbidden_types = list(
|
||||
/area/station/engineering/supermatter/engine,
|
||||
/area/station/tcommsat/server,
|
||||
)
|
||||
|
||||
for(var/area/forbidden as anything in forbidden_types)
|
||||
forbidden_types |= subtypesof(forbidden)
|
||||
|
||||
for(var/area/station/station_area_type as anything in subtypesof(/area/station) - ignored_types - forbidden_types)
|
||||
var/area/station_area = GLOB.areas_by_type[station_area_type]
|
||||
if(!isnull(station_area))
|
||||
remaining_areas += station_area
|
||||
|
||||
/datum/unit_test/atmospherics_sanity/Run()
|
||||
get_areas()
|
||||
crawl_areas()
|
||||
UNTIL(crawls == 0)
|
||||
for(var/area/missed as anything in remaining_areas)
|
||||
if(missed.has_contained_turfs())
|
||||
var/turf/first_turf = missed.get_zlevel_turf_lists()[1][1]
|
||||
TEST_FAIL("Disconnected Area '[missed]'([missed.type]) at ([first_turf.x], [first_turf.y], [first_turf.z])")
|
||||
else
|
||||
TEST_NOTICE(src, "Disconnected Area '[missed]'([missed.type]) with no turfs?")
|
||||
for(var/area/station/forbidden_area_type as anything in forbidden_types)
|
||||
var/area/forbidden_area = GLOB.areas_by_type[forbidden_area_type]
|
||||
if(!isnull(forbidden_area))
|
||||
forbidden_areas += forbidden_area
|
||||
|
||||
/// Iterates over starting_areas and ensures that all goal areas are connected to atleast one start
|
||||
/datum/unit_test/atmospherics_sanity/proc/crawl_areas()
|
||||
crawled_areas = list()
|
||||
/datum/unit_test/atmospherics_sanity/Run()
|
||||
prepare_crawl()
|
||||
for(var/area/start_area as anything in starting_areas)
|
||||
ASYNC
|
||||
crawl_area(start_area)
|
||||
starting_areas = null
|
||||
UNTIL(crawls == 0)
|
||||
|
||||
for(var/area/missed as anything in remaining_areas)
|
||||
var/turf/first_turf = missed.get_zlevel_turf_lists()[1][1]
|
||||
TEST_FAIL("Goal area '[missed]'([missed.type]) is isolated from any distribution loops ([first_turf.x], [first_turf.y], [first_turf.z])")
|
||||
|
||||
/// Crawls through an area, iterating over all vents/scrubbers and their connected pipelines
|
||||
/datum/unit_test/atmospherics_sanity/proc/crawl_area(area/the_area)
|
||||
@@ -127,12 +153,16 @@
|
||||
for(var/obj/machinery/atmospherics/components/component as anything in (the_area.air_vents + the_area.air_scrubbers))
|
||||
for(var/datum/pipeline/parent as anything in component.parents)
|
||||
if(isnull(parent))
|
||||
TEST_NOTICE(src, "Found a null parent for [component] in [the_area] at ([component.x], [component.y], [component.z])")
|
||||
TEST_NOTICE(src, "[component] at ([component.x], [component.y], [component.z]) isn't attached to a pipenet, is this on purpose?")
|
||||
continue
|
||||
pipelines |= parent
|
||||
|
||||
for(var/datum/pipeline/pipeline as anything in pipelines)
|
||||
crawl_pipeline(pipeline)
|
||||
if((the_area in forbidden_areas) && length(pipelines)) // we don't care if this area is forbidden if it isn't actually connected to the air
|
||||
var/turf/first_turf = the_area.get_zlevel_turf_lists()[1][1]
|
||||
TEST_FAIL("Forbidden area '[the_area]'([the_area.type]) is connected to a distribution loop at ([first_turf.x], [first_turf.y], [first_turf.z])")
|
||||
else
|
||||
for(var/datum/pipeline/pipeline as anything in pipelines)
|
||||
crawl_pipeline(pipeline)
|
||||
|
||||
crawls -= 1
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
///Checking all powernets to see if they are properly connected and powered.
|
||||
/datum/unit_test/cable_powernets
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
|
||||
/datum/unit_test/cable_powernets/Run()
|
||||
for(var/datum/powernet/powernets as anything in SSmachines.powernets)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/unit_test/cargo_dep_order_locations
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
|
||||
/datum/unit_test/cargo_dep_order_locations/Run()
|
||||
for(var/datum/job_department/department as anything in SSjob.joinable_departments)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
///Delete one of every type, sleep a while, then check to see if anything has gone fucky
|
||||
/datum/unit_test/create_and_destroy
|
||||
// Since this unit test takes so damn long, we split it up across all runners
|
||||
test_flags = parent_type::test_flags & ~UNIT_TEST_DEBUG_MAP_ONLY
|
||||
//You absolutely must run after (almost) everything else
|
||||
priority = TEST_CREATE_AND_DESTROY
|
||||
|
||||
@@ -15,6 +17,29 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE)
|
||||
|
||||
GLOB.running_create_and_destroy = TRUE
|
||||
var/list/type_paths_to_check = (valid_typesof(/atom/movable) + valid_typesof(/turf)) - uncreatables // No areas please
|
||||
|
||||
// This code is responsible for splitting up create & destroy across multiple integration tests.
|
||||
var/total_amount_to_check = length(type_paths_to_check)
|
||||
var/runner_count = max(length(config.maplist), 1)
|
||||
|
||||
var/split_up_amount = floor(total_amount_to_check / runner_count)
|
||||
|
||||
var/what_map_index_are_we = 1
|
||||
for(var/map_name in config.maplist)
|
||||
if(SSmapping.current_map.map_name == map_name)
|
||||
break
|
||||
what_map_index_are_we++
|
||||
|
||||
var/start_index = (what_map_index_are_we - 1) * split_up_amount
|
||||
// Instead of super trying to make it an equal split, we just give the remainder tests to the final runner
|
||||
var/end_index = (what_map_index_are_we == runner_count) ? total_amount_to_check : start_index + split_up_amount
|
||||
|
||||
// +1 because byond's list.Copy() implementation is weird
|
||||
type_paths_to_check = type_paths_to_check.Copy(start_index, end_index + 1)
|
||||
|
||||
log_world("Running create and destroy on [length(type_paths_to_check)] atoms out of the [total_amount_to_check] total")
|
||||
log_world("([start_index + 1] [type_paths_to_check[1]]) - ([end_index] [type_paths_to_check[length(type_paths_to_check)]])")
|
||||
|
||||
for(var/type_path in type_paths_to_check)
|
||||
if(ispath(type_path, /turf))
|
||||
spawn_at.ChangeTurf(type_path)
|
||||
@@ -28,6 +53,8 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE)
|
||||
else
|
||||
var/atom/creation = new type_path(spawn_at)
|
||||
if(QDELETED(creation))
|
||||
// Same as below
|
||||
creation = null
|
||||
continue
|
||||
//Go all in
|
||||
qdel(creation, force = TRUE)
|
||||
@@ -50,7 +77,7 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE)
|
||||
|
||||
var/list/queues_we_care_about = list()
|
||||
// All of em, I want hard deletes too, since we rely on the debug info from them
|
||||
for(var/i in 1 to GC_QUEUE_HARDDELETE)
|
||||
for(var/i in GC_QUEUE_FILTER to GC_QUEUE_HARDDELETE)
|
||||
queues_we_care_about += i
|
||||
|
||||
//Now that we've qdel'd everything, let's sleep until the gc has processed all the shit we care about
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
* This unit test requires every (unless ignored) atom to have been created at least once
|
||||
* for a more accurate search, which is why it's run after create_and_destroy is done running.
|
||||
*/
|
||||
test_flags = parent_type::test_flags & ~UNIT_TEST_DEBUG_MAP_ONLY
|
||||
priority = TEST_AFTER_CREATE_AND_DESTROY
|
||||
|
||||
/datum/unit_test/dcs_check_list_arguments/Run()
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* Then, checks if every non-ignored region has a fire alarm in it
|
||||
*/
|
||||
/datum/unit_test/firedoor_regions
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
priority = TEST_LONGER
|
||||
|
||||
/datum/unit_test/firedoor_regions/Run()
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
inheritability = 100
|
||||
reagents_to_add = list(/datum/reagent/fishdummy = FISH_REAGENT_AMOUNT)
|
||||
|
||||
/datum/fish_trait/dummy/apply_to_fish(obj/item/fish/fish)
|
||||
/datum/fish_trait/dummy/apply_to_fish(obj/item/fish/fish, initial = TRUE)
|
||||
. = ..()
|
||||
ADD_TRAIT(fish, TRAIT_FISH_TESTING, FISH_TRAIT_DATUM)
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/// This test ensures that multiple languages aren't mapped to the same prefix key.
|
||||
/datum/unit_test/language_key_conflicts
|
||||
|
||||
/datum/unit_test/language_key_conflicts/Run()
|
||||
var/list/used_keys = list()
|
||||
for(var/datum/language/language as anything in subtypesof(/datum/language))
|
||||
var/name = language::name
|
||||
var/key = language::key
|
||||
if(!key)
|
||||
TEST_FAIL("[name] ([language]) does not have a prefix!")
|
||||
else if(used_keys[key])
|
||||
var/datum/language/conflicting_language = used_keys[key]
|
||||
TEST_FAIL("[name] ([language]) uses the '[key]' prefix, which is also used by [conflicting_language::name] ([conflicting_language])!")
|
||||
else
|
||||
used_keys[key] = language
|
||||
@@ -1,5 +1,6 @@
|
||||
/// Tests that [/datum/job/proc/get_default_roundstart_spawn_point] returns a landmark from all joinable jobs.
|
||||
/datum/unit_test/maptest_job_roundstart_spawnpoints
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
|
||||
/datum/unit_test/maptest_job_roundstart_spawnpoints/Run()
|
||||
for(var/datum/job/job as anything in SSjob.joinable_occupations)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/// Verifies that there are no space turfs inside a station area, or on any planetary z-level. Sometimes, these are introduced during the load of the map and are not present in the DMM itself.
|
||||
/// Let's just make sure that we have a stop-gap measure in place to catch these if they pop up so we don't put it onto production servers should something errant come up.
|
||||
/datum/unit_test/maptest_mapload_space_verification
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
// This test is quite taxing time-wise, so let's run it later than other faster tests.
|
||||
priority = TEST_LONGER
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// Conveys all log_mapping messages as unit test failures, as they all indicate mapping problems.
|
||||
/datum/unit_test/maptest_log_mapping
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
// Happen before all other tests, to make sure we only capture normal mapping logs.
|
||||
priority = TEST_PRE
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
///Detects movables that may have been accidentally placed in space, as well as movables which do not have the proper nearspace area (meaning they aren't lit properly.)
|
||||
/datum/unit_test/maptest_mapping_nearstation_test
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
priority = TEST_PRE
|
||||
|
||||
/datum/unit_test/maptest_mapping_nearstation_test/Run()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/// Ensures we do not leave genturfs sitting around post work
|
||||
/// They serve as notice to the mapper and have no functionality, but it's good to make note of it here
|
||||
/datum/unit_test/orphaned_genturf
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
|
||||
/datum/unit_test/orphaned_genturf/Run()
|
||||
for(var/turf/open/genturf/orphaned in ALL_TURFS())
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* - In the type's initialize, REGISTER_REQUIRED_MAP_ITEM() a minimum and maximum
|
||||
*/
|
||||
/datum/unit_test/maptest_required_map_items
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
/// A list of all typepaths that we expect to be in the required items list
|
||||
var/list/expected_types = list()
|
||||
|
||||
@@ -15,6 +16,7 @@
|
||||
/datum/unit_test/maptest_required_map_items/proc/setup_expected_types()
|
||||
expected_types += subtypesof(/obj/item/stamp/head)
|
||||
expected_types += subtypesof(/obj/machinery/modular_computer/preset/cargochat)
|
||||
expected_types += subtypesof(/obj/machinery/fax/heads)
|
||||
|
||||
expected_types += /mob/living/basic/parrot/poly
|
||||
expected_types += /mob/living/basic/pet/dog/corgi/ian
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
// Use the new basic mobs system instead.
|
||||
// If you are refactoring a simple_animal, REMOVE it from this list
|
||||
var/list/allowed_types = list(
|
||||
/mob/living/simple_animal/bot,
|
||||
/mob/living/simple_animal/bot/mulebot,
|
||||
/mob/living/simple_animal/bot/mulebot/paranormal,
|
||||
/mob/living/simple_animal/hostile,
|
||||
/mob/living/simple_animal/hostile/asteroid,
|
||||
/mob/living/simple_animal/hostile/asteroid/elite,
|
||||
@@ -18,8 +15,6 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/legionnaire,
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/legionnairehead,
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/pandora,
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear,
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/lesser,
|
||||
/mob/living/simple_animal/hostile/megafauna,
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum,
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// Tests that all subsystems that need to properly initialize.
|
||||
/datum/unit_test/subsystem_init
|
||||
test_flags = UNIT_TEST_MAP_TEST
|
||||
|
||||
/datum/unit_test/subsystem_init/Run()
|
||||
for(var/datum/controller/subsystem/subsystem as anything in Master.subsystems)
|
||||
|
||||
@@ -27,35 +27,37 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
|
||||
/proc/focused_tests()
|
||||
var/list/focused_tests = list()
|
||||
for (var/datum/unit_test/unit_test as anything in subtypesof(/datum/unit_test))
|
||||
if (initial(unit_test.focus))
|
||||
if (unit_test::test_flags & UNIT_TEST_FOCUS)
|
||||
focused_tests += unit_test
|
||||
|
||||
return focused_tests.len > 0 ? focused_tests : null
|
||||
return length(focused_tests) ? focused_tests : null
|
||||
|
||||
/datum/unit_test
|
||||
/// Do not instantiate if type matches this
|
||||
abstract_type = /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
|
||||
///The priority of the test, the larger it is the later it fires
|
||||
/// Behavior flags for this unit test
|
||||
var/test_flags = UNIT_TEST_BASIC
|
||||
/// 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
|
||||
/// How many times this unit test will run. Use the TEST_REPEAT() macro
|
||||
var/times_to_run = 1
|
||||
|
||||
/// List of atoms that we don't want to ever initialize in an agnostic context, like for Create and Destroy. Stored on the base datum for usability in other relevant tests that need this data.
|
||||
var/static/list/uncreatables = null
|
||||
// internal shit
|
||||
/// If this test has passed or not
|
||||
var/succeeded = TRUE
|
||||
/// 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
|
||||
/// A list of instances created by this unit test. Use allocate()
|
||||
var/list/allocated
|
||||
/// Lazy list of why this unit test failed.
|
||||
var/list/fail_reasons
|
||||
|
||||
/// List of atoms that we don't want to ever initialize in an agnostic context, like for Create and Destroy.
|
||||
/// Stored on the base datum for usability in other relevant tests that need this data.
|
||||
var/static/list/uncreatables = null
|
||||
/// Reference to the blank z-level containing our testing enviroment
|
||||
var/static/datum/space_level/reservation
|
||||
|
||||
/proc/cmp_unit_test_priority(datum/unit_test/a, datum/unit_test/b)
|
||||
@@ -66,10 +68,9 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
|
||||
var/datum/map_template/unit_tests/template = new
|
||||
reservation = template.load_new_z()
|
||||
|
||||
if (isnull(uncreatables))
|
||||
uncreatables = build_list_of_uncreatables()
|
||||
uncreatables ||= build_list_of_uncreatables()
|
||||
|
||||
allocated = new
|
||||
allocated = list()
|
||||
|
||||
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)
|
||||
@@ -384,15 +385,40 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
|
||||
/proc/RunUnitTests()
|
||||
CHECK_TICK
|
||||
|
||||
var/list/tests_to_run = subtypesof(/datum/unit_test)
|
||||
// Find our primary unit test map & find out if we are the secondary
|
||||
var/datum/map_config/primary_unit_test_map
|
||||
var/is_secondary_unit_test_map = FALSE
|
||||
var/found_secondary_unit_test_map = FALSE
|
||||
for(var/map_name, _map_config in config.maplist)
|
||||
var/datum/map_config/map_config = _map_config
|
||||
if(map_config.is_unit_test_map)
|
||||
primary_unit_test_map = map_config
|
||||
if(!LAZYLEN(map_config.skipped_tests) && !found_secondary_unit_test_map)
|
||||
found_secondary_unit_test_map = TRUE
|
||||
if(SSmapping.current_map.map_name == map_name)
|
||||
is_secondary_unit_test_map = TRUE
|
||||
|
||||
var/list/tests_to_run = list()
|
||||
var/list/focused_tests = list()
|
||||
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))
|
||||
focused_tests += test_to_run
|
||||
for (var/datum/unit_test/potential_test as anything in subtypesof(/datum/unit_test))
|
||||
// If the test has [UNIT_TEST_DEBUG_MAP_ONLY] and we aren't the primary unit test map, skip it.
|
||||
// HOWEVER, some unit tests are incompatible with the primary testing map, so we must offload them a secondary one with no blacklisted tests.
|
||||
// If we didn't find a primary unit test map then we are likely a solo runner.
|
||||
if((potential_test::test_flags & UNIT_TEST_DEBUG_MAP_ONLY) && \
|
||||
!isnull(primary_unit_test_map) && \
|
||||
!SSmapping.current_map.is_unit_test_map && \
|
||||
!(primary_unit_test_map.skipped_tests?.Find(potential_test) && is_secondary_unit_test_map) \
|
||||
)
|
||||
continue
|
||||
if (potential_test::test_flags & UNIT_TEST_FOCUS)
|
||||
focused_tests += potential_test
|
||||
continue
|
||||
tests_to_run += potential_test
|
||||
if(length(focused_tests))
|
||||
tests_to_run = focused_tests
|
||||
|
||||
primary_unit_test_map = null // I'm paranoid
|
||||
|
||||
sortTim(tests_to_run, GLOBAL_PROC_REF(cmp_unit_test_priority))
|
||||
|
||||
var/list/test_results = list()
|
||||
|
||||
Reference in New Issue
Block a user