Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
color = rgb(255,0,0)

/datum/unit_test/test_change_area_appearance/RunTest()
var/area/subtype/S = new()
var/area/subtype/S = areas_by_type[/area/subtype]
var/list/block_turfs = block(locate(1,1,1), locate(2,2,2))
for(var/turf/T in block_turfs)
S.contents += T
Expand Down
217 changes: 179 additions & 38 deletions Content.IntegrationTests/DMProject/Tests/range.dm
Original file line number Diff line number Diff line change
@@ -1,40 +1,181 @@
//Tests that /proc/range() is iterating along the correct, wonky path
// tests all of range's possible cases

#define LOC(x, y) locate(x, y, 3)

/obj/contained/one
/obj/contained/two

/datum/unit_test/range/proc/run_case(atom/center, list/expected, identifier, isorange, view_size = 1)
var/error_index = 0
var/list/result = isorange ? orange(center, 1) : range(center, view_size)
try
if(result.len != expected.len)
error_index = expected.len
CRASH("result is [result.len > expected.len ? "longer" : "shorter"] than expected")
for(var/index in 1 to result.len)
if(result[index] != expected[index])
error_index = index
CRASH("result does not match expected")
catch(var/exception/exc)
var/list/error_output = list()
error_output += "[identifier]: [exc]"
error_output += "expected:"
for(var/i in 1 to expected.len)
var/atom/A = expected[i]
error_output += ("\t([A.x], [A.y]) [A.type] [i == error_index ? "<-- here" : null]")
error_output += "got:"
for(var/i in 1 to result.len)
var/atom/A = result[i]
error_output += ("\t([A.x], [A.y]) [A.type] [i == error_index ? "<-- here" : null]")


CRASH(error_output.Join("\n"))

// Tests the implementation of range() and orange()
/datum/unit_test/range/RunTest()
world.maxx = world.maxy = 5
//Test that it goes in the right order
var/list/correctCoordinates = list(
list(3,3),
list(2,2),
list(2,3),
list(2,4),
list(3,2),
list(3,4),
list(4,2),
list(4,3),
list(4,4)
)
var/i = 1
var/turf/centre = locate(3,3,1)
for(var/x in range(1,centre))
var/turf/T = x
ASSERT(!isnull(T))
var/list/coords = correctCoordinates[i]
ASSERT(coords[1] == T.x)
ASSERT(coords[2] == T.y)
i += 1
if(i != 10)
CRASH("range(1,centre) iterated over [i - 1] tiles, expected 9")
//Test that arguments are parsed correctly
var/std = range(1,centre)
if(std ~! range(centre,1))
CRASH("range(1,centre) and range(centre,1) do not return the same result.")
if(std ~! range("3x3",centre))
CRASH("ViewRange argument parsing for range() isn't working correctly.")
//Test that getting the range from a mob includes the mob's loc.
var/list/mob_seen_turfs = list()
var/mob/test/timmy = new(centre)
for(var/turf/x in range(1,timmy))
mob_seen_turfs += list(x)
if(std ~! mob_seen_turfs)
CRASH("Using a non-/turf Center for range() did not work correctly.")
del(timmy)

var/turf/center = LOC(3, 3)
var/area/outer_area = areas_by_type[/area]
var/obj/container = new /obj(center)
var/obj/contained = new /obj/contained/one(container)
var/obj/contained_trash_1 = new /obj/contained/two(contained)
var/obj/contained_trash_2 = new /obj/contained/two(contained)
var/obj/contained_trash_3 = new /obj/contained/two(contained)

var/list/turf_range_case = list(
LOC(3, 3),
outer_area,
container,
LOC(2, 2),
LOC(2, 3),
LOC(2, 4),
LOC(3, 2),
LOC(3, 4),
LOC(4, 2),
LOC(4, 3),
LOC(4, 4),
)

var/list/turf_orange_case = list(
LOC(2, 2),
outer_area,
LOC(2, 3),
LOC(2, 4),
LOC(3, 2),
LOC(3, 4),
LOC(4, 2),
LOC(4, 3),
LOC(4, 4),
)

var/list/container_range_case = list(
contained,
LOC(3, 3),
outer_area,
container,
LOC(2, 2),
LOC(2, 3),
LOC(2, 4),
LOC(3, 2),
LOC(3, 4),
LOC(4, 2),
LOC(4, 3),
LOC(4, 4),
)

