Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
48609a2
Initial plan
Copilot Oct 15, 2025
edead34
Improve code coverage for System.Text.Json with targeted unit tests
Copilot Oct 15, 2025
ea52bce
Mark DeepEquals_TooDeepJsonDocument test as OuterLoop
Copilot Oct 15, 2025
eace0c3
Add tests for SerializeToDocument/Element/Node with JsonTypeInfo and …
Copilot Oct 15, 2025
6aa1f88
Add tests for null value scenarios with JsonTypeInfo
Copilot Oct 15, 2025
24dc39a
Fix tests to use DefaultJsonTypeInfoResolver
Copilot Oct 15, 2025
40a1e92
Add 15 more tests for JsonSerializer Deserialize/Serialize methods wi…
Copilot Oct 15, 2025
0b52f02
Add 13 tests using JsonSerializerContext for various Serialize/Deseri…
Copilot Oct 15, 2025
f91acf7
Add async PipeWriter tests and numeric edge case tests for Utf8JsonRe…
Copilot Oct 16, 2025
563cffa
Add 8 validation and edge case tests for JsonWriter and JsonNode
Copilot Oct 16, 2025
7f36446
Add 4 tests for PreferredObjectCreationHandling and JsonElement Get m…
Copilot Oct 16, 2025
14b20a5
Add 8 tests for JsonArray Clear, Utf8JsonWriter minimized formatting,…
Copilot Oct 16, 2025
54d0c37
Add 8 tests for JsonValue Create methods and Utf8JsonWriter minimized…
Copilot Oct 16, 2025
f72a942
Add 6 tests for TypeInfoResolverChain and immutable collections (Stac…
Copilot Oct 16, 2025
349f455
Add 6 tests for JsonValue with JsonTypeInfo, JsonElement Try methods,…
Copilot Oct 16, 2025
84d5129
Add 6 tests for Utf8JsonWriter indented formatting and JsonDocument P…
Copilot Oct 16, 2025
e17b78e
Add 6 tests for JsonNode operations and JsonSerializerOptions propert…
Copilot Oct 16, 2025
2e10b10
Add 9 multi-segment Utf8JsonReader tests for complex edge cases
Copilot Oct 16, 2025
f0a2ce7
Fix OutOfMemoryException in extremely long string validation tests
Copilot Oct 17, 2025
d274260
Add 30 JsonNamingPolicy tests covering all naming policy variants
Copilot Oct 17, 2025
31fddfe
Convert JSON string literals to raw string literals
Copilot Oct 17, 2025
3e625d8
Use JsonSerializerOptions.Default instead of creating new instances t…
Copilot Oct 17, 2025
dc39876
Revert line 613 to use options variable instead of JsonSerializerOpti…
Copilot Oct 17, 2025
a0641ea
Convert remaining JSON strings to raw string literals in DomTests.cs
Copilot Oct 17, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -507,5 +507,42 @@ public async Task WriteImmutableCollectionWrappers()
Assert.Equal(SimpleTestClassWithImmutableSetWrapper.s_json.StripWhitespace(), await Serializer.SerializeWrapper(obj5));
Assert.Equal(SimpleTestClassWithImmutableSetWrapper.s_json.StripWhitespace(), await Serializer.SerializeWrapper<object>(obj5));
}

[Fact]
public async Task WriteImmutableStack()
{
ImmutableStack<int> input = ImmutableStack.Create<int>(1, 2, 3);
string json = await Serializer.SerializeWrapper(input);
Assert.Equal("[3,2,1]", json);
}

[Fact]
public async Task WriteImmutableQueue()
{
ImmutableQueue<int> input = ImmutableQueue.Create<int>(1, 2, 3);
string json = await Serializer.SerializeWrapper(input);
Assert.Equal("[1,2,3]", json);
}

[Fact]
public async Task WriteImmutableHashSet()
{
ImmutableHashSet<int> input = ImmutableHashSet.Create<int>(1, 2, 3);
string json = await Serializer.SerializeWrapper(input);
Assert.Contains("1", json);
Assert.Contains("2", json);
Assert.Contains("3", json);
}

