Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polymorphic record tests #137

Merged
merged 3 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -1,28 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<ProjectName>Aviationexam.GeneratedJsonConverters.SourceGenerator.Target.Tests</ProjectName>
<IsPackable>false</IsPackable>
</PropertyGroup>
<Import Project="..\WarningConfiguration.targets" />
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Aviationexam.GeneratedJsonConverters.SourceGenerator.Target\Aviationexam.GeneratedJsonConverters.SourceGenerator.Target.csproj" />
<ProjectReference Include="..\Aviationexam.GeneratedJsonConverters.SourceGenerator\Aviationexam.GeneratedJsonConverters.SourceGenerator.csproj" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<ProjectName>Aviationexam.GeneratedJsonConverters.SourceGenerator.Target.Tests</ProjectName>
<IsPackable>false</IsPackable>
</PropertyGroup>

<Import Project="..\WarningConfiguration.targets" />

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Aviationexam.GeneratedJsonConverters.SourceGenerator.Target\Aviationexam.GeneratedJsonConverters.SourceGenerator.Target.csproj" />
<ProjectReference Include="..\Aviationexam.GeneratedJsonConverters.SourceGenerator\Aviationexam.GeneratedJsonConverters.SourceGenerator.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<ProjectName>Aviationexam.GeneratedJsonConverters.SourceGenerator.Tests</ProjectName>
<IsPackable>false</IsPackable>
</PropertyGroup>
<Import Project="..\WarningConfiguration.targets" />
<ItemGroup>
<PackageReference Include="H.Generators.Tests.Extensions" Version="1.22.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.11.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="Verify.XUnit" Version="26.4.5" />
<PackageReference Include="Verify.SourceGenerators" Version="2.4.3" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Aviationexam.GeneratedJsonConverters.SourceGenerator\Aviationexam.GeneratedJsonConverters.SourceGenerator.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="JsonPolymorphicConverterGeneratorSnapshotTests.*.g.verified.cs">
<DependentUpon>JsonPolymorphicConverterGeneratorSnapshotTests.cs</DependentUpon>
</None>
<None Update="EnumJsonConverterIncrementalGeneratorSnapshotTests.*.g.verified.cs">
<DependentUpon>EnumJsonConverterIncrementalGeneratorSnapshotTests.cs</DependentUpon>
</None>
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<ProjectName>Aviationexam.GeneratedJsonConverters.SourceGenerator.Tests</ProjectName>
<IsPackable>false</IsPackable>
</PropertyGroup>

<Import Project="..\WarningConfiguration.targets" />

<ItemGroup>
<PackageReference Include="H.Generators.Tests.Extensions" Version="1.22.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.11.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="Verify.XUnit" Version="26.4.5" />
<PackageReference Include="Verify.SourceGenerators" Version="2.4.3" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Aviationexam.GeneratedJsonConverters.SourceGenerator\Aviationexam.GeneratedJsonConverters.SourceGenerator.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="JsonPolymorphicConverterGeneratorSnapshotTests.*.g.verified.cs">
<DependentUpon>JsonPolymorphicConverterGeneratorSnapshotTests.cs</DependentUpon>
</None>
<None Update="EnumJsonConverterIncrementalGeneratorSnapshotTests.*.g.verified.cs">
<DependentUpon>EnumJsonConverterIncrementalGeneratorSnapshotTests.cs</DependentUpon>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//HintName: BaseContractJsonPolymorphicConverter.g.cs
#nullable enable

namespace ApplicationNamespace;

