Skip to content

Commit

Permalink
Fix #83
Browse files Browse the repository at this point in the history
  • Loading branch information
cschreib committed Apr 13, 2023
1 parent 0954970 commit 844ab58
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 10 deletions.
48 changes: 38 additions & 10 deletions src/snitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,27 @@ small_function<void(std::string_view)> assertion_failed_handler = &terminate_wit
namespace snitch::impl {
section_entry_checker::~section_entry_checker() {
if (entered) {
if (state.sections.levels.size() == state.sections.depth) {
if (state.sections.depth == state.sections.levels.size()) {
// We just entered this section, and there was no child section in it.
// This is a leaf; flag that a leaf has been executed so that no other leaf
// is executed in this run.
// Note: don't pop this level from the section state yet, it may have siblings
// that we don't know about yet. Popping will be done when we exit from the parent,
// since then we will know if there is any sibling.
state.sections.leaf_executed = true;
} else {
auto& child = state.sections.levels[state.sections.depth];
if (child.previous_section_id == child.max_section_id) {
// Check if there is any child section left to execute, at any depth below this one.
bool no_child_section_left = true;
for (std::size_t c = state.sections.depth; c < state.sections.levels.size(); ++c) {
auto& child = state.sections.levels[c];
if (child.previous_section_id != child.max_section_id) {
no_child_section_left = false;
break;
}
}

if (no_child_section_left) {
// No more children, we can pop this level and never go back.
state.sections.levels.pop_back();
}
}
Expand Down Expand Up @@ -413,14 +429,22 @@ section_entry_checker::operator bool() {
auto& level = state.sections.levels[state.sections.depth - 1];

++level.current_section_id;
if (level.max_section_id < level.current_section_id) {
if (level.current_section_id > level.max_section_id) {
level.max_section_id = level.current_section_id;
}

if (!state.sections.leaf_executed &&
(level.previous_section_id + 1 == level.current_section_id ||
(level.previous_section_id == level.current_section_id &&
state.sections.levels.size() > state.sections.depth))) {
if (state.sections.leaf_executed) {
// We have already executed another leaf section; can't execute more
// on this run, so don't bother going inside this one now.
return false;
}

// Only enter this section if:
// - The section entered in the previous run was its immediate previous sibling, or
// - This section was already entered in the previous run, and child sections exist in it.
if (level.current_section_id == level.previous_section_id + 1 ||
(level.current_section_id == level.previous_section_id &&
state.sections.depth < state.sections.levels.size())) {

level.previous_section_id = level.current_section_id;
state.sections.current_section.push_back(section);
Expand Down Expand Up @@ -928,6 +952,7 @@ test_state registry::run(test_case& test) noexcept {

test.state = impl::test_case_state::success;

// Fetch special tags for this test case.
bool may_fail = false;
bool should_fail = false;
for_each_tag(test.id.tags, [&](const tags::parsed_tag& v) {
Expand All @@ -951,12 +976,13 @@ test_state registry::run(test_case& test) noexcept {
#endif

do {
// Reset section state.
state.sections.leaf_executed = false;
for (std::size_t i = 0; i < state.sections.levels.size(); ++i) {
state.sections.levels[i].current_section_id = 0;
}

state.sections.leaf_executed = false;

// Run the test case.
#if SNITCH_WITH_EXCEPTIONS
try {
test.func();
Expand All @@ -974,8 +1000,10 @@ test_state registry::run(test_case& test) noexcept {
#endif

if (state.sections.levels.size() == 1) {
// This test case contained sections; check if there are any more left to evaluate.
auto& child = state.sections.levels[0];
if (child.previous_section_id == child.max_section_id) {
// No more; clear the section state.
state.sections.levels.clear();
state.sections.current_section.clear();
}
Expand Down
42 changes: 42 additions & 0 deletions tests/runtime_tests/section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,48 @@ TEST_CASE("section", "[test macros]") {
CHECK_CASE(snitch::test_case_state::failed, 11u);
}

SECTION("nested sections multiple leaves") {
framework.test_case.func = []() {
SNITCH_SECTION("section 1") {
SNITCH_SECTION("section 1.1") {
SNITCH_SECTION("section 1.1.1") {
SNITCH_FAIL_CHECK("trigger");
}
SNITCH_SECTION("section 1.1.2") {
SNITCH_FAIL_CHECK("trigger");
}
SNITCH_SECTION("section 1.1.3") {
SNITCH_FAIL_CHECK("trigger");
}
}
}
SNITCH_SECTION("section 2") {
SNITCH_SECTION("section 2.1") {
SNITCH_SECTION("section 2.1.1") {
SNITCH_FAIL_CHECK("trigger");
}
SNITCH_SECTION("section 2.1.2") {
SNITCH_FAIL_CHECK("trigger");
}
SNITCH_SECTION("section 2.1.3") {
SNITCH_FAIL_CHECK("trigger");
}
}
}
};

framework.run_test();

REQUIRE(framework.get_num_failures() == 6u);
CHECK_SECTIONS_FOR_FAILURE(0u, "section 1", "section 1.1", "section 1.1.1");
CHECK_SECTIONS_FOR_FAILURE(1u, "section 1", "section 1.1", "section 1.1.2");
CHECK_SECTIONS_FOR_FAILURE(2u, "section 1", "section 1.1", "section 1.1.3");
CHECK_SECTIONS_FOR_FAILURE(3u, "section 2", "section 2.1", "section 2.1.1");
CHECK_SECTIONS_FOR_FAILURE(4u, "section 2", "section 2.1", "section 2.1.2");
CHECK_SECTIONS_FOR_FAILURE(5u, "section 2", "section 2.1", "section 2.1.3");
CHECK_CASE(snitch::test_case_state::failed, 6u);
}

SECTION("one section in a loop") {
framework.test_case.func = []() {
for (std::size_t i = 0u; i < 5u; ++i) {
Expand Down

0 comments on commit 844ab58

Please sign in to comment.