From d61199d8f2f01d1471bcefaca4b7420037dd6f6c Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Tue, 6 Aug 2019 11:40:36 -0700 Subject: [PATCH 01/16] API to implement added --- .../src/System/Text/Json/Node/JsonBoolean.cs | 28 ++++++++++++++++++ .../src/System/Text/Json/Node/JsonNode.cs | 14 +++++++++ .../src/System/Text/Json/Node/JsonString.cs | 29 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs new file mode 100644 index 000000000000..c0768d810fdb --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// for now disabling error caused by not adding documentation to methods +#pragma warning disable CS1591 + +namespace System.Text.Json +{ + public partial class JsonBoolean : JsonNode, IEquatable + { + public JsonBoolean() { } + public JsonBoolean(bool value) { } + + public bool Value { get; set; } + + public static implicit operator JsonBoolean(bool value) { throw null; } + + public override bool Equals(object obj) { throw null; } + public override int GetHashCode() { throw null; } + + public bool Equals(JsonBoolean other) { throw null; } + + public static bool operator ==(JsonBoolean left, JsonBoolean right) => throw null; + public static bool operator !=(JsonBoolean left, JsonBoolean right) => throw null; + } +} +#pragma warning restore CS1591 diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs new file mode 100644 index 000000000000..8b40fec4b3c8 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Text.Json +{ + /// + /// The base class that represents a single node within a JSON document. + /// + public abstract class JsonNode + { + private protected JsonNode() { } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs new file mode 100644 index 000000000000..99c701c50ece --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// for now disabling error caused by not adding documentation to methods +#pragma warning disable CS1591 + +namespace System.Text.Json +{ + public partial class JsonString : JsonNode, IEquatable + { + public JsonString() { } + public JsonString(string value) { } + + public string Value { get; set; } + + public static implicit operator JsonString(string value) { throw null; } + + public override bool Equals(object obj) { throw null; } + public override int GetHashCode() { throw null; } + + public bool Equals(JsonString other) { throw null; } + + public static bool operator ==(JsonString left, JsonString right) => throw null; + public static bool operator !=(JsonString left, JsonString right) => throw null; + } +} + +#pragma warning restore CS1591 From 521f115e4dc0fa92113f350acd1869f4a991091c Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Tue, 6 Aug 2019 11:53:14 -0700 Subject: [PATCH 02/16] JsonBoolean implementation added --- .../src/System/Text/Json/Node/JsonBoolean.cs | 77 ++++++++++++++++--- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index c0768d810fdb..e066e0fa34fc 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -2,27 +2,80 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// for now disabling error caused by not adding documentation to methods -#pragma warning disable CS1591 - namespace System.Text.Json { + /// + /// Represents a boolean JSON value. + /// public partial class JsonBoolean : JsonNode, IEquatable { - public JsonBoolean() { } - public JsonBoolean(bool value) { } + /// + /// Initializes a new instance of the class representing the value . + /// + public JsonBoolean() => Value = false; + + /// + /// Initializes a new instance of the class representing a specified value. + /// + public JsonBoolean(bool value) => Value = value; + /// + /// Gets or sets the boolean value represented by the instance. + /// public bool Value { get; set; } - public static implicit operator JsonBoolean(bool value) { throw null; } + /// + /// Converts a to a JSON boolean. + /// + /// The value to convert. + public static implicit operator JsonBoolean(bool value) => new JsonBoolean(value); + + /// + /// Compares to the value of this instance. + /// + /// The object to compare against. + /// + /// if the boolean value of this instance matches , + /// otherwise. + /// + public override bool Equals(object obj) => obj is JsonBoolean jsonBoolean && Value == jsonBoolean.Value; + + /// + /// Calculates a hash code of this instance. + /// + /// A hash code for this instance. + public override int GetHashCode() => Value.GetHashCode(); - public override bool Equals(object obj) { throw null; } - public override int GetHashCode() { throw null; } + /// + /// Compares other JSON boolean to the value of this instance. + /// + /// The JSON boolean to compare against. + /// + /// if the boolean value of this instance matches , + /// otherwise. + /// + public bool Equals(JsonBoolean other) => !(other is null) && Value == other.Value; - public bool Equals(JsonBoolean other) { throw null; } + /// + /// Compares values of two JSON booleans. + /// + /// The JSON boolean to compare. + /// The JSON boolean to compare. + /// + /// if values of instances match, + /// otherwise. + /// + public static bool operator ==(JsonBoolean left, JsonBoolean right) => left?.Value == right?.Value; - public static bool operator ==(JsonBoolean left, JsonBoolean right) => throw null; - public static bool operator !=(JsonBoolean left, JsonBoolean right) => throw null; + /// + /// Compares values of two JSON booleans. + /// + /// The JSON boolean to compare. + /// The JSON boolean to compare. + /// + /// if values of instances do not match, + /// otherwise. + /// + public static bool operator !=(JsonBoolean left, JsonBoolean right) => left?.Value != right?.Value; } } -#pragma warning restore CS1591 From 2c63fe8260576a518d15727841752294d54db21a Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Tue, 6 Aug 2019 11:58:29 -0700 Subject: [PATCH 03/16] JsonString implementation added --- .../src/System/Text/Json/Node/JsonString.cs | 78 +++++++++++++++---- 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs index 99c701c50ece..aa10076a843c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -2,28 +2,80 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// for now disabling error caused by not adding documentation to methods -#pragma warning disable CS1591 - namespace System.Text.Json { + /// + /// Represents a text JSON value. + /// public partial class JsonString : JsonNode, IEquatable { - public JsonString() { } - public JsonString(string value) { } + /// + /// Initializes a new instance of the class representing the empty value. + /// + public JsonString() => Value = ""; + + /// + /// Initializes a new instance of the class representing a specified value. + /// + public JsonString(string value) => Value = value; + /// + /// Gets or sets the text value represented by the instance. + /// public string Value { get; set; } - public static implicit operator JsonString(string value) { throw null; } + /// + /// Converts a to a JSON string. + /// + /// The value to convert. + public static implicit operator JsonString(string value) => new JsonString(value); + + /// + /// Compares to the value of this instance. + /// + /// The object to compare against. + /// + /// if the text value of this instance matches , + /// otherwise. + /// + public override bool Equals(object obj) => obj is JsonString jsonString && Value == jsonString.Value; - public override bool Equals(object obj) { throw null; } - public override int GetHashCode() { throw null; } + /// + /// Calculates a hash code of this instance. + /// + /// A hash code for this instance. + public override int GetHashCode() => Value.GetHashCode(); - public bool Equals(JsonString other) { throw null; } + /// + /// Compares other JSON string to the value of this instance. + /// + /// The JSON string to compare against. + /// + /// if the text value of this instance matches , + /// otherwise. + /// + public bool Equals(JsonString other) => !(other is null) && Value == other.Value; - public static bool operator ==(JsonString left, JsonString right) => throw null; - public static bool operator !=(JsonString left, JsonString right) => throw null; + /// + /// Compares values of two JSON strings. + /// + /// The JSON string to compare. + /// The JSON string to compare. + /// + /// if values of instances match, + /// otherwise. + /// + public static bool operator ==(JsonString left, JsonString right) => left?.Value == right?.Value; + + /// + /// Compares values of two JSON strings. + /// + /// The JSON string to compare. + /// The JSON string to compare. + /// + /// if values of instances do not match, + /// otherwise. + /// + public static bool operator !=(JsonString left, JsonString right) => left?.Value != right?.Value; } } - -#pragma warning restore CS1591 From f2c537d38a4067df1043c03ee2ace5d8d6e3a6e2 Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Tue, 6 Aug 2019 13:21:56 -0700 Subject: [PATCH 04/16] JsonBoolean tests added --- src/System.Text.Json/ref/System.Text.Json.cs | 28 +++++ .../src/System.Text.Json.csproj | 3 + .../tests/JsonBooleanTests.cs | 117 ++++++++++++++++++ .../tests/System.Text.Json.Tests.csproj | 1 + 4 files changed, 149 insertions(+) create mode 100644 src/System.Text.Json/tests/JsonBooleanTests.cs diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index c9560f4e005e..bd309ede50fa 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -7,6 +7,18 @@ namespace System.Text.Json { + public partial class JsonBoolean : System.Text.Json.JsonNode, System.IEquatable + { + public JsonBoolean() { } + public JsonBoolean(bool value) { } + public bool Value { get { throw null; } set { } } + public override bool Equals(object obj) { throw null; } + public bool Equals(System.Text.Json.JsonBoolean other) { throw null; } + public override int GetHashCode() { throw null; } + public static bool operator ==(System.Text.Json.JsonBoolean left, System.Text.Json.JsonBoolean right) { throw null; } + public static implicit operator System.Text.Json.JsonBoolean (bool value) { throw null; } + public static bool operator !=(System.Text.Json.JsonBoolean left, System.Text.Json.JsonBoolean right) { throw null; } + } public enum JsonCommentHandling : byte { Disallow = (byte)0, @@ -156,6 +168,10 @@ protected JsonNamingPolicy() { } public static System.Text.Json.JsonNamingPolicy CamelCase { get { throw null; } } public abstract string ConvertName(string name); } + public abstract partial class JsonNode + { + internal JsonNode() { } + } public readonly partial struct JsonProperty { private readonly object _dummy; @@ -217,6 +233,18 @@ public JsonSerializerOptions() { } public bool WriteIndented { get { throw null; } set { } } public System.Text.Json.Serialization.JsonConverter GetConverter(System.Type typeToConvert) { throw null; } } + public partial class JsonString : System.Text.Json.JsonNode, System.IEquatable + { + public JsonString() { } + public JsonString(string value) { } + public string Value { get { throw null; } set { } } + public override bool Equals(object obj) { throw null; } + public bool Equals(System.Text.Json.JsonString other) { throw null; } + public override int GetHashCode() { throw null; } + public static bool operator ==(System.Text.Json.JsonString left, System.Text.Json.JsonString right) { throw null; } + public static implicit operator System.Text.Json.JsonString (string value) { throw null; } + public static bool operator !=(System.Text.Json.JsonString left, System.Text.Json.JsonString right) { throw null; } + } public enum JsonTokenType : byte { None = (byte)0, diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index 8d2f4ddc7fb4..20538446f71c 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -23,6 +23,9 @@ + + + diff --git a/src/System.Text.Json/tests/JsonBooleanTests.cs b/src/System.Text.Json/tests/JsonBooleanTests.cs new file mode 100644 index 000000000000..b12fe7e7e03b --- /dev/null +++ b/src/System.Text.Json/tests/JsonBooleanTests.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.Text.Json.Tests +{ + public static class JsonBooleanTests + { + [Fact] + public static void TestDefaultCtor() + { + var jsonBoolean = new JsonBoolean(); + Assert.False(jsonBoolean.Value); + } + + [Fact] + public static void TestValueCtor() + { + var jsonBoolean = new JsonBoolean(true); + Assert.True(jsonBoolean.Value); + + jsonBoolean = new JsonBoolean(false); + Assert.False(jsonBoolean.Value); + } + + [Fact] + public static void TestChangingValue() + { + var jsonBoolean = new JsonBoolean(); + jsonBoolean.Value = true; + Assert.True(jsonBoolean.Value); + jsonBoolean.Value = false; + Assert.False(jsonBoolean.Value); + } + + [Fact] + public static void TestEquals() + { + var jsonBooleanTrue = new JsonBoolean(true); + var jsonBooleanFalse = new JsonBoolean(false); + + Assert.True(jsonBooleanTrue.Equals(new JsonBoolean(true))); + Assert.True(new JsonBoolean(true).Equals(jsonBooleanTrue)); + + Assert.True(jsonBooleanFalse.Equals(new JsonBoolean(false))); + Assert.True(new JsonBoolean(false).Equals(jsonBooleanFalse)); + Assert.True(new JsonBoolean().Equals(jsonBooleanFalse)); + Assert.False(new JsonBoolean().Equals(jsonBooleanTrue)); + + Assert.True(jsonBooleanTrue == new JsonBoolean(true)); + Assert.True(jsonBooleanTrue != jsonBooleanFalse); + + JsonNode jsonNodeTrue = new JsonBoolean(true); + Assert.True(jsonBooleanTrue.Equals(jsonNodeTrue)); + + JsonNode jsonNodeFalse= new JsonBoolean(false); + Assert.True(jsonBooleanFalse.Equals(jsonNodeFalse)); + + IEquatable jsonBooleanIEquatableTrue = jsonBooleanTrue; + Assert.True(jsonBooleanIEquatableTrue.Equals(jsonBooleanTrue)); + Assert.True(jsonBooleanTrue.Equals(jsonBooleanIEquatableTrue)); + + IEquatable jsonBooleanIEquatableFalse = jsonBooleanFalse; + Assert.True(jsonBooleanIEquatableFalse.Equals(jsonBooleanFalse)); + Assert.True(jsonBooleanFalse.Equals(jsonBooleanIEquatableFalse)); + + Assert.False(jsonBooleanTrue.Equals(null)); + + object jsonNumberCopyTrue = jsonBooleanTrue; + object jsonNumberObjectTrue = new JsonBoolean(true); + Assert.True(jsonNumberCopyTrue.Equals(jsonNumberObjectTrue)); + Assert.True(jsonNumberCopyTrue.Equals(jsonNumberObjectTrue)); + Assert.True(jsonNumberObjectTrue.Equals(jsonBooleanTrue)); + + object jsonNumberCopyFalse = jsonBooleanFalse; + object jsonNumberObjectFalse = new JsonBoolean(false); + Assert.True(jsonNumberCopyFalse.Equals(jsonNumberObjectFalse)); + Assert.True(jsonNumberCopyFalse.Equals(jsonBooleanFalse)); + Assert.True(jsonNumberObjectFalse.Equals(jsonBooleanFalse)); + } + + [Fact] + public static void TestGetHashCode() + { + var jsonBooleanTrue = new JsonBoolean(true); + var jsonBooleanFalse = new JsonBoolean(false); + + Assert.Equal(jsonBooleanTrue.GetHashCode(), new JsonBoolean(true).GetHashCode()); + Assert.Equal(jsonBooleanFalse.GetHashCode(), new JsonBoolean(false).GetHashCode()); + Assert.Equal(jsonBooleanFalse.GetHashCode(), new JsonBoolean().GetHashCode()); + Assert.NotEqual(jsonBooleanTrue.GetHashCode(), new JsonBoolean().GetHashCode()); + + JsonNode jsonNodeTrue = new JsonBoolean(true); + Assert.Equal(jsonBooleanTrue.GetHashCode(), jsonNodeTrue.GetHashCode()); + JsonNode jsonNodeFalse = new JsonBoolean(false); + Assert.Equal(jsonBooleanFalse.GetHashCode(), jsonNodeFalse.GetHashCode()); + + IEquatable jsonBooleanIEquatableTrue = jsonBooleanTrue; + Assert.Equal(jsonBooleanIEquatableTrue.GetHashCode(), jsonBooleanTrue.GetHashCode()); + + IEquatable jsonBooleanIEquatableFalse = jsonBooleanFalse; + Assert.Equal(jsonBooleanIEquatableFalse.GetHashCode(), jsonBooleanFalse.GetHashCode()); + + object jsonNumberCopyTrue = jsonBooleanTrue; + object jsonNumberObjectTrue = new JsonBoolean(true); + Assert.Equal(jsonBooleanTrue.GetHashCode(), jsonNumberCopyTrue.GetHashCode()); + Assert.Equal(jsonBooleanTrue.GetHashCode(), jsonNumberObjectTrue.GetHashCode()); + + object jsonNumberCopyFalse = jsonBooleanFalse; + object jsonNumberObjectFalse = new JsonBoolean(false); + Assert.Equal(jsonNumberCopyFalse.GetHashCode(), jsonBooleanFalse.GetHashCode()); + Assert.Equal(jsonNumberObjectFalse.GetHashCode(), jsonBooleanFalse.GetHashCode()); + } + } +} diff --git a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj index c60ca78db8fe..d433333a6953 100644 --- a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -15,6 +15,7 @@ + From 681ce39a7064dd9cd1389eb320662bb1489aefbb Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Tue, 6 Aug 2019 14:20:29 -0700 Subject: [PATCH 05/16] JsonString implementation started --- src/System.Text.Json/tests/JsonStringTests.cs | 35 +++++++++++++++++++ .../tests/System.Text.Json.Tests.csproj | 1 + 2 files changed, 36 insertions(+) create mode 100644 src/System.Text.Json/tests/JsonStringTests.cs diff --git a/src/System.Text.Json/tests/JsonStringTests.cs b/src/System.Text.Json/tests/JsonStringTests.cs new file mode 100644 index 000000000000..c8b231b64d18 --- /dev/null +++ b/src/System.Text.Json/tests/JsonStringTests.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.Text.Json.Tests +{ + public static class JsonStringTests + { + [Fact] + public static void TestDefaultCtor() + { + var jsonString = new JsonString(); + Assert.Equal("", jsonString.Value); + } + + [Fact] + public static void TestValueCtor() + { + var jsonString = new JsonString("property value"); + Assert.Equal("property value", jsonString.Value); + } + + [Fact] + public static void TestChangingValue() + { + var jsonString = new JsonString(); + jsonString.Value = "property value"; + Assert.Equal("property value", jsonString.Value); + jsonString.Value = "different property value"; + Assert.Equal("different property value", jsonString.Value); + } + } +} diff --git a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj index d433333a6953..51441f253d9d 100644 --- a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -25,6 +25,7 @@ + From c6f27882a28bced8c28a202498b22c77cb78512b Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Wed, 7 Aug 2019 11:00:50 -0700 Subject: [PATCH 06/16] more tests added, csproj files fixes --- .../src/System.Text.Json.csproj | 8 +- .../tests/JsonBooleanTests.cs | 19 ++++ src/System.Text.Json/tests/JsonStringTests.cs | 101 +++++++++++++++++- .../tests/System.Text.Json.Tests.csproj | 6 +- 4 files changed, 125 insertions(+), 9 deletions(-) diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index 20538446f71c..c695003b535d 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -23,9 +23,6 @@ - - - @@ -211,4 +208,9 @@ + + + + + diff --git a/src/System.Text.Json/tests/JsonBooleanTests.cs b/src/System.Text.Json/tests/JsonBooleanTests.cs index b12fe7e7e03b..7052df1aeeb3 100644 --- a/src/System.Text.Json/tests/JsonBooleanTests.cs +++ b/src/System.Text.Json/tests/JsonBooleanTests.cs @@ -25,6 +25,16 @@ public static void TestValueCtor() Assert.False(jsonBoolean.Value); } + [Fact] + public static void TestImplicitOperator() + { + JsonBoolean jsonBoolean = true; + Assert.True(jsonBoolean.Value); + + jsonBoolean = false; + Assert.False(jsonBoolean.Value); + } + [Fact] public static void TestChangingValue() { @@ -79,6 +89,15 @@ public static void TestEquals() Assert.True(jsonNumberCopyFalse.Equals(jsonNumberObjectFalse)); Assert.True(jsonNumberCopyFalse.Equals(jsonBooleanFalse)); Assert.True(jsonNumberObjectFalse.Equals(jsonBooleanFalse)); + + Assert.False(jsonBooleanTrue.Equals(new Exception())); + + JsonBoolean jsonBooleanNull = null; + Assert.False(jsonBooleanTrue == jsonBooleanNull); + Assert.False(jsonBooleanNull == jsonBooleanTrue); + + Assert.True(jsonBooleanTrue != jsonBooleanNull); + Assert.True(jsonBooleanNull != jsonBooleanTrue); } [Fact] diff --git a/src/System.Text.Json/tests/JsonStringTests.cs b/src/System.Text.Json/tests/JsonStringTests.cs index c8b231b64d18..5133c970af9a 100644 --- a/src/System.Text.Json/tests/JsonStringTests.cs +++ b/src/System.Text.Json/tests/JsonStringTests.cs @@ -15,11 +15,28 @@ public static void TestDefaultCtor() Assert.Equal("", jsonString.Value); } - [Fact] - public static void TestValueCtor() + [InlineData("value")] + [InlineData("value with some spaces")] + [InlineData(" training spaces")] + [InlineData("new lines\r\n")] + [InlineData("tabs\ttabs\t")] + [InlineData("\\u003e\\u003e\\u003e\\u003e\\u003e")] + [InlineData("zażółć gęślą jaźń")] + [InlineData("汉字 漢字")] + [InlineData("Here is a string: \\\"\\\"\":\"Here is a\",\"Here is a back slash\\\\\":[\"Multiline\\r\\n String\\r\\n\",\"\\tMul\\r\\ntiline String\",\"\\\"somequote\\\"\\tMu\\\"\\\"l\\r\\ntiline\\\"another\\\" String\\\\\"],\"str")] + [InlineData("Hello / a / b / c \\/ \\r\\b\\n\\f\\t\\/")] + [Theory] + public static void TestInitialization(string value) { - var jsonString = new JsonString("property value"); - Assert.Equal("property value", jsonString.Value); + var jsonString = new JsonString(value); + Assert.Equal(value, jsonString.Value); + + var defaultlyInitializedJsonString = new JsonString(); + defaultlyInitializedJsonString.Value = value; + Assert.Equal(value, defaultlyInitializedJsonString.Value); + + JsonString implicitlyInitializiedJsonString = value; + Assert.Equal(value, implicitlyInitializiedJsonString.Value); } [Fact] @@ -31,5 +48,81 @@ public static void TestChangingValue() jsonString.Value = "different property value"; Assert.Equal("different property value", jsonString.Value); } + + [Fact] + public static void TestEquals() + { + var jsonString = new JsonString("json property value"); + + Assert.True(jsonString.Equals(new JsonString("json property value"))); + Assert.True(new JsonString("json property value").Equals(jsonString)); + + Assert.False(jsonString.Equals(new JsonString("jsonpropertyvalue"))); + Assert.False(jsonString.Equals(new JsonString("Json Property Value"))); + Assert.False(new JsonString("jsonpropertyvalue").Equals(jsonString)); + Assert.False(new JsonString("Json Property Value").Equals(jsonString)); + + Assert.True(jsonString == new JsonString("json property value")); + Assert.True(jsonString != new JsonString("something different")); + + JsonNode jsonNode = new JsonString("json property value"); + Assert.True(jsonString.Equals(jsonNode)); + + IEquatable jsonStringIEquatable = jsonString; + Assert.True(jsonStringIEquatable.Equals(jsonString)); + Assert.True(jsonString.Equals(jsonStringIEquatable)); + + Assert.False(jsonString.Equals(null)); + + object jsonStringCopy = jsonString; + object jsonStringObject = new JsonString("json property value"); + Assert.True(jsonString.Equals(jsonStringObject)); + Assert.True(jsonStringCopy.Equals(jsonStringObject)); + Assert.True(jsonStringObject.Equals(jsonString)); + + jsonString = new JsonString(); + Assert.True(jsonString.Equals(new JsonString())); + Assert.True(jsonString.Equals(new JsonString(""))); + Assert.False(jsonString.Equals(new JsonString("something not empty"))); + + Assert.False(jsonString.Equals(new Exception())); + Assert.False(jsonString.Equals(new JsonBoolean())); + Assert.False(new JsonString("true").Equals(new JsonBoolean(true))); + + JsonString jsonStringNull = null; + Assert.False(jsonString == jsonStringNull); + Assert.False(jsonStringNull == jsonString); + + Assert.True(jsonString != jsonStringNull); + Assert.True(jsonStringNull != jsonString); + } + + [Fact] + public static void TestGetHashCode() + { + var jsonString = new JsonString("json property value"); + + Assert.Equal(jsonString.GetHashCode(), new JsonString("json property value").GetHashCode()); + Assert.NotEqual(jsonString.GetHashCode(), new JsonString("json property value ").GetHashCode()); + Assert.NotEqual(jsonString.GetHashCode(), new JsonString("jsonpropertyvalue").GetHashCode()); + Assert.NotEqual(jsonString.GetHashCode(), new JsonString("Json Property Value").GetHashCode()); + Assert.NotEqual(jsonString.GetHashCode(), new JsonString("SOMETHING COMPLETELY DIFFERENT").GetHashCode()); + Assert.NotEqual(jsonString.GetHashCode(), new JsonString("").GetHashCode()); + Assert.NotEqual(jsonString.GetHashCode(), new JsonString().GetHashCode()); + + JsonNode jsonNode = new JsonString("json property value"); + Assert.Equal(jsonString.GetHashCode(), jsonNode.GetHashCode()); + + IEquatable jsonStringIEquatable = jsonString; + Assert.Equal(jsonString.GetHashCode(), jsonStringIEquatable.GetHashCode()); + + object jsonNumberCopy = jsonString; + object jsonNumberObject = new JsonString("something different"); + + Assert.Equal(jsonString.GetHashCode(), jsonNumberCopy.GetHashCode()); + Assert.NotEqual(jsonString.GetHashCode(), jsonNumberObject.GetHashCode()); + + Assert.Equal(new JsonString().GetHashCode(), new JsonString().GetHashCode()); + } } } diff --git a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj index 51441f253d9d..c0d6af2b1128 100644 --- a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -15,7 +15,6 @@ - @@ -25,7 +24,6 @@ - @@ -115,4 +113,8 @@ + + + + From 628660fc257b70f77839d483cfafee87223a82f4 Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Wed, 7 Aug 2019 11:12:07 -0700 Subject: [PATCH 07/16] minor changes --- src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs | 2 +- src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index e066e0fa34fc..3846048bb098 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -7,7 +7,7 @@ namespace System.Text.Json /// /// Represents a boolean JSON value. /// - public partial class JsonBoolean : JsonNode, IEquatable + public class JsonBoolean : JsonNode, IEquatable { /// /// Initializes a new instance of the class representing the value . diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs index aa10076a843c..304b7ae6394d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -7,7 +7,7 @@ namespace System.Text.Json /// /// Represents a text JSON value. /// - public partial class JsonString : JsonNode, IEquatable + public class JsonString : JsonNode, IEquatable { /// /// Initializes a new instance of the class representing the empty value. From 47530741f01e9640415ad60c358af240df02c996 Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Thu, 8 Aug 2019 08:44:23 -0700 Subject: [PATCH 08/16] work on review comments --- src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs | 2 +- src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index 3846048bb098..7d6761160d8f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -7,7 +7,7 @@ namespace System.Text.Json /// /// Represents a boolean JSON value. /// - public class JsonBoolean : JsonNode, IEquatable + public sealed class JsonBoolean : JsonNode, IEquatable { /// /// Initializes a new instance of the class representing the value . diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs index 304b7ae6394d..35e5779f7b27 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -7,7 +7,7 @@ namespace System.Text.Json /// /// Represents a text JSON value. /// - public class JsonString : JsonNode, IEquatable + public sealed class JsonString : JsonNode, IEquatable { /// /// Initializes a new instance of the class representing the empty value. @@ -17,7 +17,7 @@ public class JsonString : JsonNode, IEquatable /// /// Initializes a new instance of the class representing a specified value. /// - public JsonString(string value) => Value = value; + public JsonString(string value) => Value = value ?? throw new ArgumentNullException(); /// /// Gets or sets the text value represented by the instance. From af79bec4d490fa178bbbe3a7c43d228c02040b6b Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Thu, 8 Aug 2019 10:12:28 -0700 Subject: [PATCH 09/16] trailing whitespaces fixes --- .../src/System/Text/Json/Node/JsonBoolean.cs | 8 ++++---- .../src/System/Text/Json/Node/JsonString.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index 7d6761160d8f..b36ae708058f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -31,7 +31,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable public static implicit operator JsonBoolean(bool value) => new JsonBoolean(value); /// - /// Compares to the value of this instance. + /// Compares to the value of this instance. /// /// The object to compare against. /// @@ -47,7 +47,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable public override int GetHashCode() => Value.GetHashCode(); /// - /// Compares other JSON boolean to the value of this instance. + /// Compares other JSON boolean to the value of this instance. /// /// The JSON boolean to compare against. /// @@ -57,7 +57,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable public bool Equals(JsonBoolean other) => !(other is null) && Value == other.Value; /// - /// Compares values of two JSON booleans. + /// Compares values of two JSON booleans. /// /// The JSON boolean to compare. /// The JSON boolean to compare. @@ -68,7 +68,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable public static bool operator ==(JsonBoolean left, JsonBoolean right) => left?.Value == right?.Value; /// - /// Compares values of two JSON booleans. + /// Compares values of two JSON booleans. /// /// The JSON boolean to compare. /// The JSON boolean to compare. diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs index 35e5779f7b27..81dfd79e8704 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -31,7 +31,7 @@ public sealed class JsonString : JsonNode, IEquatable public static implicit operator JsonString(string value) => new JsonString(value); /// - /// Compares to the value of this instance. + /// Compares to the value of this instance. /// /// The object to compare against. /// @@ -47,7 +47,7 @@ public sealed class JsonString : JsonNode, IEquatable public override int GetHashCode() => Value.GetHashCode(); /// - /// Compares other JSON string to the value of this instance. + /// Compares other JSON string to the value of this instance. /// /// The JSON string to compare against. /// @@ -57,7 +57,7 @@ public sealed class JsonString : JsonNode, IEquatable public bool Equals(JsonString other) => !(other is null) && Value == other.Value; /// - /// Compares values of two JSON strings. + /// Compares values of two JSON strings. /// /// The JSON string to compare. /// The JSON string to compare. @@ -68,7 +68,7 @@ public sealed class JsonString : JsonNode, IEquatable public static bool operator ==(JsonString left, JsonString right) => left?.Value == right?.Value; /// - /// Compares values of two JSON strings. + /// Compares values of two JSON strings. /// /// The JSON string to compare. /// The JSON string to compare. From df377a1be72e5dfe4e4c212dd2382ef08793b440 Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Thu, 8 Aug 2019 11:02:51 -0700 Subject: [PATCH 10/16] review comments included --- .../src/System/Text/Json/Node/JsonBoolean.cs | 22 ++++++++-- .../src/System/Text/Json/Node/JsonString.cs | 42 +++++++++++++++---- .../tests/JsonBooleanTests.cs | 7 ++++ src/System.Text.Json/tests/JsonStringTests.cs | 9 ++-- 4 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index b36ae708058f..b1b962fd3b39 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -25,7 +25,13 @@ public sealed class JsonBoolean : JsonNode, IEquatable public bool Value { get; set; } /// - /// Converts a to a JSON boolean. + /// Converts the value represented by the instance to the string in JSON format. + /// + /// The string representation of the value of this instance. + public override string ToString() => Value ? "true" : "false"; + + /// + /// Converts a to a . /// /// The value to convert. public static implicit operator JsonBoolean(bool value) => new JsonBoolean(value); @@ -38,7 +44,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if the boolean value of this instance matches , /// otherwise. /// - public override bool Equals(object obj) => obj is JsonBoolean jsonBoolean && Value == jsonBoolean.Value; + public override bool Equals(object obj) => obj is JsonBoolean jsonBoolean && Equals(jsonBoolean); /// /// Calculates a hash code of this instance. @@ -65,7 +71,15 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if values of instances match, /// otherwise. /// - public static bool operator ==(JsonBoolean left, JsonBoolean right) => left?.Value == right?.Value; + public static bool operator ==(JsonBoolean left, JsonBoolean right) + { + if (right is null) + { + return (left is null) ? true : false; + } + + return right.Equals(left); + } /// /// Compares values of two JSON booleans. @@ -76,6 +90,6 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if values of instances do not match, /// otherwise. /// - public static bool operator !=(JsonBoolean left, JsonBoolean right) => left?.Value != right?.Value; + public static bool operator !=(JsonBoolean left, JsonBoolean right) => !(left != right); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs index 81dfd79e8704..5944ffb751e1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -9,23 +9,42 @@ namespace System.Text.Json /// public sealed class JsonString : JsonNode, IEquatable { + private string _value; + /// /// Initializes a new instance of the class representing the empty value. /// - public JsonString() => Value = ""; + public JsonString() => Value = string.Empty; + + /// + /// Initializes a new instance of the class representing a specified value. + /// + /// The value to represent as a JSON string. + public JsonString(string value) => Value = value; /// /// Initializes a new instance of the class representing a specified value. /// - public JsonString(string value) => Value = value ?? throw new ArgumentNullException(); + /// The value to represent as a JSON string. + public JsonString(ReadOnlySpan value) => Value = value.ToString(); /// /// Gets or sets the text value represented by the instance. /// - public string Value { get; set; } + public string Value + { + get => _value; + set => _value = value ?? throw new ArgumentNullException(); + } /// - /// Converts a to a JSON string. + /// Returns the text value represented by the instance. + /// + /// The value represented by this instance. + public override string ToString() => _value; + + /// + /// Converts a to a . /// /// The value to convert. public static implicit operator JsonString(string value) => new JsonString(value); @@ -38,7 +57,7 @@ public sealed class JsonString : JsonNode, IEquatable /// if the text value of this instance matches , /// otherwise. /// - public override bool Equals(object obj) => obj is JsonString jsonString && Value == jsonString.Value; + public override bool Equals(object obj) => obj is JsonString jsonString && Equals(jsonString); /// /// Calculates a hash code of this instance. @@ -65,7 +84,16 @@ public sealed class JsonString : JsonNode, IEquatable /// if values of instances match, /// otherwise. /// - public static bool operator ==(JsonString left, JsonString right) => left?.Value == right?.Value; + public static bool operator ==(JsonString left, JsonString right) + { + if (right is null) + { + return (left is null) ? true : false; + } + + return right.Equals(left); + } + /// /// Compares values of two JSON strings. @@ -76,6 +104,6 @@ public sealed class JsonString : JsonNode, IEquatable /// if values of instances do not match, /// otherwise. /// - public static bool operator !=(JsonString left, JsonString right) => left?.Value != right?.Value; + public static bool operator !=(JsonString left, JsonString right) => !(left == right); } } diff --git a/src/System.Text.Json/tests/JsonBooleanTests.cs b/src/System.Text.Json/tests/JsonBooleanTests.cs index 7052df1aeeb3..d1700f0289f2 100644 --- a/src/System.Text.Json/tests/JsonBooleanTests.cs +++ b/src/System.Text.Json/tests/JsonBooleanTests.cs @@ -58,6 +58,8 @@ public static void TestEquals() Assert.True(new JsonBoolean(false).Equals(jsonBooleanFalse)); Assert.True(new JsonBoolean().Equals(jsonBooleanFalse)); Assert.False(new JsonBoolean().Equals(jsonBooleanTrue)); + Assert.False(jsonBooleanFalse.Equals(jsonBooleanTrue)); + Assert.False(jsonBooleanTrue.Equals(jsonBooleanFalse)); Assert.True(jsonBooleanTrue == new JsonBoolean(true)); Assert.True(jsonBooleanTrue != jsonBooleanFalse); @@ -106,7 +108,9 @@ public static void TestGetHashCode() var jsonBooleanTrue = new JsonBoolean(true); var jsonBooleanFalse = new JsonBoolean(false); + Assert.Equal(jsonBooleanTrue.GetHashCode(), jsonBooleanTrue.GetHashCode()); Assert.Equal(jsonBooleanTrue.GetHashCode(), new JsonBoolean(true).GetHashCode()); + Assert.Equal(jsonBooleanFalse.GetHashCode(), jsonBooleanFalse.GetHashCode()); Assert.Equal(jsonBooleanFalse.GetHashCode(), new JsonBoolean(false).GetHashCode()); Assert.Equal(jsonBooleanFalse.GetHashCode(), new JsonBoolean().GetHashCode()); Assert.NotEqual(jsonBooleanTrue.GetHashCode(), new JsonBoolean().GetHashCode()); @@ -131,6 +135,9 @@ public static void TestGetHashCode() object jsonNumberObjectFalse = new JsonBoolean(false); Assert.Equal(jsonNumberCopyFalse.GetHashCode(), jsonBooleanFalse.GetHashCode()); Assert.Equal(jsonNumberObjectFalse.GetHashCode(), jsonBooleanFalse.GetHashCode()); + + Assert.Equal(0, jsonBooleanFalse.GetHashCode()); + Assert.Equal(1, jsonBooleanTrue.GetHashCode()); } } } diff --git a/src/System.Text.Json/tests/JsonStringTests.cs b/src/System.Text.Json/tests/JsonStringTests.cs index 5133c970af9a..cb2d6f23c6d5 100644 --- a/src/System.Text.Json/tests/JsonStringTests.cs +++ b/src/System.Text.Json/tests/JsonStringTests.cs @@ -17,12 +17,14 @@ public static void TestDefaultCtor() [InlineData("value")] [InlineData("value with some spaces")] - [InlineData(" training spaces")] + [InlineData(" leading spaces")] + [InlineData("trailing spaces" )] [InlineData("new lines\r\n")] [InlineData("tabs\ttabs\t")] [InlineData("\\u003e\\u003e\\u003e\\u003e\\u003e")] [InlineData("zażółć gęślą jaźń")] - [InlineData("汉字 漢字")] + [InlineData("\u6f22\u5b57 \u6f22\u5b57")] + [InlineData(">><++>>>\">>\\>>&>>>\u6f22\u5B57>>>")] [InlineData("Here is a string: \\\"\\\"\":\"Here is a\",\"Here is a back slash\\\\\":[\"Multiline\\r\\n String\\r\\n\",\"\\tMul\\r\\ntiline String\",\"\\\"somequote\\\"\\tMu\\\"\\\"l\\r\\ntiline\\\"another\\\" String\\\\\"],\"str")] [InlineData("Hello / a / b / c \\/ \\r\\b\\n\\f\\t\\/")] [Theory] @@ -102,7 +104,8 @@ public static void TestGetHashCode() { var jsonString = new JsonString("json property value"); - Assert.Equal(jsonString.GetHashCode(), new JsonString("json property value").GetHashCode()); + int expectedHashCode = jsonString.GetHashCode(); + Assert.Equal(expectedHashCode, new JsonString("json property value").GetHashCode()); Assert.NotEqual(jsonString.GetHashCode(), new JsonString("json property value ").GetHashCode()); Assert.NotEqual(jsonString.GetHashCode(), new JsonString("jsonpropertyvalue").GetHashCode()); Assert.NotEqual(jsonString.GetHashCode(), new JsonString("Json Property Value").GetHashCode()); From 577fc6fba9fee27676598db97620c1b98b44421e Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Thu, 8 Aug 2019 11:13:01 -0700 Subject: [PATCH 11/16] minor fix --- src/System.Text.Json/ref/System.Text.Json.cs | 7 +++++-- .../src/System/Text/Json/Node/JsonBoolean.cs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index bd309ede50fa..c0e6b2f5f05a 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -7,7 +7,7 @@ namespace System.Text.Json { - public partial class JsonBoolean : System.Text.Json.JsonNode, System.IEquatable + public sealed partial class JsonBoolean : System.Text.Json.JsonNode, System.IEquatable { public JsonBoolean() { } public JsonBoolean(bool value) { } @@ -18,6 +18,7 @@ public JsonBoolean(bool value) { } public static bool operator ==(System.Text.Json.JsonBoolean left, System.Text.Json.JsonBoolean right) { throw null; } public static implicit operator System.Text.Json.JsonBoolean (bool value) { throw null; } public static bool operator !=(System.Text.Json.JsonBoolean left, System.Text.Json.JsonBoolean right) { throw null; } + public override string ToString() { throw null; } } public enum JsonCommentHandling : byte { @@ -233,9 +234,10 @@ public JsonSerializerOptions() { } public bool WriteIndented { get { throw null; } set { } } public System.Text.Json.Serialization.JsonConverter GetConverter(System.Type typeToConvert) { throw null; } } - public partial class JsonString : System.Text.Json.JsonNode, System.IEquatable + public sealed partial class JsonString : System.Text.Json.JsonNode, System.IEquatable { public JsonString() { } + public JsonString(System.ReadOnlySpan value) { } public JsonString(string value) { } public string Value { get { throw null; } set { } } public override bool Equals(object obj) { throw null; } @@ -244,6 +246,7 @@ public JsonString(string value) { } public static bool operator ==(System.Text.Json.JsonString left, System.Text.Json.JsonString right) { throw null; } public static implicit operator System.Text.Json.JsonString (string value) { throw null; } public static bool operator !=(System.Text.Json.JsonString left, System.Text.Json.JsonString right) { throw null; } + public override string ToString() { throw null; } } public enum JsonTokenType : byte { diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index b1b962fd3b39..985d379f661c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -90,6 +90,6 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if values of instances do not match, /// otherwise. /// - public static bool operator !=(JsonBoolean left, JsonBoolean right) => !(left != right); + public static bool operator !=(JsonBoolean left, JsonBoolean right) => !(left == right); } } From d05d73365d028ee5b27afd5fd65b0d2857f88474 Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Fri, 9 Aug 2019 07:28:57 -0700 Subject: [PATCH 12/16] review comments included --- .../src/System/Text/Json/Node/JsonBoolean.cs | 3 +++ .../src/System/Text/Json/Node/JsonString.cs | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index 985d379f661c..a1af8734e0cb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -73,8 +73,11 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// public static bool operator ==(JsonBoolean left, JsonBoolean right) { + // Test "right" first to allow branch elimination when inlined for null checks (== null) + // so it can become a simple test if (right is null) { + // return true/false not the test result https://github.com/dotnet/coreclr/issues/914 return (left is null) ? true : false; } diff --git a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs index 5944ffb751e1..601272d43164 100644 --- a/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs +++ b/src/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -20,6 +20,9 @@ public sealed class JsonString : JsonNode, IEquatable /// Initializes a new instance of the class representing a specified value. /// /// The value to represent as a JSON string. + /// + /// Provided value is null. + /// public JsonString(string value) => Value = value; /// @@ -31,6 +34,9 @@ public sealed class JsonString : JsonNode, IEquatable /// /// Gets or sets the text value represented by the instance. /// + /// + /// Provided value is null. + /// public string Value { get => _value; @@ -86,15 +92,17 @@ public string Value /// public static bool operator ==(JsonString left, JsonString right) { + // Test "right" first to allow branch elimination when inlined for null checks (== null) + // so it can become a simple test if (right is null) { + // return true/false not the test result https://github.com/dotnet/coreclr/issues/914 return (left is null) ? true : false; } return right.Equals(left); } - /// /// Compares values of two JSON strings. /// From 40c3b1e1930faa85e432bd4c48ee93c7d8a81511 Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Fri, 9 Aug 2019 08:20:23 -0700 Subject: [PATCH 13/16] 100% lines and branches covered --- .../tests/JsonBooleanTests.cs | 12 +++++++++ src/System.Text.Json/tests/JsonNumberTests.cs | 3 +++ src/System.Text.Json/tests/JsonStringTests.cs | 27 ++++++++++++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/System.Text.Json/tests/JsonBooleanTests.cs b/src/System.Text.Json/tests/JsonBooleanTests.cs index d1700f0289f2..586aa6e840ca 100644 --- a/src/System.Text.Json/tests/JsonBooleanTests.cs +++ b/src/System.Text.Json/tests/JsonBooleanTests.cs @@ -45,6 +45,13 @@ public static void TestChangingValue() Assert.False(jsonBoolean.Value); } + [Fact] + public static void TestToString() + { + Assert.Equal("true", new JsonBoolean(true).ToString()); + Assert.Equal("false", new JsonBoolean(false).ToString()); + } + [Fact] public static void TestEquals() { @@ -100,6 +107,9 @@ public static void TestEquals() Assert.True(jsonBooleanTrue != jsonBooleanNull); Assert.True(jsonBooleanNull != jsonBooleanTrue); + + JsonBoolean otherJsonBooleanNull = null; + Assert.True(jsonBooleanNull == otherJsonBooleanNull); } [Fact] @@ -120,6 +130,8 @@ public static void TestGetHashCode() JsonNode jsonNodeFalse = new JsonBoolean(false); Assert.Equal(jsonBooleanFalse.GetHashCode(), jsonNodeFalse.GetHashCode()); + Assert.NotEqual(jsonBooleanTrue.GetHashCode(), jsonBooleanFalse.GetHashCode()); + IEquatable jsonBooleanIEquatableTrue = jsonBooleanTrue; Assert.Equal(jsonBooleanIEquatableTrue.GetHashCode(), jsonBooleanTrue.GetHashCode()); diff --git a/src/System.Text.Json/tests/JsonNumberTests.cs b/src/System.Text.Json/tests/JsonNumberTests.cs index ed5f9d671ced..8cfc3377239c 100644 --- a/src/System.Text.Json/tests/JsonNumberTests.cs +++ b/src/System.Text.Json/tests/JsonNumberTests.cs @@ -646,6 +646,9 @@ public static void TestEquals() Assert.True(jsonNumber != jsonNumberNull); Assert.True(jsonNumberNull != jsonNumber); + + JsonNumber otherJsonNumberNull = null; + Assert.True(jsonNumberNull == otherJsonNumberNull); } [Fact] diff --git a/src/System.Text.Json/tests/JsonStringTests.cs b/src/System.Text.Json/tests/JsonStringTests.cs index cb2d6f23c6d5..4d6c61cda2ba 100644 --- a/src/System.Text.Json/tests/JsonStringTests.cs +++ b/src/System.Text.Json/tests/JsonStringTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Reflection; using Xunit; namespace System.Text.Json.Tests @@ -30,15 +31,31 @@ public static void TestDefaultCtor() [Theory] public static void TestInitialization(string value) { - var jsonString = new JsonString(value); - Assert.Equal(value, jsonString.Value); - + // Default constructor: var defaultlyInitializedJsonString = new JsonString(); defaultlyInitializedJsonString.Value = value; Assert.Equal(value, defaultlyInitializedJsonString.Value); + // To string: + Assert.Equal(value, defaultlyInitializedJsonString.ToString()); + + // Value constructor: + Assert.Equal(value, new JsonString(value).Value); + + // Implicit operator: JsonString implicitlyInitializiedJsonString = value; Assert.Equal(value, implicitlyInitializiedJsonString.Value); + + // Casted to span: + ReadOnlySpan spanValue = value; + Assert.Equal(value, new JsonString(spanValue).Value); + } + + [Fact] + public static void TestNulls() + { + Assert.Throws(() => new JsonString(null)); + Assert.Throws(() => new JsonString().Value = null); } [Fact] @@ -90,6 +107,7 @@ public static void TestEquals() Assert.False(jsonString.Equals(new Exception())); Assert.False(jsonString.Equals(new JsonBoolean())); Assert.False(new JsonString("true").Equals(new JsonBoolean(true))); + Assert.False(new JsonString("123").Equals(new JsonNumber("123"))); JsonString jsonStringNull = null; Assert.False(jsonString == jsonStringNull); @@ -97,6 +115,9 @@ public static void TestEquals() Assert.True(jsonString != jsonStringNull); Assert.True(jsonStringNull != jsonString); + + JsonString otherJsonStringNull = null; + Assert.True(jsonStringNull == otherJsonStringNull); } [Fact] From d9a76c63e5e563f86ec86bbc9328668fc3f7fc9a Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Fri, 9 Aug 2019 08:42:04 -0700 Subject: [PATCH 14/16] framework fixes --- src/System.Text.Json/tests/JsonStringTests.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/System.Text.Json/tests/JsonStringTests.cs b/src/System.Text.Json/tests/JsonStringTests.cs index 4d6c61cda2ba..274a09d47469 100644 --- a/src/System.Text.Json/tests/JsonStringTests.cs +++ b/src/System.Text.Json/tests/JsonStringTests.cs @@ -47,17 +47,35 @@ public static void TestInitialization(string value) Assert.Equal(value, implicitlyInitializiedJsonString.Value); // Casted to span: +#if BUILDING_INBOX_LIBRARY ReadOnlySpan spanValue = value; Assert.Equal(value, new JsonString(spanValue).Value); +#endif } [Fact] public static void TestNulls() { +#if BUILDING_INBOX_LIBRARY Assert.Throws(() => new JsonString(null)); +#endif Assert.Throws(() => new JsonString().Value = null); } +#if !BUILDING_INBOX_LIBRARY + [Fact] + public static void TestReadonlySpan() + { + var spanValue = new ReadOnlySpan(new char[] { 's', 'p', 'a', 'n'}); + Assert.Equal("span", new JsonString(spanValue).Value); + + Assert.Throws(() => + { + ReadOnlySpan spanValue = null; + var jsonString = new JsonString(spanValue); + }); + } +#endif [Fact] public static void TestChangingValue() { From d14e1dbe13c51e7d34dae54efb7a57a88673770a Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Fri, 9 Aug 2019 14:43:09 -0700 Subject: [PATCH 15/16] span fixes --- src/System.Text.Json/tests/JsonStringTests.cs | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/System.Text.Json/tests/JsonStringTests.cs b/src/System.Text.Json/tests/JsonStringTests.cs index 274a09d47469..af569f3c572a 100644 --- a/src/System.Text.Json/tests/JsonStringTests.cs +++ b/src/System.Text.Json/tests/JsonStringTests.cs @@ -46,36 +46,30 @@ public static void TestInitialization(string value) JsonString implicitlyInitializiedJsonString = value; Assert.Equal(value, implicitlyInitializiedJsonString.Value); - // Casted to span: -#if BUILDING_INBOX_LIBRARY - ReadOnlySpan spanValue = value; + // Casted to span: + ReadOnlySpan spanValue = value.AsSpan(); Assert.Equal(value, new JsonString(spanValue).Value); -#endif } [Fact] public static void TestNulls() { -#if BUILDING_INBOX_LIBRARY - Assert.Throws(() => new JsonString(null)); -#endif + string property = null; + Assert.Throws(() => new JsonString(property)); Assert.Throws(() => new JsonString().Value = null); } -#if !BUILDING_INBOX_LIBRARY [Fact] public static void TestReadonlySpan() { var spanValue = new ReadOnlySpan(new char[] { 's', 'p', 'a', 'n'}); Assert.Equal("span", new JsonString(spanValue).Value); - Assert.Throws(() => - { - ReadOnlySpan spanValue = null; - var jsonString = new JsonString(spanValue); - }); + string property = null; + spanValue = property.AsSpan(); + var jsonString = new JsonString(spanValue); } -#endif + [Fact] public static void TestChangingValue() { From 0157a2cac87c22a48864048375253d8bd6820592 Mon Sep 17 00:00:00 2001 From: Katarzyna Bulat Date: Fri, 9 Aug 2019 14:53:10 -0700 Subject: [PATCH 16/16] minor changes --- src/System.Text.Json/src/System.Text.Json.csproj | 2 +- src/System.Text.Json/tests/JsonStringTests.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index 80fc996edb60..a0f937e70812 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -211,7 +211,7 @@ - + diff --git a/src/System.Text.Json/tests/JsonStringTests.cs b/src/System.Text.Json/tests/JsonStringTests.cs index af569f3c572a..94339e131b53 100644 --- a/src/System.Text.Json/tests/JsonStringTests.cs +++ b/src/System.Text.Json/tests/JsonStringTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Reflection; using Xunit; namespace System.Text.Json.Tests