mirror of
https://github.com/AssetRipper/AssetRipper.Primitives.git
synced 2026-11-13 04:26:30 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3320be1312 | ||
|
|
659c382ff7 | ||
|
|
4aed9eb024 | ||
|
|
4e6f668e10 | ||
|
|
dc4e81eb28 | ||
|
|
0e2a37e920 | ||
|
|
b29d4a7a69 | ||
|
|
93ee2b0675 | ||
|
|
ebe6802570 | ||
|
|
97da17c016 | ||
|
|
475c27c28c | ||
|
|
fb0fb3f1c6 |
No files matched your search
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3.0.3
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
- name: Restore dependencies
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3.0.3
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
- name: Restore dependencies
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3.0.3
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
with:
|
||||
dotnet-version: |
|
||||
5.0.x
|
||||
|
||||
@@ -5,18 +5,24 @@ namespace AssetRipper.VersionUtilities.Tests;
|
||||
|
||||
public class ParsingTests
|
||||
{
|
||||
[TestCase("4.2.2f1", 4, 2, 2, UnityVersionType.Final, 1, false)]
|
||||
[TestCase("4.2.2f1\n1", 4, 2, 2, UnityVersionType.Final, 1, true)]
|
||||
[TestCase("2343.4.5f7", 2343, 4, 5, UnityVersionType.Final, 7, false)]
|
||||
[TestCase("2019.2.2f1c2\n2", 2019, 2, 2, UnityVersionType.China, 2, true)]//Not a real version
|
||||
public void UnityVersionParsesCorrectly(string versionString, int major, int minor, int build, UnityVersionType type, int typeNumber, bool customEngine)
|
||||
[TestCase("4.2.2f1", 4, 2, 2, UnityVersionType.Final, 1, null, "Normal Unity 4 Version")]
|
||||
[TestCase("4.2.2f1\n1", 4, 2, 2, UnityVersionType.Final, 1, 1, "Custom Unity 4 Version")]
|
||||
[TestCase("2343.4.5f7", 2343, 4, 5, UnityVersionType.Final, 7, null, "Fictitious Future Version")]
|
||||
[TestCase("2019.2.2f1c2\n2", 2019, 2, 2, UnityVersionType.China, 2, 2, "Fake Custom Chinese Version")]
|
||||
[TestCase("2019.4", 2019, 4, 0, UnityVersionType.Final, 1, null, "Major Minor Only")]
|
||||
[TestCase("2019.4.3", 2019, 4, 3, UnityVersionType.Final, 1, null, "Major Minor Build Only")]
|
||||
public void UnityVersionParsesCorrectly(string versionString, int major, int minor, int build, UnityVersionType type, int typeNumber, int? customEngine, string name)
|
||||
{
|
||||
UnityVersion expected = new UnityVersion((ushort)major, (ushort)minor, (ushort)build, type, (byte)typeNumber);
|
||||
UnityVersion parsedVersion = UnityVersion.Parse(versionString, out bool parsedCustomEngine);
|
||||
UnityVersion parsedVersion = UnityVersion.Parse(versionString, out int? parsedCustomEngine);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(parsedCustomEngine, Is.EqualTo(customEngine));
|
||||
Assert.That(parsedVersion, Is.EqualTo(expected));
|
||||
Assert.That(parsedCustomEngine, Is.EqualTo(customEngine), $"The custom engine boolean is incorrect for '{name}'");
|
||||
Assert.That(parsedVersion, Is.EqualTo(expected), $"The parsed version is incorrect for '{name}'");
|
||||
if (customEngine is not null || typeNumber is not 1)
|
||||
{
|
||||
Assert.That(parsedVersion.ToString(UnityVersionFormatFlags.Default, parsedCustomEngine), Is.EqualTo(versionString));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,32 +30,16 @@ public class ParsingTests
|
||||
public void UnityVersionToStringParsesCorrectly(UnityVersion version)
|
||||
{
|
||||
string versionString = version.ToString();
|
||||
UnityVersion parsedVersion = UnityVersion.Parse(versionString, out bool customEngine);
|
||||
UnityVersion parsedVersion = UnityVersion.Parse(versionString, out int? customEngine);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(customEngine, Is.False);
|
||||
Assert.That(customEngine, Is.Null);
|
||||
Assert.That(parsedVersion, Is.EqualTo(version));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MajorMinorOnly()
|
||||
{
|
||||
string version = "2019.4";
|
||||
UnityVersion expected = new UnityVersion(2019, 4, 0, UnityVersionType.Final, 1);
|
||||
Assert.That(UnityVersion.Parse(version), Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MajorMinorBuildOnly()
|
||||
{
|
||||
string version = "2019.4.3";
|
||||
UnityVersion expected = new UnityVersion(2019, 4, 3, UnityVersionType.Final, 1);
|
||||
Assert.That(UnityVersion.Parse(version), Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChinaVersionString()
|
||||
public void LongChineseVersionFormat()
|
||||
{
|
||||
//This is an actual version from a game.
|
||||
//Versions like 2019.3.0f2 and 2020.3.15f2 don't have corresponding Chinese versions.
|
||||
@@ -63,6 +53,20 @@ public class ParsingTests
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShortChineseVersionFormat()
|
||||
{
|
||||
//This is an actual version from a game.
|
||||
//Source: https://github.com/AssetRipper/AssetRipper/issues/841
|
||||
string version = "2017.4.40c1";
|
||||
UnityVersion expected = new UnityVersion(2017, 4, 40, UnityVersionType.China, 1);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(UnityVersion.Parse(version), Is.EqualTo(expected));
|
||||
Assert.That(expected.ToString(UnityVersionFormatFlags.UseShortChineseFormat), Is.EqualTo(version));
|
||||
});
|
||||
}
|
||||
|
||||
private static IEnumerable<UnityVersion> GenerateRandomVersions(int count)
|
||||
{
|
||||
Randomizer random = TestContext.CurrentContext.Random;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netframework3.5;netframework4.0;netframework4.8;net5.0;net6.0;net7.0</TargetFrameworks>
|
||||
@@ -10,14 +10,14 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.6.0">
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.6.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using AssetRipper.VersionUtilities.Extensions;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace AssetRipper.VersionUtilities;
|
||||
@@ -8,23 +7,49 @@ public readonly partial struct UnityVersion
|
||||
{
|
||||
private static readonly Regex majorMinorRegex = new Regex(@"^([0-9]+)\.([0-9]+)$", RegexOptions.Compiled);
|
||||
private static readonly Regex majorMinorBuildRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)$", RegexOptions.Compiled);
|
||||
private static readonly Regex normalRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)\.?([abfpx])([0-9]+)(\n[0-9]+)?$", RegexOptions.Compiled);
|
||||
private static readonly Regex normalRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)\.?([abcfpx])([0-9]+)(\n[0-9]+)?$", RegexOptions.Compiled);
|
||||
private static readonly Regex chinaRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)\.?f1c([0-9]+)(\n[0-9]+)?$", RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the version as a string
|
||||
/// Serialize the version as a string using <see cref="UnityVersionFormatFlags.Default"/>.
|
||||
/// </summary>
|
||||
/// <returns>A new string like 2019.4.3f1</returns>
|
||||
public override string ToString()
|
||||
public override string ToString() => ToString(UnityVersionFormatFlags.Default);
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the version as a string
|
||||
/// </summary>
|
||||
/// <param name="flags">The flags to control how the version is formatted</param>
|
||||
/// <returns>A new string containing the formatted version.</returns>
|
||||
public string ToString(UnityVersionFormatFlags flags)
|
||||
{
|
||||
return Type == UnityVersionType.China
|
||||
? $"{Major}.{Minor}.{Build}f1c{TypeNumber}"
|
||||
: $"{Major}.{Minor}.{Build}{Type.ToCharacter()}{TypeNumber}";
|
||||
return (flags & UnityVersionFormatFlags.ExcludeType) != 0
|
||||
? ToStringWithoutType()
|
||||
: Type is not UnityVersionType.China || (flags & UnityVersionFormatFlags.UseShortChineseFormat) != 0
|
||||
? $"{Major}.{Minor}.{Build}{Type.ToCharacter()}{TypeNumber}"
|
||||
: $"{Major}.{Minor}.{Build}f1c{TypeNumber}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the version as a string
|
||||
/// </summary>
|
||||
/// <param name="flags">The flags to control how the version is formatted</param>
|
||||
/// <param name="customEngineNumber">The custom engine number to be appended</param>
|
||||
/// <returns>A new string containing the formatted version.</returns>
|
||||
public string ToString(UnityVersionFormatFlags flags, int? customEngineNumber)
|
||||
{
|
||||
return customEngineNumber is null
|
||||
? ToString(flags)
|
||||
: (flags & UnityVersionFormatFlags.ExcludeType) != 0
|
||||
? ToStringWithoutType()
|
||||
: Type is not UnityVersionType.China || (flags & UnityVersionFormatFlags.UseShortChineseFormat) != 0
|
||||
? $"{Major}.{Minor}.{Build}{Type.ToCharacter()}{TypeNumber}\n{customEngineNumber}"
|
||||
: $"{Major}.{Minor}.{Build}f1c{TypeNumber}\n{customEngineNumber}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the version as a string using only <see cref="Major"/>, <see cref="Minor"/>, and <see cref="Build"/>.
|
||||
/// </summary>
|
||||
/// <returns>A new string like 2019.4.3</returns>
|
||||
public string ToStringWithoutType()
|
||||
{
|
||||
@@ -48,7 +73,7 @@ public readonly partial struct UnityVersion
|
||||
/// <returns>The parsed Unity version</returns>
|
||||
/// <exception cref="ArgumentNullException">If the string is null or empty</exception>
|
||||
/// <exception cref="ArgumentException">If the string is in an invalid format</exception>
|
||||
public static UnityVersion Parse(string version, out bool customEngine)
|
||||
public static UnityVersion Parse(string version, out int? customEngine)
|
||||
{
|
||||
if (string.IsNullOrEmpty(version))
|
||||
{
|
||||
@@ -62,7 +87,7 @@ public readonly partial struct UnityVersion
|
||||
int build = int.Parse(match.Groups[3].Value);
|
||||
char type = match.Groups[4].Value[0];
|
||||
int typeNumber = int.Parse(match.Groups[5].Value);
|
||||
customEngine = match.Groups[6].Length > 0;
|
||||
customEngine = ParseNullableInteger(match.Groups[6]);
|
||||
return new UnityVersion((ushort)major, (ushort)minor, (ushort)build, type.ToUnityVersionType(), (byte)typeNumber);
|
||||
}
|
||||
else if (majorMinorBuildRegex.TryMatch(version, out match))
|
||||
@@ -70,14 +95,14 @@ public readonly partial struct UnityVersion
|
||||
int major = int.Parse(match.Groups[1].Value);
|
||||
int minor = int.Parse(match.Groups[2].Value);
|
||||
int build = int.Parse(match.Groups[3].Value);
|
||||
customEngine = false;
|
||||
customEngine = null;
|
||||
return new UnityVersion((ushort)major, (ushort)minor, (ushort)build, UnityVersionType.Final, 1);
|
||||
}
|
||||
else if (majorMinorRegex.TryMatch(version, out match))
|
||||
{
|
||||
int major = int.Parse(match.Groups[1].Value);
|
||||
int minor = int.Parse(match.Groups[2].Value);
|
||||
customEngine = false;
|
||||
customEngine = null;
|
||||
return new UnityVersion((ushort)major, (ushort)minor, 0, UnityVersionType.Final, 1);
|
||||
}
|
||||
else if (chinaRegex.TryMatch(version, out match))
|
||||
@@ -86,12 +111,14 @@ public readonly partial struct UnityVersion
|
||||
int minor = int.Parse(match.Groups[2].Value);
|
||||
int build = int.Parse(match.Groups[3].Value);
|
||||
int typeNumber = int.Parse(match.Groups[4].Value);
|
||||
customEngine = match.Groups[5].Length > 0;
|
||||
customEngine = ParseNullableInteger(match.Groups[5]);
|
||||
return new UnityVersion((ushort)major, (ushort)minor, (ushort)build, UnityVersionType.China, (byte)typeNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Invalid version format: {version}", nameof(version));
|
||||
}
|
||||
|
||||
static int? ParseNullableInteger(Capture capture) => capture.Length == 0 ? null : int.Parse(capture.Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace AssetRipper.VersionUtilities;
|
||||
|
||||
/// <summary>
|
||||
/// Flags used when formatting a <see cref="UnityVersion"/>
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum UnityVersionFormatFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// The default flags when formatting.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
/// <summary>
|
||||
/// Exclude <see cref="UnityVersion.Type"/>, <see cref="UnityVersion.TypeNumber"/>, and the custom engine number when formatting.
|
||||
/// </summary>
|
||||
ExcludeType = 1 << 0,
|
||||
/// <summary>
|
||||
/// Format chinese versions as 2019.4.3c1 rather than 2019.4.3f1c1
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// An example of the long version can be found in 'unity editor resources' and 'unity_builtin_extra' for the <see href="https://unity.cn/release-notes/full/2019/2019.4.40f1">2019.4.40f1c1</see> version.<br/>
|
||||
/// An example of the short version can be found in <see href="https://github.com/AssetRipper/AssetRipper/issues/841"/>.
|
||||
/// </remarks>
|
||||
UseShortChineseFormat = 1 << 1,
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netframework3.5;netframework4.0;netstandard2.0;net5.0;net6.0;net7.0</TargetFrameworks>
|
||||
@@ -8,7 +8,7 @@
|
||||
<AssemblyName>AssetRipper.VersionUtilities</AssemblyName>
|
||||
<Authors>ds5678</Authors>
|
||||
<Company>AssetRipper</Company>
|
||||
<Version>1.4.0.0</Version>
|
||||
<Version>1.5.0.0</Version>
|
||||
<AssemblyVersion>$(Version)</AssemblyVersion>
|
||||
<PackageId>AssetRipper.VersionUtilities</PackageId>
|
||||
<PackageTags>C# version unity unity3d</PackageTags>
|
||||
@@ -32,7 +32,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="PolySharp" Version="1.12.1">
|
||||
<PackageReference Include="PolySharp" Version="1.13.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
Reference in new issue
Block a user