• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ParadoxGameConverters / Vic3ToHoI4 / 19107295354

05 Nov 2025 03:33PM UTC coverage: 92.825% (-1.0%) from 93.807%
19107295354

push

github

web-flow
Update commons (#769)

* Update commons

* Fixes for coverage

25020 of 26954 relevant lines covered (92.82%)

50121.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.91
/src/out_hoi4/characters/out_character_tests.cpp
1
#include <external/commonItems/OSCompatibilityLayer.h>
2
#include <external/commonItems/external/googletest/googlemock/include/gmock/gmock-matchers.h>
3
#include <external/commonItems/external/googletest/googletest/include/gtest/gtest.h>
4

5
#include <filesystem>
6
#include <sstream>
7

8
#include "src/out_hoi4/characters/out_character.h"
9

10

11
namespace out
12
{
13

14

15
TEST(Outhoi4Characters, GeneralsAreOutput)
4✔
16
{
17
   const hoi4::Character character({
18
       .id = 1,
19
       .first_name = "Test",
×
20
       .last_name = "Mann",
1✔
21
       .portrait_alias = "GFX_test",
1✔
22
       .general_data = std::make_optional<hoi4::General>(hoi4::General{.traits = {"trait0", "trait1"}}),
1✔
23
   });
1✔
24

25
   std::stringstream out;
1✔
26
   OutputCharacter(out, "TAG", character);
1✔
27

28
   EXPECT_EQ(out.str(),
1✔
29
       "\tTAG_1 = {\n"
30
       "\t\tname = Test_Mann\n"
31
       "\t\tportraits = {\n"
32
       "\t\t\tarmy = {\n"
33
       "\t\t\t\tlarge = GFX_test\n"
34
       "\t\t\t\tsmall = GFX_test_small\n"
35
       "\t\t\t}\n"
36
       "\t\t}\n"
37
       "\t\tcorps_commander = {\n"
38
       "\t\t\ttraits = { trait0 trait1 }\n"
39
       "\t\t\tskill = 1\n"
40
       "\t\t\tattack_skill = 1\n"
41
       "\t\t\tdefense_skill = 1\n"
42
       "\t\t\tplanning_skill = 1\n"
43
       "\t\t\tlogistics_skill = 1\n"
44
       "\t\t}\n"
45
       "\t}\n");
1✔
46
}
5✔
47

48

49
TEST(Outhoi4Characters, FieldMarshalsAreOutput)
4✔
50
{
51
   const hoi4::Character character({
52
       .id = 1,
53
       .first_name = "Test",
×
54
       .last_name = "Mann",
1✔
55
       .portrait_alias = "GFX_test",
1✔
56
       .general_data =
57
           std::make_optional<hoi4::General>(hoi4::General{.traits = {"trait0", "trait1"}, .is_field_marshal = true}),
1✔
58
   });
1✔
59

60
   std::stringstream out;
1✔
61
   OutputCharacter(out, "TAG", character);
1✔
62

63
   EXPECT_EQ(out.str(),
1✔
64
       "\tTAG_1 = {\n"
65
       "\t\tname = Test_Mann\n"
66
       "\t\tportraits = {\n"
67
       "\t\t\tarmy = {\n"
68
       "\t\t\t\tlarge = GFX_test\n"
69
       "\t\t\t\tsmall = GFX_test_small\n"
70
       "\t\t\t}\n"
71
       "\t\t}\n"
72
       "\t\tfield_marshal = {\n"
73
       "\t\t\ttraits = { trait0 trait1 }\n"
74
       "\t\t\tskill = 1\n"
75
       "\t\t\tattack_skill = 1\n"
76
       "\t\t\tdefense_skill = 1\n"
77
       "\t\t\tplanning_skill = 1\n"
78
       "\t\t\tlogistics_skill = 1\n"
79
       "\t\t}\n"
80
       "\t}\n");
1✔
81
}
5✔
82

83

84
TEST(Outhoi4Characters, AdmiralsAreOutput)
4✔
85
{
86
   const hoi4::Character character({
87
       .id = 1,
88
       .first_name = "Test",
×
89
       .last_name = "Mann",
1✔
90
       .portrait_alias = "GFX_test",
1✔
91
       .admiral_data = std::make_optional<hoi4::Admiral>(hoi4::Admiral{.traits = {"trait0", "trait1"}}),
1✔
92
   });
1✔
93

94
   std::stringstream out;
1✔
95
   OutputCharacter(out, "TAG", character);
1✔
96

97
   EXPECT_EQ(out.str(),
1✔
98
       "\tTAG_1 = {\n"
99
       "\t\tname = Test_Mann\n"
100
       "\t\tportraits = {\n"
101
       "\t\t\tnavy = {\n"
102
       "\t\t\t\tlarge = GFX_test\n"
103
       "\t\t\t\tsmall = GFX_test_small\n"
104
       "\t\t\t}\n"
105
       "\t\t}\n"
106
       "\t\tnavy_leader = {\n"
107
       "\t\t\ttraits = { trait0 trait1 }\n"
108
       "\t\t\tskill = 1\n"
109
       "\t\t\tattack_skill = 1\n"
110
       "\t\t\tdefense_skill = 1\n"
111
       "\t\t\tmaneuvering_skill = 1\n"
112
       "\t\t\tcoordination_skill = 1\n"
113
       "\t\t}\n"
114
       "\t}\n");
1✔
115
}
5✔
116

117

118
TEST(Outhoi4Characters, CountryLeadersAreOutput)
4✔
119
{
120
   const hoi4::Character character({
121
       .id = 1,
122
       .first_name = "Test",
×
123
       .last_name = "Mann",
1✔
124
       .portrait_alias = "GFX_test",
1✔
125
       .leader_data =
126
           std::make_optional<hoi4::Leader>(hoi4::Leader{.sub_ideology = "socialist", .traits = {"trait0", "trait1"}}),
3✔
127
   });
1✔
128

129
   std::stringstream out;
1✔
130
   OutputCharacter(out, "TAG", character);
1✔
131

132
   EXPECT_EQ(out.str(),
1✔
133
       "\tTAG_1 = {\n"
134
       "\t\tname = Test_Mann\n"
135
       "\t\tportraits = {\n"
136
       "\t\t\tcivilian = {\n"
137
       "\t\t\t\tlarge = GFX_test\n"
138
       "\t\t\t}\n"
139
       "\t\t}\n"
140
       "\t\tcountry_leader = {\n"
141
       "\t\t\tideology = socialist\n"
142
       "\t\t\ttraits = { trait0 trait1 }\n"
143
       "\t\t}\n"
144
       "\t}\n");
1✔
145
}
6✔
146

147

148
TEST(Outhoi4Characters, AdvisorsAreOutput)
4✔
149
{
150
   const hoi4::Character character({
151
       .id = 1,
152
       .first_name = "Test",
×
153
       .last_name = "Mann",
1✔
154
       .portrait_alias = "GFX_test",
1✔
155
       .advisor_data = std::make_optional<hoi4::Advisor>(
156
           hoi4::Advisor{.traits = {"trait0", "trait1"}, .slot = "theorist", .ledger = "army"}),
5✔
157
   });
1✔
158

159
   std::stringstream out;
1✔
160
   OutputCharacter(out, "TAG", character);
1✔
161

162
   EXPECT_EQ(out.str(),
1✔
163
       "\tTAG_1 = {\n"
164
       "\t\tname = Test_Mann\n"
165
       "\t\tportraits = {\n"
166
       "\t\t\tcivilian = {\n"
167
       "\t\t\t\tsmall = GFX_test\n"
168
       "\t\t\t}\n"
169
       "\t\t}\n"
170
       "\t\tadvisor = {\n"
171
       "\t\t\ttraits = { trait0 trait1 }\n"
172
       "\t\t\tslot = theorist\n"
173
       "\t\t\tledger = army\n"
174
       "\t\t\tidea_token = i_1\n"
175
       "\t\t\tcost = 150\n"
176
       "\t\t}\n"
177
       "\t}\n");
1✔
178
}
6✔
179

180
TEST(Outhoi4Characters, TraitlessAdvisorsAreNotOutput)
4✔
181
{
182
   const hoi4::Character character({
183
       .id = 1,
184
       .first_name = "Test",
×
185
       .last_name = "Mann",
1✔
186
       .portrait_alias = "GFX_test",
1✔
187
       .advisor_data = std::make_optional<hoi4::Advisor>(hoi4::Advisor{.slot = "theorist", .ledger = "army"}),
5✔
188
   });
1✔
189

190
   std::stringstream out;
1✔
191
   OutputCharacter(out, "TAG", character);
1✔
192

193
   EXPECT_EQ(out.str(),
1✔
194
       "\tTAG_1 = {\n"
195
       "\t\tname = Test_Mann\n"
196
       "\t\tportraits = {\n"
197
       "\t\t\tcivilian = {\n"
198
       "\t\t\t\tsmall = GFX_test\n"
199
       "\t\t\t}\n"
200
       "\t\t}\n"
201
       "\t}\n");
1✔
202
}
6✔
203

204

205
TEST(Outhoi4Characters, LedgerlessAdvisorsAreOutputWithoutLedgers)
4✔
206
{
207
   const hoi4::Character character({
208
       .id = 1,
209
       .first_name = "Test",
×
210
       .last_name = "Mann",
1✔
211
       .portrait_alias = "GFX_test",
1✔
212
       .advisor_data = std::make_optional<hoi4::Advisor>(
213
           hoi4::Advisor{.traits = {"trait0", "trait1"}, .slot = "political_advisor"}),
4✔
214
   });
1✔
215

216
   std::stringstream out;
1✔
217
   OutputCharacter(out, "TAG", character);
1✔
218

219
   EXPECT_EQ(out.str(),
1✔
220
       "\tTAG_1 = {\n"
221
       "\t\tname = Test_Mann\n"
222
       "\t\tportraits = {\n"
223
       "\t\t\tcivilian = {\n"
224
       "\t\t\t\tsmall = GFX_test\n"
225
       "\t\t\t}\n"
226
       "\t\t}\n"
227
       "\t\tadvisor = {\n"
228
       "\t\t\ttraits = { trait0 trait1 }\n"
229
       "\t\t\tslot = political_advisor\n"
230
       "\t\t\tidea_token = i_1\n"
231
       "\t\t\tcost = 150\n"
232
       "\t\t}\n"
233
       "\t}\n");
1✔
234
}
6✔
235

236

237
TEST(Outhoi4Characters, GeneralAdvisorsHaveArmyPortraits)
4✔
238
{
239
   const hoi4::Character character({
240
       .id = 1,
241
       .first_name = "Test",
×
242
       .last_name = "Mann",
1✔
243
       .portrait_alias = "GFX_test",
1✔
244
       .general_data = std::make_optional<hoi4::General>(hoi4::General{.traits = {"trait0", "trait1"}}),
1✔
245
       .advisor_data = std::make_optional<hoi4::Advisor>(
246
           hoi4::Advisor{.traits = {"trait2", "trait3"}, .slot = "theorist", .ledger = "army"}),
5✔
247
   });
1✔
248

249
   std::stringstream out;
1✔
250
   OutputCharacter(out, "TAG", character);
1✔
251

252
   EXPECT_EQ(out.str(),
1✔
253
       "\tTAG_1 = {\n"
254
       "\t\tname = Test_Mann\n"
255
       "\t\tportraits = {\n"
256
       "\t\t\tarmy = {\n"
257
       "\t\t\t\tlarge = GFX_test\n"
258
       "\t\t\t\tsmall = GFX_test_small\n"
259
       "\t\t\t}\n"
260
       "\t\t\tcivilian = {\n"
261
       "\t\t\t}\n"
262
       "\t\t}\n"
263
       "\t\tcorps_commander = {\n"
264
       "\t\t\ttraits = { trait0 trait1 }\n"
265
       "\t\t\tskill = 1\n"
266
       "\t\t\tattack_skill = 1\n"
267
       "\t\t\tdefense_skill = 1\n"
268
       "\t\t\tplanning_skill = 1\n"
269
       "\t\t\tlogistics_skill = 1\n"
270
       "\t\t}\n"
271
       "\t\tadvisor = {\n"
272
       "\t\t\ttraits = { trait2 trait3 }\n"
273
       "\t\t\tslot = theorist\n"
274
       "\t\t\tledger = army\n"
275
       "\t\t\tidea_token = i_1\n"
276
       "\t\t\tcost = 150\n"
277
       "\t\t}\n"
278
       "\t}\n");
1✔
279
}
6✔
280

281

282
TEST(Outhoi4Characters, AdmiralAdvisorsHaveNavyPortraits)
4✔
283
{
284
   const hoi4::Character character({
285
       .id = 1,
286
       .first_name = "Test",
×
287
       .last_name = "Mann",
1✔
288
       .portrait_alias = "GFX_test",
1✔
289
       .admiral_data = std::make_optional<hoi4::Admiral>(hoi4::Admiral{.traits = {"trait0", "trait1"}}),
1✔
290
       .advisor_data = std::make_optional<hoi4::Advisor>(
291
           hoi4::Advisor{.traits = {"trait2", "trait3"}, .slot = "theorist", .ledger = "navy"}),
5✔
292
   });
1✔
293

294
   std::stringstream out;
1✔
295
   OutputCharacter(out, "TAG", character);
1✔
296

297
   EXPECT_EQ(out.str(),
1✔
298
       "\tTAG_1 = {\n"
299
       "\t\tname = Test_Mann\n"
300
       "\t\tportraits = {\n"
301
       "\t\t\tnavy = {\n"
302
       "\t\t\t\tlarge = GFX_test\n"
303
       "\t\t\t\tsmall = GFX_test_small\n"
304
       "\t\t\t}\n"
305
       "\t\t\tcivilian = {\n"
306
       "\t\t\t}\n"
307
       "\t\t}\n"
308
       "\t\tnavy_leader = {\n"
309
       "\t\t\ttraits = { trait0 trait1 }\n"
310
       "\t\t\tskill = 1\n"
311
       "\t\t\tattack_skill = 1\n"
312
       "\t\t\tdefense_skill = 1\n"
313
       "\t\t\tmaneuvering_skill = 1\n"
314
       "\t\t\tcoordination_skill = 1\n"
315
       "\t\t}\n"
316
       "\t\tadvisor = {\n"
317
       "\t\t\ttraits = { trait2 trait3 }\n"
318
       "\t\t\tslot = theorist\n"
319
       "\t\t\tledger = navy\n"
320
       "\t\t\tidea_token = i_1\n"
321
       "\t\t\tcost = 150\n"
322
       "\t\t}\n"
323
       "\t}\n");
1✔
324
}
6✔
325

326

327
TEST(Outhoi4Characters, WomenAreOutput)
4✔
328
{
329
   const hoi4::Character character({
330
       .id = 1,
331
       .first_name = "Test",
×
332
       .last_name = "WoMann",
1✔
333
       .is_female = true,
334
   });
1✔
335

336
   std::stringstream out;
1✔
337
   OutputCharacter(out, "TAG", character);
1✔
338

339
   EXPECT_EQ(out.str(),
1✔
340
       "\tTAG_1 = {\n"
341
       "\t\tname = Test_WoMann\n"
342
       "\t\tgender = female\n"
343
       "\t\tportraits = {\n"
344
       "\t\t}\n"
345
       "\t}\n");
1✔
346
}
4✔
347

348

349
TEST(Outhoi4Characters, MaleSpiesAreOutput)
4✔
350
{
351
   const hoi4::Character character({
352
       .id = 1,
353
       .first_name = "Test",
×
354
       .last_name = "Mann",
1✔
355
       .portrait_alias = "GFX_test",
1✔
356
       .spy_data =
357
           std::make_optional<hoi4::Spy>(hoi4::Spy{.traits = {"trait2", "trait3"}, .nationalities = {"TAG", "TWO"}}),
2✔
358
   });
1✔
359

360
   std::stringstream out;
1✔
361
   OutputSpy(out, character);
1✔
362

363
   EXPECT_EQ(out.str(),
1✔
364
       "\tcreate_operative_leader = {\n"
365
       "\t\tname = Test_Mann\n"
366
       "\t\tGFX = GFX_test\n"
367
       "\t\ttraits = { trait2 trait3 }\n"
368
       "\t\tbypass_recruitment = no\n"
369
       "\t\tavailable_to_spy_master = yes\n"
370
       "\t\tnationalities = { TAG TWO }\n"
371
       "\t}\n");
1✔
372
}
6✔
373

374

375
TEST(Outhoi4Characters, FemaleSpiesAreOutput)
4✔
376
{
377
   const hoi4::Character character({
378
       .id = 1,
379
       .first_name = "Test",
×
380
       .last_name = "WoMann",
1✔
381
       .portrait_alias = "GFX_test",
1✔
382
       .is_female = true,
383
       .spy_data =
384
           std::make_optional<hoi4::Spy>(hoi4::Spy{.traits = {"trait2", "trait3"}, .nationalities = {"TAG", "TWO"}}),
2✔
385
   });
1✔
386

387
   std::stringstream out;
1✔
388
   OutputSpy(out, character);
1✔
389

390
   EXPECT_EQ(out.str(),
1✔
391
       "\tcreate_operative_leader = {\n"
392
       "\t\tname = Test_WoMann\n"
393
       "\t\tGFX = GFX_test\n"
394
       "\t\ttraits = { trait2 trait3 }\n"
395
       "\t\tbypass_recruitment = no\n"
396
       "\t\tavailable_to_spy_master = yes\n"
397
       "\t\tfemale = yes\n"
398
       "\t\tnationalities = { TAG TWO }\n"
399
       "\t}\n");
1✔
400
}
6✔
401

402

403
TEST(Outhoi4Characters, MissingSpiesAreLogged)
4✔
404
{
405
   const hoi4::Character character({
406
       .id = 1,
407
       .first_name = "Test",
×
408
       .last_name = "Mann",
1✔
409
       .portrait_alias = "GFX_test",
1✔
410
   });
1✔
411

412
   std::stringstream log;
1✔
413
   std::streambuf* cout_buffer = std::cout.rdbuf();
1✔
414
   std::cout.rdbuf(log.rdbuf());
1✔
415

416
   std::stringstream out;
1✔
417
   OutputSpy(out, character);
1✔
418

419
   std::cout.rdbuf(cout_buffer);
1✔
420

421
   EXPECT_THAT(log.str(), testing::HasSubstr(R"([ERROR] Attempted to output spy with no spy data.)"));
1✔
422
}
5✔
423

424

425
TEST(Outhoi4Characters, CharactersWithoutPortraitGetUnknownPortrait)
4✔
426
{
427
   const hoi4::Character character({
428
       .id = 1,
429
       .first_name = "Test",
×
430
       .last_name = "Mann",
1✔
431
       .general_data = std::make_optional<hoi4::General>(hoi4::General{.traits = {"trait0", "trait1"}}),
1✔
432
   });
1✔
433

434
   std::stringstream out;
1✔
435
   OutputCharacter(out, "TAG", character);
1✔
436

437
   EXPECT_EQ(out.str(),
1✔
438
       "\tTAG_1 = {\n"
439
       "\t\tname = Test_Mann\n"
440
       "\t\tportraits = {\n"
441
       "\t\t\tarmy = {\n"
442
       "\t\t\t\tlarge = GFX_portrait_unknown\n"
443
       "\t\t\t\tsmall = GFX_portrait_unknown_small\n"
444
       "\t\t\t}\n"
445
       "\t\t}\n"
446
       "\t\tcorps_commander = {\n"
447
       "\t\t\ttraits = { trait0 trait1 }\n"
448
       "\t\t\tskill = 1\n"
449
       "\t\t\tattack_skill = 1\n"
450
       "\t\t\tdefense_skill = 1\n"
451
       "\t\t\tplanning_skill = 1\n"
452
       "\t\t\tlogistics_skill = 1\n"
453
       "\t\t}\n"
454
       "\t}\n");
1✔
455
}
4✔
456

457

458
TEST(Outhoi4Characters, SpiesWithoutPortraitGetUnknownPortrait)
4✔
459
{
460
   const hoi4::Character character({
461
       .id = 1,
462
       .first_name = "Test",
×
463
       .last_name = "Mann",
1✔
464
       .spy_data =
465
           std::make_optional<hoi4::Spy>(hoi4::Spy{.traits = {"trait2", "trait3"}, .nationalities = {"TAG", "TWO"}}),
2✔
466
   });
1✔
467

468
   std::stringstream out;
1✔
469
   OutputSpy(out, character);
1✔
470

471
   EXPECT_EQ(out.str(),
1✔
472
       "\tcreate_operative_leader = {\n"
473
       "\t\tname = Test_Mann\n"
474
       "\t\tGFX = GFX_portrait_operative_unknown\n"
475
       "\t\ttraits = { trait2 trait3 }\n"
476
       "\t\tbypass_recruitment = no\n"
477
       "\t\tavailable_to_spy_master = yes\n"
478
       "\t\tnationalities = { TAG TWO }\n"
479
       "\t}\n");
1✔
480
}
5✔
481

482
}  // namespace out
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc