From b308580bb1c3f87a062ac1448a3e0bdaab9d40cf Mon Sep 17 00:00:00 2001 From: Jie Luo Date: Tue, 19 Dec 2017 11:54:11 -0800 Subject: Cherrypick for csharp, including: Add preserve UnknownFields Compare floating point values bitwise Add auto-generated header to C# generated files --- .../Collections/MapFieldTest.cs | 43 +++++++ .../Collections/ProtobufEqualityComparersTest.cs | 124 +++++++++++++++++++++ .../Collections/RepeatedFieldTest.cs | 13 +++ 3 files changed, 180 insertions(+) create mode 100644 csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs (limited to 'csharp/src/Google.Protobuf.Test/Collections') diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs index 68b4de45..8791dffc 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs @@ -540,6 +540,49 @@ namespace Google.Protobuf.Collections Assert.Throws(() => map.ToString()); } + [Test] + public void NaNValuesComparedBitwise() + { + var map1 = new MapField + { + { "x", SampleNaNs.Regular }, + { "y", SampleNaNs.SignallingFlipped } + }; + + var map2 = new MapField + { + { "x", SampleNaNs.Regular }, + { "y", SampleNaNs.PayloadFlipped } + }; + + var map3 = new MapField + { + { "x", SampleNaNs.Regular }, + { "y", SampleNaNs.SignallingFlipped } + }; + + EqualityTester.AssertInequality(map1, map2); + EqualityTester.AssertEquality(map1, map3); + Assert.True(map1.Values.Contains(SampleNaNs.SignallingFlipped)); + Assert.False(map2.Values.Contains(SampleNaNs.SignallingFlipped)); + } + + // This wouldn't usually happen, as protos can't use doubles as map keys, + // but let's be consistent. + [Test] + public void NaNKeysComparedBitwise() + { + var map = new MapField + { + { SampleNaNs.Regular, "x" }, + { SampleNaNs.SignallingFlipped, "y" } + }; + Assert.AreEqual("x", map[SampleNaNs.Regular]); + Assert.AreEqual("y", map[SampleNaNs.SignallingFlipped]); + string ignored; + Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out ignored)); + } + #if !NET35 [Test] public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys() diff --git a/csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs b/csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs new file mode 100644 index 00000000..c76d7ca1 --- /dev/null +++ b/csharp/src/Google.Protobuf.Test/Collections/ProtobufEqualityComparersTest.cs @@ -0,0 +1,124 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2017 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using NUnit.Framework; +using System.Collections.Generic; +using System.Linq; +using static Google.Protobuf.Collections.ProtobufEqualityComparers; + +namespace Google.Protobuf.Collections +{ + public class ProtobufEqualityComparersTest + { + private static readonly double[] doubles = + { + 0, + 1, + 1.5, + -1.5, + double.PositiveInfinity, + double.NegativeInfinity, + // Three different types of NaN... + SampleNaNs.Regular, + SampleNaNs.SignallingFlipped, + SampleNaNs.PayloadFlipped + }; + + [Test] + public void GetEqualityComparer_Default() + { + // It's more pain than it's worth to try to parameterize these tests. + Assert.AreSame(EqualityComparer.Default, GetEqualityComparer()); + Assert.AreSame(EqualityComparer.Default, GetEqualityComparer()); + Assert.AreSame(EqualityComparer.Default, GetEqualityComparer()); + Assert.AreSame(EqualityComparer.Default, GetEqualityComparer()); + } + + [Test] + public void GetEqualityComparer_NotDefault() + { + // It's more pain than it's worth to try to parameterize these tests. + Assert.AreSame(BitwiseDoubleEqualityComparer, GetEqualityComparer()); + Assert.AreSame(BitwiseSingleEqualityComparer, GetEqualityComparer()); + Assert.AreSame(BitwiseNullableDoubleEqualityComparer, GetEqualityComparer()); + Assert.AreSame(BitwiseNullableSingleEqualityComparer, GetEqualityComparer()); + } + + [Test] + public void DoubleComparisons() + { + ValidateEqualityComparer(BitwiseDoubleEqualityComparer, doubles); + } + + [Test] + public void NullableDoubleComparisons() + { + ValidateEqualityComparer(BitwiseNullableDoubleEqualityComparer, doubles.Select(d => (double?) d).Concat(new double?[] { null })); + } + + [Test] + public void SingleComparisons() + { + ValidateEqualityComparer(BitwiseSingleEqualityComparer, doubles.Select(d => (float) d)); + } + + [Test] + public void NullableSingleComparisons() + { + ValidateEqualityComparer(BitwiseNullableSingleEqualityComparer, doubles.Select(d => (float?) d).Concat(new float?[] { null })); + } + + private static void ValidateEqualityComparer(EqualityComparer comparer, IEnumerable values) + { + var array = values.ToArray(); + // Each value should be equal to itself, but not to any other value. + for (int i = 0; i < array.Length; i++) + { + for (int j = 0; j < array.Length; j++) + { + if (i == j) + { + Assert.IsTrue(comparer.Equals(array[i], array[j]), + "{0} should be equal to itself", array[i], array[j]); + } + else + { + Assert.IsFalse(comparer.Equals(array[i], array[j]), + "{0} and {1} should not be equal", array[i], array[j]); + Assert.AreNotEqual(comparer.GetHashCode(array[i]), comparer.GetHashCode(array[j]), + "Hash codes for {0} and {1} should not be equal", array[i], array[j]); + } + } + } + } + } +} diff --git a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs index 6852f75f..129923b6 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs @@ -742,5 +742,18 @@ namespace Google.Protobuf.Collections var text = list.ToString(); Assert.AreEqual(text, "[ { \"foo\": 20 } ]", message.ToString()); } + + [Test] + public void NaNValuesComparedBitwise() + { + var list1 = new RepeatedField { SampleNaNs.Regular, SampleNaNs.SignallingFlipped }; + var list2 = new RepeatedField { SampleNaNs.Regular, SampleNaNs.PayloadFlipped }; + var list3 = new RepeatedField { SampleNaNs.Regular, SampleNaNs.SignallingFlipped }; + + EqualityTester.AssertInequality(list1, list2); + EqualityTester.AssertEquality(list1, list3); + Assert.True(list1.Contains(SampleNaNs.SignallingFlipped)); + Assert.False(list2.Contains(SampleNaNs.SignallingFlipped)); + } } } -- cgit v1.2.3