var/list/container_orange_case = list(
LOC(3, 3),
outer_area,
LOC(2, 2),
LOC(2, 3),
LOC(2, 4),
LOC(3, 2),
LOC(3, 4),
LOC(4, 2),
LOC(4, 3),
LOC(4, 4),
)

var/list/contained_range_case = list(
contained_trash_1,
contained_trash_2,
contained_trash_3,
container,
contained,
)

var/list/contained_orange_case = list(
container,
)


run_case(center, turf_range_case, nameof(turf_range_case), FALSE)
run_case(center, turf_orange_case, nameof(turf_orange_case), TRUE)
run_case(container, container_range_case, nameof(container_range_case), FALSE)
run_case(container, container_orange_case, nameof(container_orange_case), TRUE)
run_case(contained, contained_range_case, nameof(contained_range_case), FALSE)
run_case(contained, contained_orange_case, nameof(contained_orange_case), TRUE)

// unusual cases

var/list/turf_range_2x2 = list(
center,
outer_area,
container,
LOC(2, 2),
LOC(2, 3),
LOC(3, 2),
)

var/list/turf_orange_2x2 = list(
LOC(2, 2),
outer_area,
LOC(2, 3),
LOC(3, 2),
)

var/list/turf_range_1x3 = list(
center,
outer_area,
container,
LOC(3, 2),
LOC(3, 4),
)

var/list/turf_orange_1x3 = list(
LOC(3, 2),
outer_area,
LOC(3, 4)
)

var/list/turf_range_3x1 = list(
center,
outer_area,
container,
LOC(2, 3),
LOC(4, 3),
)

var/list/turf_orange_3x1 = list(
LOC(2, 3),
outer_area,
LOC(4, 3),
)

run_case(center, turf_range_2x2, nameof(turf_range_2x2), FALSE, "2x2")
run_case(center, turf_orange_2x2, nameof(turf_orange_2x2), TRUE, "2x2")
run_case(center, turf_range_1x3, nameof(turf_range_1x3), FALSE, "1x3")
run_case(center, turf_orange_1x3, nameof(turf_orange_1x3), TRUE, "1x3")
run_case(center, turf_range_3x1, nameof(turf_range_3x1), FALSE, "3x1")
run_case(center, turf_orange_3x1, nameof(turf_orange_3x1), TRUE, "3x1")

// FIXME: these pass in BYOND, but the way we iterate over area turfs diverges
// var/list/area_range_case = list(outer_area) + outer_area.contents
// var/list/area_orange_case = area_range_case.Copy()
// run_case(outer_area, area_range_case, nameof(area_range_case), FALSE)
// run_case(outer_area, area_orange_case, nameof(area_orange_case), TRUE)

del(container)

#undef LOC
8 changes: 8 additions & 0 deletions Content.IntegrationTests/DMProject/code.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
/turf/border
/mob/test

var/global/list/areas_by_type = list()
/area/New()
areas_by_type[type] = src


//The actual tests
//NOTE: Tests placed in the IntegrationTests suite
// should actually require a normal server in order to work.
Expand All @@ -26,6 +31,9 @@
throw EXCEPTION("You must override RunTest()")

/world/New()
// prepare areas
for(var/area_subtype in typesof(/area) - /area)
new area_subtype()
for(var/subtype in typesof(/datum/unit_test))
if(subtype == /datum/unit_test) //skip the base class
continue
Expand Down
4 changes: 2 additions & 2 deletions OpenDreamRuntime/Objects/Types/DreamObjectClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ protected override bool TryGetVar(string varName, out DreamValue value) {
return true;
case "view":
// Number if square & centerable, string representation otherwise
if (View is { IsSquare: true, IsCenterable: true }) {
value = new DreamValue(View.Range);
if (View.CanSquareRange) {
value = new DreamValue(View.SquareRange.Value);
} else {
value = new DreamValue(View.ToString());
}
Expand Down
4 changes: 2 additions & 2 deletions OpenDreamRuntime/Objects/Types/DreamObjectWorld.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ protected override bool TryGetVar(string varName, out DreamValue value) {

case "view":
// Number if square & centerable, string representation otherwise
if (DefaultView.IsSquare && DefaultView.IsCenterable) {
value = new DreamValue(DefaultView.Range);
if (DefaultView.CanSquareRange) {
value = new DreamValue(DefaultView.SquareRange.Value);
} else {
value = new DreamValue(DefaultView.ToString());
}
Expand Down
Loading
Loading