TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
154 / 156
98.7%
Branches:
144 / 151
95.4%
Functions:
32 / 32
100.0%

config/json.cpp
Line Branch Exec Source
1 #include "terraingen/config/fields/json_io.h"
2
3 #include <cmath>
4 #include <fstream>
5 #include <sstream>
6 #include <string>
7 #include <type_traits>
8 #include <variant>
9
10 namespace terraingen {
11
12 namespace config {
13
14 70 void Fail(const std::string& path, const std::string& message) {
15
2/2
✓ Branch 2 taken 70 times.
✓ Branch 5 taken 70 times.
70 throw ConfigError(path, message);
16 }
17
18 5001 Reader::Reader(const Json& json, std::string path) : json_(json), path_(std::move(path)) {
19
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4999 times.
5001 if (!json_.is_object()) {
20
2/2
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
8 Fail(path_, std::string("expected an object, not ") + json_.type_name());
21 }
22 5003 }
23
24 4893 void Reader::Finish() const {
25
6/6
✓ Branch 5 taken 23711 times.
✓ Branch 8 taken 23711 times.
✓ Branch 11 taken 23692 times.
✓ Branch 14 taken 28585 times.
✓ Branch 16 taken 23711 times.
✓ Branch 17 taken 4874 times.
52277 for (const auto& [key, value] : json_.items()) {
26
3/3
✓ Branch 1 taken 23711 times.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 23692 times.
23711 if (known_.count(key) == 0) {
27 19 std::string expected;
28
2/2
✓ Branch 4 taken 182 times.
✓ Branch 5 taken 19 times.
201 for (const std::string& name : known_) {
29
4/4
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 163 times.
✓ Branch 4 taken 182 times.
✓ Branch 7 taken 182 times.
182 expected += (expected.empty() ? "" : ", ") + name;
30 }
31
2/2
✓ Branch 1 taken 19 times.
✓ Branch 5 taken 19 times.
57 Fail(Child(path_, key), "unknown key; expected one of: " + expected);
32 19 }
33 4912 }
34 4874 }
35
36 11111 void Read(const Json& json, const std::string& path, double& value) {
37
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 11109 times.
11111 if (!json.is_number()) {
38
2/2
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
8 Fail(path, std::string("expected a number, not ") + json.type_name());
39 }
40 11109 value = json.get<double>();
41
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11109 times.
11109 if (!std::isfinite(value)) {
42
0/1
✗ Branch 1 not taken.
✗ Fail(path, "expected a finite number");
43 }
44 11109 }
45
46 373 void Read(const Json& json, const std::string& path, float& value) {
47 373 double number = 0.0;
48
1/1
✓ Branch 1 taken 373 times.
373 Read(json, path, number);
49
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 372 times.
373 if (std::fabs(number) > static_cast<double>(std::numeric_limits<float>::max())) {
50
1/1
✓ Branch 1 taken 1 time.
2 Fail(path, "number is too large");
51 }
52 372 value = static_cast<float>(number);
53 372 }
54
55 547 void Read(const Json& json, const std::string& path, bool& value) {
56
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 546 times.
547 if (!json.is_boolean()) {
57
2/2
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
4 Fail(path, std::string("expected true or false, not ") + json.type_name());
58 }
59 546 value = json.get<bool>();
60 546 }
61
62 2316 void Read(const Json& json, const std::string& path, std::string& value) {
63
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 2315 times.
2316 if (!json.is_string()) {
64
2/2
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
4 Fail(path, std::string("expected a string, not ") + json.type_name());
65 }
66
1/1
✓ Branch 1 taken 2315 times.
2315 value = json.get<std::string>();
67 2315 }
68
69 1765 void Read(const Json& json, const std::string& path, int& value) {
70
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1763 times.
1765 if (!json.is_number_integer()) {
71
2/2
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
8 Fail(path, std::string("expected an integer, not ") + json.type_name());
72 }
73
4/4
✓ Branch 1 taken 1762 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1762 times.
3525 if (json.is_number_unsigned() &&
74
2/2
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1761 times.
1762 json.get<std::uint64_t>() > static_cast<std::uint64_t>(std::numeric_limits<int>::max())) {
75
1/1
✓ Branch 1 taken 1 time.
2 Fail(path, "integer is too large");
76 }
77 1762 const auto number = json.get<std::int64_t>();
78
5/6
✓ Branch 1 taken 1761 times.
✓ Branch 2 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 5 taken 1761 times.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 1761 times.
1762 if (number < std::numeric_limits<int>::min() || number > std::numeric_limits<int>::max()) {
79
1/1
✓ Branch 1 taken 1 time.
2 Fail(path, "integer is out of range");
80 }
81 1761 value = static_cast<int>(number);
82 1761 }
83
84 namespace {
85
86 /// Sets `output.format` from its path's extension (.json or else CSV) when `json` gives none.
87 79 void InferListFormat(const Json& json, ListOutput& output) {
88
2/2
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 14 times.
79 if (!json.contains("format")) {
89 65 const std::string& path = output.path;
90
3/4
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 63 times.
65 const bool isJson = path.size() >= 5 && path.compare(path.size() - 5, 5, ".json") == 0;
91
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 63 times.
65 output.format = isJson ? ListFormat::Json : ListFormat::Csv;
92 }
93 79 }
94
95 /// Checks a configuration's "schema_version" before any other key, which a newer version may add.
96 /// @throws ConfigError at "schema_version" when the object `json` has none, or another version
97 /// than this library reads.
98 359 void CheckSchemaVersion(const Json& json) {
99
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 357 times.
359 if (!json.is_object()) {
100 2 return;
101 }
102 const std::string supported =
103
1/1
✓ Branch 2 taken 357 times.
357 "this library reads version " + std::to_string(kConfigSchemaVersion);
104
1/1
✓ Branch 1 taken 357 times.
357 const auto found = json.find("schema_version");
105
3/3
✓ Branch 2 taken 357 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 355 times.
357 if (found == json.end()) {
106
2/2
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
8 Fail("schema_version", "required; " + supported);
107 }
108 355 int version = 0;
109
3/3
✓ Branch 1 taken 355 times.
✓ Branch 4 taken 355 times.
✓ Branch 7 taken 352 times.
358 Read(*found, "schema_version", version);
110
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 348 times.
352 if (version != kConfigSchemaVersion) {
111
1/1
✓ Branch 1 taken 4 times.
8 Fail("schema_version",
112
3/3
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
24 "version " + std::to_string(version) + " is not supported; " + supported);
113 }
114 357 }
115
116 } // namespace
117
118 57 void AfterRead(const Json& json, CraterListOutput& output) {
119 57 InferListFormat(json, output);
120 57 }
121
122 22 void AfterRead(const Json& json, BoulderListOutput& output) {
123 22 InferListFormat(json, output);
124 22 }
125
126 } // namespace config
127
128 250 ConfigError::ConfigError(std::string path, const std::string& message)
129
8/10
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 243 times.
✓ Branch 4 taken 7 times.
✓ Branch 7 taken 243 times.
✓ Branch 10 taken 243 times.
✓ Branch 13 taken 250 times.
✓ Branch 16 taken 243 times.
✓ Branch 17 taken 7 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
250 : std::runtime_error(path.empty() ? message : path + ": " + message), path_(std::move(path)) {}
130
131 361 TerrainConfig ParseConfig(std::string_view json) {
132 361 config::Json document;
133 try {
134
1/1
✓ Branch 2 taken 359 times.
363 document = config::Json::parse(json);
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 } catch (const config::Json::exception& error) {
136
4/4
✓ Branch 3 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
✓ Branch 12 taken 2 times.
10 throw ConfigError("", std::string("invalid JSON: ") + error.what());
137 2 }
138
1/1
✓ Branch 1 taken 350 times.
359 config::CheckSchemaVersion(document);
139 350 TerrainConfig parsed;
140
2/2
✓ Branch 1 taken 350 times.
✓ Branch 4 taken 289 times.
411 config::Read(document, "", parsed);
141 578 return parsed;
142 422 }
143
144 94 TerrainConfig LoadConfig(const std::filesystem::path& path) {
145
1/1
✓ Branch 1 taken 94 times.
94 std::ifstream file(path, std::ios::binary);
146
3/3
✓ Branch 1 taken 94 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 91 times.
94 if (!file) {
147
4/4
✓ Branch 2 taken 3 times.
✓ Branch 5 taken 3 times.
✓ Branch 8 taken 3 times.
✓ Branch 11 taken 3 times.
9 throw ConfigError("", "cannot read " + path.string());
148 }
149
1/1
✓ Branch 1 taken 91 times.
91 std::ostringstream text;
150
1/1
✓ Branch 2 taken 91 times.
91 text << file.rdbuf();
151
2/2
✓ Branch 1 taken 91 times.
✓ Branch 5 taken 90 times.
182 return ParseConfig(text.str());
152 95 }
153
154 66 std::string ConfigToJson(const TerrainConfig& terrainConfig, int indent) {
155
1/1
✓ Branch 1 taken 66 times.
66 config::Json json = config::ToJson(terrainConfig);
156
2/2
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 7 times.
66 if (!terrainConfig.base) {
157
1/1
✓ Branch 1 taken 59 times.
59 json.erase("base");
158 }
159
2/2
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 3 times.
66 if (!terrainConfig.materials) {
160
1/1
✓ Branch 1 taken 63 times.
63 json.erase("materials");
161 }
162
2/2
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 5 times.
66 if (!terrainConfig.albedo) {
163
1/1
✓ Branch 1 taken 61 times.
61 json.erase("albedo");
164 }
165
2/2
✓ Branch 1 taken 66 times.
✓ Branch 4 taken 66 times.
132 return json.dump(indent) + "\n";
166 66 }
167
168 321 std::string LayerType(const LayerSpec& layer) {
169 return std::visit(
170 321 [](const auto& spec) {
171 using Spec = std::decay_t<decltype(spec)>;
172
15/15
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::BedformLayerSpec>(terraingen::BedformLayerSpec const&) const:
✓ Branch 1 taken 4 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::BoulderLayerSpec>(terraingen::BoulderLayerSpec const&) const:
✓ Branch 1 taken 43 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::ClampLayerSpec>(terraingen::ClampLayerSpec const&) const:
✓ Branch 1 taken 2 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::CraterLayerSpec>(terraingen::CraterLayerSpec const&) const:
✓ Branch 1 taken 108 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::DemDetailLayerSpec>(terraingen::DemDetailLayerSpec const&) const:
✓ Branch 1 taken 1 time.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::DuneLayerSpec>(terraingen::DuneLayerSpec const&) const:
✓ Branch 1 taken 1 time.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::NoiseLayerSpec>(terraingen::NoiseLayerSpec const&) const:
✓ Branch 1 taken 133 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::PavementLayerSpec>(terraingen::PavementLayerSpec const&) const:
✓ Branch 1 taken 1 time.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::RegionLayerSpec>(terraingen::RegionLayerSpec const&) const:
✓ Branch 1 taken 7 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::RoughnessLayerSpec>(terraingen::RoughnessLayerSpec const&) const:
✓ Branch 1 taken 6 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::SandFillLayerSpec>(terraingen::SandFillLayerSpec const&) const:
✓ Branch 1 taken 5 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::SandShadowLayerSpec>(terraingen::SandShadowLayerSpec const&) const:
✓ Branch 1 taken 1 time.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::ScaleLayerSpec>(terraingen::ScaleLayerSpec const&) const:
✓ Branch 1 taken 3 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::SecondaryLayerSpec>(terraingen::SecondaryLayerSpec const&) const:
✓ Branch 1 taken 5 times.
auto terraingen::LayerType[abi:cxx11](std::variant<terraingen::NoiseLayerSpec, terraingen::CraterLayerSpec, terraingen::BoulderLayerSpec, terraingen::RoughnessLayerSpec, terraingen::BedformLayerSpec, terraingen::ScaleLayerSpec, terraingen::ClampLayerSpec, terraingen::RegionLayerSpec, terraingen::SecondaryLayerSpec, terraingen::DemDetailLayerSpec, terraingen::DuneLayerSpec, terraingen::SandFillLayerSpec, terraingen::PavementLayerSpec, terraingen::StrataLayerSpec, terraingen::SandShadowLayerSpec> const&)::{lambda(auto:1 const&)#1}::operator()<terraingen::StrataLayerSpec>(terraingen::StrataLayerSpec const&) const:
✓ Branch 1 taken 1 time.
321 std::string type(config::SpecName<Spec>::kName);
173 if constexpr (std::is_same_v<Spec, RegionLayerSpec>) {
174
4/4
✓ Branch 2 taken 7 times.
✓ Branch 5 taken 7 times.
✓ Branch 8 taken 7 times.
✓ Branch 11 taken 7 times.
7 type += " (" + LayerType(*spec.layer) + ")";
175 }
176 321 return type;
177 ✗ },
178
1/1
✓ Branch 1 taken 321 times.
642 layer);
179 }
180
181 } // namespace terraingen
182