Merge remote-tracking branch 'upstream/dev' into develop
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
using Barotrauma;
|
||||
using FluentAssertions;
|
||||
using FsCheck;
|
||||
|
||||
namespace TestProject;
|
||||
|
||||
public sealed class GenericToolBoxTests
|
||||
{
|
||||
public class CustomGenerators
|
||||
{
|
||||
public static Arbitrary<DifferentIdentifierPair> IdentifierPairGenerator()
|
||||
{
|
||||
return Arb.From(from Identifier first in Arb.Generate<Identifier>()
|
||||
from Identifier second in Arb.Generate<Identifier>().Where(second => second != first)
|
||||
select new DifferentIdentifierPair(first, second));
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct DifferentIdentifierPair
|
||||
{
|
||||
public readonly Identifier First,
|
||||
Second;
|
||||
|
||||
public DifferentIdentifierPair(Identifier first, Identifier second)
|
||||
{
|
||||
if (first == second) { throw new InvalidOperationException("Identifiers must be different"); }
|
||||
|
||||
First = first;
|
||||
Second = second;
|
||||
}
|
||||
}
|
||||
|
||||
public GenericToolBoxTests()
|
||||
{
|
||||
Arb.Register<TestProject.CustomGenerators>();
|
||||
Arb.Register<CustomGenerators>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatchesStatIdentifier()
|
||||
{
|
||||
Prop.ForAll<DifferentIdentifierPair>(static pair =>
|
||||
{
|
||||
ToolBox.StatIdentifierMatches(pair.First, $"{pair.First}~{pair.Second}".ToIdentifier()).Should().BeTrue();
|
||||
ToolBox.StatIdentifierMatches($"{pair.First}~{pair.Second}".ToIdentifier(), pair.First).Should().BeTrue();
|
||||
ToolBox.StatIdentifierMatches(pair.First, pair.First).Should().BeTrue();
|
||||
|
||||
ToolBox.StatIdentifierMatches(pair.First, $"{pair.Second}~{pair.First}".ToIdentifier()).Should().BeFalse();
|
||||
ToolBox.StatIdentifierMatches(pair.First, pair.Second).Should().BeFalse();
|
||||
}).VerboseCheckThrowOnFailure();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Barotrauma;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Xunit;
|
||||
|
||||
namespace TestProject;
|
||||
@@ -27,12 +29,56 @@ public class INetSerializableStructImplementationChecks
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
var members = NetSerializableProperties.GetPropertiesAndFields(type);
|
||||
var concreteType = type;
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
// Plug in some known good parameters to evaluate
|
||||
// a concrete instance of this generic type
|
||||
|
||||
var paramsConstraints = type.GetGenericArguments()
|
||||
.Select(p => p.GetGenericParameterConstraints())
|
||||
.ToImmutableArray();
|
||||
|
||||
var chosenArgs = new Type[paramsConstraints.Length];
|
||||
|
||||
for (int i = 0; i < paramsConstraints.Length; i++)
|
||||
{
|
||||
var constraints = paramsConstraints[i];
|
||||
bool refTypeConstraint = constraints.Any(c
|
||||
=> c.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint));
|
||||
bool valueTypeConstraint = constraints.Any(c
|
||||
=> c.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint));
|
||||
if (refTypeConstraint && valueTypeConstraint)
|
||||
{
|
||||
throw new Exception($"Type \"{type.Name}\" has invalid generic constraints");
|
||||
}
|
||||
|
||||
int rngMin = refTypeConstraint ? 3 : 0;
|
||||
int rngMax = valueTypeConstraint ? 3 : 6;
|
||||
|
||||
chosenArgs[i] = Rand.Range(rngMin, rngMax) switch
|
||||
{
|
||||
0 => typeof(Vector2),
|
||||
1 => typeof(Point),
|
||||
2 => typeof(int),
|
||||
|
||||
3 => typeof(string),
|
||||
4 => typeof(float[]),
|
||||
5 => typeof(int[]),
|
||||
|
||||
var invalid => throw new Exception($"Broken RNG ranges in test, got {invalid}")
|
||||
};
|
||||
}
|
||||
|
||||
concreteType = type.MakeGenericType(chosenArgs);
|
||||
}
|
||||
|
||||
var members = NetSerializableProperties.GetPropertiesAndFields(concreteType);
|
||||
foreach (var member in members)
|
||||
{
|
||||
void checkType(Type typeBeingChecked)
|
||||
{
|
||||
Assert.True(tryFindBehavior(typeBeingChecked, out _), $"{type}.{member.Name} of type {member.Type} is unsupported in {nameof(INetSerializableStruct)}");
|
||||
Assert.True(tryFindBehavior(typeBeingChecked, out _), $"{concreteType}.{member.Name} of type {member.Type} is unsupported in {nameof(INetSerializableStruct)}");
|
||||
Type? nestedType = null;
|
||||
if (typeBeingChecked.IsGenericType)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,12 @@ namespace TestProject
|
||||
select new Vector2(x, y));
|
||||
}
|
||||
|
||||
public static Arbitrary<Identifier> IdentifierGenerator()
|
||||
{
|
||||
return Arb.From(from string value in Arb.Generate<string>().Where(static s => s != null)
|
||||
select new Identifier(value));
|
||||
}
|
||||
|
||||
public static Arbitrary<Color> ColorGenerator()
|
||||
{
|
||||
return Arb.From(from int r in Gen.Choose(0, 255)
|
||||
|
||||
Reference in New Issue
Block a user