First working version of JSON sequence diagram generator
This commit is contained in:
@@ -12,7 +12,7 @@ YAML configuration files. The main idea behind the
|
||||
project is to easily maintain up-to-date diagrams within a code-base or document
|
||||
legacy code. The configuration file or files for `clang-uml` define the
|
||||
type and contents of each generated diagram.
|
||||
Currently, the diagrams are generated in [PlantUML](https://plantuml.com) format.
|
||||
Currently, the diagrams are generated in [PlantUML](https://plantuml.com) and JSON formats.
|
||||
|
||||
`clang-uml` currently supports C++ up to version 17 and partial support for C++ 20.
|
||||
|
||||
|
||||
@@ -20,59 +20,6 @@
|
||||
|
||||
#include "util/error.h"
|
||||
|
||||
namespace clanguml::common::model {
|
||||
using nlohmann::json;
|
||||
|
||||
void to_json(nlohmann::json &j, const source_location &sl)
|
||||
{
|
||||
j = json{{"file", sl.file_relative()}, {"line", sl.line()}};
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const element &c)
|
||||
{
|
||||
j = json{{"id", std::to_string(c.id())}, {"name", c.name()},
|
||||
{"namespace", c.get_namespace().to_string()}, {"type", c.type_name()},
|
||||
{"display_name", c.full_name(false)}};
|
||||
|
||||
if (const auto &comment = c.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
|
||||
if (!c.file().empty()) {
|
||||
j["source_location"] =
|
||||
dynamic_cast<const common::model::source_location &>(c);
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const template_parameter &c)
|
||||
{
|
||||
j["kind"] = to_string(c.kind());
|
||||
if (c.type())
|
||||
j["type"] = c.type().value();
|
||||
if (c.name())
|
||||
j["name"] = c.name().value();
|
||||
if (c.default_value())
|
||||
j["default"] = c.default_value().value();
|
||||
j["is_variadic"] = c.is_variadic();
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const relationship &c)
|
||||
{
|
||||
j["type"] = to_string(c.type());
|
||||
j["destination"] = std::to_string(c.destination());
|
||||
if (!c.multiplicity_source().empty())
|
||||
j["multiplicity_source"] = c.multiplicity_source();
|
||||
if (!c.multiplicity_destination().empty())
|
||||
j["multiplicity_destination"] = c.multiplicity_destination();
|
||||
if (c.access() != access_t::kNone)
|
||||
j["access"] = to_string(c.access());
|
||||
if (!c.label().empty())
|
||||
j["label"] = c.label();
|
||||
if (const auto &comment = c.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
}
|
||||
|
||||
} // namespace clanguml::common::model
|
||||
|
||||
namespace clanguml::class_diagram::model {
|
||||
using nlohmann::json;
|
||||
void to_json(nlohmann::json &j, const class_element &c)
|
||||
@@ -170,6 +117,9 @@ void generator::generate(std::ostream &ostr) const
|
||||
|
||||
generate_relationships(json_);
|
||||
|
||||
json_["name"] = m_model.name();
|
||||
json_["diagram_type"] = "class";
|
||||
|
||||
ostr << json_;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@ class generator : public common_generator<diagram_config, diagram_model> {
|
||||
public:
|
||||
generator(diagram_config &config, diagram_model &model);
|
||||
|
||||
void generate(std::ostream &ostr) const override;
|
||||
|
||||
void generate(const class_ &c, nlohmann::json &parent) const;
|
||||
|
||||
void generate(const enum_ &c, nlohmann::json &parent) const;
|
||||
@@ -70,8 +72,6 @@ public:
|
||||
|
||||
void generate_top_level_elements(nlohmann::json &parent) const;
|
||||
|
||||
void generate(std::ostream &ostr) const override;
|
||||
|
||||
void generate_relationships(nlohmann::json &parent) const;
|
||||
|
||||
void generate_relationships(const class_ &c, nlohmann::json &parent) const;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "config/config.h"
|
||||
#include "include_diagram/generators/plantuml/include_diagram_generator.h"
|
||||
#include "package_diagram/generators/plantuml/package_diagram_generator.h"
|
||||
#include "sequence_diagram/generators/json/sequence_diagram_generator.h"
|
||||
#include "sequence_diagram/generators/plantuml/sequence_diagram_generator.h"
|
||||
#include "util/util.h"
|
||||
#include "version.h"
|
||||
|
||||
72
src/common/generators/json/generator.cc
Normal file
72
src/common/generators/json/generator.cc
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* src/common/generators/json/generator.cc
|
||||
*
|
||||
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* 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 "generator.h"
|
||||
|
||||
namespace clanguml::common::model {
|
||||
using nlohmann::json;
|
||||
|
||||
void to_json(nlohmann::json &j, const source_location &sl)
|
||||
{
|
||||
j = json{{"file", sl.file_relative()}, {"line", sl.line()}};
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const element &c)
|
||||
{
|
||||
j = json{{"id", std::to_string(c.id())}, {"name", c.name()},
|
||||
{"namespace", c.get_namespace().to_string()}, {"type", c.type_name()},
|
||||
{"display_name", c.full_name(false)}};
|
||||
|
||||
if (const auto &comment = c.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
|
||||
if (!c.file().empty()) {
|
||||
j["source_location"] =
|
||||
dynamic_cast<const common::model::source_location &>(c);
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const template_parameter &c)
|
||||
{
|
||||
j["kind"] = to_string(c.kind());
|
||||
if (c.type())
|
||||
j["type"] = c.type().value();
|
||||
if (c.name())
|
||||
j["name"] = c.name().value();
|
||||
if (c.default_value())
|
||||
j["default"] = c.default_value().value();
|
||||
j["is_variadic"] = c.is_variadic();
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json &j, const relationship &c)
|
||||
{
|
||||
j["type"] = to_string(c.type());
|
||||
j["destination"] = std::to_string(c.destination());
|
||||
if (!c.multiplicity_source().empty())
|
||||
j["multiplicity_source"] = c.multiplicity_source();
|
||||
if (!c.multiplicity_destination().empty())
|
||||
j["multiplicity_destination"] = c.multiplicity_destination();
|
||||
if (c.access() != access_t::kNone)
|
||||
j["access"] = to_string(c.access());
|
||||
if (!c.label().empty())
|
||||
j["label"] = c.label();
|
||||
if (const auto &comment = c.comment(); comment)
|
||||
j["comment"] = comment.value();
|
||||
}
|
||||
|
||||
} // namespace clanguml::common::model
|
||||
@@ -29,6 +29,18 @@
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace clanguml::common::model {
|
||||
using nlohmann::json;
|
||||
|
||||
void to_json(nlohmann::json &j, const source_location &sl);
|
||||
|
||||
void to_json(nlohmann::json &j, const element &c);
|
||||
|
||||
void to_json(nlohmann::json &j, const template_parameter &c);
|
||||
|
||||
void to_json(nlohmann::json &j, const relationship &c);
|
||||
} // namespace clanguml::common::model
|
||||
|
||||
namespace clanguml::common::generators::json {
|
||||
|
||||
using clanguml::common::model::access_t;
|
||||
|
||||
@@ -136,6 +136,19 @@ std::string to_string(const diagram_t t)
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(const message_scope_t t)
|
||||
{
|
||||
switch (t) {
|
||||
case message_scope_t::kNormal:
|
||||
return "normal";
|
||||
case message_scope_t::kCondition:
|
||||
return "condition";
|
||||
default:
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
diagram_t from_string(const std::string &s)
|
||||
{
|
||||
if (s == "class")
|
||||
|
||||
@@ -80,6 +80,8 @@ std::string to_string(message_t m);
|
||||
|
||||
std::string to_string(diagram_t r);
|
||||
|
||||
std::string to_string(message_scope_t);
|
||||
|
||||
diagram_t from_string(const std::string &s);
|
||||
|
||||
} // namespace clanguml::common::model
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* src/sequence_diagram/generators/json/sequence_diagram_generator.h
|
||||
*
|
||||
* Copyright (c) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||
*
|
||||
* 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 "common/generators/json/generator.h"
|
||||
#include "config/config.h"
|
||||
#include "sequence_diagram/model/diagram.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <glob/glob.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
|
||||
namespace clanguml::sequence_diagram::generators::json {
|
||||
|
||||
using diagram_config = clanguml::config::sequence_diagram;
|
||||
using diagram_model = clanguml::sequence_diagram::model::diagram;
|
||||
|
||||
template <typename C, typename D>
|
||||
using common_generator = clanguml::common::generators::json::generator<C, D>;
|
||||
|
||||
class generator : public common_generator<diagram_config, diagram_model> {
|
||||
public:
|
||||
generator(diagram_config &config, diagram_model &model);
|
||||
|
||||
void generate_call(const sequence_diagram::model::message &m,
|
||||
nlohmann::json &parent) const;
|
||||
|
||||
common::id_t generate_participant(
|
||||
nlohmann::json &parent, common::id_t id, bool force = false) const;
|
||||
|
||||
void generate_participant(
|
||||
nlohmann::json &parent, const std::string &name) const;
|
||||
|
||||
void generate_activity(common::model::diagram_element::id_t activity_id,
|
||||
const sequence_diagram::model::activity &a, nlohmann::json &parent,
|
||||
std::vector<common::model::diagram_element::id_t> &visited,
|
||||
std::optional<nlohmann::json> nested_block) const;
|
||||
|
||||
void generate(std::ostream &ostr) const override;
|
||||
|
||||
nlohmann::json ¤t_block_statement() const
|
||||
{
|
||||
assert(!block_statements_stack_.empty());
|
||||
|
||||
return block_statements_stack_.back().get();
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_participant_generated(common::id_t id) const;
|
||||
|
||||
std::string render_name(std::string name) const;
|
||||
|
||||
mutable std::set<common::id_t> generated_participants_;
|
||||
|
||||
mutable nlohmann::json json_;
|
||||
|
||||
mutable std::vector<std::reference_wrapper<nlohmann::json>>
|
||||
block_statements_stack_;
|
||||
};
|
||||
|
||||
} // namespace clanguml::sequence_diagram::generators::json
|
||||
@@ -433,6 +433,10 @@ void generator::generate(std::ostream &ostr) const
|
||||
render_mode =
|
||||
model::function::message_render_mode::no_arguments;
|
||||
|
||||
// For methods or functions in diagrams where they are combined into
|
||||
// file participants, we need to add an 'entry' point call to know
|
||||
// which method relates to the first activity for this 'start_from'
|
||||
// condition
|
||||
if (from.value().type_name() == "method" ||
|
||||
m_config.combine_free_functions_into_file_participants()) {
|
||||
ostr << "[->"
|
||||
|
||||
@@ -47,4 +47,20 @@ TEST_CASE("t20001", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasComment("t20001 test diagram of type sequence"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
REQUIRE(j["participants"][0]["name"] == "clanguml::t20001::tmain()");
|
||||
REQUIRE(j["participants"][1]["name"] == "clanguml::t20001::A");
|
||||
REQUIRE(j["participants"][2]["name"] == "clanguml::t20001::B");
|
||||
|
||||
auto &messages = j["sequences"][0]["messages"];
|
||||
REQUIRE(messages[0]["name"] == "add(int,int)");
|
||||
REQUIRE(messages[1]["name"] == "wrap_add3(int,int,int)");
|
||||
REQUIRE(messages[2]["name"] == "add3(int,int,int)");
|
||||
REQUIRE(messages[3]["name"] == "add(int,int)");
|
||||
REQUIRE(messages[4]["name"] == "__log_result(int)__");
|
||||
REQUIRE(messages[5]["name"] == "__log_result(int)__");
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
|
||||
@@ -39,4 +39,10 @@ TEST_CASE("t20002", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("m3()"), _A("m4()"), ""));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
|
||||
@@ -39,4 +39,10 @@ TEST_CASE("t20003", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("m3<T>(T)"), _A("m4<T>(T)"), ""));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
|
||||
@@ -57,4 +57,10 @@ TEST_CASE("t20004", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -40,4 +40,10 @@ TEST_CASE("t20005", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("B<T>"), _A("A<T>"), "a(T)"));
|
||||
REQUIRE_THAT(puml, HasExitpoint(_A("C<T>")));
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -70,4 +70,10 @@ TEST_CASE("t20006", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("BB<int,float>"), _A("AA<int>"), "aa2(int)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -45,4 +45,10 @@ TEST_CASE("t20007", "[test-case][sequence]")
|
||||
"add(std::string &&,std::string &&,std::string &&)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -52,4 +52,10 @@ TEST_CASE("t20008", "[test-case][sequence]")
|
||||
HasCall(_A("B<std::string>"), _A("A<std::string>"), "a3(std::string)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -46,4 +46,10 @@ TEST_CASE("t20009", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("tmain()"), _A("B<float>"), "b(float)"));
|
||||
REQUIRE_THAT(puml, HasCall(_A("B<float>"), _A("A<float>"), "a(float)"));
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -48,4 +48,10 @@ TEST_CASE("t20010", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("B<int>"), _A("A"), "a4()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -44,4 +44,10 @@ TEST_CASE("t20011", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("A"), _A("A"), "b(int)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -77,4 +77,10 @@ TEST_CASE("t20012", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("tmain()"), _A("D"), "add5(int)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -46,4 +46,10 @@ TEST_CASE("t20013", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("B"), _A("A"), "a3(const char *)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -45,4 +45,10 @@ TEST_CASE("t20014", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("C<B,int>"), _A("B"), "b1(int,int)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -47,4 +47,10 @@ TEST_CASE("t20015", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, !HasCall(_A("B"), _A("B"), "set_z(int)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -42,4 +42,10 @@ TEST_CASE("t20016", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("B<long>"), _A("A"), "a2(const long &)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -49,4 +49,10 @@ TEST_CASE("t20017", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasExitpoint(_A("t20017.cc")));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -52,4 +52,10 @@ TEST_CASE("t20018", "[test-case][sequence]")
|
||||
HasCall(_A("Factorial<1>"), _A("Factorial<0>"), "__print(int)__"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -41,4 +41,10 @@ TEST_CASE("t20019", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("Base<D2>"), _A("D2"), "impl()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -51,4 +51,10 @@ TEST_CASE("t20020", "[test-case][sequence]")
|
||||
puml, HasCallInControlCondition(_A("tmain()"), _A("C"), "c3(int)"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -58,4 +58,10 @@ TEST_CASE("t20021", "[test-case][sequence]")
|
||||
puml, HasCallInControlCondition(_A("tmain()"), _A("C"), "contents()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -39,4 +39,10 @@ TEST_CASE("t20022", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("A"), _A("B"), "b()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -42,4 +42,10 @@ TEST_CASE("t20023", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("A"), _A("A"), "a4()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -47,4 +47,10 @@ TEST_CASE("t20024", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("B"), _A("B"), "green()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -42,4 +42,10 @@ TEST_CASE("t20025", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, !HasCall(_A("tmain()"), _A("add2(int,int)"), ""));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -38,4 +38,10 @@ TEST_CASE("t20026", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, HasCall(_A("tmain()"), _A("A"), "a()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -40,4 +40,10 @@ TEST_CASE("t20027", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, !HasCall(_A("A"), _A("A"), "aaa()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -42,4 +42,10 @@ TEST_CASE("t20028", "[test-case][sequence]")
|
||||
REQUIRE_THAT(puml, !HasCall(_A("tmain()"), _A("B"), "e()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
// REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -57,4 +57,231 @@ TEST_CASE("t20029", "[test-case][sequence]")
|
||||
!HasCall(_A("ConnectionPool"), _A("ConnectionPool"), "connect_impl()"));
|
||||
|
||||
save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml);
|
||||
|
||||
const std::string expected_json = R"###(
|
||||
{
|
||||
"diagram_type": "sequence",
|
||||
"name": "t20029_sequence",
|
||||
"participants": [
|
||||
{
|
||||
"id": "2091374738808319642",
|
||||
"name": "clanguml::t20029::tmain()",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 55
|
||||
},
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"id": "1673261195873192383",
|
||||
"name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 11
|
||||
},
|
||||
"type": "class"
|
||||
},
|
||||
{
|
||||
"id": "658058855590948094",
|
||||
"name": "clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 22
|
||||
},
|
||||
"type": "class"
|
||||
},
|
||||
{
|
||||
"id": "1896406205097618937",
|
||||
"name": "clanguml::t20029::ConnectionPool",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 39
|
||||
},
|
||||
"type": "class"
|
||||
},
|
||||
{
|
||||
"id": "1362646431260879440",
|
||||
"name": "clanguml::t20029::encode_b64(std::string &&)",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 9
|
||||
},
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"sequences": [
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"from": {
|
||||
"id": "2091374738808319642",
|
||||
"name": "clanguml::t20029::tmain()"
|
||||
},
|
||||
"name": "connect()",
|
||||
"return_type": "void",
|
||||
"scope": "normal",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 59
|
||||
},
|
||||
"to": {
|
||||
"activity_id": "940428568182104530",
|
||||
"activity_name": "clanguml::t20029::ConnectionPool::connect()",
|
||||
"participant_id": "1896406205097618937",
|
||||
"participant_name": "clanguml::t20029::ConnectionPool"
|
||||
},
|
||||
"type": "message"
|
||||
},
|
||||
{
|
||||
"activity_id": "2091374738808319642",
|
||||
"messages": [
|
||||
{
|
||||
"activity_id": "2091374738808319642",
|
||||
"branches": [
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"from": {
|
||||
"id": "2091374738808319642",
|
||||
"name": "clanguml::t20029::tmain()"
|
||||
},
|
||||
"name": "send(std::string &&)",
|
||||
"return_type": "_Bool",
|
||||
"scope": "condition",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 62
|
||||
},
|
||||
"to": {
|
||||
"activity_id": "2026763864005979273",
|
||||
"activity_name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>::send(std::string &&)",
|
||||
"participant_id": "1673261195873192383",
|
||||
"participant_name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>"
|
||||
},
|
||||
"type": "message"
|
||||
},
|
||||
{
|
||||
"from": {
|
||||
"id": "2026763864005979273",
|
||||
"name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>::send(std::string &&)"
|
||||
},
|
||||
"name": "encode(std::string &&)",
|
||||
"return_type": "std::string",
|
||||
"scope": "normal",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 15
|
||||
},
|
||||
"to": {
|
||||
"activity_id": "1468258269466480773",
|
||||
"activity_name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>::encode(std::string &&)",
|
||||
"participant_id": "1673261195873192383",
|
||||
"participant_name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>"
|
||||
},
|
||||
"type": "message"
|
||||
},
|
||||
{
|
||||
"from": {
|
||||
"id": "1468258269466480773",
|
||||
"name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>::encode(std::string &&)"
|
||||
},
|
||||
"name": "",
|
||||
"return_type": "",
|
||||
"scope": "normal",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 19
|
||||
},
|
||||
"to": {
|
||||
"activity_id": "1362646431260879440",
|
||||
"activity_name": "clanguml::t20029::encode_b64(std::string &&)"
|
||||
},
|
||||
"type": "message"
|
||||
},
|
||||
{
|
||||
"from": {
|
||||
"id": "2026763864005979273",
|
||||
"name": "clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>::send(std::string &&)"
|
||||
},
|
||||
"name": "send(std::string &&)",
|
||||
"return_type": "_Bool",
|
||||
"scope": "normal",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 15
|
||||
},
|
||||
"to": {
|
||||
"activity_id": "30515971485361302",
|
||||
"activity_name": "clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>::send(std::string &&)",
|
||||
"participant_id": "658058855590948094",
|
||||
"participant_name": "clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>"
|
||||
},
|
||||
"type": "message"
|
||||
},
|
||||
{
|
||||
"activity_id": "30515971485361302",
|
||||
"messages": [
|
||||
{
|
||||
"activity_id": "30515971485361302",
|
||||
"branches": [
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"from": {
|
||||
"id": "30515971485361302",
|
||||
"name": "clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>::send(std::string &&)"
|
||||
},
|
||||
"name": "send(const std::string &)",
|
||||
"return_type": "_Bool",
|
||||
"scope": "condition",
|
||||
"source_location": {
|
||||
"file": "../../tests/t20029/t20029.cc",
|
||||
"line": 31
|
||||
},
|
||||
"to": {
|
||||
"activity_id": "972625940114169157",
|
||||
"activity_name": "clanguml::t20029::ConnectionPool::send(const std::string &)",
|
||||
"participant_id": "1896406205097618937",
|
||||
"participant_name": "clanguml::t20029::ConnectionPool"
|
||||
},
|
||||
"type": "message"
|
||||
}
|
||||
],
|
||||
"type": "consequent"
|
||||
}
|
||||
],
|
||||
"name": "if",
|
||||
"type": "alt"
|
||||
}
|
||||
],
|
||||
"name": "while",
|
||||
"type": "loop"
|
||||
}
|
||||
],
|
||||
"type": "consequent"
|
||||
}
|
||||
],
|
||||
"name": "if",
|
||||
"type": "alt"
|
||||
}
|
||||
],
|
||||
"name": "for",
|
||||
"type": "loop"
|
||||
}
|
||||
],
|
||||
"start_from": {
|
||||
"id": 2091374738808319700,
|
||||
"location": "clanguml::t20029::tmain()"
|
||||
}
|
||||
}
|
||||
],
|
||||
"using_namespace": "clanguml::t20029"
|
||||
}
|
||||
)###";
|
||||
|
||||
auto j = generate_sequence_json(diagram, *model);
|
||||
|
||||
REQUIRE(j == nlohmann::json::parse(expected_json));
|
||||
|
||||
save_json(config.output_directory() + "/" + diagram->name + ".json", j);
|
||||
}
|
||||
@@ -142,6 +142,20 @@ std::string generate_sequence_puml(
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
nlohmann::json generate_sequence_json(
|
||||
std::shared_ptr<clanguml::config::diagram> config,
|
||||
clanguml::sequence_diagram::model::diagram &model)
|
||||
{
|
||||
using namespace clanguml::sequence_diagram::generators::json;
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << generator(
|
||||
dynamic_cast<clanguml::config::sequence_diagram &>(*config), model);
|
||||
|
||||
return nlohmann::json::parse(ss.str());
|
||||
}
|
||||
|
||||
std::string generate_class_puml(
|
||||
std::shared_ptr<clanguml::config::diagram> config,
|
||||
clanguml::class_diagram::model::diagram &model)
|
||||
|
||||
@@ -68,3 +68,12 @@ with open(r'tests/test_cases.yaml') as f:
|
||||
copyfile(f'debug/tests/puml/{diagram_name}.svg',
|
||||
f'docs/test_cases/{diagram_name}.svg')
|
||||
tc.write(f'\n')
|
||||
|
||||
tc.write("## Generated JSON models\n")
|
||||
for diagram_name, _ in config_dict['diagrams'].items():
|
||||
if os.path.exists(f'debug/tests/puml/{diagram_name}.json'):
|
||||
with open(f'debug/tests/puml/{diagram_name}.json') as f:
|
||||
contents = f.read()
|
||||
tc.write("```json\n")
|
||||
tc.write(contents)
|
||||
tc.write("\n```\n")
|
||||
Reference in New Issue
Block a user