diff options
author | onqtam <vik.kirilov@gmail.com> | 2019-09-22 17:34:50 +0300 |
---|---|---|
committer | onqtam <vik.kirilov@gmail.com> | 2019-09-22 21:14:41 +0300 |
commit | dca8b66f8785683097a3c0136c57941505d0adce (patch) | |
tree | 4bc76cf2394e8f49bb800acd4399d995899bc770 | |
parent | 5856bb93a63c43c6562eb2773d9a3d4d6f677f15 (diff) |
fixed #282
-rw-r--r-- | doctest/doctest.h | 59 | ||||
-rw-r--r-- | doctest/parts/doctest.cpp | 54 | ||||
-rw-r--r-- | doctest/parts/doctest_fwd.h | 5 | ||||
-rw-r--r-- | examples/all_features/subcases.cpp | 24 | ||||
-rw-r--r-- | examples/all_features/test_output/filter_2.txt | 2 | ||||
-rw-r--r-- | examples/all_features/test_output/filter_2_xml.txt | 3 | ||||
-rw-r--r-- | examples/all_features/test_output/filter_3.txt | 2 | ||||
-rw-r--r-- | examples/all_features/test_output/filter_3_xml.txt | 5 | ||||
-rw-r--r-- | examples/all_features/test_output/subcases.cpp.txt | 4 | ||||
-rw-r--r-- | examples/all_features/test_output/subcases.cpp_xml.txt | 23 | ||||
-rw-r--r-- | scripts/coverage_maxout.cpp | 2 |
11 files changed, 110 insertions, 73 deletions
diff --git a/doctest/doctest.h b/doctest/doctest.h index 037dd56..59fcd65 100644 --- a/doctest/doctest.h +++ b/doctest/doctest.h @@ -701,12 +701,7 @@ struct DOCTEST_INTERFACE SubcaseSignature const char* m_file; int m_line; - SubcaseSignature(const char* name, const char* file, int line); - bool operator<(const SubcaseSignature& other) const; - - DOCTEST_DECLARE_DEFAULTS(SubcaseSignature); - DOCTEST_DECLARE_COPIES(SubcaseSignature); }; struct DOCTEST_INTERFACE IContextScope @@ -2992,10 +2987,10 @@ namespace detail { std::vector<String> stringifiedContexts; // logging from INFO() due to an exception // stuff for subcases - std::set<SubcaseSignature> subcasesPassed; - std::set<int> subcasesEnteredLevels; - int subcasesCurrentLevel; - bool should_reenter; + std::vector<SubcaseSignature> subcaseStack; + std::set<decltype(subcaseStack)> subcasesPassed; + int subcasesCurrentMaxLevel; + bool should_reenter; void resetRunData() { numTestCases = 0; @@ -3336,14 +3331,6 @@ DOCTEST_DEFINE_DEFAULTS(AssertData); DOCTEST_DEFINE_DEFAULTS(MessageData); -SubcaseSignature::SubcaseSignature(const char* name, const char* file, int line) - : m_name(name) - , m_file(file) - , m_line(line) {} - -DOCTEST_DEFINE_DEFAULTS(SubcaseSignature); -DOCTEST_DEFINE_COPIES(SubcaseSignature); - bool SubcaseSignature::operator<(const SubcaseSignature& other) const { if(m_line != other.m_line) return m_line < other.m_line; @@ -3592,28 +3579,33 @@ namespace { namespace detail { Subcase::Subcase(const char* name, const char* file, int line) - : m_signature(name, file, line) { + : m_signature({name, file, line}) { ContextState* s = g_cs; - // if we have already completed it - if(s->subcasesPassed.count(m_signature) != 0) - return; - // check subcase filters - if(s->subcasesCurrentLevel < s->subcase_filter_levels) { + if(s->subcaseStack.size() < size_t(s->subcase_filter_levels)) { if(!matchesAny(m_signature.m_name, s->filters[6], true, s->case_sensitive)) return; if(matchesAny(m_signature.m_name, s->filters[7], false, s->case_sensitive)) return; } - + // if a Subcase on the same level has already been entered - if(s->subcasesEnteredLevels.count(s->subcasesCurrentLevel) != 0) { + if(s->subcaseStack.size() < size_t(s->subcasesCurrentMaxLevel)) { s->should_reenter = true; return; } - s->subcasesEnteredLevels.insert(s->subcasesCurrentLevel++); + // push the current signature to the stack so we can check if the + // current stack + the current new subcase have been traversed + s->subcaseStack.push_back(m_signature); + if(s->subcasesPassed.count(s->subcaseStack) != 0) { + // pop - revert to previous stack since we've already passed this + s->subcaseStack.pop_back(); + return; + } + + s->subcasesCurrentMaxLevel = s->subcaseStack.size(); m_entered = true; DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); @@ -3623,10 +3615,11 @@ namespace detail { if(m_entered) { ContextState* s = g_cs; - s->subcasesCurrentLevel--; // only mark the subcase as passed if no subcases have been skipped if(s->should_reenter == false) - s->subcasesPassed.insert(m_signature); + s->subcasesPassed.insert(s->subcaseStack); + + s->subcaseStack.pop_back(); DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); } @@ -4165,8 +4158,10 @@ namespace { DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true}); - while(g_cs->subcasesCurrentLevel--) + while(g_cs->subcaseStack.size()) { + g_cs->subcaseStack.pop_back(); DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); + } g_cs->finalizeTestCaseData(); @@ -5907,9 +5902,9 @@ int Context::run() { do { // reset some of the fields for subcases (except for the set of fully passed ones) - p->should_reenter = false; - p->subcasesCurrentLevel = 0; - p->subcasesEnteredLevels.clear(); + p->should_reenter = false; + p->subcasesCurrentMaxLevel = 0; + p->subcaseStack.clear(); // reset stuff for logging with INFO() p->stringifiedContexts.clear(); diff --git a/doctest/parts/doctest.cpp b/doctest/parts/doctest.cpp index ab9df2e..4187884 100644 --- a/doctest/parts/doctest.cpp +++ b/doctest/parts/doctest.cpp @@ -315,10 +315,10 @@ namespace detail { std::vector<String> stringifiedContexts; // logging from INFO() due to an exception // stuff for subcases - std::set<SubcaseSignature> subcasesPassed; - std::set<int> subcasesEnteredLevels; - int subcasesCurrentLevel; - bool should_reenter; + std::vector<SubcaseSignature> subcaseStack; + std::set<decltype(subcaseStack)> subcasesPassed; + int subcasesCurrentMaxLevel; + bool should_reenter; void resetRunData() { numTestCases = 0; @@ -659,14 +659,6 @@ DOCTEST_DEFINE_DEFAULTS(AssertData); DOCTEST_DEFINE_DEFAULTS(MessageData); -SubcaseSignature::SubcaseSignature(const char* name, const char* file, int line) - : m_name(name) - , m_file(file) - , m_line(line) {} - -DOCTEST_DEFINE_DEFAULTS(SubcaseSignature); -DOCTEST_DEFINE_COPIES(SubcaseSignature); - bool SubcaseSignature::operator<(const SubcaseSignature& other) const { if(m_line != other.m_line) return m_line < other.m_line; @@ -915,28 +907,33 @@ namespace { namespace detail { Subcase::Subcase(const char* name, const char* file, int line) - : m_signature(name, file, line) { + : m_signature({name, file, line}) { ContextState* s = g_cs; - // if we have already completed it - if(s->subcasesPassed.count(m_signature) != 0) - return; - // check subcase filters - if(s->subcasesCurrentLevel < s->subcase_filter_levels) { + if(s->subcaseStack.size() < size_t(s->subcase_filter_levels)) { if(!matchesAny(m_signature.m_name, s->filters[6], true, s->case_sensitive)) return; if(matchesAny(m_signature.m_name, s->filters[7], false, s->case_sensitive)) return; } - + // if a Subcase on the same level has already been entered - if(s->subcasesEnteredLevels.count(s->subcasesCurrentLevel) != 0) { + if(s->subcaseStack.size() < size_t(s->subcasesCurrentMaxLevel)) { s->should_reenter = true; return; } - s->subcasesEnteredLevels.insert(s->subcasesCurrentLevel++); + // push the current signature to the stack so we can check if the + // current stack + the current new subcase have been traversed + s->subcaseStack.push_back(m_signature); + if(s->subcasesPassed.count(s->subcaseStack) != 0) { + // pop - revert to previous stack since we've already passed this + s->subcaseStack.pop_back(); + return; + } + + s->subcasesCurrentMaxLevel = s->subcaseStack.size(); m_entered = true; DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); @@ -946,10 +943,11 @@ namespace detail { if(m_entered) { ContextState* s = g_cs; - s->subcasesCurrentLevel--; // only mark the subcase as passed if no subcases have been skipped if(s->should_reenter == false) - s->subcasesPassed.insert(m_signature); + s->subcasesPassed.insert(s->subcaseStack); + + s->subcaseStack.pop_back(); DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); } @@ -1488,8 +1486,10 @@ namespace { DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true}); - while(g_cs->subcasesCurrentLevel--) + while(g_cs->subcaseStack.size()) { + g_cs->subcaseStack.pop_back(); DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); + } g_cs->finalizeTestCaseData(); @@ -3230,9 +3230,9 @@ int Context::run() { do { // reset some of the fields for subcases (except for the set of fully passed ones) - p->should_reenter = false; - p->subcasesCurrentLevel = 0; - p->subcasesEnteredLevels.clear(); + p->should_reenter = false; + p->subcasesCurrentMaxLevel = 0; + p->subcaseStack.clear(); // reset stuff for logging with INFO() p->stringifiedContexts.clear(); diff --git a/doctest/parts/doctest_fwd.h b/doctest/parts/doctest_fwd.h index 0e9938e..ad8345d 100644 --- a/doctest/parts/doctest_fwd.h +++ b/doctest/parts/doctest_fwd.h @@ -698,12 +698,7 @@ struct DOCTEST_INTERFACE SubcaseSignature const char* m_file; int m_line; - SubcaseSignature(const char* name, const char* file, int line); - bool operator<(const SubcaseSignature& other) const; - - DOCTEST_DECLARE_DEFAULTS(SubcaseSignature); - DOCTEST_DECLARE_COPIES(SubcaseSignature); }; struct DOCTEST_INTERFACE IContextScope diff --git a/examples/all_features/subcases.cpp b/examples/all_features/subcases.cpp index 8fb49a9..8becba0 100644 --- a/examples/all_features/subcases.cpp +++ b/examples/all_features/subcases.cpp @@ -113,3 +113,27 @@ TEST_CASE("fails from an exception but gets re-entered to traverse all subcases" throw_if(true, "failure... but the show must go on!"); } } + +static void checks(int data) +{ + DOCTEST_SUBCASE("check data 1") { REQUIRE(data % 2 == 0); } + DOCTEST_SUBCASE("check data 2") { REQUIRE(data % 4 == 0); } +} + +TEST_CASE("Nested - related to https://github.com/onqtam/doctest/issues/282") +{ + DOCTEST_SUBCASE("generate data variant 1") + { + int data(44); + + // checks + checks(data); + } + DOCTEST_SUBCASE("generate data variant 1") + { + int data(80); + + // checks (identical in both variants) + checks(data); + } +} diff --git a/examples/all_features/test_output/filter_2.txt b/examples/all_features/test_output/filter_2.txt index 2c565bb..bb80ff8 100644 --- a/examples/all_features/test_output/filter_2.txt +++ b/examples/all_features/test_output/filter_2.txt @@ -1,6 +1,6 @@ [doctest] run with "--help" for options =============================================================================== -[doctest] test cases: 0 | 0 passed | 0 failed | 76 skipped +[doctest] test cases: 0 | 0 passed | 0 failed | 77 skipped [doctest] assertions: 0 | 0 passed | 0 failed | [doctest] Status: SUCCESS! Program code. diff --git a/examples/all_features/test_output/filter_2_xml.txt b/examples/all_features/test_output/filter_2_xml.txt index 4a6a03a..8539325 100644 --- a/examples/all_features/test_output/filter_2_xml.txt +++ b/examples/all_features/test_output/filter_2_xml.txt @@ -4,6 +4,7 @@ <TestSuite> <TestCase name=" Scenario: vectors can be sized and resized" filename="subcases.cpp" line="0" skipped="true"/> <TestCase name="CHECK level of asserts fail the test case but don't abort it" filename="assertion_macros.cpp" line="0" skipped="true"/> + <TestCase name="Nested - related to https://github.com/onqtam/doctest/issues/282" filename="subcases.cpp" line="0" skipped="true"/> <TestCase name="REQUIRE level of asserts fail and abort the test case - 1" filename="assertion_macros.cpp" line="0" skipped="true"/> <TestCase name="REQUIRE level of asserts fail and abort the test case - 10" filename="assertion_macros.cpp" line="0" skipped="true"/> <TestCase name="REQUIRE level of asserts fail and abort the test case - 11" filename="assertion_macros.cpp" line="0" skipped="true"/> @@ -114,6 +115,6 @@ <TestCase name="will end from an unknown exception" filename="coverage_maxout.cpp" line="0" skipped="true"/> </TestSuite> <OverallResultsAsserts successes="0" failures="0"/> - <OverallResultsTestCases successes="0" failures="0" skipped="76"/> + <OverallResultsTestCases successes="0" failures="0" skipped="77"/> </doctest> Program code. diff --git a/examples/all_features/test_output/filter_3.txt b/examples/all_features/test_output/filter_3.txt index f61eb82..c0cb430 100644 --- a/examples/all_features/test_output/filter_3.txt +++ b/examples/all_features/test_output/filter_3.txt @@ -23,7 +23,7 @@ TEST CASE: subcases can be used in a separate function as well subcases.cpp(0): MESSAGE: lala =============================================================================== -[doctest] test cases: 5 | 5 passed | 0 failed | +[doctest] test cases: 6 | 6 passed | 0 failed | [doctest] assertions: 0 | 0 passed | 0 failed | [doctest] Status: SUCCESS! Program code. diff --git a/examples/all_features/test_output/filter_3_xml.txt b/examples/all_features/test_output/filter_3_xml.txt index c363fa4..3e56aa9 100644 --- a/examples/all_features/test_output/filter_3_xml.txt +++ b/examples/all_features/test_output/filter_3_xml.txt @@ -38,8 +38,11 @@ root <TestCase name="fails from an exception but gets re-entered to traverse all subcases" filename="subcases.cpp" line="0"> <OverallResultsAsserts successes="0" failures="0"/> </TestCase> + <TestCase name="Nested - related to https://github.com/onqtam/doctest/issues/282" filename="subcases.cpp" line="0"> + <OverallResultsAsserts successes="0" failures="0"/> + </TestCase> </TestSuite> <OverallResultsAsserts successes="0" failures="0"/> - <OverallResultsTestCases successes="5" failures="0"/> + <OverallResultsTestCases successes="6" failures="0"/> </doctest> Program code. diff --git a/examples/all_features/test_output/subcases.cpp.txt b/examples/all_features/test_output/subcases.cpp.txt index 9204383..89151c3 100644 --- a/examples/all_features/test_output/subcases.cpp.txt +++ b/examples/all_features/test_output/subcases.cpp.txt @@ -117,7 +117,7 @@ TEST CASE: fails from an exception but gets re-entered to traverse all subcases subcases.cpp(0): ERROR: test case THREW exception: failure... but the show must go on! =============================================================================== -[doctest] test cases: 5 | 1 passed | 4 failed | -[doctest] assertions: 21 | 15 passed | 6 failed | +[doctest] test cases: 6 | 2 passed | 4 failed | +[doctest] assertions: 25 | 19 passed | 6 failed | [doctest] Status: FAILURE! Program code. diff --git a/examples/all_features/test_output/subcases.cpp_xml.txt b/examples/all_features/test_output/subcases.cpp_xml.txt index c5a5b94..95bbd7f 100644 --- a/examples/all_features/test_output/subcases.cpp_xml.txt +++ b/examples/all_features/test_output/subcases.cpp_xml.txt @@ -163,8 +163,27 @@ root </Exception> <OverallResultsAsserts successes="0" failures="2"/> </TestCase> + <TestCase name="Nested - related to https://github.com/onqtam/doctest/issues/282" filename="subcases.cpp" line="0"> + <SubCase name="generate data variant 1" filename="subcases.cpp" line="0"> + <SubCase name="check data 1" filename="subcases.cpp" line="0"> + </SubCase> + </SubCase> + <SubCase name="generate data variant 1" filename="subcases.cpp" line="0"> + <SubCase name="check data 2" filename="subcases.cpp" line="0"> + </SubCase> + </SubCase> + <SubCase name="generate data variant 1" filename="subcases.cpp" line="0"> + <SubCase name="check data 1" filename="subcases.cpp" line="0"> + </SubCase> + </SubCase> + <SubCase name="generate data variant 1" filename="subcases.cpp" line="0"> + <SubCase name="check data 2" filename="subcases.cpp" line="0"> + </SubCase> + </SubCase> + <OverallResultsAsserts successes="4" failures="0"/> + </TestCase> </TestSuite> - <OverallResultsAsserts successes="15" failures="6"/> - <OverallResultsTestCases successes="1" failures="4"/> + <OverallResultsAsserts successes="19" failures="6"/> + <OverallResultsTestCases successes="2" failures="4"/> </doctest> Program code. diff --git a/scripts/coverage_maxout.cpp b/scripts/coverage_maxout.cpp index 6cf7ed8..ed3b4fb 100644 --- a/scripts/coverage_maxout.cpp +++ b/scripts/coverage_maxout.cpp @@ -27,7 +27,7 @@ TEST_CASE("exercising tricky code paths of doctest") { using namespace doctest; // trigger code path for comparing the file in "operator<" of SubcaseSignature - CHECK(SubcaseSignature("", "a.cpp", 0) < SubcaseSignature("", "b.cpp", 0)); + CHECK(SubcaseSignature{"", "a.cpp", 0} < SubcaseSignature{"", "b.cpp", 0}); // same for String CHECK(String("a.cpp") < String("b.cpp")); |