Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create interaction test harness. #27643

Merged
merged 7 commits into from
Dec 23, 2024
68 changes: 68 additions & 0 deletions code/tests/_game_test_puppeteer.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* A testing object used to control mobs in game tests.
*
* Puppeteers provide an easy way to create mobs and objects,
* perform interactions in the same way that a player would,
* and check the state of the mob during tests.
*/
/datum/test_puppeteer
var/mob/living/carbon/puppet
var/datum/game_test/origin_test

/datum/test_puppeteer/New(datum/game_test/origin_test_, carbon_type = /mob/living/carbon/human, turf/initial_location)
if(!ispath(carbon_type, /mob/living/carbon/human))
origin_test.Fail("unexpected puppeteer carbon type [carbon_type]", __FILE__, __LINE__)

if(!initial_location)
initial_location = locate(179, 136, 1) // Center of admin testing area
origin_test = origin_test_
puppet = origin_test.allocate(carbon_type, initial_location)
var/datum/mind/new_mind = new("interaction_test_[puppet.UID()]")
new_mind.transfer_to(puppet)

/datum/test_puppeteer/proc/spawn_puppet_nearby(carbon_type = /mob/living/carbon/human)
for(var/turf/T in RANGE_TURFS(1, puppet.loc))
if(!is_blocked_turf(T, exclude_mobs = FALSE))
return new/datum/test_puppeteer(origin_test, carbon_type, T)

origin_test.Fail("could not spawn puppeteer near [src]")

/datum/test_puppeteer/proc/spawn_obj_in_hand(obj_type)
var/obj/new_obj = origin_test.allocate(obj_type, null)
if(puppet.put_in_hands(new_obj))
return new_obj

origin_test.Fail("could not spawn obj [obj_type] in hand of [puppet]")

/datum/test_puppeteer/proc/spawn_obj_nearby(obj_type)
for(var/turf/T in RANGE_TURFS(1, puppet.loc))
if(!is_blocked_turf(T, exclude_mobs = FALSE))
return origin_test.allocate(obj_type, T)

origin_test.Fail("could not spawn obj [obj_type] near [src]")

/datum/test_puppeteer/proc/click_on(target, params)
var/datum/test_puppeteer/puppet_target = target
sleep(max(puppet.next_click, puppet.next_move) - world.time + 1)
if(istype(puppet_target))
puppet.ClickOn(puppet_target.puppet, params)
return

puppet.ClickOn(target, params)

/datum/test_puppeteer/proc/spawn_mob_nearby(mob_type)
for(var/turf/T in RANGE_TURFS(1, puppet))
if(!is_blocked_turf(T, exclude_mobs = FALSE))
var/mob/new_mob = origin_test.allocate(mob_type, T)
return new_mob

/datum/test_puppeteer/proc/check_attack_log(snippet)
for(var/log_text in puppet.attack_log_old)
if(findtextEx(log_text, snippet))
return TRUE

/datum/test_puppeteer/proc/set_intent(new_intent)
puppet.a_intent_change(new_intent)

/datum/test_puppeteer/proc/rejuvenate()
puppet.rejuvenate()
17 changes: 17 additions & 0 deletions code/tests/attack_chain/test_attack_chain_cult_dagger.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/datum/game_test/attack_chain_cult_dagger/Run()
var/datum/test_puppeteer/cultist = new(src)
var/datum/test_puppeteer/target = cultist.spawn_puppet_nearby()

cultist.puppet.mind.add_antag_datum(/datum/antagonist/cultist)
cultist.spawn_obj_in_hand(/obj/item/melee/cultblade/dagger)
cultist.set_intent("harm")
cultist.click_on(target)

TEST_ASSERT(target.check_attack_log("Attacked with ritual dagger"), "non-cultist missing dagger attack log")
TEST_ASSERT_NOTEQUAL(target.puppet.health, target.puppet.getMaxHealth(), "cultist attacking non-cultist with dagger caused no damage")

target.rejuvenate()
target.puppet.mind.add_antag_datum(/datum/antagonist/cultist)

cultist.click_on(target)
TEST_ASSERT_EQUAL(target.puppet.health, target.puppet.getMaxHealth(), "cultist attacking cultist with dagger caused damage")
26 changes: 26 additions & 0 deletions code/tests/attack_chain/test_attack_chain_vehicles.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/datum/game_test/attack_chain_vehicles/Run()
var/datum/test_puppeteer/player = new(src)
var/obj/item/key/janitor/janicart_key = player.spawn_obj_in_hand(/obj/item/key/janitor)
var/obj/vehicle/janicart/janicart = player.spawn_obj_nearby(/obj/vehicle/janicart)

player.click_on(janicart)
TEST_ASSERT_EQUAL(janicart.inserted_key, janicart_key, "did not find janicart key in vehicle")

var/move_delay = janicart.vehicle_move_delay
player.spawn_obj_in_hand(/obj/item/borg/upgrade/vtec)
player.click_on(janicart)
TEST_ASSERT(janicart.vehicle_move_delay < move_delay, "VTEC upgrade not applied properly")

TEST_ASSERT_NULL(janicart.mybag, "unexpected trash bag on janicart")
var/obj/item/storage/bag/trash/bag = player.spawn_obj_in_hand(/obj/item/storage/bag/trash)
player.click_on(janicart)
TEST_ASSERT_EQUAL(janicart.mybag, bag, "trash bag not attached to janicart")

var/obj/item/kitchen/knife/knife = player.spawn_obj_in_hand(/obj/item/kitchen/knife)
player.set_intent("harm")
player.click_on(janicart)
TEST_ASSERT(janicart.obj_integrity < janicart.max_integrity, "knife attack not performed")

player.set_intent("help")
player.click_on(janicart)
TEST_ASSERT(knife in bag, "knife not placed in trash bag")
3 changes: 3 additions & 0 deletions code/tests/game_tests.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
//Keep this sorted alphabetically

#ifdef GAME_TESTS
#include "_game_test_puppeteer.dm"
#include "_game_test.dm"
#include "atmos\test_ventcrawl.dm"
#include "attack_chain\test_attack_chain_cult_dagger.dm"
#include "attack_chain\test_attack_chain_vehicles.dm"
#include "games\test_cards.dm"
#include "jobs\test_job_globals.dm"
#include "test_aicard_icons.dm"
Expand Down
10 changes: 9 additions & 1 deletion code/tests/test_runner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,15 @@

if(!test.succeeded)
failed_any_test = TRUE
test_logs[I] += test.fail_reasons
for(var/fail_reason in test.fail_reasons)
if(islist(fail_reason))
var/text = fail_reason[1]
var/file = fail_reason[2]
var/line = fail_reason[3]

test_logs[I] += "[file]:[line]: [text]"
else
test_logs[I] += fail_reason

qdel(test)

Expand Down
Loading