Skip to content

Commit 865ea42

Browse files
authored
Improve code coverage (#2726)
1 parent b998cad commit 865ea42

File tree

6 files changed

+376
-4
lines changed

6 files changed

+376
-4
lines changed

.vscode/tasks.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "test: run unit tests",
6+
"type": "shell",
7+
"command": "dotnet test",
8+
"isBackground": false,
9+
"problemMatcher": [
10+
"$msCompile"
11+
],
12+
"group": "test"
13+
}
14+
]
15+
}

ImperatorToCK3.UnitTests/CK3/Religions/FaithTests.cs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,144 @@ public void ReligiousHeadTitleIdIsCorrectlyReturned() {
124124
var atheism = new Faith("atheism", faithData, testReligion);
125125
Assert.Null(atheism.ReligiousHeadTitleId);
126126
}
127+
128+
[Fact]
129+
public void FixupAddsReformedIconForUnreformedFaiths() {
130+
// Faith has unreformed_faith_doctrine and an icon, but no reformed_icon.
131+
var faithData = new FaithData {
132+
Attributes = new List<KeyValuePair<string, StringOfItem>> {
133+
new("icon", new StringOfItem("celtic_pagan"))
134+
}
135+
};
136+
faithData.DoctrineIds.Add("unreformed_faith_doctrine");
137+
var faith = new Faith("celtic_pagan", faithData, testReligion);
138+
139+
var faithStr = PDXSerializer.Serialize(faith);
140+
faithStr.Should().Contain("reformed_icon = celtic_pagan");
141+
}
142+
143+
[Fact]
144+
public void TooManyDoctrinesInCategoryAreTrimmedKeepingLastPicks() {
145+
// Arrange doctrine category with 2 picks allowed and 3 possible doctrines.
146+
var categoryReader = new BufferedReader(
147+
"number_of_picks = 2\n" +
148+
"doc_a1 = {}\n" +
149+
"doc_a2 = {}\n" +
150+
"doc_a3 = {}\n"
151+
);
152+
testReligion.ReligionCollection.DoctrineCategories.AddOrReplace(new DoctrineCategory("catA", categoryReader));
153+
154+
var output = new StringWriter();
155+
Console.SetOut(output);
156+
157+
// Faith initially has 3 doctrines from the same category (exceeds picks).
158+
var faithData = new FaithData();
159+
faithData.DoctrineIds.Add("doc_a1");
160+
faithData.DoctrineIds.Add("doc_a2");
161+
faithData.DoctrineIds.Add("doc_a3");
162+
var faith = new Faith("too_many_doctrines", faithData, testReligion);
163+
164+
// Should keep only the last 2 among these and drop the first.
165+
Assert.Contains("doc_a2", faith.DoctrineIds);
166+
Assert.Contains("doc_a3", faith.DoctrineIds);
167+
Assert.DoesNotContain("doc_a1", faith.DoctrineIds);
168+
169+
// Warning is logged.
170+
output.ToString().Should().Contain("Faith too_many_doctrines has too many doctrines in category catA");
171+
}
172+
173+
[Fact]
174+
public void GetDoctrineIdsForDoctrineCategory_PrefersFaithOverReligion() {
175+
// Arrange category with two doctrines.
176+
var categoryReader = new BufferedReader(
177+
"doc_b1 = {}\n" +
178+
"doc_b2 = {}\n"
179+
);
180+
testReligion.ReligionCollection.DoctrineCategories.AddOrReplace(new DoctrineCategory("catB", categoryReader));
181+
182+
// Religion has doc_b2, faith has doc_b1.
183+
testReligion.DoctrineIds.Clear();
184+
testReligion.DoctrineIds.Add("doc_b2");
185+
186+
var faithData = new FaithData();
187+
faithData.DoctrineIds.Add("doc_b1");
188+
var faith = new Faith("prefers_faith", faithData, testReligion);
189+
190+
var picks = faith.GetDoctrineIdsForDoctrineCategoryId("catB");
191+
picks.Should().Equal("doc_b1");
192+
}
193+
194+
[Fact]
195+
public void GetDoctrineIdsForDoctrineCategory_FallsBackToReligion() {
196+
// Arrange category with two doctrines.
197+
var categoryReader = new BufferedReader(
198+
"doc_b1 = {}\n" +
199+
"doc_b2 = {}\n"
200+
);
201+
testReligion.ReligionCollection.DoctrineCategories.AddOrReplace(new DoctrineCategory("catB_fallback", categoryReader));
202+
203+
// Religion has doc_b2, faith has none from this category.
204+
testReligion.DoctrineIds.Clear();
205+
testReligion.DoctrineIds.Add("doc_b2");
206+
207+
var faithData = new FaithData();
208+
faithData.DoctrineIds.Add("unrelated_doctrine");
209+
var faith = new Faith("fallback_faith", faithData, testReligion);
210+
211+
var picks = faith.GetDoctrineIdsForDoctrineCategoryId("catB_fallback");
212+
picks.Should().Equal("doc_b2");
213+
}
214+
215+
[Fact]
216+
public void GetDoctrineIdsForDoctrineCategory_UnknownCategoryReturnsEmpty() {
217+
var faithData = new FaithData();
218+
faithData.DoctrineIds.Add("anything");
219+
var faith = new Faith("unknown_cat", faithData, testReligion);
220+
221+
var picks = faith.GetDoctrineIdsForDoctrineCategoryId("no_such_category");
222+
Assert.Empty(picks);
223+
}
224+
225+
[Fact]
226+
public void HasDoctrine_TrueWhenFaithHasDoctrine() {
227+
var categoryReader = new BufferedReader(
228+
"doc_c1 = {}\n" +
229+
"doc_c2 = {}\n"
230+
);
231+
testReligion.ReligionCollection.DoctrineCategories.AddOrReplace(new DoctrineCategory("catC", categoryReader));
232+
233+
var faithData = new FaithData();
234+
faithData.DoctrineIds.Add("doc_c1");
235+
var faith = new Faith("has_doctrine", faithData, testReligion);
236+
237+
Assert.True(faith.HasDoctrine("doc_c1"));
238+
Assert.False(faith.HasDoctrine("doc_c2"));
239+
}
240+
241+
[Fact]
242+
public void HasDoctrine_FallsBackToReligionWhenFaithHasNoneInCategory() {
243+
var categoryReader = new BufferedReader(
244+
"doc_c1 = {}\n" +
245+
"doc_c2 = {}\n"
246+
);
247+
testReligion.ReligionCollection.DoctrineCategories.AddOrReplace(new DoctrineCategory("catC_fallback", categoryReader));
248+
249+
testReligion.DoctrineIds.Clear();
250+
testReligion.DoctrineIds.Add("doc_c2");
251+
252+
var faithData = new FaithData();
253+
faithData.DoctrineIds.Add("unrelated");
254+
var faith = new Faith("fallback_has_doctrine", faithData, testReligion);
255+
256+
Assert.True(faith.HasDoctrine("doc_c2"));
257+
}
258+
259+
[Fact]
260+
public void HasDoctrine_ReturnsFalseForUnknownDoctrine() {
261+
var faithData = new FaithData();
262+
faithData.DoctrineIds.Add("some");
263+
var faith = new Faith("unknown_doctrine", faithData, testReligion);
264+
265+
Assert.False(faith.HasDoctrine("does_not_exist_anywhere"));
266+
}
127267
}

