diff --git a/test/unit/utils/test_utils.cpp b/test/unit/utils/test_utils.cpp index cd8f40e2b..97c693876 100644 --- a/test/unit/utils/test_utils.cpp +++ b/test/unit/utils/test_utils.cpp @@ -101,107 +101,109 @@ TempFile::~TempFile() { logger->error("Cannot delete temporary file {}", path_.string()); } } - bool MyersDiff::do_diff() { +bool MyersDiff::diff() { edits = std::deque(); - auto x = a.size(); - auto y = b.size(); - + auto x = static_cast(a.size()); + auto y = static_cast(b.size()); + bool identical = true; - + auto trace = shortest_edit(); - std::size_t d = trace.size(); + auto d = static_cast(trace.size()); for (auto v_it = trace.rbegin(); v_it != trace.rend(); v_it++, d--) { - - auto v = *v_it; - int k = x - y; - int prev_k{}; - if ((k == -d) || ((k != d) && (v[idx(k - 1)] < v[idx(k + 1)]))) { - prev_k = k + 1; - } else { - prev_k = k - 1; - } - std::size_t prev_x = v[idx(prev_k)]; - std::size_t prev_y = prev_x - prev_k; - - while ((x > prev_x) && (y > prev_y)) { - edits.emplace_front(Edit::etype::eql, &a[x - 1], &b[y - 1]); - x--; y--; - } - if (x == prev_x) { - edits.emplace_front(Edit::etype::ins, nullptr, &b[y - 1]); - identical = false; - } else if (y == prev_y) { - edits.emplace_front(Edit::etype::del, &a[x - 1], nullptr); - identical = false; - } - x = prev_x; - y = prev_y; + auto v = *v_it; + int k = x - y; + int prev_k{}; + if ((k == -d) || ((k != d) && (v[idx(k - 1)] < v[idx(k + 1)]))) { + prev_k = k + 1; + } else { + prev_k = k - 1; + } + int prev_x = v[idx(prev_k)]; + int prev_y = prev_x - prev_k; + + while ((x > prev_x) && (y > prev_y)) { + edits.emplace_front(Edit::etype::eql, &a[x - 1], &b[y - 1]); + x--; + y--; + } + if (x == prev_x) { + edits.emplace_front(Edit::etype::ins, nullptr, &b[y - 1]); + identical = false; + } else if (y == prev_y) { + edits.emplace_front(Edit::etype::del, &a[x - 1], nullptr); + identical = false; + } + x = prev_x; + y = prev_y; } return identical; - } - - std::deque MyersDiff::get_edits() { +} + +std::deque MyersDiff::get_edits() const { return edits; - } - - std::vector> MyersDiff::shortest_edit() { - auto n = a.size(); - auto m = b.size(); - int x{}, y{}; +} + +std::vector> MyersDiff::shortest_edit() { + auto n = static_cast(a.size()); + auto m = static_cast(b.size()); + int x{}; + int y{}; auto trace = std::vector>(); auto v = std::vector(2 * max + 1, 0); for (int d = 0; d <= max; ++d) { - trace.push_back(v); - for (int k = -d; k <= d; k += 2) { - if ((k == -d) || (k != d && (v[idx(k - 1)] < v[idx(k + 1)]))) { - x = v[idx(k + 1)]; - } else { - x = v[idx(k - 1)] + 1; - } - y = x - k; - while ((x < n) && (y < m) && (a[x].second == b[y].second)) { - x++; y++; - } - v[idx(k)] = x; + trace.push_back(v); + for (int k = -d; k <= d; k += 2) { + if ((k == -d) || (k != d && (v[idx(k - 1)] < v[idx(k + 1)]))) { + x = v[idx(k + 1)]; + } else { + x = v[idx(k - 1)] + 1; + } + y = x - k; + while ((x < n) && (y < m) && (a[x].second == b[y].second)) { + x++; + y++; + } + v[idx(k)] = x; - if ((x >= n) && (y >= m)) { - trace.push_back(v); - return trace; + if ((x >= n) && (y >= m)) { + trace.push_back(v); + return trace; + } } - } } return trace; - } - - string_lines MyersDiff::split_lines(const std::string& txt) { - std::size_t pos = 0, ppos = 0; - std::size_t lineno = 1; - string_lines lines; - while ((pos = txt.find('\n', ppos)) != std::string::npos) { - lines.emplace_back(lineno++, txt.substr(ppos, pos - ppos)); - ppos = pos + 1; - } - if (ppos < txt.length()) { - lines.emplace_back(lineno, txt.substr(ppos)); - } - - return lines; - } - std::ostringstream& operator<<(std::ostringstream& oss, MyersDiff::Edit& edit) { +} + +string_lines MyersDiff::split_lines(const std::string& txt) const { + std::size_t pos = 0; + std::size_t ppos = 0; + std::size_t lineno = 1; + string_lines lines; + while ((pos = txt.find('\n', ppos)) != std::string::npos) { + lines.emplace_back(lineno++, txt.substr(ppos, pos - ppos)); + ppos = pos + 1; + } + if (ppos < txt.length()) { + lines.emplace_back(lineno, txt.substr(ppos)); + } + + return lines; +} +std::ostringstream& operator<<(std::ostringstream& oss, MyersDiff::Edit& edit) { if (edit.edit == MyersDiff::Edit::etype::ins) { - oss << fmt::format("{} {:>3s} {:>3d} {}", '+', "", edit.new_line->first, edit.new_line->second); + oss << fmt::format("{} {}", '+', edit.new_line->second); } else if (edit.edit == MyersDiff::Edit::etype::del) { - oss << fmt::format("{} {:>3d} {:>3s} {}", '-', edit.old_line->first, "", edit.old_line->second); + oss << fmt::format("{} {}", '-', edit.old_line->second); } else { - oss << fmt::format("{} {:>3d} {:>3d} {}", ' ', edit.old_line->first, edit.new_line->first, edit.old_line->second); + oss << fmt::format("{} {}", ' ', edit.old_line->second); } return oss; - } +} } // namespace test_utils } // namespace nmodl - diff --git a/test/unit/utils/test_utils.hpp b/test/unit/utils/test_utils.hpp index fd974537f..191996923 100644 --- a/test/unit/utils/test_utils.hpp +++ b/test/unit/utils/test_utils.hpp @@ -37,45 +37,55 @@ class MyersDiff { public: - struct Edit { - enum etype {ins, del, eql}; - etype edit; - const line* old_line = nullptr; - const line* new_line = nullptr; - Edit(etype e, const line* o, const line* n) : edit(e), old_line(o), new_line(n) {}; - - friend std::ostringstream& operator<<(std::ostringstream& out, Edit&); - }; - - MyersDiff(const std::string& str_a, const std::string& str_b) { - a = split_lines(str_a); - b = split_lines(str_b); - max = a.size() + b.size(); - } - - bool do_diff(); - std::deque get_edits(); + struct Edit { + enum etype { ins, del, eql }; + etype edit; + const line* old_line = nullptr; + const line* new_line = nullptr; + Edit(etype e, const line* o, const line* n) + : edit(e) + , old_line(o) + , new_line(n){}; + + friend std::ostringstream& operator<<(std::ostringstream& out, Edit&); + }; + + MyersDiff(const std::string& str_a, const std::string& str_b) + : a(split_lines(str_a)) + , b(split_lines(str_b)) + , max(a.size() + b.size()) { + identical = diff(); + } + + bool is_identical() const { + return identical; + } + + std::deque get_edits() const; private: - struct TraceTuple { - std::size_t prev_x = 0; - std::size_t prev_y = 0; - std::size_t x = 0; - std::size_t y = 0; - }; - - string_lines a, b; - std::size_t max{}; - std::deque edits; + bool diff(); - inline std::size_t idx(int i) const { - return (i + max) % max; - } + struct TraceTuple { + std::size_t prev_x = 0; + std::size_t prev_y = 0; + std::size_t x = 0; + std::size_t y = 0; + }; - string_lines split_lines(const std::string& txt); - std::vector> shortest_edit(); + string_lines a{}; + string_lines b{}; + std::size_t max{}; + bool identical{}; + std::deque edits; + inline std::size_t idx(int i) const { + return (i + max) % max; + } + + string_lines split_lines(const std::string& txt) const; + std::vector> shortest_edit(); }; } // namespace test_utils diff --git a/test/unit/visitor/loop_unroll.cpp b/test/unit/visitor/loop_unroll.cpp index b5d6925db..8f8c9f2b5 100644 --- a/test/unit/visitor/loop_unroll.cpp +++ b/test/unit/visitor/loop_unroll.cpp @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include #include "ast/program.hpp" #include "parser/nmodl_driver.hpp" @@ -90,15 +90,15 @@ SCENARIO("Perform loop unrolling of FROM construct", "[visitor][unroll]") { THEN("Loop body gets correctly unrolled") { auto result = run_loop_unroll_visitor(input_nmodl); if (reindent_text(output_nmodl) != reindent_text(result)) { - auto diff = MyersDiff(reindent_text(output_nmodl), reindent_text(result)); - diff.do_diff(); - std::ostringstream edits; - for (auto& edit : diff.get_edits()) { - edits << edit << "\n"; - } - FAIL(edits.str()); + auto diff = MyersDiff(reindent_text(output_nmodl), reindent_text(result)); + if (!diff.is_identical()) { + std::ostringstream edits; + for (auto& edit: diff.get_edits()) { + edits << edit << "\n"; + } + FAIL(edits.str()); + } } - //REQUIRE(reindent_text(output_nmodl) == reindent_text(result)); } }