rd-net/Test.RdFramework/Reflection/ScalarTests.cs (373 lines of code) (raw):
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Collections.Viewable;
using JetBrains.Rd.Impl;
using JetBrains.Rd.Reflection;
using JetBrains.Serialization;
using NUnit.Framework;
namespace Test.RdFramework.Reflection
{
[TestFixture]
public class ScalarTests : RdReflectionTestBase
{
[Test]
public void TestColor1()
{
WithExts<ColorsExt>((c, s) =>
{
c.Map.Add(new ColorFields(100, 100, 100), long.MaxValue);
Assert.AreEqual(s.Map[new ColorFields(100, 100, 100)], c.Map.Values.First());
});
}
[Test]
public void TestColor2()
{
WithExts<ColorsExt>((c, s) =>
{
c.List.Add(new ColorStruct() {Blue = 1, Green = 2, Red = 3});
c.List.Add(new ColorStruct());
CollectionAssert.AreEqual(s.List, c.List);
});
}
[Test]
public void TestColor3()
{
WithExts<ColorsExt>((c, s) =>
{
c.List.Add(new ColorStruct() {Blue = 1, Green = 2, Red = 3});
c.List.Add(new ColorStruct());
CollectionAssert.AreEqual(s.List, c.List);
});
}
[Test]
public void TestValueTuple()
{
WithExts<ValueTuplesExt>((c, s) =>
{
var val = ("test", "test2");
c.SimpleTuple.Value = val;
Assert.AreEqual(val, s.SimpleTuple.Value);
});
}
[Test]
public void TestValueTupleNested()
{
WithExts<ValueTuplesExt>((c, s) =>
{
var val = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1);
s.NestedTuple.Value = val;
Assert.AreEqual(val, c.NestedTuple.Value);
});
}
[Test]
public void TestArrays()
{
WithExts<ArraysExt>((c, s) =>
{
s.IntArray.Value = new[] {1, 2, 3};
CollectionAssert.AreEqual(s.IntArray.Value, c.IntArray.Value);
});
}
[Test]
public void TestArrays2()
{
WithExts<ArraysExt>((c, s) =>
{
s.ComplexArray.Value = new[] {new[] {new[] {1, 2, 3}}};
CollectionAssert.AreEqual(s.ComplexArray.Value[0][0], c.ComplexArray.Value[0][0]);
});
}
[Test]
public void TestArrays3()
{
WithExts<ArraysExt>((c, s) =>
{
s.ValueTupleArray.Value = new[] {("key", "value"), ("key", "value")};
CollectionAssert.AreEqual(s.ValueTupleArray.Value, c.ValueTupleArray.Value);
});
}
[Test]
public void TestArraysClass()
{
WithExts<ArraysExt2>((c, s) =>
{
s.Property.Value = new ColorFields(1, 1, 1);
s.PropertyArray.Value = new[] {new ColorFields(2, 2, 2)};
Assert.AreEqual(s.Property.Value, c.Property.Value);
CollectionAssert.AreEqual(s.PropertyArray.Value, c.PropertyArray.Value);
});
}
[Test]
public void TestList2()
{
AddType(typeof(ColorFields));
WithExts<ListObjectsExt>((c, s) =>
{
s.Objects.Value = new ListOwner()
{
Ints = new List<int>() {1, 2, 3},
Polymorphic = new List<ColorFields>()
{
new ColorFields(1, 2, 3)
},
PolymorphicArray = new List<ColorFields[]>()
{
new ColorFields[30]
}
};
CollectionAssert.AreEqual(s.Objects.Value.Ints, c.Objects.Value.Ints);
Assert.AreEqual(s.Objects.Value.Polymorphic[0].Blue, s.Objects.Value.Polymorphic[0].Blue);
Assert.AreEqual(s.Objects.Value.PolymorphicArray[0].Length, s.Objects.Value.PolymorphicArray[0].Length);
});
}
[Test]
public void TestListInterface()
{
WithExts<ListInterfacesExt>((c, s) =>
{
c.Objects.Value = new ListInterfacesExt.ListOwner1()
{
InterfaceListOfInts = new List<int>() {1, 2, 3},
ListOfInts = new List<int>() {1, 2, 3},
CollectionOfInts = new List<int>() {1, 2, 3},
ReadonlyListInts = new List<int>() {1, 2, 3},
EnumerableInts = new List<int>() {1, 2, 3},
};
CollectionAssert.AreEqual(c.Objects.Value.InterfaceListOfInts , s.Objects.Value.InterfaceListOfInts );
CollectionAssert.AreEqual(c.Objects.Value.ListOfInts , s.Objects.Value.ListOfInts );
CollectionAssert.AreEqual(c.Objects.Value.CollectionOfInts , s.Objects.Value.CollectionOfInts );
CollectionAssert.AreEqual(c.Objects.Value.ReadonlyListInts , s.Objects.Value.ReadonlyListInts );
CollectionAssert.AreEqual(c.Objects.Value.EnumerableInts , s.Objects.Value.EnumerableInts );
});
}
[RdExt]
public class ListInterfacesExt : RdExtReflectionBindableBase
{
public IViewableProperty<ListOwner1> Objects { get; }
public class ListOwner1
{
public IList<int> InterfaceListOfInts;
public List<int> ListOfInts;
public IList<int> CollectionOfInts;
public IReadOnlyList<int> ReadonlyListInts;
public IEnumerable<int> EnumerableInts;
}
}
[Test]
public void TestEventArgs()
{
WithExts<EventArgsExt>((c, s) =>
{
c.Objects.Value = new MyEventArgs<int?>() { Value = 42 };
Assert.AreEqual(42, s.Objects.Value.Value);
});
}
[Test]
public void TestGenericStruct()
{
WithExts<GenericStructExt>((c, s) =>
{
c.EnumStruct.Value = new TextControlOverridableValue<MyEnum>(MyEnum.First, MyEnum.Second);
c.IntStruct.Value = new TextControlOverridableValue<int>(1,2);
Assert.AreEqual(MyEnum.First, s.EnumStruct.Value.Original);
Assert.AreEqual(MyEnum.Second, s.EnumStruct.Value.Override);
Assert.AreEqual(1, s.IntStruct.Value.Original);
Assert.AreEqual(2, s.IntStruct.Value.Override);
});
}
[Test]
public void TestDictionary()
{
RunScalarTest(new Dictionary<string, string>() { {"a", "b"}}, CollectionAssert.AreEqual);
}
[Test]
public void TestIDictionary()
{
RunScalarTest(new Dictionary<string, string>() { {"a", "b"}} as IDictionary<string, string>, CollectionAssert.AreEqual);
}
[Test]
public void TestReadOnlyDictionary()
{
RunScalarTest(new Dictionary<string, string>() { {"a", "b"}} as IReadOnlyDictionary<string, string>, CollectionAssert.AreEqual);
}
[Test]
public void TestBoxing()
{
RunScalarTest<object>(true, (a, b) => Assert.AreEqual((bool)a, (bool)b));
RunScalarTest<object>(MyEnum.First, (a, b) => Assert.AreEqual((MyEnum)a, (MyEnum)b));
}
[Test]
public void TestCyclic()
{
RunScalarTest(new RedBlackList {Start = new RedBlackList.BlackNode() {Next = new RedBlackList.RedNode()}}, (a, b) =>
{
Assert.NotNull(b.Start.Next);
Assert.Null(b.Start.Next.Next);
});
}
[Test]
public void TestInvalidPointers()
{
Assert.Throws<ArgumentException>(() => { RunScalarTest(new NonScalarPtr(), (a, b) => { }); });
}
public class NonScalarPtr
{
public Action X;
}
public sealed class RedBlackList
{
public BlackNode Start;
public sealed class BlackNode
{
public RedNode Next;
}
public sealed class RedNode
{
public BlackNode Next;
}
}
public void RunScalarTest<T>(T instance, Action<T, T> checkEqual)
{
var scalar = new ReflectionSerializers(CFacade.TypesCatalog);
var serializerPair = scalar.GetOrRegisterSerializerPair(typeof(T), true);
var reader = serializerPair.GetReader<T>();
var writer = serializerPair.GetWriter<T>();
using (var cookie = UnsafeWriter.NewThreadLocalWriter())
{
unsafe
{
writer(default, cookie.Writer, instance);
var unsafeReader = UnsafeReader.CreateReader(cookie.Data, cookie.Count);
var restored = reader(default, unsafeReader);
checkEqual(instance, restored);
}
}
}
[RdExt]
public class GenericStructExt : RdExtReflectionBindableBase
{
public IViewableProperty<TextControlOverridableValue<int>> IntStruct { get; }
public IViewableProperty<TextControlOverridableValue<MyEnum>> EnumStruct { get; }
}
[RdScalar]
public struct TextControlOverridableValue<T>
{
public TextControlOverridableValue(T original, T @override)
{
Original = original;
Override = @override;
}
public T Original;
public T Override;
}
[RdExt]
public class EventArgsExt : RdExtReflectionBindableBase
{
public IViewableProperty<MyEventArgs<int?>> Objects { get; }
}
[RdScalar]
public class MyEventArgs<T> : EventArgs
{
public T Value;
}
[RdExt]
public class ListObjectsExt : RdExtReflectionBindableBase
{
public IViewableProperty<ListOwner> Objects { get; }
}
[RdScalar] // not required
public class ListOwner
{
public List<ColorFields> Polymorphic;
public List<ColorFields[]> PolymorphicArray;
public List<int> Ints;
}
[RdExt]
public class ArraysExt : RdExtReflectionBindableBase
{
public IViewableProperty<int[]> IntArray { get; }
public IViewableProperty<int[][][]> ComplexArray { get; }
public IViewableProperty<(string, string)[]> ValueTupleArray { get; }
}
[RdExt]
public class ArraysExt2 : RdExtReflectionBindableBase
{
public IViewableProperty<ColorFields> Property { get; }
public IViewableProperty<ColorFields[]> PropertyArray { get; }
}
[RdExt]
public class ValueTuplesExt : RdExtReflectionBindableBase
{
public IViewableProperty<(string, string)> SimpleTuple { get; }
public IViewableProperty<(int, int, int, int, int, int, int, int, int, int, int, int, int)> NestedTuple { get; }
}
[RdExt]
public class ColorsExt : RdExtReflectionBindableBase
{
public RdProperty<ColorClass> Property { get; }
public IViewableMap<ColorFields, long> Map { get; }
public IViewableList<ColorStruct> List { get; }
}
[RdScalar] // not required
public struct ColorClass
{
public int Red { get; set; }
public int Green { get; set; }
public int Blue { get; set; }
}
[RdScalar] // not required
public struct ColorStruct
{
public int Red { get; set; }
public int Green { get; set; }
public int Blue { get; set; }
}
[RdScalar] // not required
public sealed class ColorFields
{
public int Red { get; }
public int Green { get; }
public int Blue { get; }
public ColorFields(int red, int green, int blue)
{
Red = red;
Green = green;
Blue = blue;
}
public ColorFields()
{
}
private bool Equals(ColorFields other)
{
return Red == other.Red;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((ColorFields) obj);
}
public override int GetHashCode()
{
return Red;
}
}
public class Scalar1
{
public string Name;
public Scalar2 Value;
}
public class Scalar2
{
public Scalar2(long value, int only)
{
Value = value;
SetOnly = only;
}
public long Value { get; set; }
public int SetOnly { get; }
}
}
}