Skip to content

Commit 479ce61

Browse files
committed
new api for creating mod references
1 parent b2a03f1 commit 479ce61

5 files changed

Lines changed: 263 additions & 165 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.IO.Abstractions;
3+
using System.IO.Abstractions.TestingHelpers;
4+
using EawModinfo.Model;
5+
using EawModinfo.Spec;
6+
using EawModinfo.Utilities;
7+
using Xunit;
8+
9+
namespace EawModinfo.Tests;
10+
11+
public class DetectedModReferenceTest
12+
{
13+
private readonly IFileSystem _fileSystem = new MockFileSystem();
14+
15+
[Fact]
16+
public void Constructor_ThrowsArgumentNullException()
17+
{
18+
var modReference = new ModReference("TestMod", ModType.Default);
19+
var directory = _fileSystem.DirectoryInfo.New("TestDirectory");
20+
Assert.Throws<ArgumentNullException>(() => new DetectedModReference(modReference, null!, null));
21+
Assert.Throws<ArgumentNullException>(() => new DetectedModReference(null!, directory, null));
22+
}
23+
24+
[Theory]
25+
[InlineData(null)]
26+
[InlineData("string")]
27+
public void Constructor_InitializesPropertiesCorrectly_WhenValidArgumentsArePassed(string? modName)
28+
{
29+
var directory = _fileSystem.DirectoryInfo.New("TestDirectory");
30+
var modReference = new ModReference("TestMod", ModType.Default);
31+
IModinfo? modinfo = modName is null ? null : new ModinfoData(modName);
32+
33+
var detectedModReference = new DetectedModReference(modReference, directory, modinfo);
34+
35+
Assert.Equal(modReference, detectedModReference.ModReference);
36+
Assert.Same(directory, detectedModReference.Directory);
37+
Assert.Same(modinfo, detectedModReference.Modinfo);
38+
}
39+
}

src/EawModinfo.Tests/ModReferenceBuilderTest.cs

Lines changed: 162 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,99 @@ public void CreateVirtualModIdentifier_ThrowsArgumentNullException_WhenModinfoIs
3131
Assert.Throws<ArgumentNullException>(() => ModReferenceBuilder.CreateVirtualModIdentifier(null!));
3232
}
3333

