From a9f793e4078a0902bc890d1515728af002c3546f Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Wed, 18 Jan 2023 21:32:21 +0100 Subject: [PATCH] Removed dead code and improve test coverage --- src/class_diagram/model/class.cc | 6 --- src/class_diagram/model/class.h | 4 -- src/class_diagram/model/diagram.cc | 8 ---- src/class_diagram/model/diagram.h | 5 --- src/class_diagram/model/type_alias.cc | 34 ----------------- src/class_diagram/model/type_alias.h | 37 ------------------- src/config/yaml_emitters.cc | 5 +-- .../plantuml/include_diagram_generator.cc | 2 + .../plantuml/package_diagram_generator.cc | 2 + .../plantuml/sequence_diagram_generator.cc | 2 + src/sequence_diagram/model/diagram.h | 16 ++++++++ src/sequence_diagram/model/participant.h | 4 -- .../visitor/call_expression_context.cc | 22 ----------- .../visitor/call_expression_context.h | 7 ---- .../visitor/translation_unit_visitor.cc | 7 +++- src/util/error.h | 6 --- src/util/thread_pool_executor.cc | 4 -- src/util/thread_pool_executor.h | 4 +- src/util/util.cc | 14 ------- src/util/util.h | 9 ----- tests/t20001/.clang-uml | 2 +- tests/t20001/test_case.h | 2 + tests/t30001/.clang-uml | 2 +- tests/t30001/test_case.h | 4 +- tests/t40001/.clang-uml | 2 +- tests/t40001/test_case.h | 2 + tests/test_cases.h | 7 ++++ tests/test_config.cc | 2 +- tests/test_config_data/complete.yml | 18 ++++++++- tests/test_util.cc | 33 +++++++++++++++++ 30 files changed, 98 insertions(+), 174 deletions(-) delete mode 100644 src/class_diagram/model/type_alias.cc delete mode 100644 src/class_diagram/model/type_alias.h diff --git a/src/class_diagram/model/class.cc b/src/class_diagram/model/class.cc index 69e35473..96b7a139 100644 --- a/src/class_diagram/model/class.cc +++ b/src/class_diagram/model/class.cc @@ -93,12 +93,6 @@ std::string class_::base_template() const { return base_template_full_name_; } bool operator==(const class_ &l, const class_ &r) { return l.id() == r.id(); } -void class_::add_type_alias(type_alias &&ta) -{ - LOG_DBG("Adding class alias: {} -> {}", ta.alias(), ta.underlying_type()); - type_aliases_[ta.alias()] = std::move(ta); -} - std::string class_::full_name_no_ns() const { using namespace clanguml::util; diff --git a/src/class_diagram/model/class.h b/src/class_diagram/model/class.h index f4d10f35..eb9af5ef 100644 --- a/src/class_diagram/model/class.h +++ b/src/class_diagram/model/class.h @@ -25,7 +25,6 @@ #include "common/model/stylable_element.h" #include "common/types.h" #include "template_parameter.h" -#include "type_alias.h" #include #include @@ -68,8 +67,6 @@ public: friend bool operator==(const class_ &l, const class_ &r); - void add_type_alias(type_alias &&ta); - std::string full_name(bool relative = true) const override; std::string full_name_no_ns() const override; @@ -100,7 +97,6 @@ private: std::vector bases_; std::vector templates_; std::string base_template_full_name_; - std::map type_aliases_; std::string full_name_; }; diff --git a/src/class_diagram/model/diagram.cc b/src/class_diagram/model/diagram.cc index 643379f0..2a365684 100644 --- a/src/class_diagram/model/diagram.cc +++ b/src/class_diagram/model/diagram.cc @@ -126,14 +126,6 @@ common::optional_ref diagram::get_enum( return {}; } -void diagram::add_type_alias(std::unique_ptr &&ta) -{ - LOG_DBG( - "Adding global alias: {} -> {}", ta->alias(), ta->underlying_type()); - - type_aliases_[ta->alias()] = std::move(ta); -} - bool diagram::add_package(std::unique_ptr &&p) { LOG_DBG("Adding namespace package: {}, {}", p->name(), p->full_name(true)); diff --git a/src/class_diagram/model/diagram.h b/src/class_diagram/model/diagram.h index 3d9703dd..61ffee1a 100644 --- a/src/class_diagram/model/diagram.h +++ b/src/class_diagram/model/diagram.h @@ -23,7 +23,6 @@ #include "common/model/package.h" #include "common/types.h" #include "enum.h" -#include "type_alias.h" #include #include @@ -69,8 +68,6 @@ public: common::optional_ref get_enum( clanguml::common::model::diagram_element::id_t id) const; - void add_type_alias(std::unique_ptr &&ta); - bool add_class(std::unique_ptr &&c); bool add_enum(std::unique_ptr &&e); @@ -93,8 +90,6 @@ private: common::reference_vector classes_; common::reference_vector enums_; - - std::map> type_aliases_; }; } // namespace clanguml::class_diagram::model diff --git a/src/class_diagram/model/type_alias.cc b/src/class_diagram/model/type_alias.cc deleted file mode 100644 index 7b3a3267..00000000 --- a/src/class_diagram/model/type_alias.cc +++ /dev/null @@ -1,34 +0,0 @@ -/** - * src/class_diagram/model/type_alias.cc - * - * Copyright (c) 2021-2023 Bartek Kryza - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "type_alias.h" - -namespace clanguml::class_diagram::model { - -void type_alias::set_alias(const std::string &alias) { alias_ = alias; } - -std::string type_alias::alias() const { return alias_; } - -void type_alias::set_underlying_type(const std::string &type) -{ - underlying_type_ = type; -} - -std::string type_alias::underlying_type() const { return underlying_type_; } - -} // namespace clanguml::class_diagram::model diff --git a/src/class_diagram/model/type_alias.h b/src/class_diagram/model/type_alias.h deleted file mode 100644 index b0461226..00000000 --- a/src/class_diagram/model/type_alias.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * src/class_diagram/model/type_alias.h - * - * Copyright (c) 2021-2023 Bartek Kryza - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include - -namespace clanguml::class_diagram::model { - -class type_alias { -public: - void set_alias(const std::string &alias); - std::string alias() const; - - void set_underlying_type(const std::string &type); - std::string underlying_type() const; - -private: - std::string alias_; - std::string underlying_type_; -}; - -} // namespace clanguml::class_diagram::model diff --git a/src/config/yaml_emitters.cc b/src/config/yaml_emitters.cc index 00b2c5fa..8737a6ee 100644 --- a/src/config/yaml_emitters.cc +++ b/src/config/yaml_emitters.cc @@ -149,9 +149,8 @@ YAML::Emitter &operator<<(YAML::Emitter &out, const layout_hint &c) YAML::Emitter &operator<<(YAML::Emitter &out, const source_location &sc) { out << YAML::BeginMap; - out << YAML::Key << "location" << YAML::Value << sc.location; - out << YAML::Key << "location_type" << YAML::Value - << to_string(sc.location_type); + out << YAML::Key << to_string(sc.location_type) << YAML::Value + << sc.location; out << YAML::EndMap; return out; } diff --git a/src/include_diagram/generators/plantuml/include_diagram_generator.cc b/src/include_diagram/generators/plantuml/include_diagram_generator.cc index 7c10148d..cdf94f4e 100644 --- a/src/include_diagram/generators/plantuml/include_diagram_generator.cc +++ b/src/include_diagram/generators/plantuml/include_diagram_generator.cc @@ -96,6 +96,8 @@ void generator::generate(const source_file &f, std::ostream &ostr) const void generator::generate(std::ostream &ostr) const { + update_context(); + ostr << "@startuml" << '\n'; if (m_config.puml) diff --git a/src/package_diagram/generators/plantuml/package_diagram_generator.cc b/src/package_diagram/generators/plantuml/package_diagram_generator.cc index 126f527d..244f65f6 100644 --- a/src/package_diagram/generators/plantuml/package_diagram_generator.cc +++ b/src/package_diagram/generators/plantuml/package_diagram_generator.cc @@ -97,6 +97,8 @@ void generator::generate(const package &p, std::ostream &ostr) const void generator::generate(std::ostream &ostr) const { + update_context(); + ostr << "@startuml" << '\n'; generate_plantuml_directives(ostr, m_config.puml().before); diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index fe332656..0695d68d 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -369,6 +369,8 @@ bool generator::is_participant_generated(common::id_t id) const void generator::generate(std::ostream &ostr) const { + update_context(); + m_model.print(); ostr << "@startuml" << std::endl; diff --git a/src/sequence_diagram/model/diagram.h b/src/sequence_diagram/model/diagram.h index 631e5017..8abf9b64 100644 --- a/src/sequence_diagram/model/diagram.h +++ b/src/sequence_diagram/model/diagram.h @@ -110,6 +110,22 @@ public: active_participants() const; private: + /** + * This method checks the last messages in sequence (current_messages), + * if they represent a block sequence identified by statement_begin + * (e.g. if/else) and there are no actual call expressions within this block + * statement the entire block statement is removed from the end of the + * sequence. + * + * Otherwise the block statement is ended with a proper statement + * (e.g. endif) + * + * @param m Message to add to the sequence + * @param statement_begin Type of message which begins this type of block + * statement (e.g. message_t::kIf) + * @param current_messages Reference to the sequence messages which should + * be amended + */ void fold_or_end_block_statement(message &&m, common::model::message_t statement_begin, std::vector ¤t_messages) const; diff --git a/src/sequence_diagram/model/participant.h b/src/sequence_diagram/model/participant.h index 061635e2..25275927 100644 --- a/src/sequence_diagram/model/participant.h +++ b/src/sequence_diagram/model/participant.h @@ -18,7 +18,6 @@ #pragma once #include "class_diagram/model/template_parameter.h" -#include "class_diagram/model/type_alias.h" #include "common/model/element.h" #include @@ -122,9 +121,6 @@ private: bool is_alias_{false}; bool is_lambda_{false}; - std::map - type_aliases_; - std::string full_name_; }; diff --git a/src/sequence_diagram/visitor/call_expression_context.cc b/src/sequence_diagram/visitor/call_expression_context.cc index 0c0999b8..91756a67 100644 --- a/src/sequence_diagram/visitor/call_expression_context.cc +++ b/src/sequence_diagram/visitor/call_expression_context.cc @@ -126,22 +126,6 @@ void call_expression_context::update( current_function_template_decl_ = function_template; } -bool call_expression_context::in_class_method() const -{ - return current_class_decl_ != nullptr; -} - -bool call_expression_context::in_function() const -{ - return current_class_decl_ == nullptr && current_function_decl_ != nullptr; -} - -bool call_expression_context::in_function_template() const -{ - return current_function_decl_ != nullptr && - current_function_template_decl_ != nullptr; -} - std::int64_t call_expression_context::caller_id() const { return current_caller_id_; @@ -207,12 +191,6 @@ void call_expression_context::enter_elseifstmt(clang::IfStmt *stmt) elseif_stmt_stack_.push(stmt); } -void call_expression_context::leave_elseifstmt() -{ - if (!elseif_stmt_stack_.empty()) - elseif_stmt_stack_.pop(); -} - clang::IfStmt *call_expression_context::current_elseifstmt() const { if (elseif_stmt_stack_.empty()) diff --git a/src/sequence_diagram/visitor/call_expression_context.h b/src/sequence_diagram/visitor/call_expression_context.h index b4f1a6b8..127020b4 100644 --- a/src/sequence_diagram/visitor/call_expression_context.h +++ b/src/sequence_diagram/visitor/call_expression_context.h @@ -51,12 +51,6 @@ struct call_expression_context { void update(clang::FunctionTemplateDecl *function_template); - bool in_class_method() const; - - bool in_function() const; - - bool in_function_template() const; - std::int64_t caller_id() const; std::int64_t lambda_caller_id() const; @@ -73,7 +67,6 @@ struct call_expression_context { void leave_ifstmt(); void enter_elseifstmt(clang::IfStmt *stmt); - void leave_elseifstmt(); clang::IfStmt *current_elseifstmt() const; clang::Stmt *current_loopstmt() const; diff --git a/src/sequence_diagram/visitor/translation_unit_visitor.cc b/src/sequence_diagram/visitor/translation_unit_visitor.cc index 9e328fcb..5073fd8a 100644 --- a/src/sequence_diagram/visitor/translation_unit_visitor.cc +++ b/src/sequence_diagram/visitor/translation_unit_visitor.cc @@ -577,6 +577,7 @@ bool translation_unit_visitor::TraverseIfStmt(clang::IfStmt *stmt) if ((current_caller_id != 0) && !stmt->isConstexpr() && !elseif_block) { diagram().end_block_message( {message_t::kIfEnd, current_caller_id}, message_t::kIf); + context().leave_ifstmt(); } return true; @@ -769,7 +770,8 @@ bool translation_unit_visitor::TraverseCaseStmt(clang::CaseStmt *stmt) const auto current_caller_id = context().caller_id(); - if (current_caller_id != 0) { + if ((current_caller_id != 0) && + (context().current_switchstmt() != nullptr)) { model::message m{message_t::kCase, current_caller_id}; m.set_message_name(common::to_string(stmt->getLHS())); diagram().add_case_stmt_message(std::move(m)); @@ -786,7 +788,8 @@ bool translation_unit_visitor::TraverseDefaultStmt(clang::DefaultStmt *stmt) const auto current_caller_id = context().caller_id(); - if (current_caller_id != 0) { + if ((current_caller_id != 0) && + (context().current_switchstmt() != nullptr)) { model::message m{message_t::kCase, current_caller_id}; m.set_message_name("default"); diagram().add_case_stmt_message(std::move(m)); diff --git a/src/util/error.h b/src/util/error.h index ab7bb761..ab90a8f6 100644 --- a/src/util/error.h +++ b/src/util/error.h @@ -28,10 +28,4 @@ struct uml_alias_missing : public virtual std::runtime_error { } }; -struct substring_delimiter_not_found : public virtual std::runtime_error { - substring_delimiter_not_found(const std::string &message) - : std::runtime_error(message) - { - } -}; } // namespace clanguml::error diff --git a/src/util/thread_pool_executor.cc b/src/util/thread_pool_executor.cc index 7eaaf79d..f6705972 100644 --- a/src/util/thread_pool_executor.cc +++ b/src/util/thread_pool_executor.cc @@ -19,10 +19,6 @@ #include "thread_pool_executor.h" namespace clanguml::util { -thread_pool_executor::thread_pool_executor() - : thread_pool_executor{0} -{ -} thread_pool_executor::thread_pool_executor(unsigned int pool_size) : done_{false} diff --git a/src/util/thread_pool_executor.h b/src/util/thread_pool_executor.h index bb748f9d..21a44e09 100644 --- a/src/util/thread_pool_executor.h +++ b/src/util/thread_pool_executor.h @@ -25,15 +25,13 @@ namespace clanguml::util { class thread_pool_executor { public: - thread_pool_executor(); + explicit thread_pool_executor(unsigned int pool_size); thread_pool_executor(const thread_pool_executor &) = delete; thread_pool_executor(thread_pool_executor &&) = delete; thread_pool_executor &operator=(const thread_pool_executor &) = delete; thread_pool_executor &operator=(thread_pool_executor &&) = delete; - explicit thread_pool_executor(unsigned int pool_size); - ~thread_pool_executor(); std::future add(std::function &&task); diff --git a/src/util/util.cc b/src/util/util.cc index e41644df..ae243560 100644 --- a/src/util/util.cc +++ b/src/util/util.cc @@ -191,20 +191,6 @@ std::string join( return fmt::format("{}", fmt::join(toks, delimiter)); } -std::string unqualify(const std::string &s) -{ - auto toks = clanguml::util::split(s, " "); - const std::vector qualifiers = {"static", "const", "volatile", - "register", "constexpr", "mutable", "struct", "enum"}; - - toks.erase(toks.begin(), - std::find_if(toks.begin(), toks.end(), [&qualifiers](const auto &t) { - return std::count(qualifiers.begin(), qualifiers.end(), t) == 0; - })); - - return fmt::format("{}", fmt::join(toks, " ")); -} - std::string abbreviate(const std::string &s, const unsigned int max_length) { if (s.size() <= max_length) diff --git a/src/util/util.h b/src/util/util.h index 0d1e99fe..90ca7775 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -96,15 +96,6 @@ std::vector split( std::string join( const std::vector &toks, std::string_view delimiter); -/** - * @brief Remove any qualifiers (e.g. const) from type. - * - * @param s String spelling of the type. - * - * @return Unqualified type spelling. - */ -std::string unqualify(const std::string &s); - /** * @brief Abbreviate string to max_length, and replace last 3 characters * with ellipsis. diff --git a/tests/t20001/.clang-uml b/tests/t20001/.clang-uml index 0e443a01..508c5de1 100644 --- a/tests/t20001/.clang-uml +++ b/tests/t20001/.clang-uml @@ -17,6 +17,6 @@ diagrams: - function: "clanguml::t20001::tmain()" plantuml: before: - - "' t20001 test sequence diagram" + - "' t20001 test diagram of type {{ diagram.type }}" after: - '{% set e=element("clanguml::t20001::tmain()") %} note over {{ e.alias) }}: Main test function' diff --git a/tests/t20001/test_case.h b/tests/t20001/test_case.h index b35edd17..4799c97a 100644 --- a/tests/t20001/test_case.h +++ b/tests/t20001/test_case.h @@ -44,6 +44,8 @@ TEST_CASE("t20001", "[test-case][sequence]") REQUIRE_THAT(puml, HasCall(_A("A"), "__log_result(int)__")); REQUIRE_THAT(puml, HasCall(_A("B"), _A("A"), "__log_result(int)__")); + REQUIRE_THAT(puml, HasComment("t20001 test diagram of type sequence")); + save_puml( "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); } diff --git a/tests/t30001/.clang-uml b/tests/t30001/.clang-uml index 375e6528..0825068b 100644 --- a/tests/t30001/.clang-uml +++ b/tests/t30001/.clang-uml @@ -15,7 +15,7 @@ diagrams: - clanguml::t30001 plantuml: before: - - "' t30001 test package diagram" + - "' t30001 test diagram of type {{ diagram.type }}" after: - 'note right of {{ alias("A::AA::AAA") }}: A AAA note...' - '{% set e=element("A::AA") %} note top of {{ alias("A::AA") }} : {{ e.comment.formatted }}' diff --git a/tests/t30001/test_case.h b/tests/t30001/test_case.h index 4d4ac8f0..553b0666 100644 --- a/tests/t30001/test_case.h +++ b/tests/t30001/test_case.h @@ -43,7 +43,7 @@ TEST_CASE("t30001", "[test-case][package]") REQUIRE_THAT(puml, IsPackage("AAA")); // TODO: Fix _A() to handle fully qualified names, right - // now it only finds the first element with unqalified + // now it only finds the first element with unqualified // name match REQUIRE_THAT( puml, HasNote(_A("AA"), "top", "This is namespace AA in namespace A")); @@ -62,6 +62,8 @@ TEST_CASE("t30001", "[test-case][package]") clanguml::util::get_git_commit()), "BBB")); + REQUIRE_THAT(puml, HasComment("t30001 test diagram of type package")); + save_puml( "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); } diff --git a/tests/t40001/.clang-uml b/tests/t40001/.clang-uml index c4c549b5..208c7397 100644 --- a/tests/t40001/.clang-uml +++ b/tests/t40001/.clang-uml @@ -17,7 +17,7 @@ diagrams: - . plantuml: before: - - "' t40001 test include diagram" + - "' t40001 test diagram of type {{ diagram.type }}" after: - 'note right of {{ alias("include/lib1") }}: This is a lib1 include dir' - 'note right of {{ alias("include/t40001_include1.h") }}: This is a t40001_include1.h include file' \ No newline at end of file diff --git a/tests/t40001/test_case.h b/tests/t40001/test_case.h index d3a15495..a9c9352d 100644 --- a/tests/t40001/test_case.h +++ b/tests/t40001/test_case.h @@ -48,6 +48,8 @@ TEST_CASE("t40001", "[test-case][include]") REQUIRE_THAT(puml, IsDependency(_A("t40001_include1.h"), _A("string"))); + REQUIRE_THAT(puml, HasComment("t40001 test diagram of type include")); + save_puml( "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); } diff --git a/tests/test_cases.h b/tests/test_cases.h index 2a929ff6..0f693234 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -423,6 +423,13 @@ ContainsMatcher IsLayoutHint(std::string const &from, std::string const &hint, fmt::format("{} -[hidden]{}- {}", from, hint, to), caseSensitivity)); } +ContainsMatcher HasComment(std::string const &comment, + CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) +{ + return ContainsMatcher( + CasedString(fmt::format("' {}", comment), caseSensitivity)); +} + ContainsMatcher HasNote(std::string const &cls, std::string const &position, std::string const ¬e = "", CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) diff --git a/tests/test_config.cc b/tests/test_config.cc index fbe1c82d..6c07a5eb 100644 --- a/tests/test_config.cc +++ b/tests/test_config.cc @@ -201,7 +201,7 @@ TEST_CASE("Test config emitters", "[unit-test]") // Write the emitted YAML to a temp file auto tmp_file = std::filesystem::temp_directory_path() / - fmt::format("clang-uml-{:16}", rand()); + fmt::format("clang-uml-{:016}", rand()); { std::ofstream stream(tmp_file.string().c_str(), std::ios::binary); diff --git a/tests/test_config_data/complete.yml b/tests/test_config_data/complete.yml index 1ede29bc..f5244d1c 100644 --- a/tests/test_config_data/complete.yml +++ b/tests/test_config_data/complete.yml @@ -58,4 +58,20 @@ diagrams: plantuml: # Add this line to the beginning of the resulting puml file before: - - 'title clang-uml class diagram model' \ No newline at end of file + - 'title clang-uml class diagram model' + config_sequence: + type: sequence + start_from: + - function: main(int,const char**) + config_include: + type: include + include: + paths: + - src + config_package: + type: package + using_namespace: + - ns1 + include: + namespaces: + - ns1::ns2 \ No newline at end of file diff --git a/tests/test_util.cc b/tests/test_util.cc index 9e015f56..9c067fff 100644 --- a/tests/test_util.cc +++ b/tests/test_util.cc @@ -170,6 +170,30 @@ TEST_CASE("Test parse_unexposed_template_params", "[unit-test]") CHECK(declaration_template[2].type() == "Tail"); } +TEST_CASE("Test remove_prefix", "[unit-test]") +{ + using namespace clanguml::util; + + const std::vector collection_base = {"aa", "bb", "cc", "dd"}; + std::vector collection = collection_base; + + const std::vector prefix1 = {"xx", "yy"}; + const std::vector prefix2 = {"aa", "bb"}; + const std::vector prefix3 = {"cc", "dd"}; + + remove_prefix(collection, prefix1); + + CHECK(collection == collection_base); + + remove_prefix(collection, prefix2); + + CHECK(collection == prefix3); + + remove_prefix(collection, prefix3); + + CHECK(collection.empty()); +} + TEST_CASE("Test path_to_url", "[unit-test]") { namespace fs = std::filesystem; @@ -203,3 +227,12 @@ TEST_CASE("Test path_to_url", "[unit-test]") CHECK(path_to_url(p7) == "A/B/include.h"); #endif } + +TEST_CASE("Test hash_seed", "[unit-test]") +{ + using namespace clanguml::util; + + CHECK(hash_seed(1) != 1); + CHECK(hash_seed(1) == hash_seed(1)); + CHECK(hash_seed(1) != hash_seed(2)); +}