1 // Copyright 2024 The Kyua Authors. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "engine/googletest_list.hpp" 30 31 #include <sstream> 32 #include <string> 33 34 #include <atf-c++.hpp> 35 36 #include "engine/exceptions.hpp" 37 #include "model/metadata.hpp" 38 #include "model/test_case.hpp" 39 #include "model/types.hpp" 40 #include "utils/datetime.hpp" 41 #include "utils/format/containers.ipp" 42 #include "utils/fs/path.hpp" 43 #include "utils/units.hpp" 44 45 namespace datetime = utils::datetime; 46 namespace fs = utils::fs; 47 namespace units = utils::units; 48 49 50 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__invalid_testcase_definition); 51 ATF_TEST_CASE_BODY(parse_googletest_list__invalid_testcase_definition) 52 { 53 std::istringstream input1(" \n"); 54 55 ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases", 56 engine::parse_googletest_list(input1)); 57 58 std::istringstream input2(" TestcaseWithoutSuite\n"); 59 ATF_REQUIRE_THROW_RE(engine::format_error, 60 "Invalid testcase definition: not preceded by a test suite definition", 61 engine::parse_googletest_list(input2)); 62 } 63 64 65 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__invalid_testsuite_definition); 66 ATF_TEST_CASE_BODY(parse_googletest_list__invalid_testsuite_definition) 67 { 68 std::istringstream input1("\n"); 69 ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases", 70 engine::parse_googletest_list(input1)); 71 72 std::istringstream input2( 73 "TestSuiteWithoutSeparator\n" 74 ); 75 ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases", 76 engine::parse_googletest_list(input2)); 77 } 78 79 80 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__no_test_cases); 81 ATF_TEST_CASE_BODY(parse_googletest_list__no_test_cases) 82 { 83 std::istringstream input(""); 84 ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases", 85 engine::parse_googletest_list(input)); 86 } 87 88 89 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_test_case); 90 ATF_TEST_CASE_BODY(parse_googletest_list__one_test_case) 91 { 92 std::istringstream input( 93 "TestSuite.\n" 94 " TestCase\n" 95 ); 96 const model::test_cases_map tests = engine::parse_googletest_list(input); 97 98 const model::test_cases_map exp_tests = model::test_cases_map_builder() 99 .add("TestSuite.TestCase").build(); 100 ATF_REQUIRE_EQ(exp_tests, tests); 101 } 102 103 104 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_parameterized_test_case); 105 ATF_TEST_CASE_BODY(parse_googletest_list__one_parameterized_test_case) 106 { 107 std::istringstream input( 108 "TestSuite.\n" 109 " TestCase/0 # GetParam() = 'c'\n" 110 ); 111 const model::test_cases_map tests = engine::parse_googletest_list(input); 112 113 const model::test_cases_map exp_tests = model::test_cases_map_builder() 114 .add("TestSuite.TestCase/0").build(); 115 ATF_REQUIRE_EQ(exp_tests, tests); 116 } 117 118 119 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_parameterized_test_suite); 120 ATF_TEST_CASE_BODY(parse_googletest_list__one_parameterized_test_suite) 121 { 122 std::string text = 123 "TestSuite/0. # TypeParam = int\n" 124 " TestCase\n" 125 ; 126 std::istringstream input(text); 127 const model::test_cases_map tests = engine::parse_googletest_list(input); 128 129 const model::test_cases_map exp_tests = model::test_cases_map_builder() 130 .add("TestSuite/0.TestCase").build(); 131 ATF_REQUIRE_EQ(exp_tests, tests); 132 } 133 134 135 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_parameterized_test_case_and_test_suite); 136 ATF_TEST_CASE_BODY(parse_googletest_list__one_parameterized_test_case_and_test_suite) 137 { 138 std::string text = 139 "TestSuite/0. # TypeParam = int\n" 140 " TestCase/0 # GetParam() = \"herp\"\n" 141 " TestCase/1 # GetParam() = \"derp\"\n" 142 ; 143 std::istringstream input(text); 144 const model::test_cases_map tests = engine::parse_googletest_list(input); 145 146 const model::test_cases_map exp_tests = model::test_cases_map_builder() 147 .add("TestSuite/0.TestCase/0") 148 .add("TestSuite/0.TestCase/1") 149 .build(); 150 ATF_REQUIRE_EQ(exp_tests, tests); 151 } 152 153 154 ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__many_test_cases); 155 ATF_TEST_CASE_BODY(parse_googletest_list__many_test_cases) 156 { 157 std::string text = 158 "FirstTestSuite.\n" 159 " ATestCase\n" 160 "SecondTestSuite.\n" 161 " AnotherTestCase\n" 162 "ThirdTestSuite.\n" 163 " _\n" 164 "FourthTestSuite/0. # TypeParam = std::list<int>\n" 165 " TestCase\n" 166 "FourthTestSuite/1. # TypeParam = std::list<int>\n" 167 " TestCase\n" 168 "FifthTestSuite.\n" 169 " TestCase/0 # GetParam() = 0\n" 170 " TestCase/1 # GetParam() = (1, 2, 3)\n" 171 " TestCase/2 # GetParam() = \"developers. developers\"\n" 172 "SixthTestSuite/0. # TypeParam = std::map<std::basic_string, int>\n" 173 " TestCase/0 # GetParam() = 0\n" 174 " TestCase/1 # GetParam() = (1, 2, 3)\n" 175 ; 176 std::istringstream input(text); 177 const model::test_cases_map tests = engine::parse_googletest_list(input); 178 179 const model::test_cases_map exp_tests = model::test_cases_map_builder() 180 .add("FirstTestSuite.ATestCase", model::metadata_builder() 181 .build()) 182 .add("SecondTestSuite.AnotherTestCase", model::metadata_builder() 183 .build()) 184 .add("ThirdTestSuite._") 185 .add("FourthTestSuite/0.TestCase") 186 .add("FourthTestSuite/1.TestCase") 187 .add("FifthTestSuite.TestCase/0") 188 .add("FifthTestSuite.TestCase/1") 189 .add("FifthTestSuite.TestCase/2") 190 .add("SixthTestSuite/0.TestCase/0") 191 .add("SixthTestSuite/0.TestCase/1") 192 .build(); 193 ATF_REQUIRE_EQ(exp_tests, tests); 194 } 195 196 197 ATF_INIT_TEST_CASES(tcs) 198 { 199 ATF_ADD_TEST_CASE(tcs, parse_googletest_list__invalid_testcase_definition); 200 ATF_ADD_TEST_CASE(tcs, parse_googletest_list__invalid_testsuite_definition); 201 ATF_ADD_TEST_CASE(tcs, parse_googletest_list__no_test_cases); 202 ATF_ADD_TEST_CASE(tcs, parse_googletest_list__one_test_case); 203 ATF_ADD_TEST_CASE(tcs, parse_googletest_list__one_parameterized_test_case); 204 ATF_ADD_TEST_CASE(tcs, parse_googletest_list__one_parameterized_test_suite); 205 ATF_ADD_TEST_CASE(tcs, 206 parse_googletest_list__one_parameterized_test_case_and_test_suite); 207 ATF_ADD_TEST_CASE(tcs, parse_googletest_list__many_test_cases); 208 } 209