34+
#region CreateIdentifiers
35+
36+
public static IEnumerable<object?[]> GetCombinedModinfoFilesTestData()
37+
{
38+
var mainModinfoStates = new bool?[]
39+
{
40+
// no main modinfo
41+
null,
42+
// valid main modinfo
43+
true,
44+
// invalid main modinfo
45+
false
46+
};
47+
48+
foreach (var pathData in ModDirectoryTestData())
49+
{
50+
var locationKind = (ModReferenceBuilder.ModLocationKind)pathData[0];
51+
var modPath = (string)pathData[1];
52+
var expectedIdentifier = (string)pathData[2];
53+
54+
foreach (var mainModinfoState in mainModinfoStates)
55+
{
56+
yield return
57+
[
58+
modPath,
59+
locationKind,
60+
mainModinfoState,
61+
Array.Empty<string>(), // no variants
62+
Array.Empty<string>(), // no invalid variants
63+
expectedIdentifier
64+
];
65+
yield return
66+
[
67+
modPath,
68+
locationKind,
69+
mainModinfoState,
70+
new[] {"variant1"},// one variants
71+
Array.Empty<string>(),
72+
expectedIdentifier
73+
];
74+
yield return
75+
[
76+
modPath,
77+
locationKind,
78+
mainModinfoState,
79+
new[] {"variant1", "variant2"},// many variants
80+
Array.Empty<string>(),
81+
expectedIdentifier
82+
];
83+
yield return
84+
[
85+
modPath,
86+
locationKind,
87+
mainModinfoState,
88+
new[] {"variant1", "variant2"}, // many variants
89+
new[] {"variant3"}, // invalid variant
90+
expectedIdentifier
91+
];
92+
yield return
93+
[
94+
modPath,
95+
locationKind,
96+
mainModinfoState,
97+
new[] {"variant1", "variant2"}, // many variants
98+
new[] {"variant3", "variant4"}, // invalid variants
99+
expectedIdentifier
100+
];
101+
yield return
102+
[
103+
modPath,
104+
locationKind,
105+
mainModinfoState,
106+
Array.Empty<string>(), // no valid variants
107+
new[] {"variant3", "variant4"}, // invalid variants
108+
expectedIdentifier
109+
];
110+
}
111+
}
112+
}
113+
114+
public static IEnumerable<object[]> ModDirectoryTestData()
115+
{
116+
yield return [ModReferenceBuilder.ModLocationKind.SteamWorkshops, "Game/Mods/1234567890", "1234567890"];
117+
yield return [ModReferenceBuilder.ModLocationKind.GameModsDirectory, "Game/Mods/DefaultMod", "DefaultMod"];
118+
yield return [ModReferenceBuilder.ModLocationKind.External, "path/ExternalMod", "path/ExternalMod"];
119+
}
120+
121+
34122
[Theory]
35-
[InlineData(ModLocationKind.GameModsDirectory)]
36-
[InlineData(ModLocationKind.SteamWorkshops)]
37-
[InlineData(ModLocationKind.External)]
38-
public void ThrowsArgumentNullException_WhenInputIsNull(ModLocationKind modLocation)
123+
[InlineData(ModReferenceBuilder.ModLocationKind.GameModsDirectory)]
124+
[InlineData(ModReferenceBuilder.ModLocationKind.SteamWorkshops)]
125+
[InlineData(ModReferenceBuilder.ModLocationKind.External)]
126+
public void CreateIdentifiers_ThrowsArgumentNullException_WhenInputIsNull(ModReferenceBuilder.ModLocationKind modLocation)
39127
{
40128
Assert.Throws<ArgumentNullException>(() =>
41129
ModReferenceBuilder.CreateIdentifiers(null!, modLocation));
@@ -50,13 +138,13 @@ public void CreateIdentifiers_ThrowsModinfoException_WhenModIsSteamWorkshopButNo
50138
var modinfoFinderCollection = new ModinfoFinderCollection(modDirectory, null, []);
51139

52140
Assert.Throws<ModinfoException>(() =>
53-
ModReferenceBuilder.CreateIdentifiers(modinfoFinderCollection, ModLocationKind.SteamWorkshops));
141+
ModReferenceBuilder.CreateIdentifiers(modinfoFinderCollection, ModReferenceBuilder.ModLocationKind.SteamWorkshops));
54142
}
55143