internal class BaseContractJsonPolymorphicConverter : Aviationexam.GeneratedJsonConverters.PolymorphicJsonConvertor<global::ApplicationNamespace.Contracts.BaseContract>
{
protected override System.ReadOnlySpan<byte> GetDiscriminatorPropertyName() => "$type"u8;

protected override System.Type GetTypeForDiscriminator(
Aviationexam.GeneratedJsonConverters.IDiscriminatorStruct discriminator
) => discriminator switch
{
Aviationexam.GeneratedJsonConverters.DiscriminatorStruct<string> { Value: "LeafContract" } => typeof(ApplicationNamespace.Contracts.LeafContract),
Aviationexam.GeneratedJsonConverters.DiscriminatorStruct<int> { Value: 2 } => typeof(ApplicationNamespace.Contracts.AnotherLeafContract),
Aviationexam.GeneratedJsonConverters.DiscriminatorStruct<string> { Value: "AnonymousLeafContract" } => typeof(ApplicationNamespace.Contracts.AnonymousLeafContract),

_ => throw new System.ArgumentOutOfRangeException(nameof(discriminator), discriminator, null),
};

protected override Aviationexam.GeneratedJsonConverters.IDiscriminatorStruct GetDiscriminatorForType(
System.Type type
)
{
if (type == typeof(ApplicationNamespace.Contracts.LeafContract))
{
return new Aviationexam.GeneratedJsonConverters.DiscriminatorStruct<string>("LeafContract");
}
if (type == typeof(ApplicationNamespace.Contracts.AnotherLeafContract))
{
return new Aviationexam.GeneratedJsonConverters.DiscriminatorStruct<int>(2);
}
if (type == typeof(ApplicationNamespace.Contracts.AnonymousLeafContract))
{
return new Aviationexam.GeneratedJsonConverters.DiscriminatorStruct<string>("AnonymousLeafContract");
}

throw new System.ArgumentOutOfRangeException(nameof(type), type, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//HintName: DiscriminatorStruct.g.cs
// ReSharper disable once RedundantNullableDirective

#nullable enable

namespace Aviationexam.GeneratedJsonConverters;

internal readonly struct DiscriminatorStruct<T> : IDiscriminatorStruct
{
public T Value { get; init; }

public DiscriminatorStruct(T value)
{
Value = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//HintName: IDiscriminatorStruct.g.cs
// ReSharper disable once RedundantNullableDirective

#nullable enable

namespace Aviationexam.GeneratedJsonConverters;

internal interface IDiscriminatorStruct;
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//HintName: JsonDerivedTypeAttribute.g.cs
#nullable enable

namespace Aviationexam.GeneratedJsonConverters.Attributes;

/// <summary>
/// This is a copy of System.Text.Json.Serialization.JsonDerivedTypeAttribute.
/// It's purpose is to replace this attribute to silence System.Text.Json.Serialization.Metadata.PolymorphicTypeResolver{ThrowHelper.ThrowNotSupportedException_BaseConverterDoesNotSupportMetadata}
///
/// When placed on a type declaration, indicates that the specified subtype should be opted into polymorphic serialization.
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
internal class JsonDerivedTypeAttribute : System.Text.Json.Serialization.JsonAttribute
{
/// <summary>
/// Initializes a new attribute with specified parameters.
/// </summary>
/// <param name="derivedType">A derived type that should be supported in polymorphic serialization of the declared based type.</param>
public JsonDerivedTypeAttribute(System.Type derivedType)
{
DerivedType = derivedType;
}

/// <summary>
/// Initializes a new attribute with specified parameters.
/// </summary>
/// <param name="derivedType">A derived type that should be supported in polymorphic serialization of the declared base type.</param>
/// <param name="typeDiscriminator">The type discriminator identifier to be used for the serialization of the subtype.</param>
public JsonDerivedTypeAttribute(System.Type derivedType, string typeDiscriminator)
{
DerivedType = derivedType;
TypeDiscriminator = typeDiscriminator;
}

/// <summary>
/// Initializes a new attribute with specified parameters.
/// </summary>
/// <param name="derivedType">A derived type that should be supported in polymorphic serialization of the declared base type.</param>
/// <param name="typeDiscriminator">The type discriminator identifier to be used for the serialization of the subtype.</param>
public JsonDerivedTypeAttribute(System.Type derivedType, int typeDiscriminator)
{
DerivedType = derivedType;
TypeDiscriminator = typeDiscriminator;
}

/// <summary>
/// A derived type that should be supported in polymorphic serialization of the declared base type.
/// </summary>
public System.Type DerivedType { get; }

/// <summary>
/// The type discriminator identifier to be used for the serialization of the subtype.
/// </summary>
public object? TypeDiscriminator { get; }
}

[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
internal class JsonDerivedTypeAttribute<TDerivedType> : JsonDerivedTypeAttribute
{
/// <summary>
/// Initializes a new attribute with specified parameters.
/// </summary>
public JsonDerivedTypeAttribute() : base(typeof(TDerivedType))
{
}

/// <summary>
/// Initializes a new attribute with specified parameters.
/// </summary>
/// <param name="typeDiscriminator">The type discriminator identifier to be used for the serialization of the subtype.</param>
public JsonDerivedTypeAttribute(string typeDiscriminator) : base(typeof(TDerivedType), typeDiscriminator)
{
}

/// <summary>
/// Initializes a new attribute with specified parameters.
/// </summary>
/// <param name="typeDiscriminator">The type discriminator identifier to be used for the serialization of the subtype.</param>
public JsonDerivedTypeAttribute(int typeDiscriminator) : base(typeof(TDerivedType), typeDiscriminator)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//HintName: JsonPolymorphicAttribute.g.cs
#nullable enable

namespace Aviationexam.GeneratedJsonConverters.Attributes;

/// <summary>
/// This is a copy of System.Text.Json.Serialization.JsonPolymorphicAttribute.
/// It's purpose is to replace this attribute to silence System.Text.Json.Serialization.Metadata.PolymorphicTypeResolver{ThrowHelper.ThrowNotSupportedException_BaseConverterDoesNotSupportMetadata}
///
/// When placed on a type, indicates that the type should be serialized polymorphically.
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
internal sealed class JsonPolymorphicAttribute : System.Text.Json.Serialization.JsonAttribute
{
/// <summary>
/// Gets or sets a custom type discriminator property name for the polymorhic type.
/// Uses the default '$type' property name if left unset.
/// </summary>
public string? TypeDiscriminatorPropertyName { get; set; }

/// <summary>
/// Gets or sets the behavior when serializing an undeclared derived runtime type.
/// </summary>
public System.Text.Json.Serialization.JsonUnknownDerivedTypeHandling UnknownDerivedTypeHandling { get; set; }

/// <summary>
/// When set to <see langword="true"/>, instructs the deserializer to ignore any
/// unrecognized type discriminator id's and reverts to the contract of the base type.
/// Otherwise, it will fail the deserialization.
/// </summary>
public bool IgnoreUnrecognizedTypeDiscriminators { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//HintName: MyJsonSerializerContext.g.cs
#nullable enable

namespace ApplicationNamespace;

public partial class MyJsonSerializerContext
{
public static System.Collections.Generic.IReadOnlyCollection<System.Text.Json.Serialization.JsonConverter> GetPolymorphicConverters() => new System.Text.Json.Serialization.JsonConverter[]
{
new ApplicationNamespace.BaseContractJsonPolymorphicConverter(),
};

public static void UsePolymorphicConverters(
System.Collections.Generic.ICollection<System.Text.Json.Serialization.JsonConverter> optionsConverters
)
{
foreach (var converter in GetPolymorphicConverters())
{
optionsConverters.Add(converter);
}
}
}
Loading
Loading