ImperatorToCK3.UnitTests/CK3/Religions/HolySiteTests.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,73 @@ public void CountyChoicesAreUsedToPickFirstExistingCounty() {
9494

9595
Assert.Equal("c_county", site.CountyId);
9696
}
97+
98+
[Fact]
99+
public void BaronyCountyMismatchIsFixedWhenCorrectCountyExists() {
100+
var titles = new Title.LandedTitles();
101+
// Create a structure where barony belongs to correct_county, but site specifies wrong_county
102+
titles.LoadTitles(new BufferedReader(@"
103+
c_correct_county = {
104+
b_test_barony = {}
105+
}
106+
c_wrong_county = {}
107+
"));
108+
109+
var siteReader = new BufferedReader(@"
110+
county = c_wrong_county
111+
barony = b_test_barony
112+
character_modifier = {}
113+
");
114+
115+
var site = new HolySite("test_site", siteReader, titles, isFromConverter: false);
116+
117+
// County should be corrected to the barony's de jure liege
118+
Assert.Equal("c_correct_county", site.CountyId);
119+
Assert.Equal("b_test_barony", site.BaronyId);
120+
}
121+
122+
[Fact]
123+
public void BaronyCountyMismatchIsNotFixedWhenBaronyHasNoDeJureLiege() {
124+
var titles = new Title.LandedTitles();
125+
// Create a barony without a parent county and a separate county
126+
titles.LoadTitles(new BufferedReader(@"
127+
b_orphan_barony = {}
128+
c_some_county = {}
129+
"));
130+
131+
var siteReader = new BufferedReader(@"
132+
county = c_some_county
133+
barony = b_orphan_barony
134+
character_modifier = {}
135+
");
136+
137+
var site = new HolySite("test_site", siteReader, titles, isFromConverter: false);
138+
139+
// County should remain unchanged since barony has no de jure liege
140+
Assert.Equal("c_some_county", site.CountyId);
141+
Assert.Equal("b_orphan_barony", site.BaronyId);
142+
}
143+
144+
[Fact]
145+
public void BaronyCountyMatchingIsNotChangedWhenAlreadyCorrect() {
146+
var titles = new Title.LandedTitles();
147+
// Create a structure where barony correctly belongs to the specified county
148+
titles.LoadTitles(new BufferedReader(@"
149+
c_correct_county = {
150+
b_test_barony = {}
151+
}
152+
"));
153+
154+
var siteReader = new BufferedReader(@"
155+
county = c_correct_county
156+
barony = b_test_barony
157+
character_modifier = {}
158+
");
159+
160+
var site = new HolySite("test_site", siteReader, titles, isFromConverter: false);
161+
162+
// County should remain unchanged since it's already correct
163+
Assert.Equal("c_correct_county", site.CountyId);
164+
Assert.Equal("b_test_barony", site.BaronyId);
165+
}
97166
}

ImperatorToCK3.UnitTests/CK3/Religions/ReligionTests.cs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
using AwesomeAssertions;
55
using ImperatorToCK3.CK3.Religions;
66
using ImperatorToCK3.CK3.Titles;
7+
using System;
8+
using System.IO;
9+
using System.Linq;
710
using System.Text.RegularExpressions;
811
using Xunit;
912

@@ -41,4 +44,149 @@ public void ReligionAttributesAreReadAndSerialized() {
4144
"doctrine=doctrine_gender_male_dominated"
4245
);
4346
}
47+
48+
[Fact]
49+
public void DoctrinesInSameCategoryAreLimitedToNumberOfPicks() {
50+
// Arrange: Create a doctrine category with only 2 picks allowed
51+
var categoryReader = new BufferedReader(
52+
"number_of_picks = 2\n" +
53+
"doctrine_head_1 = {}\n" +
54+
"doctrine_head_2 = {}\n" +
55+
"doctrine_head_3 = {}\n" +
56+
"doctrine_head_4 = {}\n"
57+
);
58+
var religions = new ReligionCollection(new Title.LandedTitles());
59+
religions.DoctrineCategories.AddOrReplace(new DoctrineCategory("head_category", categoryReader));
60+
61+
// Act: Create a religion with 4 doctrines from the same category (exceeds limit)
62+
var reader = new BufferedReader(@"{
63+
doctrine = doctrine_head_1
64+
doctrine = doctrine_head_2
65+
doctrine = doctrine_head_3
66+
doctrine = doctrine_head_4
67+
}");
68+
var religion = new Religion("test_religion", reader, religions, new ColorFactory());
69+
70+
// Assert: Should keep only the last 2 doctrines (doctrine_head_3 and doctrine_head_4)
71+
Assert.Equal(2, religion.DoctrineIds.Count);
72+
Assert.Contains("doctrine_head_3", religion.DoctrineIds);
73+
Assert.Contains("doctrine_head_4", religion.DoctrineIds);
74+
Assert.DoesNotContain("doctrine_head_1", religion.DoctrineIds);
75+
Assert.DoesNotContain("doctrine_head_2", religion.DoctrineIds);
76+
}
77+
78+
[Fact]
79+
public void InvalidColorInFaithLogsWarning() {
80+
// Arrange: Create a religion with a faith that has an invalid color format.
81+
var reader = new BufferedReader(@"{
82+
faiths = {
83+
test_faith = {
84+
color = hex #345345345
85+
}
86+
}
87+
}");
88+
var religions = new ReligionCollection(new Title.LandedTitles());
89+
90+
// Act: Capture log output during religion creation.
91+
var logWriter = new StringWriter();
92+
Console.SetOut(logWriter);
93+
var religion = new Religion("test_religion", reader, religions, new ColorFactory());
94+
95+
// Assert: Faith should still be created despite the invalid color.
96+
Assert.Single(religion.Faiths);
97+
var faith = religion.Faiths.First(f => f.Id == "test_faith");
98+
Assert.Null(faith.Color);
99+
100+
// Assert: Warning should be logged.
101+
var logOutput = logWriter.ToString();
102+
logOutput.Should().Contain("Found invalid color");
103+
}
104+
105+
[Fact]
106+
public void ReligiousHeadIsSetWhenNotNone() {
107+
// Arrange: Create a religion with a faith that has a religious head title
108+
var reader = new BufferedReader(@"{
109+
faiths = {
110+
test_faith = {
111+
religious_head = k_papal_state
112+
}
113+
}
114+
}");
115+
var religions = new ReligionCollection(new Title.LandedTitles());
116+
var religion = new Religion("test_religion", reader, religions, new ColorFactory());
117+
118+
// Assert: Faith should be created with the religious head title
119+
Assert.Single(religion.Faiths);
120+
var faith = religion.Faiths.First(f => f.Id == "test_faith");
121+
Assert.Equal("k_papal_state", faith.ReligiousHeadTitleId);
122+
}
123+
124+
[Fact]
125+
public void ReligiousHeadIsNotSetWhenNone() {
126+
// Arrange: Create a religion with a faith that has religious_head = none
127+
var reader = new BufferedReader(@"{
128+
faiths = {
129+
test_faith = {
130+
religious_head = none
131+
}
132+
}
133+
}");
134+
var religions = new ReligionCollection(new Title.LandedTitles());
135+
var religion = new Religion("test_religion", reader, religions, new ColorFactory());
136+
137+
// Assert: Faith should be created but ReligiousHeadTitleId should be null
138+
Assert.Single(religion.Faiths);
139+
var faith = religion.Faiths.First(f => f.Id == "test_faith");
140+
Assert.Null(faith.ReligiousHeadTitleId);
141+
}
142+
143+
[Fact]
144+
public void ReligiousHeadIsSerializedWhenSet() {
145+
// Arrange: Create a religion with a faith that has a religious head title
146+
var reader = new BufferedReader(@"{
147+
faiths = {
148+
test_faith = {
149+
religious_head = k_papal_state
150+
}
151+
}
152+
}");
153+
var religions = new ReligionCollection(new Title.LandedTitles());
154+
var religion = new Religion("test_religion", reader, religions, new ColorFactory());
155+
156+
// Act: Serialize the religion
157+
var religionStr = PDXSerializer.Serialize(religion);
158+
159+
// Assert: The religious head should be serialized in the faith
160+
religionStr.Should().Contain("religious_head=k_papal_state");
161+
}
162+
163+
[Fact]
164+
public void FaithAttributesAreParsedAndStored() {
165+
// Arrange: Create a religion with a faith that has custom attributes (not specially handled keywords)
166+
var reader = new BufferedReader(@"{
167+
faiths = {
168+
test_faith = {
169+
icon = custom_faith_icon
170+
localization = test_faith_loc
171+
custom_modifier = some_value
172+
special_mechanic = yes
173+
}
174+
}
175+
}");
176+
var religions = new ReligionCollection(new Title.LandedTitles());
177+
var religion = new Religion("test_religion", reader, religions, new ColorFactory());
178+
179+
// Assert: Faith should be created and attributes should be accessible through serialization
180+
Assert.Single(religion.Faiths);
181+
var faith = religion.Faiths.First(f => f.Id == "test_faith");
182+
183+
// Serialize to verify attributes are stored and output correctly
184+
var faithStr = PDXSerializer.Serialize(faith);
185+
faithStr.Should().ContainAll(
186+
"icon = custom_faith_icon",
187+
"localization = test_faith_loc",
188+
"custom_modifier = some_value",
189+
"special_mechanic = yes"
190+
);
191+
}
44192
}

0 commit comments

Comments
 (0)