From 552cb162dcb1f2e94f0b8b3a5e06e2da56167fc8 Mon Sep 17 00:00:00 2001 From: ehughsbaird <44244083+ehughsbaird@users.noreply.github.com> Date: Sun, 28 Jul 2024 00:16:35 +0000 Subject: [PATCH 1/2] Stop iteminfo test from failing w/ mod damage type When mods add additional damage types, additional data is added to the iteminfo strings, making testing for the whole string fail. But we can instead test for the specific damage types and the coverage header that we're testing for, and the test will no longer fail with additional damage types. A Beak bodypart is also added by the test mod, changing the protection of some items. --- tests/iteminfo_test.cpp | 300 ++++++++++++++++++++++++++-------------- 1 file changed, 196 insertions(+), 104 deletions(-) diff --git a/tests/iteminfo_test.cpp b/tests/iteminfo_test.cpp index 96a9d67435c95..35c72751e1f20 100644 --- a/tests/iteminfo_test.cpp +++ b/tests/iteminfo_test.cpp @@ -1237,6 +1237,13 @@ TEST_CASE( "armor_stats", "[armor][protection]" ) expected_armor_values( item( itype_dress_shirt ), 0.1f, 0.1f, 0.08f, 0.1f ); } +static void test_string( const std::string &info, const std::string &tested ) +{ + INFO( string_format( "Checking for \"%s\" in:", tested ) ); + INFO( info ); + CHECK( info.find( tested ) != std::string::npos ); +} + // Armor protction is based on materials, thickness, and/or environmental protection rating. // For armor defined in JSON: // @@ -1249,7 +1256,7 @@ TEST_CASE( "armor_stats", "[armor][protection]" ) // Materials and protection calculations are not tested here; only their display in item info. // // item::armor_protection_info -TEST_CASE( "armor_protection", "[iteminfo][armor][protection][!mayfail]" ) +TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) { clear_avatar(); @@ -1287,21 +1294,39 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection][!mayfail]" ) REQUIRE( hazmat.get_covered_body_parts().any() ); expected_armor_values( hazmat, 4, 4, 3.2, 2, 9, 1, 20 ); + const std::vector bodyparts = { + "The arms.", + " The eyes.", + " The feet.", + " The hands.", + " The head.", + " The legs.", + " The mouth.", + " The torso." + }; + const std::string coverage_string = + "Coverage: Outer.\n" + " Default: 100\n"; + const std::string bash_string = " Bash: 4.00\n"; + const std::string cut_string = " Cut: 4.00\n"; + const std::string ballistic_string = " Ballistic: 2.00\n"; + const std::string pierce_string = " Pierce: 3.20\n"; + const std::string acid_string = " Acid: 9.00\n"; + const std::string fire_string = " Fire: 1.00\n"; + const std::string env_string = " Environmental: 20\n"; // Protection info displayed on two lines - CHECK( item_info_str( hazmat, protection ) == - "--\n" - "Protection for: The arms. The eyes. The feet. The hands. The head. The legs. The mouth. The torso.\n" - "Coverage: Outer.\n" - " Default: 100\n" - "Protection:\n" - " Bash: 4.00\n" - " Cut: 4.00\n" - " Ballistic: 2.00\n" - " Pierce: 3.20\n" - " Acid: 9.00\n" - " Fire: 1.00\n" - " Environmental: 20\n" - ); + const std::string info = item_info_str( hazmat, protection ); + for( const std::string &bodyparts_string : bodyparts ) { + test_string( info, bodyparts_string ); + } + test_string( info, coverage_string ); + test_string( info, bash_string ); + test_string( info, cut_string ); + test_string( info, ballistic_string ); + test_string( info, pierce_string ); + test_string( info, acid_string ); + test_string( info, fire_string ); + test_string( info, env_string ); } SECTION( "check that material resistances are properly overriden" ) { @@ -1312,20 +1337,41 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection][!mayfail]" ) expected_armor_values( zentai, 2, 2, 50, 2, 9, 2, 10 ); // Protection info displayed on two lines - CHECK( item_info_str( zentai, protection ) == - "--\n" - "Protection for: The arms. The eyes. The feet. The hands. The head. The legs. The mouth. The torso.\n" - "Coverage: Close to skin.\n" - " Default: 100\n" - "Protection:\n" - " Bash: 2.00\n" - " Cut: 2.00\n" - " Ballistic: 2.00\n" - " Pierce: 50.00\n" - " Acid: 9.00\n" - " Fire: 2.00\n" - " Environmental: 10\n" - ); + const std::string info = item_info_str( zentai, protection ); + const std::string protection_head_str = + "Protection for:"; + const std::vector bodyparts = { + "The arms.", + " The eyes.", + " The feet.", + " The hands.", + " The head.", + " The legs.", + " The mouth.", + " The torso." + }; + const std::string coverage_str = + "Coverage: Close to skin.\n" + " Default: 100\n"; + const std::string bash_str = " Bash: 2.00\n"; + const std::string cut_str = " Cut: 2.00\n"; + const std::string ballistic_str = " Ballistic: 2.00\n"; + const std::string pierce_str = " Pierce: 50.00\n"; + const std::string acid_str = " Acid: 9.00\n"; + const std::string fire_str = " Fire: 2.00\n"; + const std::string env_str = " Environmental: 10\n"; + test_string( info, protection_head_str ); + for( const std::string &bodyparts_str : bodyparts ) { + test_string( info, bodyparts_str ); + } + test_string( info, coverage_str ); + test_string( info, bash_str ); + test_string( info, cut_str ); + test_string( info, ballistic_str ); + test_string( info, pierce_str ); + test_string( info, acid_str ); + test_string( info, fire_str ); + test_string( info, env_str ); } SECTION( "complex protection from physical and environmental damage" ) { @@ -1335,19 +1381,32 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection][!mayfail]" ) expected_armor_values( super_tanktop, 15.33333f, 15.33333f, 12.26667f, 10.66667f ); // Protection info displayed on two lines - CHECK( item_info_str( super_tanktop, more_protection ) == - "--\n" - "Encumbrance 7: The torso.\n" - "--\n" - "Protection for: The torso.\n" - "Coverage: Close to skin.\n" - " Default: 100\n" - "Protection: 4%, Median, 4%\n" - " Bash: 1.00, 12.00, 23.00\n" - " Cut: 1.00, 12.00, 23.00\n" - " Ballistic: 1.00, 8.50, 16.00\n" - " Pierce: 0.80, 9.60, 18.40\n" - ); + const std::string info = item_info_str( super_tanktop, more_protection ); + const std::string encumbrance_str = + "Encumbrance 7: The torso.\n"; + const std::string bodyparts_str = + "Protection for: The torso.\n"; + const std::string coverage_str = + "Coverage: Close to skin.\n" + " Default: 100\n"; + const std::string protection_str = + "Protection: 4%, Median, 4%\n"; + const std::string bash_str = + " Bash: 1.00, 12.00, 23.00\n"; + const std::string cut_str = + " Cut: 1.00, 12.00, 23.00\n"; + const std::string ballistic_str = + " Ballistic: 1.00, 8.50, 16.00\n"; + const std::string pierce_str = + " Pierce: 0.80, 9.60, 18.40\n"; + test_string( info, encumbrance_str ); + test_string( info, bodyparts_str ); + test_string( info, coverage_str ); + test_string( info, protection_str ); + test_string( info, bash_str ); + test_string( info, cut_str ); + test_string( info, ballistic_str ); + test_string( info, pierce_str ); } SECTION( "pet armor with good physical and environmental protection" ) { @@ -1358,16 +1417,19 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection][!mayfail]" ) item meower_armor( "test_meower_armor" ); expected_armor_values( meower_armor, 3, 4, 3.2, 10, 5, 3, 10 ); - CHECK( item_info_str( meower_armor, protection ) == - "--\n" - "Protection:\n" - " Bash: 3.00\n" - " Cut: 4.00\n" - " Ballistic: 10.00\n" - " Acid: 5.00\n" - " Fire: 3.00\n" - " Environmental: 10\n" - ); + const std::string info = item_info_str( meower_armor, protection ); + const std::string bash_str = " Bash: 3.00\n"; + const std::string cut_str = " Cut: 4.00\n"; + const std::string ballistic_str = " Ballistic: 10.00\n"; + const std::string acid_str = " Acid: 5.00\n"; + const std::string fire_str = " Fire: 3.00\n"; + const std::string env_str = " Environmental: 10\n"; + test_string( info, bash_str ); + test_string( info, cut_str ); + test_string( info, ballistic_str ); + test_string( info, acid_str ); + test_string( info, fire_str ); + test_string( info, env_str ); } } @@ -2961,7 +3023,7 @@ TEST_CASE( "item_debug_info", "[iteminfo][debug][!mayfail][.]" ) } } -TEST_CASE( "Armor_values_preserved_after_copy-from", "[iteminfo][armor][protection][!mayfail]" ) +TEST_CASE( "Armor_values_preserved_after_copy-from", "[iteminfo][armor][protection]" ) { // Normal item definition, no copy item armor( itype_test_armor_chitin ); @@ -2988,55 +3050,85 @@ TEST_CASE( "Armor_values_preserved_after_copy-from", "[iteminfo][armor][protecti std::string a_copy_rel_str = item_info_str( armor_copy_rel, infoparts ); std::string a_copy_w_armor_rel_str = item_info_str( armor_copy_w_armor_rel, infoparts ); - const std::string info_str = - "--\n" - "Protection for: The legs. The torso.\n" - "Coverage: Outer.\n" - " Default: 90\n" - "Protection:\n" - " Bash: 10.00\n" - " Cut: 16.00\n" - " Ballistic: 5.60\n" - " Pierce: 12.80\n" - " Acid: 3.60\n" - " Fire: 1.50\n" - " Environmental: 6\n"; - - CHECK( a_str == info_str ); - CHECK( a_copy_str == info_str ); - CHECK( a_copy_w_armor_str == info_str ); - - const std::string info_prop_str = - "--\n" - "Protection for: The legs. The torso.\n" - "Coverage: Outer.\n" - " Default: 90\n" - "Protection:\n" - " Bash: 12.00\n" - " Cut: 19.20\n" - " Ballistic: 6.72\n" - " Pierce: 15.36\n" - " Acid: 4.20\n" - " Fire: 1.75\n" - " Environmental: 7\n"; - - CHECK( a_copy_prop_str == info_prop_str ); - CHECK( a_copy_w_armor_prop_str == info_prop_str ); - - const std::string info_rel_str = - "--\n" - "Protection for: The legs. The torso.\n" - "Coverage: Outer.\n" - " Default: 90\n" - "Protection:\n" - " Bash: 15.00\n" - " Cut: 24.00\n" - " Ballistic: 8.40\n" - " Pierce: 19.20\n" - " Acid: 4.80\n" - " Fire: 2.00\n" - " Environmental: 8\n"; - - CHECK( a_copy_rel_str == info_rel_str ); - CHECK( a_copy_w_armor_rel_str == info_rel_str ); + const auto copy_from_test = []( const std::string & info ) { + const std::string header_string = + "--\n" + "Protection for: The legs. The torso.\n" + "Coverage: Outer.\n" + " Default: 90\n" + "Protection:\n"; + const std::string bash_string = " Bash: 10.00\n"; + const std::string cut_string = " Cut: 16.00\n"; + const std::string ballistic_string = " Ballistic: 5.60\n"; + const std::string pierce_string = " Pierce: 12.80\n"; + const std::string acid_string = " Acid: 3.60\n"; + const std::string fire_string = " Fire: 1.50\n"; + const std::string env_string = " Environmental: 6\n"; + + test_string( info, header_string ); + test_string( info, bash_string ); + test_string( info, cut_string ); + test_string( info, ballistic_string ); + test_string( info, acid_string ); + test_string( info, fire_string ); + test_string( info, env_string ); + }; + + copy_from_test( a_str ); + copy_from_test( a_copy_str ); + copy_from_test( a_copy_w_armor_str ); + + const auto proportional_test = []( const std::string & info ) { + const std::string header_str = + "--\n" + "Protection for: The legs. The torso.\n" + "Coverage: Outer.\n" + " Default: 90\n" + "Protection:\n"; + const std::string bash_str = " Bash: 12.00\n"; + const std::string cut_str = " Cut: 19.20\n"; + const std::string ballistic_str = " Ballistic: 6.72\n"; + const std::string pierce_str = " Pierce: 15.36\n"; + const std::string acid_str = " Acid: 4.20\n"; + const std::string fire_str = " Fire: 1.75\n"; + const std::string env_str = " Environmental: 7\n"; + + test_string( info, header_str ); + test_string( info, bash_str ); + test_string( info, cut_str ); + test_string( info, ballistic_str ); + test_string( info, acid_str ); + test_string( info, fire_str ); + test_string( info, env_str ); + }; + + proportional_test( a_copy_prop_str ); + proportional_test( a_copy_w_armor_prop_str ); + + const auto relative_test = []( const std::string & info ) { + const std::string header_str = + "--\n" + "Protection for: The legs. The torso.\n" + "Coverage: Outer.\n" + " Default: 90\n" + "Protection:\n"; + const std::string bash_str = " Bash: 15.00\n"; + const std::string cut_str = " Cut: 24.00\n"; + const std::string ballistic_str = " Ballistic: 8.40\n"; + const std::string pierce_str = " Pierce: 19.20\n"; + const std::string acid_str = " Acid: 4.80\n"; + const std::string fire_str = " Fire: 2.00\n"; + const std::string env_str = " Environmental: 8\n"; + + test_string( info, header_str ); + test_string( info, bash_str ); + test_string( info, cut_str ); + test_string( info, ballistic_str ); + test_string( info, acid_str ); + test_string( info, fire_str ); + test_string( info, env_str ); + }; + + relative_test( a_copy_rel_str ); + relative_test( a_copy_w_armor_rel_str ); } From c740cce234aa316716ef4ef7f3c4fa6f0cd5b5d2 Mon Sep 17 00:00:00 2001 From: ehughsbaird <44244083+ehughsbaird@users.noreply.github.com> Date: Sun, 28 Jul 2024 00:16:37 +0000 Subject: [PATCH 2/2] Check ordering of protection info in iteminfo test Now that it's no longer checking the whole message, we can get back some of the strictness that was lost by checking it's at least in increasing order. --- tests/iteminfo_test.cpp | 132 +++++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/tests/iteminfo_test.cpp b/tests/iteminfo_test.cpp index 35c72751e1f20..a3b95c34a6892 100644 --- a/tests/iteminfo_test.cpp +++ b/tests/iteminfo_test.cpp @@ -1237,11 +1237,16 @@ TEST_CASE( "armor_stats", "[armor][protection]" ) expected_armor_values( item( itype_dress_shirt ), 0.1f, 0.1f, 0.08f, 0.1f ); } -static void test_string( const std::string &info, const std::string &tested ) +// Check that a string is provided in some iteminfo +// By providing last_pos, order can also be checked +static void test_string( const std::string &info, const std::string &tested, size_t &last_pos ) { INFO( string_format( "Checking for \"%s\" in:", tested ) ); INFO( info ); - CHECK( info.find( tested ) != std::string::npos ); + size_t pos = info.find( tested ); + CHECK( pos != std::string::npos ); + CHECK( pos >= last_pos ); + last_pos = pos; } // Armor protction is based on materials, thickness, and/or environmental protection rating. @@ -1294,6 +1299,7 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) REQUIRE( hazmat.get_covered_body_parts().any() ); expected_armor_values( hazmat, 4, 4, 3.2, 2, 9, 1, 20 ); + const std::string bp_header_string = "Protection for:"; const std::vector bodyparts = { "The arms.", " The eyes.", @@ -1307,6 +1313,7 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) const std::string coverage_string = "Coverage: Outer.\n" " Default: 100\n"; + const std::string prot_header_string = "Protection:\n"; const std::string bash_string = " Bash: 4.00\n"; const std::string cut_string = " Cut: 4.00\n"; const std::string ballistic_string = " Ballistic: 2.00\n"; @@ -1316,17 +1323,20 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) const std::string env_string = " Environmental: 20\n"; // Protection info displayed on two lines const std::string info = item_info_str( hazmat, protection ); + size_t pos = 0; + test_string( info, bp_header_string, pos ); for( const std::string &bodyparts_string : bodyparts ) { - test_string( info, bodyparts_string ); + test_string( info, bodyparts_string, pos ); } - test_string( info, coverage_string ); - test_string( info, bash_string ); - test_string( info, cut_string ); - test_string( info, ballistic_string ); - test_string( info, pierce_string ); - test_string( info, acid_string ); - test_string( info, fire_string ); - test_string( info, env_string ); + test_string( info, coverage_string, pos ); + test_string( info, prot_header_string, pos ); + test_string( info, bash_string, pos ); + test_string( info, cut_string, pos ); + test_string( info, ballistic_string, pos ); + test_string( info, pierce_string, pos ); + test_string( info, acid_string, pos ); + test_string( info, fire_string, pos ); + test_string( info, env_string, pos ); } SECTION( "check that material resistances are properly overriden" ) { @@ -1353,6 +1363,7 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) const std::string coverage_str = "Coverage: Close to skin.\n" " Default: 100\n"; + const std::string prot_header_str = "Protection:\n"; const std::string bash_str = " Bash: 2.00\n"; const std::string cut_str = " Cut: 2.00\n"; const std::string ballistic_str = " Ballistic: 2.00\n"; @@ -1360,18 +1371,20 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) const std::string acid_str = " Acid: 9.00\n"; const std::string fire_str = " Fire: 2.00\n"; const std::string env_str = " Environmental: 10\n"; - test_string( info, protection_head_str ); + size_t pos = 0; + test_string( info, protection_head_str, pos ); for( const std::string &bodyparts_str : bodyparts ) { - test_string( info, bodyparts_str ); + test_string( info, bodyparts_str, pos ); } - test_string( info, coverage_str ); - test_string( info, bash_str ); - test_string( info, cut_str ); - test_string( info, ballistic_str ); - test_string( info, pierce_str ); - test_string( info, acid_str ); - test_string( info, fire_str ); - test_string( info, env_str ); + test_string( info, coverage_str, pos ); + test_string( info, prot_header_str, pos ); + test_string( info, bash_str, pos ); + test_string( info, cut_str, pos ); + test_string( info, ballistic_str, pos ); + test_string( info, pierce_str, pos ); + test_string( info, acid_str, pos ); + test_string( info, fire_str, pos ); + test_string( info, env_str, pos ); } SECTION( "complex protection from physical and environmental damage" ) { @@ -1399,14 +1412,15 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) " Ballistic: 1.00, 8.50, 16.00\n"; const std::string pierce_str = " Pierce: 0.80, 9.60, 18.40\n"; - test_string( info, encumbrance_str ); - test_string( info, bodyparts_str ); - test_string( info, coverage_str ); - test_string( info, protection_str ); - test_string( info, bash_str ); - test_string( info, cut_str ); - test_string( info, ballistic_str ); - test_string( info, pierce_str ); + size_t pos = 0; + test_string( info, encumbrance_str, pos ); + test_string( info, bodyparts_str, pos ); + test_string( info, coverage_str, pos ); + test_string( info, protection_str, pos ); + test_string( info, bash_str, pos ); + test_string( info, cut_str, pos ); + test_string( info, ballistic_str, pos ); + test_string( info, pierce_str, pos ); } SECTION( "pet armor with good physical and environmental protection" ) { @@ -1418,18 +1432,21 @@ TEST_CASE( "armor_protection", "[iteminfo][armor][protection]" ) expected_armor_values( meower_armor, 3, 4, 3.2, 10, 5, 3, 10 ); const std::string info = item_info_str( meower_armor, protection ); + const std::string header_str = "Protection:\n"; const std::string bash_str = " Bash: 3.00\n"; const std::string cut_str = " Cut: 4.00\n"; const std::string ballistic_str = " Ballistic: 10.00\n"; const std::string acid_str = " Acid: 5.00\n"; const std::string fire_str = " Fire: 3.00\n"; const std::string env_str = " Environmental: 10\n"; - test_string( info, bash_str ); - test_string( info, cut_str ); - test_string( info, ballistic_str ); - test_string( info, acid_str ); - test_string( info, fire_str ); - test_string( info, env_str ); + size_t pos = 0; + test_string( info, header_str, pos ); + test_string( info, bash_str, pos ); + test_string( info, cut_str, pos ); + test_string( info, ballistic_str, pos ); + test_string( info, acid_str, pos ); + test_string( info, fire_str, pos ); + test_string( info, env_str, pos ); } } @@ -3065,13 +3082,14 @@ TEST_CASE( "Armor_values_preserved_after_copy-from", "[iteminfo][armor][protecti const std::string fire_string = " Fire: 1.50\n"; const std::string env_string = " Environmental: 6\n"; - test_string( info, header_string ); - test_string( info, bash_string ); - test_string( info, cut_string ); - test_string( info, ballistic_string ); - test_string( info, acid_string ); - test_string( info, fire_string ); - test_string( info, env_string ); + size_t pos = 0; + test_string( info, header_string, pos ); + test_string( info, bash_string, pos ); + test_string( info, cut_string, pos ); + test_string( info, ballistic_string, pos ); + test_string( info, acid_string, pos ); + test_string( info, fire_string, pos ); + test_string( info, env_string, pos ); }; copy_from_test( a_str ); @@ -3093,13 +3111,14 @@ TEST_CASE( "Armor_values_preserved_after_copy-from", "[iteminfo][armor][protecti const std::string fire_str = " Fire: 1.75\n"; const std::string env_str = " Environmental: 7\n"; - test_string( info, header_str ); - test_string( info, bash_str ); - test_string( info, cut_str ); - test_string( info, ballistic_str ); - test_string( info, acid_str ); - test_string( info, fire_str ); - test_string( info, env_str ); + size_t pos = 0; + test_string( info, header_str, pos ); + test_string( info, bash_str, pos ); + test_string( info, cut_str, pos ); + test_string( info, ballistic_str, pos ); + test_string( info, acid_str, pos ); + test_string( info, fire_str, pos ); + test_string( info, env_str, pos ); }; proportional_test( a_copy_prop_str ); @@ -3120,13 +3139,14 @@ TEST_CASE( "Armor_values_preserved_after_copy-from", "[iteminfo][armor][protecti const std::string fire_str = " Fire: 2.00\n"; const std::string env_str = " Environmental: 8\n"; - test_string( info, header_str ); - test_string( info, bash_str ); - test_string( info, cut_str ); - test_string( info, ballistic_str ); - test_string( info, acid_str ); - test_string( info, fire_str ); - test_string( info, env_str ); + size_t pos = 0; + test_string( info, header_str, pos ); + test_string( info, bash_str, pos ); + test_string( info, cut_str, pos ); + test_string( info, ballistic_str, pos ); + test_string( info, acid_str, pos ); + test_string( info, fire_str, pos ); + test_string( info, env_str, pos ); }; relative_test( a_copy_rel_str );