[Fact]
public async Task WriteImmutableDictionaryStringKey()
{
ImmutableDictionary<string, int> input = ImmutableDictionary.Create<string, int>()
.Add("a", 1)
.Add("b", 2);
string json = await Serializer.SerializeWrapper(input);
Assert.Contains("\"a\":1", json);
Assert.Contains("\"b\":2", json);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3996,6 +3996,72 @@ public static void ParseJsonDuplicatePropertiesErrorMessageEscaped()
() => JsonDocument.Parse(json, s_noDuplicateParamsOptions),
"'0'");
}

[Fact]
public static void JsonElement_GetDouble_EdgeCases()
{
using JsonDocument doc = JsonDocument.Parse("0.0");
double value = doc.RootElement.GetDouble();
Assert.Equal(0.0, value);

using JsonDocument doc2 = JsonDocument.Parse("1.7976931348623157E+308");
double value2 = doc2.RootElement.GetDouble();
Assert.True(value2 > 1E+307);

using JsonDocument doc3 = JsonDocument.Parse("-1.7976931348623157E+308");
double value3 = doc3.RootElement.GetDouble();
Assert.True(value3 < -1E+307);
}

[Fact]
public static void JsonElement_GetSingle_EdgeCases()
{
using JsonDocument doc = JsonDocument.Parse("0.0");
float value = doc.RootElement.GetSingle();
Assert.Equal(0.0f, value);

using JsonDocument doc2 = JsonDocument.Parse("3.4028235E+38");
float value2 = doc2.RootElement.GetSingle();
Assert.True(value2 > 1E+37f);

using JsonDocument doc3 = JsonDocument.Parse("-3.4028235E+38");
float value3 = doc3.RootElement.GetSingle();
Assert.True(value3 < -1E+37f);
}

[Fact]
public static void ParseWithMaxDepthOption()
{
string json = """{"a":{"b":{"c":{"d":1}}}}""";
var options = new JsonDocumentOptions { MaxDepth = 10 };
using var doc = JsonDocument.Parse(json, options);
Assert.Equal(1, doc.RootElement.GetProperty("a").GetProperty("b").GetProperty("c").GetProperty("d").GetInt32());
}

[Fact]
public static void ParseWithAllowTrailingCommas()
{
string json = """{"a":1,}""";
var options = new JsonDocumentOptions { AllowTrailingCommas = true };
using var doc = JsonDocument.Parse(json, options);
Assert.Equal(1, doc.RootElement.GetProperty("a").GetInt32());
}

[Fact]
public static void JsonElement_TryGetDouble()
{
using JsonDocument doc = JsonDocument.Parse("3.14159");
Assert.True(doc.RootElement.TryGetDouble(out double value));
Assert.Equal(3.14159, value, precision: 5);
}

[Fact]
public static void JsonElement_TryGetSingle()
{
using JsonDocument doc = JsonDocument.Parse("3.14");
Assert.True(doc.RootElement.TryGetSingle(out float value));
Assert.Equal(3.14f, value, precision: 2);
}
}

public class ThrowOnReadStream : MemoryStream
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit;

