Skip to content

Commit ee3b63b

Browse files
committed
update to spec 3.0.2
1 parent 3e9af72 commit ee3b63b

4 files changed

Lines changed: 55 additions & 18 deletions

File tree

src/EawModinfo.Tests/ModinfoValidatorTests.cs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,21 +164,22 @@ public static IEnumerable<object[]> GetSteamData()
164164
},
165165
false
166166
];
167+
yield return
168+
[
169+
new JsonSteamData
170+
{
171+
Id = long.MaxValue.ToString(), Tags = ["EAW"], ContentFolder = "testFolder",
172+
Description = "Some description", Title = "MyTitle"
173+
},
174+
false
175+
];
167176
}
168-
177+
169178
public static IEnumerable<object[]> GetInvalidSteamData()
170179
{
171180
yield return [new JsonSteamData(), true];
172181
yield return [new JsonSteamData { Id = null! }, true];
173-
yield return [new JsonSteamData {Id = "asd", Tags = ["EAW"], ContentFolder = "testFolder"}, true];
174182
yield return [new JsonSteamData {Id = "1234", Tags = ["EAW"], ContentFolder = "testFolder"}, true];
175-
yield return [new JsonSteamData {Id = "0", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title"}, true];
176-
yield return [new JsonSteamData {Id = "-123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
177-
yield return
178-
[
179-
new JsonSteamData {Id = "129381209812430981329048", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title"},
180-
true
181-
];
182183
yield return [new JsonSteamData {Id = "1234", Tags = Array.Empty<string>(), ContentFolder = "testFolder", Title = "Title" }, true];
183184
yield return [new JsonSteamData { Id = "1234", Tags = null!, ContentFolder = "testFolder", Title = "Title" }, true];
184185
yield return [new JsonSteamData { Id = "1234", Tags = null!, ContentFolder = "testFolder", Title = "Title" }, true];
@@ -192,9 +193,41 @@ public static IEnumerable<object[]> GetInvalidSteamData()
192193
yield return [new JsonSteamData { Id = "1234312", Tags = ["FOC", new string('a', 256)], Metadata = "bla", ContentFolder = "testFolder", Title = "Title" }, true];
193194
}
194195

196+
public static IEnumerable<object[]> GetInvalidSteamIDs()
197+
{
198+
var random = new Random();
199+
yield return [new JsonSteamData { Id = "NaN", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
200+
yield return [new JsonSteamData { Id = "1abc", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
201+
yield return [new JsonSteamData { Id = "abc1", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
202+
yield return [new JsonSteamData { Id = "abc", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
203+
yield return [new JsonSteamData { Id = "1d", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
204+
yield return [new JsonSteamData { Id = "1f", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
205+
yield return [new JsonSteamData { Id = "0x1", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
206+
yield return [new JsonSteamData { Id = "0", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
207+
yield return [new JsonSteamData { Id = "1AF", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
208+
yield return [new JsonSteamData { Id = "1+", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
209+
yield return [new JsonSteamData { Id = "1e2", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
210+
yield return [new JsonSteamData { Id = "1E2", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
211+
yield return [new JsonSteamData { Id = random.Next(int.MinValue, -1).ToString(), Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
212+
yield return [new JsonSteamData { Id = "+123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
213+
yield return [new JsonSteamData { Id = "-+123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
214+
yield return [new JsonSteamData { Id = "1_23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
215+
yield return [new JsonSteamData { Id = "1-23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
216+
yield return [new JsonSteamData { Id = "1.23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
217+
yield return [new JsonSteamData { Id = "1,23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
218+
yield return [new JsonSteamData { Id = "0123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
219+
yield return [new JsonSteamData { Id = "00123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
220+
yield return [new JsonSteamData { Id = " 00123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
221+
yield return [new JsonSteamData { Id = " 123", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
222+
yield return [new JsonSteamData { Id = "123 ", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
223+
yield return [new JsonSteamData { Id = "1 23", Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
224+
yield return [new JsonSteamData { Id = "1" + ulong.MaxValue, Tags = ["EAW"], ContentFolder = "testFolder", Title = "Title" }, true];
225+
}
226+
195227
[Theory]
196228
[MemberData(nameof(GetSteamData))]
197229
[MemberData(nameof(GetInvalidSteamData))]
230+
[MemberData(nameof(GetInvalidSteamIDs))]
198231
public void Validate_SteamData(ISteamData steamData, bool shallThrow)
199232
{
200233
if (!shallThrow)

src/EawModinfo/Spec/IModReference.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ namespace EawModinfo.Spec;
99
public interface IModReference : IEquatable<IModReference>, IConvertibleToJson
1010
{
1111
/// <summary>
12-
/// Gets the unique identifier as a textual representation. The <see cref="Type"/> property my indicate how the data can be interpreted.
12+
/// Gets the unique, predictable identifier of the mod.
1313
/// </summary>
14+
/// <remarks>
15+
/// The identifier can hold any data to uniquely identify a mod, however the concrete value shall be predictable,
16+
/// so that it can be used to code it into modinfo JSON files to reference mod dependencies.
17+
/// For Steam Workshop mods it is therefore recommended to use the Steam Workshops ID and for local
18+
/// The <see cref="Type"/> property may indicate how the data can be interpreted.
19+
/// </remarks>
1420
string Identifier { get; }
1521

1622
/// <summary>
@@ -25,5 +31,4 @@ public interface IModReference : IEquatable<IModReference>, IConvertibleToJson
2531
/// As stated in the specification this property is not used for equality matching.
2632
/// </remarks>
2733
SemVersionRange? VersionRange { get; }
28-
2934
}

src/EawModinfo/Spec/ModType.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ public enum ModType
77
{
88
/// <summary>
99
/// The mod îs stored on the file system at a well known file system location (e.g. the game's 'Mods' directory).
10-
/// The associated <see cref="IModReference.Identifier"/> should be able to parse into a relative or absolute file system path.
1110
/// </summary>
1211
Default = 0,
1312
/// <summary>
1413
/// The mod is a Steam Workshops Item.
15-
/// The associated <see cref="IModReference.Identifier"/> <b>must</b> be able to parse into an <see cref="uint"/> which represents a Steam Workshops identifier.
1614
/// </summary>
1715
Workshops = 1,
1816
/// <summary>

src/EawModinfo/Utilities/ModinfoValidator.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Globalization;
44
using System.Linq;
55
using System.Runtime.CompilerServices;
6-
using EawModinfo.Model.Json;
76
using EawModinfo.Spec;
87
using EawModinfo.Spec.Steam;
98

@@ -16,7 +15,7 @@ public static class ModinfoValidator
1615
{
1716
/// <summary>
1817
/// Validates an <see cref="IModinfo"/> data. Throws an <see cref="ModinfoException"/> when validation failed.
19-
/// Also throws is subsequent data such as <see cref="ISteamData"/> are invalid, if present.
18+
/// Also throws if subsequent data such as <see cref="ISteamData"/> are invalid, if present.
2019
/// </summary>
2120
/// <param name="modinfo">The data to validate.</param>
2221
/// <exception cref="ModinfoException">The validation failed.</exception>
@@ -47,7 +46,7 @@ public static void Validate(this ISteamData steamData)
4746
{
4847
if (string.IsNullOrEmpty(steamData.Id))
4948
throw new ModinfoException("Steam data is invalid: Identifier is missing.");
50-
ValidateSteamId(steamData.Id, "Steam data is invalid: ");
49+
ValidateSteamId(steamData.Id, $"Steam data is invalid: '{steamData.Id}'");
5150

5251
if (string.IsNullOrEmpty(steamData.ContentFolder))
5352
throw new ModinfoException("Steam data is invalid: ContentFolder is missing.");
@@ -81,7 +80,6 @@ private static bool ContainsInvalidCharacter(ReadOnlySpan<char> value)
8180
if (c == ',' || (uint)(c - '\x0020') > '\x007F' - '\x0020') // (c >= '\x0020' && c <= '\x007F'
8281
return true;
8382
}
84-
8583
return false;
8684
}
8785

@@ -152,7 +150,10 @@ private static void ValidateSteamId(string data, string errorSourceMessage)
152150

153151
private static (bool Valid, string Error) ValidateSteamId(string data)
154152
{
155-
if (!uint.TryParse(data, out var id))
153+
// Leading spaces, etc. is not a problem, because this case is handled with NumberStyles.None
154+
if (data[0] == '0')
155+
return (false, "Workshops ID cannot have leading zeros.");
156+
if (!ulong.TryParse(data, NumberStyles.None, CultureInfo.InvariantCulture, out var id))
156157
return (false, "Workshops ID must be an uint number.");
157158
if (id == 0)
158159
return (false, "Workshops ID cannot be 0.");

0 commit comments

Comments
 (0)