56144
[Theory]
57145
[MemberData(nameof(ModDirectoryTestData))]
58146
public void CreateIdentifiers_NoModinfoFiles_ReturnsCorrectIdentifier(
59-
ModLocationKind locationKind,
147+
ModReferenceBuilder.ModLocationKind locationKind,
60148
string modDirectoryPath,
61149
string expectedIdentifier)
62150
{
@@ -68,29 +156,33 @@ public void CreateIdentifiers_NoModinfoFiles_ReturnsCorrectIdentifier(
68156
.ToList();
69157

70158
var modRef = Assert.Single(modReferences);
71-
if (locationKind is ModLocationKind.External)
159+
if (locationKind is ModReferenceBuilder.ModLocationKind.External)
72160
expectedIdentifier = _fileSystem.Path.GetFullPath(expectedIdentifier);
73161
Assert.Equal(expectedIdentifier, modRef.ModReference.Identifier);
74-
Assert.Equal(locationKind is ModLocationKind.SteamWorkshops ? ModType.Workshops : ModType.Default, modRef.ModReference.Type);
162+
Assert.Equal(locationKind is ModReferenceBuilder.ModLocationKind.SteamWorkshops ? ModType.Workshops : ModType.Default, modRef.ModReference.Type);
75163
Assert.Null(modRef.Modinfo);
76164
}
77165

78166
[Theory]
79167
[MemberData(nameof(GetCombinedModinfoFilesTestData))]
80168
public void CreateIdentifiers_TestScenario(
81-
string modPath,
82-
ModLocationKind locationKind,
83-
bool? hasValidMainModinfo,
84-
ICollection<string> validVariants,
85-
ICollection<string> malformedVariants,
86-
string expectedBaseIdentifier)
169+
string modPath,
170+
ModReferenceBuilder.ModLocationKind locationKind,
171+
bool? hasValidMainModinfo,
172+
ICollection<string> validVariants,
173+
ICollection<string> malformedVariants,
174+
string expectedBaseIdentifier)
87175
{
176+
// Adjust expected identifier if it's external
177+
if (locationKind is ModReferenceBuilder.ModLocationKind.External)
178+
expectedBaseIdentifier = _fileSystem.Path.GetFullPath(expectedBaseIdentifier);
179+
88180
var modDir = _fileSystem.DirectoryInfo.New(modPath);
89181

90182
// Simulate the creation of a main modinfo file
91183
var mainModinfo = hasValidMainModinfo switch
92184
{
93-
true => CreateValidMainFile(modDir, "ValidMain.json"),
185+
true => CreateValidMainFile(modDir),
94186
false => CreateInvalidMainModinfoFile(modDir),
95187
_ => null
96188
};
@@ -104,117 +196,70 @@ public void CreateIdentifiers_TestScenario(
104196

105197
var result = ModReferenceBuilder.CreateIdentifiers(modinfoFinderResult, locationKind).ToList();
106198

107-
// Adjust expected identifier if it's external
108-
if (locationKind is ModLocationKind.External)
109-
expectedBaseIdentifier = _fileSystem.Path.GetFullPath(expectedBaseIdentifier);
110-
111-
var expectedCount = 1 + validVariants.Count;
112-
Assert.Equal(expectedCount, result.Count);
113-
114-
var currentIndex = 0;
199+
var expectedResults = new List<(string Identifier, ModType Type, string? Name)>();
115200

116-
// Validate main modinfo if it exists
201+
// Add the expected main modinfo entry
117202
if (hasValidMainModinfo == true)
118203
{
119-
Assert.Equal(expectedBaseIdentifier, result[currentIndex].ModReference.Identifier);
120-
Assert.Equal(locationKind is ModLocationKind.SteamWorkshops ? ModType.Workshops : ModType.Default, result[currentIndex].ModReference.Type);
121-
Assert.NotNull(result[currentIndex].Modinfo);
122-
Assert.Equal("ValidMain.json", result[currentIndex].Modinfo.Name);
123-
currentIndex++;
204+
expectedResults.Add((
205+
Identifier: expectedBaseIdentifier,
206+
Type: locationKind == ModReferenceBuilder.ModLocationKind.SteamWorkshops ? ModType.Workshops : ModType.Default,
207+
Name: "testmod"
208+
));
124209
}
125-
126-
// Validate valid variants
127-
var validVariantsList = validVariants.ToList(); // Ensure we can index into validVariants
128-
for (int i = 0; i < validVariantsList.Count; i++)
210+
// The main modinfo file exists but is invalid OR no valid variant modinfo files exist
211+
else if (hasValidMainModinfo == false || (hasValidMainModinfo is null && validVariants.Count == 0))
129212
{
130-
var expectedVariant = validVariantsList[i];
131-
var modReference = result[currentIndex];
132-
Assert.Equal($"{expectedBaseIdentifier}:{expectedVariant}", modReference.ModReference.Identifier);
133-
Assert.Equal(locationKind is ModLocationKind.SteamWorkshops ? ModType.Workshops : ModType.Default, modReference.ModReference.Type);
134-
Assert.NotNull(modReference.Modinfo);
135-
Assert.Equal(expectedVariant, modReference.Modinfo.Name);
136-
currentIndex++;
213+
expectedResults.Add((
214+
Identifier: expectedBaseIdentifier,
215+
Type: locationKind == ModReferenceBuilder.ModLocationKind.SteamWorkshops ? ModType.Workshops : ModType.Default,
216+
Name: null
217+
));
137218
}
138-
}
139-
140-
public static IEnumerable<object[]> GetCombinedModinfoFilesTestData()
141-
{
142-
foreach (var pathData in ModDirectoryTestData())
219+
// Add the expected variant entries
220+
expectedResults.AddRange(validVariants.Select(variant => (
221+
Identifier: $"{expectedBaseIdentifier}:{variant}",
222+
Type: locationKind == ModReferenceBuilder.ModLocationKind.SteamWorkshops ? ModType.Workshops : ModType.Default,
223+
Name: variant
224+
)));
225+
226+
Assert.Equal(expectedResults.Count, result.Count);
227+
228+
foreach (var expected in expectedResults)
143229
{
144-
var locationKind = (ModLocationKind)pathData[0];
145-
var modPath = (string)pathData[1];
146-
var expectedIdentifier = (string)pathData[2];
230+
var actual = result.Single(r =>
231+
r.ModReference.Identifier == expected.Identifier &&
232+
r.ModReference.Type == expected.Type &&
233+
(expected.Name == null || r.Modinfo?.Name == expected.Name));
234+
235+
if (expected.Name == null)
236+
Assert.Null(actual.Modinfo);
237+
else
238+
Assert.Equal(expected.Name, actual.Modinfo!.Name);
147239

148-
yield return
149-
[
150-
modPath,
151-
locationKind,
152-
null!, // No main modinfo
153-
Array.Empty<string>(), // No main modinfo
154-
Array.Empty<string>(),
155-
expectedIdentifier
156-
];
157-
158-
yield return
159-
[
160-
modPath,
161-
locationKind,
162-
false, // Invalid main file
163-
Array.Empty<string>(), // No main modinfo
164-
Array.Empty<string>(),
165-
expectedIdentifier
166-
];
167-
168-
//yield return
169-
//[
170-
// modPath,
171-
// isSteamWorkshopMod,
172-
// true, // Valid main modinfo
173-
// new[] { "ValidVariant2" },
174-
// Enumerable.Empty<string>(),
175-
// expectedIdentifier,
176-
// isExternalMod
177-
//];
178-
179-
//yield return
180-
//[
181-
// modPath,
182-
// isSteamWorkshopMod,
183-
// false, // Malformed main modinfo
184-
// Enumerable.Empty<string>(),
185-
// new[] { "MalformedVariant2" },
186-
// expectedIdentifier,
187-
// isExternalMod
188-
//];
240+
Assert.Equal(modDir.FullName, actual.Directory.FullName);
189241
}
190242
}
191-
192-
public static IEnumerable<object[]> ModDirectoryTestData()
193-
{
194-
yield return [ModLocationKind.SteamWorkshops, "Game/Mods/1234567890", "1234567890"];
195-
yield return [ModLocationKind.GameModsDirectory, "Game/Mods/DefaultMod", "DefaultMod"];
196-
yield return [ModLocationKind.External, "path/ExternalMod", "ExternalMod"];
197-
}
198243

199-
private MainModinfoFile? CreateValidMainFile(IDirectoryInfo dir, string mainmodinfoJson)
244+
#endregion
245+
246+
private MainModinfoFile CreateValidMainFile(IDirectoryInfo dir)
200247
{
201-
throw new NotImplementedException();
248+
var file = CreateFile(dir, "modinfo.json", TestUtilities.MainModinfoData);
249+
return new MainModinfoFile(file);
202250
}
203251

204252
private MainModinfoFile CreateInvalidMainModinfoFile(IDirectoryInfo dir)
205253
{
206-
dir.Create();
207-
var file = _fileSystem.FileInfo.New(_fileSystem.Path.Combine(dir.FullName, "modinfo.json"));
208-
using var sw = file.CreateText();
209-
sw.Write("This is not a valid modinfo file");
210-
file.Refresh();
254+
var file = CreateFile(dir, "modinfo.json", "This is not a valid modinfo content");
211255
return new MainModinfoFile(file);
212256
}
213257

214258
private ModinfoVariantFile CreateInvalidVariantFile(IDirectoryInfo dir)
215259
{
216260
dir.Create();
217-
var file = _fileSystem.FileInfo.New(_fileSystem.Path.Combine(dir.FullName, "modinfo.json"));
261+
var random = _fileSystem.Path.GetRandomFileName();
262+
var file = _fileSystem.FileInfo.New(_fileSystem.Path.Combine(dir.FullName, $"{random}-modinfo.json"));
218263
using var sw = file.CreateText();
219264
sw.Write("This is not a valid modinfo file");
220265
file.Refresh();
@@ -223,6 +268,17 @@ private ModinfoVariantFile CreateInvalidVariantFile(IDirectoryInfo dir)
223268

224269
private ModinfoVariantFile CreateValidVariantFile(IDirectoryInfo dir, string name)
225270
{
226-
throw new NotImplementedException();
271+
var file = CreateFile(dir, $"{name}-modinfo.json", new ModinfoData(name).ToJson());
272+
return new ModinfoVariantFile(file);
273+
}
274+
275+
private IFileInfo CreateFile(IDirectoryInfo dir, string fileName, string content)
276+
{
277+
dir.Create();
278+
var file = _fileSystem.FileInfo.New(_fileSystem.Path.Combine(dir.FullName, fileName));
279+
using var sw = file.CreateText();
280+
sw.Write(content);
281+
file.Refresh();
282+
return file;
227283
}
228-
}
284+
}

0 commit comments

Comments
 (0)