Skip to content

Commit

Permalink
Fix bug in System.Text.JSon source generator serializers (#136)
Browse files Browse the repository at this point in the history
* Add regression test

* Fix JSON converters
  • Loading branch information
andrewlock authored Apr 25, 2024
1 parent 79c19cd commit c303bd9
Show file tree
Hide file tree
Showing 31 changed files with 129 additions and 84 deletions.
3 changes: 0 additions & 3 deletions src/StronglyTypedIds.Templates/guid-full.typedid
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@

public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());

Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds.Templates/int-full.typedid
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@

public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(int) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetInt32());

Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds.Templates/long-full.typedid
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@

public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(long) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetInt32());

Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds.Templates/newid-full.typedid
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@

public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(string) || typeToConvert == typeof(global::System.Guid) || base.CanConvert(typeToConvert);

public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (global::MassTransit.NewId.FromGuid(reader.GetGuid()));

Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds.Templates/nullablestring-full.typedid
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,6 @@

public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetString());

Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds.Templates/string-full.typedid
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@

public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetString()!);

Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds/EmbeddedSources.Guid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorC
public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);
public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());
Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds/EmbeddedSources.Int.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorC
public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(int) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);
public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetInt32());
Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds/EmbeddedSources.Long.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorC
public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(long) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);
public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetInt64());
Expand Down
3 changes: 0 additions & 3 deletions src/StronglyTypedIds/EmbeddedSources.String.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,6 @@ public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorC
public partial class PLACEHOLDERIDSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<PLACEHOLDERID>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(string) || base.CanConvert(typeToConvert);
public override PLACEHOLDERID Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetString()!);
Expand Down
30 changes: 29 additions & 1 deletion test/StronglyTypedIds.IntegrationTests/GuidIdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.ComponentModel;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Dapper;
using Microsoft.Data.Sqlite;
Expand All @@ -14,7 +15,7 @@

namespace StronglyTypedIds.IntegrationTests
{
public class GuidIdTests
public partial class GuidIdTests
{
[Fact]
public void SameValuesAreEqual()
Expand Down Expand Up @@ -114,6 +115,24 @@ public void CanSerializeToGuid_WithSystemTextJsonProvider()
Assert.Equal(serializedFoo, serializedGuid);
}

[Fact]
public void CanRoundTripWhenInRecord()
{
var foo = new ToSerialize()
{
Id = GuidId1.New(),
};

var serialized = SystemTextJsonSerializer.Serialize(foo);
var deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized);
Assert.Equal(foo, deserialized);
#if NET6_0_OR_GREATER
serialized = SystemTextJsonSerializer.Serialize(foo, SystemTextJsonSerializerContext.Custom.GuidIdTests);
deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized, SystemTextJsonSerializerContext.Custom.GuidIdTests);
Assert.Equal(foo, deserialized);
#endif
}

[Fact]
public void CanDeserializeFromGuid_WithSystemTextJsonProvider()
{
Expand Down Expand Up @@ -590,5 +609,14 @@ internal class EntityWithNullableId2
{
public ConvertersGuidId2? Id { get; set; }
}

internal record ToSerialize
{
public GuidId1 Id { get; set; }
public Guid Guid { get; set; } = Guid.NewGuid();
public long Long { get; set; } = 123;
public int Int { get; set; } = 456;
public string String { get; set; } = "Something";
}
}
}
31 changes: 30 additions & 1 deletion test/StronglyTypedIds.IntegrationTests/IntIdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Data.SqlClient;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Dapper;
using Microsoft.Data.Sqlite;
Expand All @@ -15,7 +16,7 @@

namespace StronglyTypedIds.IntegrationTests;

public class IntIdTests
public partial class IntIdTests
{
[Fact]
public void SameValuesAreEqual()
Expand Down Expand Up @@ -370,6 +371,25 @@ public void CanSerializeToInt_WithMultiTemplates_WithSystemTextJsonProvider()
Assert.Equal(serializedFoo, serializedInt);
}

[Fact]
public void CanRoundTripWhenInRecord()
{
var foo = new ToSerialize()
{
Id = new ConvertersIntId(123),
};

var serialized = SystemTextJsonSerializer.Serialize(foo);
var deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized);
Assert.Equal(foo, deserialized);

#if NET6_0_OR_GREATER
serialized = SystemTextJsonSerializer.Serialize(foo, SystemTextJsonSerializerContext.Custom.IntIdTests);
deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized, SystemTextJsonSerializerContext.Custom.IntIdTests);
Assert.Equal(foo, deserialized);
#endif
}

[Fact]
public void CanDeserializeFromInt_WithMultiTemplates_WithNewtonsoftJsonProvider()
{
Expand Down Expand Up @@ -568,4 +588,13 @@ internal class TypeWithDictionaryKeys
{
public Dictionary<IntId, string> Values { get; set; }
}

internal record ToSerialize
{
public ConvertersIntId Id { get; set; }
public Guid Guid { get; set; } = Guid.NewGuid();
public long Long { get; set; } = 123;
public int Int { get; set; } = 456;
public string String { get; set; } = "Something";
}
}
31 changes: 30 additions & 1 deletion test/StronglyTypedIds.IntegrationTests/LongIdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Data.SqlClient;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Dapper;
using Microsoft.Data.Sqlite;
Expand All @@ -15,7 +16,7 @@

