Skip to content

Commit

Permalink
Enable Native AOT testing in System.Text.Json. Fix dotnet#73431.
Browse files Browse the repository at this point in the history
  • Loading branch information
eiriktsarpalis committed May 31, 2023
1 parent 1af3c9e commit 1786935
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public abstract partial class CollectionTests
{
[Theory]
[MemberData(nameof(GetAsyncEnumerableSources))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public async Task WriteRootLevelAsyncEnumerable<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer?.IsAsyncSerializer != true)
Expand All @@ -41,6 +42,7 @@ public async Task WriteRootLevelAsyncEnumerable<TElement>(IEnumerable<TElement>

[Theory]
[MemberData(nameof(GetAsyncEnumerableSources))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public async Task WriteNestedAsyncEnumerable<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer?.IsAsyncSerializer != true)
Expand All @@ -66,6 +68,7 @@ public async Task WriteNestedAsyncEnumerable<TElement>(IEnumerable<TElement> sou

[Theory]
[MemberData(nameof(GetAsyncEnumerableSources))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public async Task WriteNestedAsyncEnumerable_DTO<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer?.IsAsyncSerializer != true)
Expand All @@ -91,6 +94,7 @@ public async Task WriteNestedAsyncEnumerable_DTO<TElement>(IEnumerable<TElement>

[Theory]
[MemberData(nameof(GetAsyncEnumerableSources))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public async Task WriteNestedAsyncEnumerable_Nullable<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer?.IsAsyncSerializer != true)
Expand Down Expand Up @@ -177,6 +181,7 @@ public class AsyncEnumerableDtoWithTwoProperties<TElement>

[Theory]
[MemberData(nameof(GetAsyncEnumerableSources))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public async Task WriteSequentialNestedAsyncEnumerables<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer?.IsAsyncSerializer != true)
Expand All @@ -202,6 +207,7 @@ public async Task WriteSequentialNestedAsyncEnumerables<TElement>(IEnumerable<TE

[Theory]
[MemberData(nameof(GetAsyncEnumerableSources))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public async Task WriteAsyncEnumerableOfAsyncEnumerables<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
{
if (StreamingSerializer?.IsAsyncSerializer != true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,13 +624,13 @@ public async Task ReadISetTOfHashSetT()

if (result.First().Contains(1))
{
Assert.Equal(new HashSet<int> { 1, 2 }, result.First());
Assert.Equal(new HashSet<int> { 3, 4 }, result.Last());
Assert.True(result.First().SetEquals(new []{ 1, 2 }));
Assert.True(result.Last().SetEquals(new []{ 3, 4 }));
}
else
{
Assert.Equal(new HashSet<int> { 3, 4 }, result.First());
Assert.Equal(new HashSet<int> { 1, 2 }, result.Last());
Assert.True(result.First().SetEquals(new[] { 3, 4 }));
Assert.True(result.Last().SetEquals(new[] { 1, 2 }));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,13 +449,13 @@ public async Task WriteISetTOfHashSetT()

if (input.First().Contains(1))
{
Assert.Equal(new HashSet<int> { 1, 2 }, input.First());
Assert.Equal(new HashSet<int> { 3, 4 }, input.Last());
Assert.True(input.First().SetEquals(new[] { 1, 2 }));
Assert.True(input.Last().SetEquals(new[] { 3, 4 }));
}
else
{
Assert.Equal(new HashSet<int> { 3, 4 }, input.First());
Assert.Equal(new HashSet<int> { 1, 2 }, input.Last());
Assert.True(input.First().SetEquals(new[] { 3, 4 }));
Assert.True(input.Last().SetEquals(new[] { 1, 2 }));
}
}

Expand Down Expand Up @@ -649,13 +649,13 @@ public async Task WriteHashSetTOfHashSetT()

if (input.First().Contains(1))
{
Assert.Equal(new HashSet<int> { 1, 2 }, input.First());
Assert.Equal(new HashSet<int> { 3, 4 }, input.Last());
Assert.True(input.First().SetEquals(new[] { 1, 2 }));
Assert.True(input.Last().SetEquals(new[] { 3, 4 }));
}
else
{
Assert.Equal(new HashSet<int> { 3, 4 }, input.First());
Assert.Equal(new HashSet<int> { 1, 2 }, input.Last());
Assert.True(input.First().SetEquals(new[] { 3, 4 }));
Assert.True(input.Last().SetEquals(new[] { 1, 2 }));
}

GenericHashSetWrapper<StringHashSetWrapper> input2 = new GenericHashSetWrapper<StringHashSetWrapper>(new List<StringHashSetWrapper>
Expand Down Expand Up @@ -707,8 +707,8 @@ public async Task WriteArrayOfHashSetT()

// Because order isn't guaranteed, roundtrip data to ensure write was accurate.
input = await Serializer.DeserializeWrapper<HashSet<int>[]>(json);
Assert.Equal(new HashSet<int> { 1, 2 }, input.First());
Assert.Equal(new HashSet<int> { 3, 4 }, input.Last());
Assert.True(input.First().SetEquals(new[] { 1, 2}));
Assert.True(input.Last().SetEquals(new[] { 3, 4 }));
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ async Task SerializeObject(Type type, JsonSerializerOptions options)
async Task RunTestAsync(Type type)
{
// Use local options to avoid obtaining already cached metadata from the default options.
var options = new JsonSerializerOptions();
JsonSerializerOptions options = Serializer.CreateOptions();

const int ThreadCount = 8;
const int ConcurrentTestsCount = 4;
Expand Down Expand Up @@ -90,7 +90,7 @@ async Task RunTestAsync(Type type)
public async Task PropertyCacheWithMinInputsFirst()
{
// Use local options to avoid obtaining already cached metadata from the default options.
var options = new JsonSerializerOptions();
JsonSerializerOptions options = Serializer.CreateOptions();

string json = "{}";
await Serializer.DeserializeWrapper<ObjWCtorMixedParams>(json, options);
Expand All @@ -107,7 +107,7 @@ public async Task PropertyCacheWithMinInputsFirst()
public async Task PropertyCacheWithMinInputsLast()
{
// Use local options to avoid obtaining already cached metadata from the default options.
var options = new JsonSerializerOptions();
JsonSerializerOptions options = Serializer.CreateOptions();

ObjWCtorMixedParams testObj = ObjWCtorMixedParams.GetInstance();
testObj.Verify();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,7 @@ public async Task InvalidJsonFails()
await Assert.ThrowsAsync<JsonException>(() => Serializer.DeserializeWrapper<Point_2D_Struct>("{true"));
}

#if !BUILDING_SOURCE_GENERATOR_TESTS // Anonymous types not supported in source gen
[Fact]
public void AnonymousObject()
{
Expand Down Expand Up @@ -1087,6 +1088,7 @@ public void AnonymousObject_NamingPolicy()
// Verify match with naming policy
Assert.Equal(5, objType.GetProperty("Prop").GetValue(newObj));
}
#endif

public record MyRecord(int Prop);

Expand Down Expand Up @@ -1329,29 +1331,29 @@ public ClassWithIgnoredSameType(ClassWithIgnoredSameType prop) { }
}

[Fact]
public void StructWithPropertyInit_DeseralizeEmptyObject()
public async Task StructWithPropertyInit_DeseralizeEmptyObject()
{
string json = @"{}";
var obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
var obj = await Serializer.DeserializeWrapper<StructWithPropertyInit>(json);
Assert.Equal(42, obj.A);
Assert.Equal(0, obj.B);
}

[Fact]
public void StructWithPropertyInit_OverrideInitedProperty()
public async Task StructWithPropertyInit_OverrideInitedProperty()
{
string json = @"{""A"":43}";
var obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
var obj = await Serializer.DeserializeWrapper<StructWithPropertyInit>(json);
Assert.Equal(43, obj.A);
Assert.Equal(0, obj.B);

json = @"{""A"":0,""B"":44}";
obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
obj = await Serializer.DeserializeWrapper<StructWithPropertyInit>(json);
Assert.Equal(0, obj.A);
Assert.Equal(44, obj.B);

json = @"{""B"":45}";
obj = JsonSerializer.Deserialize<StructWithPropertyInit>(json);
obj = await Serializer.DeserializeWrapper<StructWithPropertyInit>(json);
Assert.Equal(42, obj.A); // JSON doesn't set A property so it's expected to be 42
Assert.Equal(45, obj.B);
}
Expand All @@ -1364,10 +1366,10 @@ public struct StructWithPropertyInit
}

[Fact]
public void StructWithFieldInit_DeseralizeEmptyObject()
public async Task StructWithFieldInit_DeseralizeEmptyObject()
{
string json = @"{}";
var obj = JsonSerializer.Deserialize<StructWithFieldInit>(json);
var obj = await Serializer.DeserializeWrapper<StructWithFieldInit>(json);
Assert.Equal(0, obj.A);
Assert.Equal(42, obj.B);
}
Expand All @@ -1380,10 +1382,10 @@ public struct StructWithFieldInit
}

[Fact]
public void StructWithExplicitParameterlessCtor_DeseralizeEmptyObject()
public async Task StructWithExplicitParameterlessCtor_DeseralizeEmptyObject()
{
string json = @"{}";
var obj = JsonSerializer.Deserialize<StructWithExplicitParameterlessCtor>(json);
var obj = await Serializer.DeserializeWrapper<StructWithExplicitParameterlessCtor>(json);
Assert.Equal(42, obj.A);
}

Expand Down Expand Up @@ -1431,18 +1433,17 @@ public async Task TestClassWithDefaultCtorParams()
JsonTestHelper.AssertJsonEqual(json, await Serializer.SerializeWrapper(obj));
}

#if FIXED // https://github.com/dotnet/roslyn/issues/66900
[Fact]
public async Task TestClassWithManyConstructorParameters()
{
ClassWithManyConstructorParameters value = ClassWithManyConstructorParameters.Create();
string json = JsonSerializer.Serialize(value);
string json = await Serializer.SerializeWrapper(value);

ClassWithManyConstructorParameters result = await Serializer.DeserializeWrapper<ClassWithManyConstructorParameters>(json);

Assert.Equal(value, result); // Type is C# record that implements structural equality.
}
#endif

public class ClassWithDefaultCtorParams
{
public Point_2D_Struct_WithAttribute Struct { get; }
Expand Down Expand Up @@ -1543,6 +1544,7 @@ public ClassWithDefaultCtorParams(
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/79311", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public async Task TestTypeWithEnumParameters()
{
// Regression test for https://github.com/dotnet/runtime/issues/68647
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ private static void ExtensionProperty_SupportsWritingToCustomSerializerWithExpli
[InlineData(typeof(Dictionary<string, JsonElement>), typeof(JsonElementOverflowConverter), typeof(JsonElement))]
[InlineData(typeof(CustomOverflowDictionary<object>), typeof(CustomObjectDictionaryOverflowConverter), typeof(object))]
[InlineData(typeof(CustomOverflowDictionary<JsonElement>), typeof(CustomJsonElementDictionaryOverflowConverter), typeof(JsonElement))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public void ExtensionProperty_IgnoresCustomSerializerWithOptions(Type overflowType, Type converterType, Type elementType)
{
typeof(ExtensionDataTests)
Expand Down Expand Up @@ -559,6 +560,7 @@ ClassWithExtensionData<TDictionary> obj
[InlineData(typeof(ClassWithJsonElementExtensionDataWithAttributedConverter), typeof(Dictionary<string, JsonElement>), typeof(JsonElement))]
[InlineData(typeof(ClassWithCustomElementExtensionDataWithAttributedConverter), typeof(CustomOverflowDictionary<object>), typeof(object))]
[InlineData(typeof(ClassWithCustomJsonElementExtensionDataWithAttributedConverter), typeof(CustomOverflowDictionary<JsonElement>), typeof(JsonElement))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/86973", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))]
public void ExtensionProperty_IgnoresCustomSerializerWithExplicitConverter(Type attributedType, Type dictionaryType, Type elementType)
{
typeof(ExtensionDataTests)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

Expand Down Expand Up @@ -580,7 +581,16 @@ internal struct ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfString
public ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfStringToJsonElement() {}

[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
public IDictionary Property { get; } = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>("""{"a":1,"b":2,"c":3}""");
public IDictionary Property { get; } = ParseJsonObject("""{"a":1,"b":2,"c":3}""").ToDictionary(kv => kv.Key, kv => kv.Value);
}

private static IEnumerable<KeyValuePair<string, JsonElement>> ParseJsonObject(string json)
{
JsonDocument doc = JsonDocument.Parse(json);
foreach (var entry in doc.RootElement.EnumerateObject())
{
yield return new KeyValuePair<string, JsonElement>(entry.Name, entry.Value);
}
}

[Fact]
Expand Down Expand Up @@ -625,15 +635,15 @@ internal struct ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfString
{
public ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfStringToJsonElementWithoutPopulateAttribute() {}

public IDictionary Property { get; } = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>("""{"a":1,"b":2,"c":3}""");
public IDictionary Property { get; } = ParseJsonObject("""{"a":1,"b":2,"c":3}""").ToDictionary(kv => kv.Key, kv => kv.Value);
}

[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
internal struct ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfStringToJsonElementWithAttributeOnType
{
public ClassWithReadOnlyPropertyIDictionary_BackedBy_DictionaryOfStringToJsonElementWithAttributeOnType() {}

public IDictionary Property { get; } = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>("""{"a":1,"b":2,"c":3}""");
public IDictionary Property { get; } = ParseJsonObject("""{"a":1,"b":2,"c":3}""").ToDictionary(kv => kv.Key, kv => kv.Value);
}

[Fact]
Expand Down Expand Up @@ -670,7 +680,7 @@ public async Task CreationHandlingSetWithAttribute_CanPopulate_IDictionary_Backe
internal class ClassWithReadOnlyPropertyIDictionary_BackedBy_StructDictionaryOfStringToJsonElement
{
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
public IDictionary Property { get; } = JsonSerializer.Deserialize<StructDictionary<string, JsonElement>>("""{"a":1,"b":2,"c":3}""");
public IDictionary Property { get; } = new StructDictionary<string, JsonElement>(ParseJsonObject("""{"a":1,"b":2,"c":3}"""));
}

[Fact]
Expand Down Expand Up @@ -716,13 +726,13 @@ public async Task CreationHandlingSetWithOptions_CanPopulate_IDictionary_BackedB

internal class ClassWithReadOnlyPropertyIDictionary_BackedBy_StructDictionaryOfStringToJsonElementWithoutPopulateAttribute
{
public IDictionary Property { get; } = JsonSerializer.Deserialize<StructDictionary<string, JsonElement>>("""{"a":1,"b":2,"c":3}""");
public IDictionary Property { get; } = new StructDictionary<string, JsonElement>(ParseJsonObject("""{"a":1,"b":2,"c":3}"""));
}

[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
internal class ClassWithReadOnlyPropertyIDictionary_BackedBy_StructDictionaryOfStringToJsonElementWithAttributeOnType
{
public IDictionary Property { get; } = JsonSerializer.Deserialize<StructDictionary<string, JsonElement>>("""{"a":1,"b":2,"c":3}""");
public IDictionary Property { get; } = new StructDictionary<string, JsonElement>(ParseJsonObject("""{"a":1,"b":2,"c":3}"""));
}

[Fact]
Expand Down
Loading

0 comments on commit 1786935

Please sign in to comment.