Merge pull request #13349 from LetterN/git-updates

Updates git, travis, and build tests
This commit is contained in:
silicons
2020-10-11 01:24:09 -07:00
committed by GitHub
35 changed files with 746 additions and 230 deletions
+6 -3
View File
@@ -1,11 +1,14 @@
[*]
insert_final_newline = true
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
#end_of_line = lf
[*.yml]
indent_style = space
indent_size = 2
[*.txt]
insert_final_newline = false
[*.py]
indent_style = space
+41 -8
View File
@@ -1,9 +1,42 @@
# merger hooks, run tools/hooks/install.bat or install.sh to set up
*.dmm merge=dmm
*.dmi merge=dmi
# force changelog merging to use union
html/changelog.html merge=union
# force all files to be LF
* text=auto
## Enforce text mode and LF line breaks
## porter note: not yet LFing dm.
# *.bat text eol=lf
*.css text eol=lf
# *.dm text eol=lf
# *.dme text eol=lf
# *.dmf text eol=lf
*.htm text eol=lf
*.html text eol=lf
*.js text eol=lf
*.json text eol=lf
*.jsx text eol=lf
# *.md text eol=lf
*.py text eol=lf
*.scss text eol=lf
# *.sh text eol=lf
# *.sql text eol=lf
*.svg text eol=lf
*.ts text eol=lf
*.tsx text eol=lf
# *.txt text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
## Enforce binary mode
*.bmp binary
*.dll binary
*.dmb binary
*.exe binary
*.gif binary
*.jpg binary
*.png binary
*.so binary
## Merger hooks, run tools/hooks/install.bat or install.sh to set up
*.dmm text eol=lf merge=dmm
*.dmi binary merge=dmi
## Force changelog merging to use union
html/changelog.html text eol=lf merge=union
-36
View File
@@ -1,36 +0,0 @@
name: Autobuild TGUI
on:
push:
branches:
- 'master'
paths:
- 'tgui/**.js'
- 'tgui/**.scss'
jobs:
build:
name: Rebuild TGUI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
with:
fetch-depth: 25
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '>=12.13'
- name: Build TGUI
run: bin/tgui --ci
working-directory: ./tgui
- name: Commit Artifacts
run: |
git config --local user.email "action@github.com"
git config --local user.name "TGUI"
git pull origin master
git commit -m "Automatic TGUI Rebuild [ci skip]" -a || true
- name: Push Artifacts
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_MASTER_KEY }}
+12
View File
@@ -0,0 +1,12 @@
name: "Round ID Linker"
on:
issues:
types: [opened]
jobs:
link_rounds:
runs-on: ubuntu-latest
steps:
- uses: Cidatel-Station-13/round_linker@master #notice: fork the round linkies from tg!!
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
+25 -2
View File
@@ -198,13 +198,36 @@ Temporary Items
!/.vscode/extensions.json
tools/MapAtmosFixer/MapAtmosFixer/obj/*
tools/MapAtmosFixer/MapAtmosFixer/bin/*
tools/CreditsTool/bin/*
tools/CreditsTool/obj/*
#GitHub Atom
.atom-build.json
#Jukebox audio files
/config/jukebox_music/**/*
#KDevelop and Kate
*.kdev4*
*.kate-swp
#extra map stuff
/_maps/**/backup/
/_maps/templates.dm
#dmdoc default folder
/dmdoc
# Ignore custom music and title screens (amend as appropriate)
/config/jukebox_music/sounds/*
!/config/jukebox_music/sounds/exclude
/config/title_music/sounds/*
!/config/title_music/sounds/exclude
/config/title_screens/images/*
!/config/title_screens/images/exclude
#Linux docker
tools/LinuxOneShot/SetupProgram/obj/*
tools/LinuxOneShot/SetupProgram/bin/*
tools/LinuxOneShot/SetupProgram/.vs
tools/LinuxOneShot/Database
tools/LinuxOneShot/TGS_Config
tools/LinuxOneShot/TGS_Instances
tools/LinuxOneShot/TGS_Logs
+11
View File
@@ -0,0 +1,11 @@
build:
stage: build
rules:
- if: $CI_MERGE_REQUEST_IID || $CI_COMMIT_REF_NAME == "master"
changes:
- tgui/**/*.js
- tgui/**/*.scss
when: always
image: node:lts
script:
- tgui/bin/tgui --ci
View File
+27 -3
View File
@@ -1,13 +1,13 @@
language: generic
os: linux
dist: xenial
sudo: false
branches:
except:
- ___TGS3TempBranch
- ___TGSTempBranch
matrix:
jobs:
include:
- name: "Run Linters"
addons:
@@ -16,9 +16,15 @@ matrix:
- python3
- python3-pip
- python3-setuptools
- pcregrep
- rustc
- cargo
cache:
directories:
- $HOME/SpacemanDMM
install:
- tools/travis/install_build_tools.sh
- tools/travis/install_dreamchecker.sh
- tools/travis/install_spaceman_dmm.sh dreamchecker
script:
- tools/travis/check_filedirs.sh tgstation.dme
- tools/travis/check_changelogs.sh
@@ -76,3 +82,21 @@ matrix:
script:
- tools/travis/dm.sh -DTRAVISBUILDING tgstation.dme || travis_terminate 1
- tools/travis/run_server.sh
# - name: "Generate Documentation"
# # Only run for non-PR commits to the real master branch.
# if: branch = master AND head_branch IS blank
# install:
# - tools/travis/install_spaceman_dmm.sh dmdoc
# before_script:
# # Travis checks out a hash, try to get back on a branch.
# - git checkout $TRAVIS_BRANCH || true
# script:
# - ~/dmdoc
# - touch dmdoc/.nojekyll
# deploy:
# provider: pages
# skip_cleanup: true
# local_dir: dmdoc
# token: $DMDOC_GITHUB_TOKEN
# fqdn: codedocs.tgstation13.org
+40 -120
View File
@@ -12556,15 +12556,11 @@
/area/engine/atmospherics_engine)
"aAb" = (
/turf/closed/wall,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aAc" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/closed/wall,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aAd" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/neutral{
@@ -13138,9 +13134,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBh" = (
/obj/item/kirbyplants/random,
/obj/machinery/light/small{
@@ -13149,25 +13143,19 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBi" = (
/obj/structure/table,
/obj/item/clothing/suit/apron/overalls,
/obj/item/cultivator,
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBj" = (
/obj/machinery/biogenerator,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBk" = (
/obj/structure/table,
/obj/item/reagent_containers/food/snacks/grown/wheat,
@@ -13182,18 +13170,14 @@
pixel_y = 4
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBl" = (
/obj/machinery/hydroponics/soil,
/obj/item/seeds/tea,
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBm" = (
/obj/item/kirbyplants/random,
/obj/machinery/status_display/evac{
@@ -13201,9 +13185,7 @@
},
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBn" = (
/obj/structure/table,
/obj/item/stack/packageWrap,
@@ -13213,9 +13195,7 @@
/obj/item/reagent_containers/food/snacks/grown/cherries,
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBo" = (
/obj/item/kirbyplants/random,
/obj/machinery/light/small{
@@ -13225,18 +13205,14 @@
/obj/effect/turf_decal/delivery,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBp" = (
/obj/machinery/hydroponics/soil,
/obj/item/seeds/poppy,
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aBq" = (
/obj/structure/cable/white{
icon_state = "2-4"
@@ -13817,33 +13793,25 @@
/area/engine/atmospherics_engine)
"aCv" = (
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aCw" = (
/obj/effect/turf_decal/delivery,
/obj/machinery/hydroponics/soil,
/obj/item/seeds/watermelon,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aCx" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aCy" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aCz" = (
/obj/structure/cable/white{
icon_state = "1-2"
@@ -14459,21 +14427,15 @@
},
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aDy" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aDz" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aDA" = (
/obj/structure/sink{
dir = 4;
@@ -14484,9 +14446,7 @@
},
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aDB" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -14968,34 +14928,26 @@
icon_state = "2-4"
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aEC" = (
/obj/structure/cable/white{
icon_state = "4-8"
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aED" = (
/obj/structure/cable/white{
icon_state = "4-8"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aEE" = (
/obj/structure/cable/white{
icon_state = "2-8"
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aEG" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -15628,18 +15580,14 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFK" = (
/obj/machinery/hydroponics/soil,
/obj/item/seeds/harebell,
/obj/machinery/light/small,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFL" = (
/obj/structure/table,
/obj/item/shovel/spade,
@@ -15658,9 +15606,7 @@
},
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFM" = (
/obj/machinery/status_display/evac{
pixel_y = -32
@@ -15669,34 +15615,26 @@
/obj/machinery/hydroponics/soil,
/obj/item/seeds/poppy/geranium,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFN" = (
/obj/structure/table,
/obj/item/plant_analyzer,
/obj/item/hatchet,
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFO" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFP" = (
/obj/structure/cable/white{
icon_state = "1-2"
},
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFQ" = (
/obj/structure/table,
/obj/item/crowbar,
@@ -15704,9 +15642,7 @@
/obj/item/reagent_containers/glass/bucket,
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFR" = (
/obj/machinery/hydroponics/soil,
/obj/item/seeds/tower,
@@ -15715,9 +15651,7 @@
/obj/effect/turf_decal/delivery,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aFS" = (
/obj/structure/cable/white{
icon_state = "1-2"
@@ -16707,9 +16641,7 @@
"aHl" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aHm" = (
/obj/machinery/door/airlock/maintenance_hatch{
name = "Maintenance Hatch";
@@ -16721,9 +16653,7 @@
dir = 1
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aHn" = (
/obj/machinery/door/airlock/maintenance_hatch{
name = "Maintenance Hatch";
@@ -16737,16 +16667,12 @@
dir = 1
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aHo" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"aHp" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable/white{
@@ -125347,9 +125273,7 @@
/obj/item/reagent_containers/glass/bucket,
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"etO" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -125474,9 +125398,7 @@
/obj/machinery/hydroponics/soil,
/obj/item/seeds/grape,
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"faI" = (
/obj/structure/cable/white{
icon_state = "1-2"
@@ -126395,9 +126317,7 @@
pixel_x = 6
},
/turf/open/floor/plasteel,
/area/hydroponics/garden/abandoned{
name = "Maintenance Garden"
})
/area/hydroponics/garden/abandoned)
"loH" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
+1 -3
View File
@@ -75352,9 +75352,7 @@
/obj/machinery/atmospherics/pipe/simple/orange/visible{
dir = 4
},
/obj/machinery/airalarm{
pixel_z = 24
},
/obj/machinery/airalarm,
/obj/machinery/light/small,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating{
+1
View File
@@ -36,6 +36,7 @@
var/grab_state = 0
var/throwforce = 0
var/datum/component/orbiter/orbiting
/// Used for space ztransit stuff
var/can_be_z_moved = TRUE
///If we were without gravity and another animation happened, the bouncing will stop, and we need to restart it in next life().
var/floating_need_update = FALSE
+20 -14
View File
@@ -133,13 +133,10 @@
else
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")
/turf/open/space/Entered(atom/movable/A, atom/OldLoc)
. = ..()
var/turf/old = get_turf(OldLoc)
if(!isspaceturf(old) && ismob(A))
var/mob/M = A
M.update_gravity(M.mob_has_gravity())
/turf/open/space/Entered(atom/movable/A)
..()
if ((!(A) || src != A.loc))
return
if(destination_z && destination_x && destination_y && !(A.pulledby || !A.can_be_z_moved))
var/tx = destination_x
@@ -160,18 +157,27 @@
ty--
DT = locate(tx, ty, destination_z)
var/atom/movable/AM = A.pulling
var/atom/movable/pulling = A.pulling
var/atom/movable/puller = A
A.forceMove(DT)
if(AM)
var/turf/T = get_step(A.loc,turn(A.dir, 180))
AM.can_be_z_moved = FALSE
AM.forceMove(T)
A.start_pulling(AM)
AM.can_be_z_moved = TRUE
while (pulling != null)
var/next_pulling = pulling.pulling
var/turf/T = get_step(puller.loc, turn(puller.dir, 180))
pulling.can_be_z_moved = FALSE
pulling.forceMove(T)
puller.start_pulling(pulling)
pulling.can_be_z_moved = TRUE
puller = pulling
pulling = next_pulling
//now we're on the new z_level, proceed the space drifting
stoplag()//Let a diagonal move finish, if necessary
A.newtonian_move(A.inertia_dir)
A.inertia_moving = TRUE
/turf/open/space/Exited(atom/movable/AM, atom/OldLoc)
. = ..()
+28
View File
@@ -2,13 +2,41 @@
//Keep this sorted alphabetically
#ifdef UNIT_TESTS
/// Asserts that a condition is true
/// If the condition is not true, fails the test
#define TEST_ASSERT(assertion, reason) if (!(assertion)) { return Fail("Assertion failed: [reason || "No reason"]") }
/// Asserts that the two parameters passed are equal, fails otherwise
/// Optionally allows an additional message in the case of a failure
#define TEST_ASSERT_EQUAL(a, b, message) if ((a) != (b)) { return Fail("Expected [isnull(a) ? "null" : a] to be equal to [isnull(b) ? "null" : b].[message ? " [message]" : ""]") }
#include "anchored_mobs.dm"
#include "bespoke_id.dm"
// #include "binary_insert.dm"
// #include "card_mismatch.dm" shame we don't have this!
#include "chain_pull_through_space.dm"
#include "character_saving.dm"
#include "component_tests.dm"
// #include "confusion.dm"
// #include "keybinding_init.dm"
#include "machine_disassembly.dm"
#include "medical_wounds.dm"
// #include "metabolizing.dm"
// #include "outfit_sanity.dm"
// #include "plantgrowth_tests.dm"
// #include "quick_swap_sanity.dm" - we don't have quick swap yet
#include "reagent_id_typos.dm"
#include "reagent_recipe_collisions.dm"
#include "resist.dm"
// #include "say.dm" //no saymods, someone update saycode please.
// #include "siunit.dm"
#include "spawn_humans.dm"
// #include "species_whitelists.dm"
#include "subsystem_init.dm"
#include "surgeries.dm"
#include "timer_sanity.dm"
#include "unit_test.dm"
#undef TEST_ASSERT
#undef TEST_ASSERT_EQUAL
#endif
+1 -1
View File
@@ -6,4 +6,4 @@
L += "[i]"
if(!L.len)
return //passed!
Fail("The following mobs are defined as anchored. This is incompatible with the new move force/resist system and needs to be revised.: [L.Join(" ")]")
Fail("The following mobs are defined as anchored. This is incompatible with the new move force/resist system and needs to be revised.: [L.Join(" ")]")
+8
View File
@@ -0,0 +1,8 @@
/datum/unit_test/bespoke_id/Run()
var/datum/element/base = /datum/element
var/base_index = initial(base.id_arg_index)
for(var/i in subtypesof(/datum/element))
var/datum/element/faketype = i
if((initial(faketype.element_flags) & ELEMENT_BESPOKE) && initial(faketype.id_arg_index) == base_index)
Fail("A bespoke element was not configured with a proper id_arg_index: [faketype]")
+26
View File
@@ -0,0 +1,26 @@
/// A test to ensure the sanity of BINARY_INSERT
/datum/unit_test/binary_insert/Run()
var/list/datum/binary_insert_node/nodes = list()
var/datum/binary_insert_node/node_a = new /datum/binary_insert_node(10)
BINARY_INSERT(node_a, nodes, /datum/binary_insert_node, node_a, x, COMPARE_KEY)
TEST_ASSERT_EQUAL(nodes.len, 1, "List should have one node")
var/datum/binary_insert_node/node_b = new /datum/binary_insert_node(5)
BINARY_INSERT(node_b, nodes, /datum/binary_insert_node, node_b, x, COMPARE_KEY)
TEST_ASSERT_EQUAL(nodes.len, 2, "List should have two nodes")
TEST_ASSERT_EQUAL(nodes[1].x, 5, "The first node should be the one with 5")
TEST_ASSERT_EQUAL(nodes[2].x, 10, "The second node should be the one with 10")
var/datum/binary_insert_node/node_c = new /datum/binary_insert_node(15)
BINARY_INSERT(node_c, nodes, /datum/binary_insert_node, node_c, x, COMPARE_KEY)
TEST_ASSERT_EQUAL(nodes.len, 3, "List should have three nodes")
TEST_ASSERT_EQUAL(nodes[1].x, 5, "The first node should be the one with 5")
TEST_ASSERT_EQUAL(nodes[2].x, 10, "The second node should be the one with 10")
TEST_ASSERT_EQUAL(nodes[3].x, 15, "The third node should be the one with 15")
/datum/binary_insert_node
var/x
/datum/binary_insert_node/New(_x)
x = _x
@@ -0,0 +1,62 @@
/datum/unit_test/chain_pull_through_space
var/turf/open/space/space_tile
var/turf/claimed_tile
var/mob/living/carbon/human/alice
var/mob/living/carbon/human/bob
var/mob/living/carbon/human/charlie
/datum/unit_test/chain_pull_through_space/New()
..()
// Create a space tile that goes to another z-level
claimed_tile = run_loc_bottom_left
space_tile = new(locate(run_loc_bottom_left.x, run_loc_bottom_left.y, run_loc_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.name = "Alice"
bob = new(locate(run_loc_bottom_left.x + 3, run_loc_bottom_left.y, run_loc_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.name = "Charlie"
/datum/unit_test/chain_pull_through_space/Destroy()
space_tile.copyTurf(claimed_tile)
qdel(alice)
qdel(bob)
qdel(charlie)
return ..()
/datum/unit_test/chain_pull_through_space/Run()
// Alice pulls Bob, who pulls Charlie
// Normally, when Alice moves forward, the rest follow
alice.start_pulling(bob)
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)
return Fail("During normal move, Bob was not at the correct x ([bob.x])")
if (charlie.x != run_loc_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)
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])")
if (bob.z != space_tile.destination_z)
return Fail("Bob did not teleport to the destination z-level. Current location: ([bob.x], [bob.y], [bob.z])")
if (!bob.Adjacent(alice))
return Fail("Bob is not adjacent to Alice. Bob is at [bob.x], Alice is at [alice.x]")
if (charlie.z != space_tile.destination_z)
return Fail("Charlie did not teleport to the destination z-level. Current location: ([charlie.x], [charlie.y], [charlie.z])")
if (!charlie.Adjacent(bob))
return Fail("Charlie is not adjacent to Bob. Charlie is at [charlie.x], Bob is at [bob.x]")
+1 -1
View File
@@ -9,4 +9,4 @@
if(dupe_type && !ispath(dupe_type))
bad_dts += t
if(length(bad_dms) || length(bad_dts))
Fail("Components with invalid dupe modes: ([bad_dms.Join(",")]) ||| Components with invalid dupe types: ([bad_dts.Join(",")])")
Fail("Components with invalid dupe modes: ([bad_dms.Join(",")]) ||| Components with invalid dupe types: ([bad_dts.Join(",")])")
@@ -0,0 +1,13 @@
/// Ensures that when disassembling a machine, all the parts are given back
/datum/unit_test/machine_disassembly/Run()
var/obj/machinery/freezer = allocate(/obj/machinery/atmospherics/components/unary/thermomachine/freezer)
var/turf/freezer_location = freezer.loc
freezer_location.ChangeTurf(/turf/open/floor/plasteel)
freezer.deconstruct()
// Check that the components are created
TEST_ASSERT(locate(/obj/item/stock_parts/micro_laser) in freezer_location, "Couldn't find micro-laser when disassembling freezer")
// Check that the circuit board itself is created
TEST_ASSERT(locate(/obj/item/circuitboard/machine/thermomachine/freezer) in freezer_location, "Couldn't find the circuit board when disassembling freezer")
+87
View File
@@ -0,0 +1,87 @@
/// This test is used to make sure a flesh-and-bone base human can suffer all the types of wounds, and that suffering more severe wounds removes and replaces the lesser wound. Also tests that [/mob/living/carbon/proc/fully_heal] removes all wounds
/datum/unit_test/test_human_base/Run()
var/mob/living/carbon/human/victim = allocate(/mob/living/carbon/human)
/// the limbs have no wound resistance like the chest and head do, so let's go with the r_arm
var/obj/item/bodypart/tested_part = victim.get_bodypart(BODY_ZONE_R_ARM)
/// In order of the wound types we're trying to inflict, what sharpness do we need to deal them?
var/list/sharps = list(SHARP_NONE, SHARP_EDGED, SHARP_POINTY, SHARP_NONE)
/// Since burn wounds need burn damage, duh
var/list/dam_types = list(BRUTE, BRUTE, BRUTE, BURN)
var/i = 1
var/list/iter_test_wound_list
for(iter_test_wound_list in list(list(/datum/wound/blunt/moderate, /datum/wound/blunt/severe, /datum/wound/blunt/critical),\
list(/datum/wound/slash/moderate, /datum/wound/slash/severe, /datum/wound/slash/critical),\
list(/datum/wound/pierce/moderate, /datum/wound/pierce/severe, /datum/wound/pierce/critical),\
list(/datum/wound/burn/moderate, /datum/wound/burn/severe, /datum/wound/burn/critical)))
TEST_ASSERT_EQUAL(length(victim.all_wounds), 0, "Patient is somehow wounded before test")
var/datum/wound/iter_test_wound
var/threshold_penalty = 0
for(iter_test_wound in iter_test_wound_list)
var/threshold = initial(iter_test_wound.threshold_minimum) - threshold_penalty // just enough to guarantee the next tier of wound, given the existing wound threshold penalty
if(dam_types[i] == BRUTE)
tested_part.receive_damage(WOUND_MINIMUM_DAMAGE, 0, wound_bonus = threshold, sharpness=sharps[i])
else if(dam_types[i] == BURN)
tested_part.receive_damage(0, WOUND_MINIMUM_DAMAGE, wound_bonus = threshold, sharpness=sharps[i])
TEST_ASSERT(length(victim.all_wounds), "Patient has no wounds when one wound is expected. Severity: [initial(iter_test_wound.severity)]")
TEST_ASSERT_EQUAL(length(victim.all_wounds), 1, "Patient has more than one wound when only one is expected. Severity: [initial(iter_test_wound.severity)]")
var/datum/wound/actual_wound = victim.all_wounds[1]
TEST_ASSERT_EQUAL(actual_wound.type, iter_test_wound, "Patient has wound of incorrect severity. Expected: [initial(iter_test_wound.name)] Got: [actual_wound]")
threshold_penalty = actual_wound.threshold_penalty
i++
victim.fully_heal(TRUE) // should clear all wounds between types
/// This test is used for making sure species with bones but no flesh (skeletons, plasmamen) can only suffer BONE_WOUNDS, and nothing tagged with FLESH_WOUND (it's possible to require both)
/datum/unit_test/test_human_bone/Run()
var/mob/living/carbon/human/victim = allocate(/mob/living/carbon/human)
/// the limbs have no wound resistance like the chest and head do, so let's go with the r_arm
var/obj/item/bodypart/tested_part = victim.get_bodypart(BODY_ZONE_R_ARM)
/// In order of the wound types we're trying to inflict, what sharpness do we need to deal them?
var/list/sharps = list(SHARP_NONE, SHARP_EDGED, SHARP_POINTY, SHARP_NONE)
/// Since burn wounds need burn damage, duh
var/list/dam_types = list(BRUTE, BRUTE, BRUTE, BURN)
var/i = 1
var/list/iter_test_wound_list
victim.dna.species.species_traits &= HAS_FLESH // take away the base human's flesh (ouchie!) ((not actually ouchie, this just affects their wounds and dismemberment handling))
for(iter_test_wound_list in list(list(/datum/wound/blunt/moderate, /datum/wound/blunt/severe, /datum/wound/blunt/critical),\
list(/datum/wound/slash/moderate, /datum/wound/slash/severe, /datum/wound/slash/critical),\
list(/datum/wound/pierce/moderate, /datum/wound/pierce/severe, /datum/wound/pierce/critical),\
list(/datum/wound/burn/moderate, /datum/wound/burn/severe, /datum/wound/burn/critical)))
TEST_ASSERT_EQUAL(length(victim.all_wounds), 0, "Patient is somehow wounded before test")
var/datum/wound/iter_test_wound
var/threshold_penalty = 0
for(iter_test_wound in iter_test_wound_list)
var/threshold = initial(iter_test_wound.threshold_minimum) - threshold_penalty // just enough to guarantee the next tier of wound, given the existing wound threshold penalty
if(dam_types[i] == BRUTE)
tested_part.receive_damage(WOUND_MINIMUM_DAMAGE, 0, wound_bonus = threshold, sharpness=sharps[i])
else if(dam_types[i] == BURN)
tested_part.receive_damage(0, WOUND_MINIMUM_DAMAGE, wound_bonus = threshold, sharpness=sharps[i])
// so if we just tried to deal a flesh wound, make sure we didn't actually suffer it. We may have suffered a bone wound instead, but we just want to make sure we don't have a flesh wound
if(initial(iter_test_wound.wound_flags) & FLESH_WOUND)
if(!length(victim.all_wounds)) // not having a wound is good news
continue
else // we have to check that it's actually a bone wound and not the intended wound type
TEST_ASSERT_EQUAL(length(victim.all_wounds), 1, "Patient has more than one wound when only one is expected. Severity: [initial(iter_test_wound.severity)]")
var/datum/wound/actual_wound = victim.all_wounds[1]
TEST_ASSERT((actual_wound.wound_flags & ~FLESH_WOUND), "Patient has flesh wound despite no HAS_FLESH flag, expected either no wound or bone wound. Offending wound: [actual_wound]")
threshold_penalty = actual_wound.threshold_penalty
else // otherwise if it's a bone wound, check that we have it per usual
TEST_ASSERT(length(victim.all_wounds), "Patient has no wounds when one wound is expected. Severity: [initial(iter_test_wound.severity)]")
TEST_ASSERT_EQUAL(length(victim.all_wounds), 1, "Patient has more than one wound when only one is expected. Severity: [initial(iter_test_wound.severity)]")
var/datum/wound/actual_wound = victim.all_wounds[1]
TEST_ASSERT_EQUAL(actual_wound.type, iter_test_wound, "Patient has wound of incorrect severity. Expected: [initial(iter_test_wound.name)] Got: [actual_wound]")
threshold_penalty = actual_wound.threshold_penalty
i++
victim.fully_heal(TRUE) // should clear all wounds between types
+19
View File
@@ -0,0 +1,19 @@
/datum/unit_test/metabolization/Run()
// Pause natural mob life so it can be handled entirely by the test
SSmobs.pause()
var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human)
var/mob/living/carbon/monkey/monkey = allocate(/mob/living/carbon/monkey)
for (var/reagent_type in subtypesof(/datum/reagent))
test_reagent(human, reagent_type)
test_reagent(monkey, reagent_type)
/datum/unit_test/metabolization/proc/test_reagent(mob/living/carbon/C, reagent_type)
C.reagents.add_reagent(reagent_type, 10)
C.reagents.metabolize(C, can_overdose = TRUE)
C.reagents.clear_reagents()
/datum/unit_test/metabolization/Destroy()
SSmobs.ignite()
return ..()
+50
View File
@@ -0,0 +1,50 @@
#define CHECK_OUTFIT_SLOT(outfit_key, slot_name) if (outfit.##outfit_key) { \
H.equip_to_slot_or_del(new outfit.##outfit_key(H), ##slot_name, TRUE); \
/* We don't check the result of equip_to_slot_or_del because it returns false for random jumpsuits, as they delete themselves on init */ \
if (!H.get_item_by_slot(##slot_name)) { \
Fail("[outfit.name]'s [#outfit_key] is invalid!"); \
} \
}
/datum/unit_test/outfit_sanity/Run()
var/mob/living/carbon/human/H = allocate(/mob/living/carbon/human)
for (var/outfit_type in subtypesof(/datum/outfit))
// Only make one human and keep undressing it because it's much faster
for (var/obj/item/I in H.get_equipped_items(include_pockets = TRUE))
qdel(I)
var/datum/outfit/outfit = new outfit_type
outfit.pre_equip(H, TRUE)
CHECK_OUTFIT_SLOT(uniform, ITEM_SLOT_ICLOTHING)
CHECK_OUTFIT_SLOT(suit, ITEM_SLOT_OCLOTHING)
CHECK_OUTFIT_SLOT(back, ITEM_SLOT_BACK)
CHECK_OUTFIT_SLOT(belt, ITEM_SLOT_BELT)
CHECK_OUTFIT_SLOT(gloves, ITEM_SLOT_GLOVES)
CHECK_OUTFIT_SLOT(shoes, ITEM_SLOT_FEET)
CHECK_OUTFIT_SLOT(head, ITEM_SLOT_HEAD)
CHECK_OUTFIT_SLOT(mask, ITEM_SLOT_MASK)
CHECK_OUTFIT_SLOT(neck, ITEM_SLOT_NECK)
CHECK_OUTFIT_SLOT(ears, ITEM_SLOT_EARS)
CHECK_OUTFIT_SLOT(glasses, ITEM_SLOT_EYES)
CHECK_OUTFIT_SLOT(id, ITEM_SLOT_ID)
CHECK_OUTFIT_SLOT(suit_store, ITEM_SLOT_SUITSTORE)
CHECK_OUTFIT_SLOT(l_pocket, ITEM_SLOT_POCKET)
CHECK_OUTFIT_SLOT(r_pocket, ITEM_SLOT_POCKET)
if (outfit.backpack_contents || outfit.box)
var/list/backpack_contents = outfit.backpack_contents?.Copy()
if (outfit.box)
if (!backpack_contents)
backpack_contents = list()
backpack_contents.Insert(1, outfit.box)
backpack_contents[outfit.box] = 1
for (var/path in backpack_contents)
var/number = backpack_contents[path] || 1
for (var/_ in 1 to number)
if (!H.equip_to_slot_or_del(new path(H), ITEM_SLOT_BACKPACK, TRUE))
Fail("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.")
#undef CHECK_OUTFIT_SLOT
@@ -0,0 +1,27 @@
// Checks plants for broken tray icons. Use Advanced Proc Call to activate.
// Maybe some day it would be used as unit test.
// -------- IT IS NOW!
/datum/unit_test/plantgrowth/Run()
var/list/states = icon_states('icons/obj/hydroponics/growing.dmi')
states |= icon_states('icons/obj/hydroponics/growing_fruits.dmi')
states |= icon_states('icons/obj/hydroponics/growing_flowers.dmi')
states |= icon_states('icons/obj/hydroponics/growing_mushrooms.dmi')
states |= icon_states('icons/obj/hydroponics/growing_vegetables.dmi')
states |= icon_states('goon/icons/obj/hydroponics.dmi')
var/list/paths = subtypesof(/obj/item/seeds) - /obj/item/seeds - typesof(/obj/item/seeds/sample) - /obj/item/seeds/lavaland
for(var/seedpath in paths)
var/obj/item/seeds/seed = new seedpath
for(var/i in 1 to seed.growthstages)
if("[seed.icon_grow][i]" in states)
continue
Fail("[seed.name] ([seed.type]) lacks the [seed.icon_grow][i] icon!")
if(!(seed.icon_dead in states))
Fail("[seed.name] ([seed.type]) lacks the [seed.icon_dead] icon!")
if(seed.icon_harvest) // mushrooms have no grown sprites, same for items with no product
if(!(seed.icon_harvest in states))
Fail("[seed.name] ([seed.type]) lacks the [seed.icon_harvest] icon!")
@@ -0,0 +1,31 @@
/// Test that quick swap correctly swaps items and invalidates suit storage
/datum/unit_test/quick_swap_sanity/Run()
// Create a human with a medical winter coat and a health analyzer in suit storage
var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human)
var/obj/item/coat = allocate(/obj/item/clothing/suit/hooded/wintercoat/medical)
TEST_ASSERT(human.equip_to_slot_if_possible(coat, ITEM_SLOT_OCLOTHING), "Couldn't equip winter coat")
var/obj/item/analyzer = allocate(/obj/item/healthanalyzer)
TEST_ASSERT(human.equip_to_slot_if_possible(analyzer, ITEM_SLOT_SUITSTORE), "Couldn't equip health analyzer")
// Then, have them quick swap between the coat and a space suit
var/obj/item/hardsuit = allocate(/obj/item/clothing/suit/space/hardsuit)
TEST_ASSERT(human.equip_to_appropriate_slot(hardsuit, swap = TRUE), "Couldn't quick swap to hardsuit")
// Check if the human has the hardsuit on
TEST_ASSERT_EQUAL(human.wear_suit, hardsuit, "Human didn't equip the hardsuit")
// Make sure the health analyzer was dropped as part of the swap
// Since health analyzers are an invalid suit storage item
TEST_ASSERT_EQUAL(human.s_store, null, "Human didn't drop the health analyzer")
// Give the human an emergency oxygen tank
// This is valid suit storage for both the winter coat AND the hardsuit
var/obj/item/tank = allocate(/obj/item/tank/internals/emergency_oxygen)
TEST_ASSERT(human.equip_to_slot_if_possible(tank, ITEM_SLOT_SUITSTORE), "Couldn't equip emergency oxygen tank")
// Now, quick swap back to the coat
// Since the tank is a valid suit storage item, it should not be dropped
TEST_ASSERT(human.equip_to_appropriate_slot(coat, swap = TRUE), "Couldn't quick swap to coat")
TEST_ASSERT_EQUAL(human.s_store, tank, "Human dropped the oxygen tank, when it was a valid item to keep in suit storage")
+29
View File
@@ -0,0 +1,29 @@
/// Test that stop, drop, and roll lowers fire stacks
/datum/unit_test/stop_drop_and_roll/Run()
var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human)
TEST_ASSERT_EQUAL(human.fire_stacks, 0, "Human does not have 0 fire stacks pre-ignition")
human.adjust_fire_stacks(5)
human.IgniteMob()
TEST_ASSERT_EQUAL(human.fire_stacks, 5, "Human does not have 5 fire stacks pre-resist")
// Stop, drop, and roll has a sleep call. This would delay the test, and is not necessary.
CallAsync(human, /mob/living/verb/resist)
TEST_ASSERT(human.fire_stacks < 5, "Human did not lower fire stacks after resisting")
/// Test that you can resist out of a container
/datum/unit_test/container_resist/Run()
var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human)
var/obj/structure/closet/closet = allocate(/obj/structure/closet, get_turf(human))
closet.open(human)
TEST_ASSERT(!(human in closet.contents), "Human was in the contents of an open closet")
closet.close(human)
TEST_ASSERT(human in closet.contents, "Human was not in the contents of the closed closet")
human.resist()
TEST_ASSERT(!(human in closet.contents), "Human resisted out of a standard closet, but was still in it")
+24
View File
@@ -0,0 +1,24 @@
/// Test to verify message mods are parsed correctly
/datum/unit_test/get_message_mods
var/mob/host_mob
/datum/unit_test/get_message_mods/Run()
host_mob = allocate(/mob/living/carbon/human)
test("Hello", "Hello", list())
test(";HELP", "HELP", list(MODE_HEADSET = TRUE))
test(";%Never gonna give you up", "Never gonna give you up", list(MODE_HEADSET = TRUE, MODE_SING = TRUE))
test(".s Gun plz", "Gun plz", list(RADIO_KEY = RADIO_KEY_SECURITY, RADIO_EXTENSION = RADIO_CHANNEL_SECURITY))
test("...What", "...What", list())
//note to lettern: add the ++, ||, __, and the verb*text checks
/datum/unit_test/get_message_mods/proc/test(message, expected_message, list/expected_mods)
var/list/mods = list()
TEST_ASSERT_EQUAL(host_mob.get_message_mods(message, mods), expected_message, "Chopped message was not what we expected. Message: [message]")
for (var/mod_key in mods)
TEST_ASSERT_EQUAL(mods[mod_key], expected_mods[mod_key], "The value for [mod_key] was not what we expected. Message: [message]")
expected_mods -= mod_key
if (expected_mods.len)
Fail("Some message mods were expected, but were not returned by get_message_mods: [json_encode(expected_mods)]. Message: [message]")
+4 -4
View File
@@ -1,7 +1,7 @@
/datum/unit_test/spawn_humans/Run()
var/locs = block(run_loc_bottom_left, run_loc_top_right)
var/locs = block(run_loc_bottom_left, run_loc_top_right)
for(var/I in 1 to 5)
new /mob/living/carbon/human(pick(locs))
for(var/I in 1 to 5)
new /mob/living/carbon/human(pick(locs))
sleep(50)
sleep(50)
+1 -1
View File
@@ -4,4 +4,4 @@
if(ss.flags & SS_NO_INIT)
continue
if(!ss.initialized)
Fail("[ss]([ss.type]) is a subsystem meant to initialize but doesn't get set as initialized.")
Fail("[ss]([ss.type]) is a subsystem meant to initialize but doesn't get set as initialized.")
+79
View File
@@ -0,0 +1,79 @@
/datum/unit_test/amputation/Run()
var/mob/living/carbon/human/patient = allocate(/mob/living/carbon/human)
var/mob/living/carbon/human/user = allocate(/mob/living/carbon/human)
TEST_ASSERT_EQUAL(patient.get_missing_limbs().len, 0, "Patient is somehow missing limbs before surgery")
var/datum/surgery/amputation/surgery = new(patient, BODY_ZONE_R_ARM, patient.get_bodypart(BODY_ZONE_R_ARM))
var/datum/surgery_step/sever_limb/sever_limb = new
sever_limb.success(user, patient, BODY_ZONE_R_ARM, null, surgery)
TEST_ASSERT_EQUAL(patient.get_missing_limbs().len, 1, "Patient did not lose any limbs")
TEST_ASSERT_EQUAL(patient.get_missing_limbs()[1], BODY_ZONE_R_ARM, "Patient is missing a limb that isn't the one we operated on")
/datum/unit_test/brain_surgery/Run()
var/mob/living/carbon/human/patient = allocate(/mob/living/carbon/human)
patient.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_SURGERY)
patient.setOrganLoss(ORGAN_SLOT_BRAIN, 20)
TEST_ASSERT(patient.has_trauma_type(), "Patient does not have any traumas, despite being given one")
var/mob/living/carbon/human/user = allocate(/mob/living/carbon/human)
var/datum/surgery_step/fix_brain/fix_brain = new
fix_brain.success(user, patient)
TEST_ASSERT(!patient.has_trauma_type(), "Patient kept their brain trauma after brain surgery")
TEST_ASSERT(patient.getOrganLoss(ORGAN_SLOT_BRAIN) < 20, "Patient did not heal their brain damage after brain surgery")
/datum/unit_test/multiple_surgeries/Run()
var/mob/living/carbon/human/user = allocate(/mob/living/carbon/human)
var/mob/living/carbon/human/patient_zero = allocate(/mob/living/carbon/human)
var/mob/living/carbon/human/patient_one = allocate(/mob/living/carbon/human)
var/obj/item/scalpel/scalpel = allocate(/obj/item/scalpel)
var/datum/surgery_step/incise/surgery_step = new
var/datum/surgery/organ_manipulation/surgery_for_zero = new
INVOKE_ASYNC(surgery_step, /datum/surgery_step/proc/initiate, user, patient_zero, BODY_ZONE_CHEST, scalpel, surgery_for_zero)
TEST_ASSERT(surgery_for_zero.step_in_progress, "Surgery on patient zero was not initiated")
var/datum/surgery/organ_manipulation/surgery_for_one = new
// Without waiting for the incision to complete, try to start a new surgery
TEST_ASSERT(!surgery_step.initiate(user, patient_one, BODY_ZONE_CHEST, scalpel, surgery_for_one), "Was allowed to start a second surgery without the rod of asclepius")
TEST_ASSERT(!surgery_for_one.step_in_progress, "Surgery for patient one is somehow in progress, despite not initiating")
user.apply_status_effect(STATUS_EFFECT_HIPPOCRATIC_OATH)
INVOKE_ASYNC(surgery_step, /datum/surgery_step/proc/initiate, user, patient_one, BODY_ZONE_CHEST, scalpel, surgery_for_one)
TEST_ASSERT(surgery_for_one.step_in_progress, "Surgery on patient one was not initiated, despite having rod of asclepius")
/datum/unit_test/tend_wounds/Run()
var/mob/living/carbon/human/patient = allocate(/mob/living/carbon/human)
patient.take_overall_damage(100, 100)
var/mob/living/carbon/human/user = allocate(/mob/living/carbon/human)
// Test that tending wounds actually lowers damage
var/datum/surgery_step/heal/brute/basic/basic_brute_heal = new
basic_brute_heal.success(user, patient, BODY_ZONE_CHEST)
TEST_ASSERT(patient.getBruteLoss() < 100, "Tending brute wounds didn't lower brute damage ([patient.getBruteLoss()])")
var/datum/surgery_step/heal/burn/basic/basic_burn_heal = new
basic_burn_heal.success(user, patient, BODY_ZONE_CHEST)
TEST_ASSERT(patient.getFireLoss() < 100, "Tending burn wounds didn't lower burn damage ([patient.getFireLoss()])")
// Test that wearing clothing lowers heal amount
var/mob/living/carbon/human/naked_patient = allocate(/mob/living/carbon/human)
naked_patient.take_overall_damage(100)
var/mob/living/carbon/human/clothed_patient = allocate(/mob/living/carbon/human)
clothed_patient.equipOutfit(/datum/outfit/job/doctor, TRUE)
clothed_patient.take_overall_damage(100)
basic_brute_heal.success(user, naked_patient, BODY_ZONE_CHEST)
basic_brute_heal.success(user, clothed_patient, BODY_ZONE_CHEST)
TEST_ASSERT(naked_patient.getBruteLoss() < clothed_patient.getBruteLoss(), "Naked patient did not heal more from wounds tending than a clothed patient")
+16 -6
View File
@@ -1,14 +1,9 @@
/*
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_bottom_left and run_loc_top_right to get turfs for testing
*/
GLOBAL_DATUM(current_test, /datum/unit_test)
@@ -18,16 +13,18 @@ GLOBAL_VAR(test_log)
/datum/unit_test
//Bit of metadata for the future maybe
var/list/procs_tested
//usable vars
var/turf/run_loc_bottom_left
var/turf/run_loc_top_right
//internal shit
var/succeeded = TRUE
var/list/allocated
var/list/fail_reasons
/datum/unit_test/New()
allocated = new
run_loc_bottom_left = locate(1, 1, 1)
run_loc_top_right = locate(5, 5, 1)
@@ -35,6 +32,7 @@ GLOBAL_VAR(test_log)
//clear the test area
for(var/atom/movable/AM in block(run_loc_bottom_left, run_loc_top_right))
qdel(AM)
QDEL_LIST(allocated)
return ..()
/datum/unit_test/proc/Run()
@@ -48,6 +46,18 @@ GLOBAL_VAR(test_log)
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_bottom_left)
else if (arguments[1] == null)
arguments[1] = run_loc_bottom_left
var/instance = new type(arglist(arguments))
allocated += instance
return instance
/proc/RunUnitTests()
CHECK_TICK
+3 -3
View File
@@ -1,15 +1,15 @@
#!/bin/bash
if [ -n "$1" ]
then
dme=$1
else
echo "Specify a DME to check"
echo "ERROR: Specify a DME to check"
exit 1
fi
if [[ $(awk '/BEGIN_FILE_DIR/{flag=1;next}/END_FILE_DIR/{flag=0}flag' $dme | wc -l) -ne 1 ]]
then
echo "File DIR was ticked, please untick it, see: https://tgstation13.org/phpBB/viewtopic.php?f=5&t=321 for more"
echo "ERROR: File DIR was ticked, please untick it, see: https://tgstation13.org/phpBB/viewtopic.php?f=5&t=321 for more"
exit 1
fi
+44 -17
View File
@@ -7,43 +7,70 @@ shopt -s globstar
st=0
if grep -El '^\".+\" = \(.+\)' _maps/**/*.dmm; then
echo "Non-TGM formatted map detected. Please convert it using Map Merger!"
echo "ERROR: Non-TGM formatted map detected. Please convert it using Map Merger!"
st=1
fi;
if grep -P '^\ttag = \"icon' _maps/**/*.dmm; then
echo "tag vars from icon state generation detected in maps, please remove them."
echo "ERROR: tag vars from icon state generation detected in maps, please remove them."
st=1
fi;
if grep 'step_[xy]' _maps/**/*.dmm; then
echo "step_x/step_y variables detected in maps, please remove them."
if grep -P 'step_[xy]' _maps/**/*.dmm; then
echo "ERROR: step_x/step_y variables detected in maps, please remove them."
st=1
fi;
if grep 'pixel_[xy] = 0' _maps/**/*.dmm; then
echo "pixel_x/pixel_y = 0 variables detected in maps, please review to ensure they are not dirty varedits."
if grep -P 'pixel_[^xy]' _maps/**/*.dmm; then
echo "ERROR: incorrect pixel offset variables detected in maps, please remove them."
st=1
fi;
if grep -P '\td[1-2] =' _maps/**/*.dmm; then
echo "d1/d2 cable variables detected in maps, please remove them."
echo "ERROR: d1/d2 cable variables detected in maps, please remove them."
st=1
fi;
if grep '^/area/.+[\{]' _maps/**/*.dmm; then
echo "Vareditted /area path use detected in maps, please replace with proper paths."
if grep -P '^/area/.+[\{]' _maps/**/*.dmm; then
echo "WARNING: Vareditted /area path use detected in maps, please replace with proper paths."
#st=1
fi;
if grep -P '\W\/turf\s*[,\){]' _maps/**/*.dmm; then
echo "ERROR: base /turf path use detected in maps, please replace with proper paths."
st=1
fi;
if grep '\W\/turf\s*[,\){]' _maps/**/*.dmm; then
echo "base /turf path use detected in maps, please replace with proper paths."
st=1
fi;
if grep '^/*var/' code/**/*.dm; then
echo "Unmanaged global var use detected in code, please use the helpers."
if grep -P '^/*var/' code/**/*.dm; then
echo "ERROR: Unmanaged global var use detected in code, please use the helpers."
st=1
fi;
nl='
'
nl=$'\n'
while read f; do
t=$(tail -c2 "$f"; printf x); r1="${nl}$"; r2="${nl}${r1}"
if [[ ! ${t%x} =~ $r1 ]]; then
echo "file $f is missing a trailing newline"
#st=1
fi;
done < <(find . -type f -name '*.dm')
if grep -i 'centcomm' code/**/*.dm; then
echo "Misspelling(s) of CENTCOM detected in code, please remove the extra M(s)."
echo "ERROR: Misspelling(s) of CENTCOM detected in code, please remove the extra M(s)."
st=1
fi;
if grep -i 'centcomm' _maps/**/*.dmm; then
echo "Misspelling(s) of CENTCOM detected in maps, please remove the extra M(s)."
echo "ERROR: Misspelling(s) of CENTCOM detected in maps, please remove the extra M(s)."
st=1
fi;
if ls _maps/*.json | grep -P "[A-Z]"; then
echo "Uppercase in a map json detected, these must be all lowercase."
st=1
fi;
for json in _maps/*.json
do
map_path=$(jq -r '.map_path' $json)
while read map_file; do
filename="_maps/$map_path/$map_file"
if [ ! -f $filename ]
then
echo "found invalid file reference to $filename in _maps/$json"
st=1
fi
done < <(jq -r '[.map_file] | flatten | .[]' $json)
done
exit $st
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
set -euo pipefail
source dependencies.sh
wget -O ~/dreamchecker "https://github.com/SpaceManiac/SpacemanDMM/releases/download/$SPACEMAN_DMM_VERSION/dreamchecker"
chmod +x ~/dreamchecker
~/dreamchecker --version
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
set -euo pipefail
source dependencies.sh
wget -O ~/$1 "https://github.com/SpaceManiac/SpacemanDMM/releases/download/$SPACEMAN_DMM_VERSION/$1"
chmod +x ~/$1
~/$1 --version
+1
View File
@@ -2,6 +2,7 @@
set -euo pipefail
tools/deploy.sh travis_test
rm travis_test/*.dll
mkdir travis_test/config
#test config