namespace StronglyTypedIds.IntegrationTests
{
public class LongIdTests
public partial class LongIdTests
{
[Fact]
public void SameValuesAreEqual()
Expand Down Expand Up @@ -367,6 +368,25 @@ public void CanSerializeToLong_WithMultiTemplates_WithSystemTextJsonProvider()
Assert.Equal(serializedFoo, serializedLong);
}

[Fact]
public void CanRoundTripWhenInRecord()
{
var foo = new ToSerialize()
{
Id = new ConvertersLongId(123),
};

var serialized = SystemTextJsonSerializer.Serialize(foo);
var deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized);
Assert.Equal(foo, deserialized);

#if NET6_0_OR_GREATER
serialized = SystemTextJsonSerializer.Serialize(foo, SystemTextJsonSerializerContext.Custom.LongIdTests);
deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized, SystemTextJsonSerializerContext.Custom.LongIdTests);
Assert.Equal(foo, deserialized);
#endif
}

[Fact]
public void CanDeserializeFromLong_WithMultiTemplates_WithNewtonsoftJsonProvider()
{
Expand Down Expand Up @@ -550,5 +570,14 @@ internal class TypeWithDictionaryKeys
{
public Dictionary<LongId, string> Values { get; set; }
}

internal record ToSerialize
{
public ConvertersLongId Id { get; set; }
public Guid Guid { get; set; } = Guid.NewGuid();
public long Long { get; set; } = 123;
public int Int { get; set; } = 456;
public string String { get; set; } = "Something";
}
}
}
30 changes: 30 additions & 0 deletions test/StronglyTypedIds.IntegrationTests/StringIdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.ComponentModel;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Dapper;
using Microsoft.Data.Sqlite;
Expand Down Expand Up @@ -211,6 +212,26 @@ public void CanSerializeToString_WithSystemTextJsonProvider()
Assert.Equal(serializedFoo, serializedString);
}


[Fact]
public void CanRoundTripWhenInRecord()
{
var foo = new ToSerialize()
{
Id = new ConvertersStringId("123"),
};

var serialized = SystemTextJsonSerializer.Serialize(foo);
var deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized);
Assert.Equal(foo, deserialized);

#if NET6_0_OR_GREATER
serialized = SystemTextJsonSerializer.Serialize(foo, SystemTextJsonSerializerContext.Custom.StringIdTests);
deserialized = SystemTextJsonSerializer.Deserialize<ToSerialize>(serialized, SystemTextJsonSerializerContext.Custom.StringIdTests);
Assert.Equal(foo, deserialized);
#endif
}

[Fact]
public void CanDeserializeFromString_WithNewtonsoftJsonProvider()
{
Expand Down Expand Up @@ -540,5 +561,14 @@ internal class TypeWithDictionaryKeys
{
public Dictionary<StringId, string> Values { get; set; }
}

internal record ToSerialize
{
public ConvertersStringId Id { get; set; }
public Guid Guid { get; set; } = Guid.NewGuid();
public long Long { get; set; } = 123;
public int Int { get; set; } = 456;
public string String { get; set; } = "Something";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ namespace StronglyTypedIds.IntegrationTests;
[JsonSerializable(typeof(ConvertersGuidId))]
[JsonSerializable(typeof(ConvertersGuidId2))]
[JsonSerializable(typeof(GuidIdTests.TypeWithDictionaryKeys))]
[JsonSerializable(typeof(GuidIdTests.ToSerialize), TypeInfoPropertyName = "GuidIdTests")]
[JsonSerializable(typeof(IntIdTests.ToSerialize), TypeInfoPropertyName = "IntIdTests")]
[JsonSerializable(typeof(LongIdTests.ToSerialize), TypeInfoPropertyName = "LongIdTests")]
[JsonSerializable(typeof(StringIdTests.ToSerialize), TypeInfoPropertyName = "StringIdTests")]
internal partial class SystemTextJsonSerializerContext : JsonSerializerContext
{
internal static SystemTextJsonSerializerContext Custom
Expand All @@ -19,6 +23,9 @@ internal static SystemTextJsonSerializerContext Custom
new GuidId1.GuidId1SystemTextJsonConverter(),
new ConvertersGuidId.ConvertersGuidIdSystemTextJsonConverter(),
new ConvertersGuidId2.ConvertersGuidId2SystemTextJsonConverter(),
new ConvertersIntId.ConvertersIntIdSystemTextJsonConverter(),
new ConvertersLongId.ConvertersLongIdSystemTextJsonConverter(),
new ConvertersStringId.ConvertersStringIdSystemTextJsonConverter(),
}
});

Expand All @@ -32,6 +39,9 @@ internal static SystemTextJsonSerializerContext Web
new GuidId1.GuidId1SystemTextJsonConverter(),
new ConvertersGuidId.ConvertersGuidIdSystemTextJsonConverter(),
new ConvertersGuidId2.ConvertersGuidId2SystemTextJsonConverter(),
new ConvertersIntId.ConvertersIntIdSystemTextJsonConverter(),
new ConvertersLongId.ConvertersLongIdSystemTextJsonConverter(),
new ConvertersStringId.ConvertersStringIdSystemTextJsonConverter(),
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@

public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<MyId>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@ namespace SomeNamespace

public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<MyId>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(string) || typeToConvert == typeof(global::System.Guid) || base.CanConvert(typeToConvert);

public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (global::MassTransit.NewId.FromGuid(reader.GetGuid()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,6 @@ namespace SomeNamespace

public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<MyId>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ namespace SomeNamespace

public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<MyId>
{
public override bool CanConvert(global::System.Type typeToConvert)
=> typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert);

public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());

Expand Down
Loading

0 comments on commit c303bd9

Please sign in to comment.