Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions Yuzu/YuzuTest/Samples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,97 @@ public class BadMerge2
public int F;
}

public class TypedNumberSample : IEquatable<TypedNumberSample>
{
public TypedNumberSample(int number) { this.number = number; }
public TypedNumberSample() { }
private int number;

[YuzuToSurrogate]
public int Serialize() => number;

[YuzuFromSurrogate]
public static TypedNumberSample Deserialize(int value) => new TypedNumberSample { number = value };

public override int GetHashCode() => number.GetHashCode();
public bool Equals(TypedNumberSample other) => ReferenceEquals(this, other) || (other != null) && number == other.number;
public override bool Equals(object other) => (other != null) && (GetType() == other.GetType()) && Equals(other as TypedNumberSample);
public static bool operator ==(TypedNumberSample lhs, TypedNumberSample rhs) => Equals(lhs, rhs);
public static bool operator !=(TypedNumberSample lhs, TypedNumberSample rhs) => !Equals(lhs, rhs);
}

public class SurrogateDictionaryKey
{
[YuzuMember]
public Dictionary<TypedNumberSample, int> F = new Dictionary<TypedNumberSample, int>();
}

public class SurrogateDictionaryValue
{
[YuzuMember]
public Dictionary<int, TypedNumberSample> F = new Dictionary<int, TypedNumberSample>();
}

public class SurrogateListElement
{
[YuzuMember]
public List<TypedNumberSample> F = new List<TypedNumberSample>();
}

public class SurrogateHashSetElement
{
[YuzuMember]
public HashSet<TypedNumberSample> F = new HashSet<TypedNumberSample>();
}

public class SurrogateIntToStringSample
{
public SurrogateIntToStringSample() { }
public SurrogateIntToStringSample(int number) { Number = number; }
public int Number;

[YuzuToSurrogate]
public string Serialize() => Number.ToString();

[YuzuFromSurrogate]
public static SurrogateIntToStringSample Deserialize(string value) => new SurrogateIntToStringSample(int.Parse(value));
}

public class SurrogateCustomGenericArgument
{
public class Generic<T>
{
[YuzuMember]
public T F;
}

[YuzuMember]
public Generic<SurrogateIntToStringSample> F;
}

public class SurrogateCustomGeneric
{
public class Generic<T>
{
public T F;

public Generic(T f)
{
F = f;
}

[YuzuToSurrogate]
public string Serialize() => F.ToString();

[YuzuFromSurrogate]
// this generic will only work where T : int, see hack below
public static Generic<T> Deserialize(string value) => new Generic<T>((T)(object)int.Parse(value));
}

[YuzuMember]
public Generic<int> F;
}

public static class XAssert
{
public static void Throws<TExpectedException>(Action exceptionThrower, string expectedExceptionMessage = "")
Expand Down
53 changes: 53 additions & 0 deletions Yuzu/YuzuTest/TestBinary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1985,5 +1985,58 @@ public void TestErrors()

}

[TestMethod]
public void TestSurrogatesWithGenericsSimple()
{
var b1Etalon = SX("20 01 00 " + XS(typeof(SurrogateDictionaryKey)) + " 01 00 " +
XS(nameof(SurrogateDictionaryKey.F)) +
" 22 05 05 01 00 03 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 00 00");

var b2Etalon = SX("20 02 00 " + XS(typeof(SurrogateDictionaryValue)) + " 01 00 " +
XS(nameof(SurrogateDictionaryValue.F)) +
" 22 05 05 01 00 03 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00 00 00");

var b3Etalon = SX("20 03 00 " + XS(typeof(SurrogateListElement)) + " 01 00 " +
XS(nameof(SurrogateListElement.F)) +
" 21 05 01 00 04 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 00 00");

var b4Etalon = SX("20 04 00 " + XS(typeof(SurrogateHashSetElement)) + " 01 00 " +
XS(nameof(SurrogateHashSetElement.F)) +
" 21 05 01 00 04 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 00 00");

var b5Etalon = SX("20 05 00 " + XS(typeof(SurrogateCustomGenericArgument)) + " 01 00 " +
XS(nameof(SurrogateCustomGenericArgument.F)) + " 20 01 00 06 00 " +
XS(Yuzu.Util.TypeSerializer.Serialize(typeof(SurrogateCustomGenericArgument.Generic<string>))) + " 01 00 " +
XS(nameof(SurrogateCustomGenericArgument.Generic<string>.F)) + " 10 01 00 02 34 37 00 00 00 00");

var b6Etalon = SX("20 07 00 " + XS(typeof(SurrogateCustomGeneric)) + " 01 00 " +
XS(nameof(SurrogateCustomGeneric.F)) + " 10 01 00 02 33 31 00 00");

var bd = new BinaryDeserializer();
var s1 = bd.FromBytes<SurrogateDictionaryKey>(b1Etalon);
Assert.IsTrue(s1.F[new TypedNumberSample(1)] == 2);
Assert.IsTrue(s1.F[new TypedNumberSample(3)] == 4);
Assert.IsTrue(s1.F[new TypedNumberSample(5)] == 6);
var s2 = bd.FromBytes<SurrogateDictionaryValue>(b2Etalon);
Assert.IsTrue(s2.F[7] == new TypedNumberSample(8));
Assert.IsTrue(s2.F[9] == new TypedNumberSample(10));
Assert.IsTrue(s2.F[11] == new TypedNumberSample(12));
var s3 = bd.FromBytes<SurrogateListElement>(b3Etalon);
Assert.IsTrue(s3.F.SequenceEqual(new List<TypedNumberSample> {
new TypedNumberSample(1), new TypedNumberSample(2),
new TypedNumberSample(3), new TypedNumberSample(4)
}));
var s4 = bd.FromBytes<SurrogateHashSetElement>(b4Etalon);
Assert.IsTrue(s4.F.Contains(new TypedNumberSample(6)));
Assert.IsTrue(s4.F.Contains(new TypedNumberSample(7)));
Assert.IsTrue(s4.F.Contains(new TypedNumberSample(8)));
Assert.IsTrue(s4.F.Contains(new TypedNumberSample(9)));
Assert.IsTrue(s4.F.Count == 4);
var s5 = bd.FromBytes<SurrogateCustomGenericArgument>(b5Etalon);
Assert.IsTrue(s5.F.F.Number == 47);
var s6 = bd.FromBytes<SurrogateCustomGeneric>(b6Etalon);
Assert.IsTrue(s6.F.F == 31);
}

}
}