public void ContractCollectionGarbageCollects() { var contractCollection = new ContractCollection(); var s1 = (Contract)contractCollection.GetOrAddReadContract(typeof(Person)); var s2 = (Contract)contractCollection.GetOrAddReadContract(typeof(Wrapper <Person>)); Assert.Equal(4, contractCollection.Contracts.Count); Assert.True(contractCollection.Contracts.Contains(s1)); Assert.True(contractCollection.Contracts.Contains(s2)); contractCollection.GarbageCollect(new[] { s2 }); Assert.Equal(4, contractCollection.Contracts.Count); Assert.True(contractCollection.Contracts.Contains(s1)); Assert.True(contractCollection.Contracts.Contains(s2)); contractCollection.GarbageCollect(new[] { s1 }); Assert.Equal(3, contractCollection.Contracts.Count); Assert.True(contractCollection.Contracts.Contains(s1)); Assert.False(contractCollection.Contracts.Contains(s2)); contractCollection.GarbageCollect(new Contract[0]); Assert.Equal(0, contractCollection.Contracts.Count); Assert.False(contractCollection.Contracts.Contains(s1)); Assert.False(contractCollection.Contracts.Contains(s2)); }
internal DictionaryReadContract(Type type, ContractCollection contractCollection) { if (!CanProcess(type)) { throw new ArgumentException($"Type {type} must be {nameof(IReadOnlyDictionary<int, int>)}<,>.", nameof(type)); } KeyContract = contractCollection.GetOrAddReadContract(type.GetGenericArguments()[0]); ValueContract = contractCollection.GetOrAddReadContract(type.GetGenericArguments()[1]); }
public void ContractCollection_ConsolidatesContracts() { var contractCollection = new ContractCollection(); var s1 = contractCollection.GetOrAddReadContract(typeof(Person)); var s2 = contractCollection.GetOrAddReadContract(typeof(Person)); Assert.Same(s1, s2); var s3 = contractCollection.GetOrAddReadContract(typeof(Wrapper <Person>)); Assert.Same(s2, ((Contract)s3).Children.Single()); }
internal NullableReadContract(Type type, ContractCollection contractCollection) { if (!CanProcess(type)) { throw new ArgumentException($"Type {type} must be nullable.", nameof(type)); } Inner = contractCollection.GetOrAddReadContract(Nullable.GetUnderlyingType(type)); }
internal ListReadContract(Type type, ContractCollection contractCollection) { if (!CanProcess(type)) { throw new ArgumentException($"Type {type} must be {nameof(IReadOnlyList<int>)}<>.", nameof(type)); } ItemContract = contractCollection.GetOrAddReadContract(type.GetGenericArguments().Single()); }
private static IReadOnlyList <TRead> Test <TWrite, TRead>(TWrite write, TRead read, bool matchIfRelaxed, bool matchIfStrict) { var contractCollection = new ContractCollection(); var w = contractCollection.GetOrAddWriteContract(typeof(TWrite)); var r = contractCollection.GetOrAddReadContract(typeof(TRead)); var actualMatchIfRelaxed = r.CanReadFrom(w, strict: false); var actualMatchIfStrict = r.CanReadFrom(w, strict: true); Assert.Equal(matchIfRelaxed, actualMatchIfRelaxed); Assert.Equal(matchIfStrict, actualMatchIfStrict); if (!actualMatchIfRelaxed && !actualMatchIfStrict) { return(new TRead[0]); } var stream = new MemoryStream(); new Serialiser <Wrapper <TWrite> >().Serialise(stream, new Wrapper <TWrite>(write)); var values = new List <TRead>(); if (actualMatchIfRelaxed) { stream.Position = 0; values.Add(new Deserialiser <Wrapper <TRead> >(UnexpectedFieldBehaviour.Ignore).Deserialise(stream).Value); } if (actualMatchIfStrict) { stream.Position = 0; values.Add(new Deserialiser <Wrapper <TRead> >(UnexpectedFieldBehaviour.Throw).Deserialise(stream).Value); } return(values); }
public void ContractEquality() { void Test(Type type) { var c1 = new ContractCollection(); var c2 = new ContractCollection(); var r1 = c1.GetOrAddReadContract(type); var r2 = c2.GetOrAddReadContract(type); var w1 = c1.GetOrAddWriteContract(type); var w2 = c2.GetOrAddWriteContract(type); Assert.Equal(r1, r2); Assert.Equal(r2, r1); Assert.Equal(r1.GetHashCode(), r2.GetHashCode()); Assert.Equal(w1, w2); Assert.Equal(w2, w1); Assert.Equal(w1.GetHashCode(), w2.GetHashCode()); } Test(typeof(Person)); Test(typeof(Wrapper <Person>)); Test(typeof(EnumAbc)); Test(typeof(int?)); Test(typeof(IReadOnlyList <EnumAbc>)); Test(typeof(IReadOnlyDictionary <EnumAbc, int?>)); Test(typeof(Tuple <int, long, double>)); Test(typeof(Union <int, long, double>)); Test(typeof(int)); Test(typeof(long)); Test(typeof(byte[])); Test(typeof(ArraySegment <byte>)); ////// var c = new ContractCollection(); // Intern Assert.Same(c.GetOrAddReadContract(typeof(int)), c.GetOrAddReadContract(typeof(int))); // Read and write same for some types Assert.Same(c.GetOrAddReadContract(typeof(int)), c.GetOrAddWriteContract(typeof(int))); Assert.Same(c.GetOrAddReadContract(typeof(double)), c.GetOrAddWriteContract(typeof(double))); Assert.Same(c.GetOrAddReadContract(typeof(EnumAbc)), c.GetOrAddWriteContract(typeof(EnumAbc))); Assert.Same(c.GetOrAddReadContract(typeof(int)), c.GetOrAddWriteContract(typeof(int))); Assert.Same(c.GetOrAddReadContract(typeof(Empty)), c.GetOrAddWriteContract(typeof(Empty))); // NOTE for some types, read and write contract are equal (can this cause trouble?) Assert.Equal((object)c.GetOrAddReadContract(typeof(int)), c.GetOrAddWriteContract(typeof(int))); Assert.Equal((object)c.GetOrAddReadContract(typeof(double)), c.GetOrAddWriteContract(typeof(double))); Assert.Equal((object)c.GetOrAddReadContract(typeof(EnumAbc)), c.GetOrAddWriteContract(typeof(EnumAbc))); Assert.Equal((object)c.GetOrAddReadContract(typeof(int)), c.GetOrAddWriteContract(typeof(int))); Assert.Equal((object)c.GetOrAddReadContract(typeof(Empty)), c.GetOrAddWriteContract(typeof(Empty))); var contracts = new object[] { c.GetOrAddReadContract(typeof(int)), c.GetOrAddReadContract(typeof(EnumAbc)), c.GetOrAddReadContract(typeof(EnumAbcd)), c.GetOrAddReadContract(typeof(double)), c.GetOrAddReadContract(typeof(Person)), c.GetOrAddWriteContract(typeof(Person)), c.GetOrAddReadContract(typeof(Wrapper <double>)), c.GetOrAddWriteContract(typeof(Wrapper <double>)) }; foreach (var contract in contracts) { Assert.Equal(1, contracts.Count(s => s.Equals(contract))); Assert.Equal(1, contracts.Count(s => s.GetHashCode().Equals(contract.GetHashCode()))); } }
public void ContractCollection_XmlRoundTrip() { var before = new ContractCollection(); before.GetOrAddReadContract(typeof(Person)); before.GetOrAddWriteContract(typeof(Person)); before.GetOrAddReadContract(typeof(Wrapper <Person>)); before.GetOrAddReadContract(typeof(EnumAbc)); before.GetOrAddWriteContract(typeof(EnumAbc)); before.GetOrAddReadContract(typeof(Wrapper <EnumAbc>)); before.GetOrAddReadContract(typeof(Union <int, string, Person, EnumAbcd>)); before.GetOrAddWriteContract(typeof(Union <int, string, Person, EnumAbcd>)); Assert.Equal(8, before.Contracts.OfType <ByRefContract>().Count()); before.UpdateByRefIds(); var xml = before.ToXml(); const string expectedXml = @"<Contracts> <ComplexRead Id=""Contract1""> <Field Name=""age"" Contract=""Int32"" IsRequired=""true"" /> <Field Name=""name"" Contract=""String"" IsRequired=""true"" /> </ComplexRead> <ComplexWrite Id=""Contract2""> <Field Name=""Age"" Contract=""Int32"" /> <Field Name=""Name"" Contract=""String"" /> </ComplexWrite> <ComplexRead Id=""Contract3""> <Field Name=""value"" Contract=""#Contract1"" IsRequired=""true"" /> </ComplexRead> <Enum Id=""Contract4""> <Member Name=""A"" /> <Member Name=""B"" /> <Member Name=""C"" /> </Enum> <ComplexRead Id=""Contract5""> <Field Name=""value"" Contract=""#Contract4"" IsRequired=""true"" /> </ComplexRead> <Enum Id=""Contract6""> <Member Name=""A"" /> <Member Name=""B"" /> <Member Name=""C"" /> <Member Name=""D"" /> </Enum> <UnionRead Id=""Contract7""> <Member Id=""Dasher.Tests.EnumAbcd"" Contract=""#Contract6"" /> <Member Id=""Dasher.Tests.Person"" Contract=""#Contract1"" /> <Member Id=""Int32"" Contract=""Int32"" /> <Member Id=""String"" Contract=""String"" /> </UnionRead> <UnionWrite Id=""Contract8""> <Member Id=""Dasher.Tests.EnumAbcd"" Contract=""#Contract6"" /> <Member Id=""Dasher.Tests.Person"" Contract=""#Contract2"" /> <Member Id=""Int32"" Contract=""Int32"" /> <Member Id=""String"" Contract=""String"" /> </UnionWrite> </Contracts>"; var actualXml = xml.ToString(); _output.WriteLine(actualXml); Assert.Equal(expectedXml, actualXml, new SelectiveStringComparer()); Assert.Equal(8, xml.Elements().Count()); var after = ContractCollection.FromXml(xml); Assert.True(new HashSet <Contract>(before.Contracts).SetEquals(new HashSet <Contract>(after.Contracts))); Assert.Equal(before.Contracts.Count, after.Contracts.Count); foreach (var b in before.Contracts) { Assert.Equal(1, after.Contracts.Count(s => s.Equals(b))); } foreach (var a in after.Contracts) { Assert.Equal(1, before.Contracts.Count(s => s.Equals(a))); } }