namespace System.Text.Json.Tests
{
public static class JsonNamingPolicyTests
{
[Theory]
[InlineData("MyProperty", "myProperty")]
[InlineData("PropertyName", "propertyName")]
[InlineData("ABC", "aBC")]
[InlineData("A", "a")]
[InlineData("", "")]
public static void CamelCase_ConvertName(string input, string expected)
{
string result = JsonNamingPolicy.CamelCase.ConvertName(input);
Assert.Equal(expected, result);
}

[Theory]
[InlineData("MyProperty", "my_property")]
[InlineData("PropertyName", "property_name")]
[InlineData("ABC", "a_b_c")]
[InlineData("HTMLParser", "h_t_m_l_parser")]
[InlineData("A", "a")]
[InlineData("", "")]
public static void SnakeCaseLower_ConvertName(string input, string expected)
{
string result = JsonNamingPolicy.SnakeCaseLower.ConvertName(input);
Assert.Equal(expected, result);
}

[Theory]
[InlineData("MyProperty", "MY_PROPERTY")]
[InlineData("PropertyName", "PROPERTY_NAME")]
[InlineData("ABC", "A_B_C")]
[InlineData("HTMLParser", "H_T_M_L_PARSER")]
[InlineData("A", "A")]
[InlineData("", "")]
public static void SnakeCaseUpper_ConvertName(string input, string expected)
{
string result = JsonNamingPolicy.SnakeCaseUpper.ConvertName(input);
Assert.Equal(expected, result);
}

[Theory]
[InlineData("MyProperty", "my-property")]
[InlineData("PropertyName", "property-name")]
[InlineData("ABC", "a-b-c")]
[InlineData("HTMLParser", "h-t-m-l-parser")]
[InlineData("A", "a")]
[InlineData("", "")]
public static void KebabCaseLower_ConvertName(string input, string expected)
{
string result = JsonNamingPolicy.KebabCaseLower.ConvertName(input);
Assert.Equal(expected, result);
}

[Theory]
[InlineData("MyProperty", "MY-PROPERTY")]
[InlineData("PropertyName", "PROPERTY-NAME")]
[InlineData("ABC", "A-B-C")]
[InlineData("HTMLParser", "H-T-M-L-PARSER")]
[InlineData("A", "A")]
[InlineData("", "")]
public static void KebabCaseUpper_ConvertName(string input, string expected)
{
string result = JsonNamingPolicy.KebabCaseUpper.ConvertName(input);
Assert.Equal(expected, result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -897,5 +897,41 @@ public static void Deserialize_WrongType(string json)
{
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<JsonArray>(json));
}

[Fact]
public static void DeepEquals_WithNestedArrays()
{
JsonArray array1 = new JsonArray { 1, 2, new JsonArray { 3, 4 } };
JsonArray array2 = new JsonArray { 1, 2, new JsonArray { 3, 4 } };
JsonArray array3 = new JsonArray { 1, 2, new JsonArray { 3, 5 } };

Assert.True(JsonNode.DeepEquals(array1, array2));
Assert.False(JsonNode.DeepEquals(array1, array3));
Assert.False(JsonNode.DeepEquals(array1, null));
}

[Fact]
public static void DeepEquals_DifferentLengths()
{
JsonArray array1 = new JsonArray { 1, 2, 3 };
JsonArray array2 = new JsonArray { 1, 2 };

Assert.False(JsonNode.DeepEquals(array1, array2));
}

[Fact]
public static void Clear_RemovesAllItemsAndDetachesParent()
{
JsonArray array = new JsonArray { 1, 2, 3 };
JsonNode item = array[0];

Assert.Equal(3, array.Count);
Assert.Same(array, item.Parent);

array.Clear();

Assert.Equal(0, array.Count);
Assert.Null(item.Parent);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -303,5 +303,41 @@ public static void DeepEquals_NotEqualValuesReturnFalse(string value1, string va

AssertNotDeepEqual(obj1, obj2);
}

[Fact]
public static void JsonNode_ReplaceWith()
{
JsonObject obj = new JsonObject();
obj["name"] = "test";
JsonNode node = obj["name"];

node.ReplaceWith(JsonValue.Create("replaced"));
Assert.Equal("replaced", obj["name"].GetValue<string>());
}

[Fact]
public static void JsonArray_Replace()
{
JsonArray arr = new JsonArray(1, 2, 3);
arr[1] = JsonValue.Create(99);
Assert.Equal(99, arr[1].GetValue<int>());
}

[Fact]
public static void JsonObject_SetProperty()
{
JsonObject obj = new JsonObject();
obj["key"] = "value";
obj["key"] = "newValue";
Assert.Equal("newValue", obj["key"].GetValue<string>());
}

[Fact]
public static void JsonValue_AsValue()
{
JsonNode node = JsonValue.Create(42);
JsonValue value = node.AsValue();
Assert.Equal(42, value.GetValue<int>());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1810,5 +1810,46 @@ public static void GetPath_IsThreadSafe()
});
}
}

[Fact]
public static void DeepEquals_WithNestedObjects()
{
JsonObject obj1 = new JsonObject { ["a"] = 1, ["b"] = new JsonObject { ["c"] = 2 } };
JsonObject obj2 = new JsonObject { ["a"] = 1, ["b"] = new JsonObject { ["c"] = 2 } };
JsonObject obj3 = new JsonObject { ["a"] = 1, ["b"] = new JsonObject { ["c"] = 3 } };

Assert.True(JsonNode.DeepEquals(obj1, obj2));
Assert.False(JsonNode.DeepEquals(obj1, obj3));
Assert.False(JsonNode.DeepEquals(obj1, null));
}

[Fact]
public static void DeepEquals_DifferentKeys()
{
JsonObject obj1 = new JsonObject { ["a"] = 1, ["b"] = 2 };
JsonObject obj2 = new JsonObject { ["a"] = 1, ["c"] = 2 };

Assert.False(JsonNode.DeepEquals(obj1, obj2));
}

[Fact]
public static void TryGetPropertyValue_NonExistentProperty()
{
JsonObject obj = new JsonObject { ["a"] = 1 };

bool result = obj.TryGetPropertyValue("b", out JsonNode value);

Assert.False(result);
Assert.Null(value);
}

[Fact]
public static void ContainsKey_ChecksForProperty()
{
JsonObject obj = new JsonObject { ["a"] = 1, ["b"] = 2 };

Assert.True(obj.ContainsKey("a"));
Assert.False(obj.ContainsKey("c"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -909,5 +909,62 @@ private class ExcludeType_TypeInfoResolver(Type excludeType) : IJsonTypeInfoReso
}

private record DummyClass;

[Fact]
public static void JsonValue_CreateFromInt()
{
JsonValue value = JsonValue.Create(42);
Assert.Equal(42, value.GetValue<int>());
Assert.True(value.TryGetValue(out int result));
Assert.Equal(42, result);
}

[Fact]
public static void JsonValue_CreateFromString()
{
JsonValue value = JsonValue.Create("test");
Assert.Equal("test", value.GetValue<string>());
Assert.True(value.TryGetValue(out string result));
Assert.Equal("test", result);
}

[Fact]
public static void JsonValue_CreateFromBool()
{
JsonValue value = JsonValue.Create(true);
Assert.True(value.GetValue<bool>());
Assert.True(value.TryGetValue(out bool result));
Assert.True(result);
}

[Fact]
public static void JsonValue_CreateFromDouble()
{
JsonValue value = JsonValue.Create(3.14);
Assert.Equal(3.14, value.GetValue<double>());
Assert.True(value.TryGetValue(out double result));
Assert.Equal(3.14, result);
}

[Fact]
public static void JsonValue_CreateWithJsonTypeInfo()
{
var options = new JsonSerializerOptions { TypeInfoResolver = new DefaultJsonTypeInfoResolver() };
JsonTypeInfo<int> typeInfo = (JsonTypeInfo<int>)options.GetTypeInfo(typeof(int));

JsonValue value = JsonValue.Create(42, typeInfo);
Assert.Equal(42, value.GetValue<int>());
}

[Fact]
public static void JsonValue_CreateWithJsonTypeInfoAndOptions()
{
var options = new JsonSerializerOptions { TypeInfoResolver = new DefaultJsonTypeInfoResolver() };
JsonTypeInfo<string> typeInfo = (JsonTypeInfo<string>)options.GetTypeInfo(typeof(string));
var nodeOptions = new JsonNodeOptions { PropertyNameCaseInsensitive = true };

JsonValue value = JsonValue.Create("test", typeInfo, nodeOptions);
Assert.Equal("test", value.GetValue<string>());
}
}
}
Loading
Loading