From 83dc4c095ceb702d3c26395da4c0f6711559925e Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Sun, 21 Sep 2025 14:51:21 -0700 Subject: [PATCH] [MIRROR] Even STRICTER reaction unittest (#11711) Co-authored-by: Will <7099514+Willburd@users.noreply.github.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> --- code/__defines/dcs/signals.dm | 5 ++ code/modules/reagents/holder/holder.dm | 6 +- .../reagents/reactions/instant/drinks.dm | 2 + .../reagents/reactions/instant/food.dm | 1 + .../reagents/reactions/instant/instant.dm | 1 + .../reagents/reactions/instant/virology.dm | 2 +- code/modules/unit_tests/clothing_tests.dm | 2 +- code/modules/unit_tests/reagent_tests.dm | 65 ++++++++++++------- .../reagents/reactions/instant/drinks.dm | 1 + 9 files changed, 57 insertions(+), 28 deletions(-) diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index f1ee0a6d59..2bd0775f19 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -692,6 +692,11 @@ ///called when you wash your face at a sink: (num/strength) #define COMSIG_COMPONENT_CLEAN_FACE_ACT "clean_face_act" +//Reagent holder + +///from base of /datum/reagents/proc/handle_reactions(): (list/decl/chemical_reaction) +#define COMSIG_REAGENTS_HOLDER_REACTED "reagents_holder_reacted" + //Food ///from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder) diff --git a/code/modules/reagents/holder/holder.dm b/code/modules/reagents/holder/holder.dm index 6618ddab8e..e3f3245cf7 100644 --- a/code/modules/reagents/holder/holder.dm +++ b/code/modules/reagents/holder/holder.dm @@ -101,11 +101,9 @@ while(reaction_occurred) for(var/decl/chemical_reaction/C as anything in effect_reactions) C.post_reaction(src) - #ifdef UNIT_TESTS - SEND_SIGNAL(src, COMSIG_UNITTEST_DATA, list(C)) - #endif update_total() - return TRUE + SEND_SIGNAL(src, COMSIG_REAGENTS_HOLDER_REACTED, effect_reactions) + return effect_reactions.len /* Holder-to-chemical */ diff --git a/code/modules/reagents/reactions/instant/drinks.dm b/code/modules/reagents/reactions/instant/drinks.dm index c68dcc4024..fa04bbabc1 100644 --- a/code/modules/reagents/reactions/instant/drinks.dm +++ b/code/modules/reagents/reactions/instant/drinks.dm @@ -382,6 +382,7 @@ name = REAGENT_IRISHCREAM id = REAGENT_ID_IRISHCREAM result = REAGENT_ID_IRISHCREAM + inhibitors = list(REAGENT_ID_WATERMELONJUICE = 1) // Blocks aloe required_reagents = list(REAGENT_ID_WHISKEY = 2, REAGENT_ID_CREAM = 1) result_amount = 3 @@ -799,6 +800,7 @@ name = REAGENT_MILKSHAKE id = REAGENT_ID_MILKSHAKE result = REAGENT_ID_MILKSHAKE + inhibitors = list(REAGENT_ID_PEANUTBUTTER = 1) // Blocks peanutbutter milkshake required_reagents = list(REAGENT_ID_CREAM = 1, REAGENT_ID_ICE = 2, REAGENT_ID_MILK = 2) result_amount = 5 diff --git a/code/modules/reagents/reactions/instant/food.dm b/code/modules/reagents/reactions/instant/food.dm index 5739969956..7c6a4b4a2e 100644 --- a/code/modules/reagents/reactions/instant/food.dm +++ b/code/modules/reagents/reactions/instant/food.dm @@ -62,6 +62,7 @@ name = "corn " + REAGENT_COOKINGOIL id = "cookingoilcorn" result = REAGENT_ID_COOKINGOIL + inhibitors = list(REAGENT_ID_FLOUR = 1) // Blocks spacebeer required_reagents = list(REAGENT_ID_CORNOIL = 10) catalysts = list(REAGENT_ID_ENZYME = 5) result_amount = 10 diff --git a/code/modules/reagents/reactions/instant/instant.dm b/code/modules/reagents/reactions/instant/instant.dm index 10d6b366f5..1ca0d15b82 100644 --- a/code/modules/reagents/reactions/instant/instant.dm +++ b/code/modules/reagents/reactions/instant/instant.dm @@ -446,6 +446,7 @@ name = REAGENT_LYE id = REAGENT_ID_LYE result = REAGENT_ID_LYE + inhibitors = list(REAGENT_ID_CARBON = 1) // Or it blocks aphrodisiac required_reagents = list(REAGENT_ID_SODIUM = 1, REAGENT_ID_HYDROGEN = 1, REAGENT_ID_OXYGEN = 1) result_amount = 3 diff --git a/code/modules/reagents/reactions/instant/virology.dm b/code/modules/reagents/reactions/instant/virology.dm index aa9e82431d..bc49ec45bb 100644 --- a/code/modules/reagents/reactions/instant/virology.dm +++ b/code/modules/reagents/reactions/instant/virology.dm @@ -111,7 +111,7 @@ /decl/chemical_reaction/instant/mix_virus/mix_virus_3 name = "Mix Virus 3" id = "mixvirus3" - required_reagents = list(REAGENT_ID_PHORON = 1) + required_reagents = list(REAGENT_ID_VIRUSFOOD = 1, REAGENT_ID_PHORON = 1) level_min = 4 level_max = 6 diff --git a/code/modules/unit_tests/clothing_tests.dm b/code/modules/unit_tests/clothing_tests.dm index d4141027c3..082abe2356 100644 --- a/code/modules/unit_tests/clothing_tests.dm +++ b/code/modules/unit_tests/clothing_tests.dm @@ -62,7 +62,7 @@ failed = TRUE // Disabled, as currently not working in a presentable way, spams the CI hard, do not enable unless fixed - #ifdef UNIT_TEST + #ifdef UNIT_TESTS // Time for the most brutal part. Dressing up some mobs with set species, and checking they have art // An entire signal just for unittests had to be made for this! var/list/body_types = list(SPECIES_HUMAN,SPECIES_VOX,SPECIES_TESHARI) // Otherwise we would be here for centuries diff --git a/code/modules/unit_tests/reagent_tests.dm b/code/modules/unit_tests/reagent_tests.dm index af37651f48..34ac2d3bdd 100644 --- a/code/modules/unit_tests/reagent_tests.dm +++ b/code/modules/unit_tests/reagent_tests.dm @@ -1,6 +1,9 @@ /// converted unit test, maybe should be fully refactored /// MIGHT REQUIRE BIGGER REWORK +#define RESULT_REACTION_FAILED 1 +#define RESULT_REACTION_SUCCESS 0 + /// Test that makes sure that reagent ids and names are unique /datum/unit_test/reagent_shall_have_unique_name_and_id @@ -103,12 +106,18 @@ /// Test that makes sure that chemical reactions do not conflict /datum/unit_test/chemical_reactions_shall_not_conflict var/obj/fake_beaker = null + var/obj/instant_beaker = null // For distilling only var/list/result_reactions = list() /datum/unit_test/chemical_reactions_shall_not_conflict/Run() var/failed = FALSE - #ifdef UNIT_TEST + // need to test for instant reactions blocking distillation! + instant_beaker = new /obj/item/reagent_containers/glass/beaker() + instant_beaker.reagents.maximum_volume = 5000 + RegisterSignal(instant_beaker.reagents, COMSIG_REAGENTS_HOLDER_REACTED, PROC_REF(get_signal_data)) + + //actual test var/list/all_reactions = decls_repository.get_decls_of_subtype(/decl/chemical_reaction) for(var/rtype in all_reactions) var/decl/chemical_reaction/CR = all_reactions[rtype] @@ -134,27 +143,31 @@ // distilling var/obj/distilling_tester/D = new() QDEL_SWAP(fake_beaker, D) - fake_beaker.reagents.maximum_volume = 5000 else // regular beaker QDEL_SWAP(fake_beaker, new /obj/item/reagent_containers/glass/beaker()) fake_beaker.reagents.maximum_volume = 5000 // Perform test! If it fails once, it will perform a deeper check trying to use the inhibitors of anything in the beaker - RegisterSignal(fake_beaker.reagents, COMSIG_UNITTEST_DATA, PROC_REF(get_signal_data)) + RegisterSignal(fake_beaker.reagents, COMSIG_REAGENTS_HOLDER_REACTED, PROC_REF(get_signal_data)) // Check if we failed the test with inhibitors in use, if so we absolutely couldn't make it... // Uncomment the UNIT_TEST section in code\modules\reagents\reactions\_reactions.dm if you require more info - TEST_ASSERT(!perform_reaction(CR), "[CR.type]: Reagents - chemical reaction did not produce \"[CR.result]\". CONTAINS: \"[fake_beaker.reagents.get_reagents()]\"") - UnregisterSignal(fake_beaker.reagents, COMSIG_UNITTEST_DATA) + if(perform_reaction(CR) == RESULT_REACTION_FAILED) + TEST_NOTICE(src, "[CR.type]: Reagents - !!!!chemical reaction did not produce \"[CR.result]\"!!!! CONTAINS: \"[fake_beaker.reagents.get_reagents()]\"") + failed = TRUE + UnregisterSignal(fake_beaker.reagents, COMSIG_REAGENTS_HOLDER_REACTED) + + // Cleanup + UnregisterSignal(instant_beaker.reagents, COMSIG_REAGENTS_HOLDER_REACTED) QDEL_NULL(fake_beaker) - #endif + QDEL_NULL(instant_beaker) if(failed) TEST_FAIL("One or more /decl/chemical_reaction subtypes conflict with another reaction.") /datum/unit_test/chemical_reactions_shall_not_conflict/proc/perform_reaction(var/decl/chemical_reaction/CR, var/list/inhib = list()) - var/scale = 1 + var/scale = 10 if(CR.result_amount < 1) scale = 1 / CR.result_amount // Create at least 1 unit @@ -169,42 +182,43 @@ if(inhib.len) // taken from argument and not reaction! Put in FIRST! for(var/RR in inhib) - fake_beaker.reagents.add_reagent(RR, inhib[RR] * scale) + fake_beaker.reagents.add_reagent(RR, inhib[RR]) // Does not need to scale if(CR.catalysts) // Required for reaction for(var/RR in CR.catalysts) - fake_beaker.reagents.add_reagent(RR, CR.catalysts[RR] * scale) + fake_beaker.reagents.add_reagent(RR, CR.catalysts[RR]) // Does not need to scale if(CR.required_reagents) for(var/RR in CR.required_reagents) fake_beaker.reagents.add_reagent(RR, CR.required_reagents[RR] * scale) if(!istype(CR, /decl/chemical_reaction/distilling)) + fake_beaker.reagents.handle_reactions() break // Skip the next section if we're not distilling // Check distillation at 10 points along its temperature range! // This is so multiple reactions with the same requirements, but different temps, can be tested. temp_test += 0.1 var/obj/distilling_tester/DD = fake_beaker + check_instants() DD.test_distilling(CR,temp_test) - + check_instants() if(fake_beaker.reagents.has_reagent(CR.result)) - return FALSE // Distilling success + return RESULT_REACTION_SUCCESS // Distilling success while(temp_test > 1) // Check beaker to see if we reached our goal! if(fake_beaker.reagents.has_reagent(CR.result)) - return FALSE // INSTANT SUCCESS! + return RESULT_REACTION_SUCCESS // INSTANT SUCCESS! if(inhib.len) // We've checked with inhibitors, so we're already in inhibitor checking phase. // So we've absolutely failed this time. There is no way to make this... - return TRUE + return RESULT_REACTION_FAILED if(!result_reactions.len) // Nothing to check for inhibitors... for(var/decl/chemical_reaction/test_react in result_reactions) - TEST_FAIL("[CR.type]: Reagents - Used [test_react] but failed.") - return TRUE + return RESULT_REACTION_FAILED // Otherwise we check the resulting reagents and use their inhibitor this time! for(var/decl/chemical_reaction/test_react in result_reactions) @@ -215,22 +229,26 @@ // Test one by one for(var/each in test_react.inhibitors) if(!perform_reaction(CR, list("[each]" = test_react.inhibitors["[each]"]))) - return FALSE // SUCCESS using an inhibitor! + return RESULT_REACTION_SUCCESS // SUCCESS using an inhibitor! // Test all at once if(!perform_reaction(CR, test_react.inhibitors)) - return FALSE // SUCCESS using all inhibitors! + return RESULT_REACTION_SUCCESS // SUCCESS using all inhibitors! // No inhibiting reagent worked... for(var/decl/chemical_reaction/test_react in result_reactions) - TEST_FAIL("[CR.type]: Reagents - Used [test_react] but failed.") - return TRUE + TEST_NOTICE(src, "[CR.type]: Reagents - Used inhibitor for: [test_react]") + return RESULT_REACTION_FAILED /datum/unit_test/chemical_reactions_shall_not_conflict/proc/get_signal_data(atom/source, list/data = list()) - result_reactions.Add(data[1]) // Append the reactions that happened, then use that to check their inhibitors + SIGNAL_HANDLER + result_reactions += data // Append the reactions that happened, then use that to check their inhibitors + +/datum/unit_test/chemical_reactions_shall_not_conflict/proc/check_instants() + instant_beaker.reagents.clear_reagents() + fake_beaker.reagents.trans_to_holder(instant_beaker.reagents, fake_beaker.reagents.total_volume) + instant_beaker.reagents.trans_to_holder(fake_beaker.reagents, instant_beaker.reagents.total_volume) /// Test that makes sure that chemical grinding has valid results -/datum/unit_test/chemical_grinding_must_produce_valid_results - /datum/unit_test/chemical_grinding_must_produce_valid_results/Run() for(var/grind in GLOB.sheet_reagents + GLOB.ore_reagents) var/list/results = GLOB.sheet_reagents[grind] @@ -249,3 +267,6 @@ for(var/reg_id in results) TEST_ASSERT(SSchemistry.chemical_reagents[reg_id], "[grind]: Reagents - Grinding result had invalid reagent id \"[reg_id]\".") + +#undef RESULT_REACTION_FAILED +#undef RESULT_REACTION_SUCCESS diff --git a/modular_chomp/code/modules/reagents/reactions/instant/drinks.dm b/modular_chomp/code/modules/reagents/reactions/instant/drinks.dm index aac1dd0e4e..7d9e0eed73 100644 --- a/modular_chomp/code/modules/reagents/reactions/instant/drinks.dm +++ b/modular_chomp/code/modules/reagents/reactions/instant/drinks.dm @@ -346,6 +346,7 @@ id = REAGENT_ID_FRINGEWEAVER result = REAGENT_ID_FRINGEWEAVER required_reagents = list(REAGENT_ID_ETHANOL = 9, REAGENT_ID_SUGAR = 1) + inhibitors = list(REAGENT_ID_FUEL = 1) result_amount = 10 /decl/chemical_reaction/instant/drinks/crevice_spike