Skip to content

Commit

Permalink
Merge pull request #1 from bryanjhogan/SystemTextJson
Browse files Browse the repository at this point in the history
Added System.Text.Json
  • Loading branch information
reisenberger authored Jan 30, 2020
2 parents 25fdc82 + 5d5133b commit 4afd1cf
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 0 deletions.
31 changes: 31 additions & 0 deletions Polly.Caching.Serialization.System.Text.Json.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Caching.Serialization.System.Text.Json", "src\Polly.Caching.Serialization.System.Text.Json\Polly.Caching.Serialization.System.Text.Json.csproj", "{C9D59F30-246F-4BA6-B999-1B51BC8FA304}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Caching.Serialization.System.Text.Json.Specs", "src\Polly.Caching.Serialization.System.Text.Json.Specs\Polly.Caching.Serialization.System.Text.Json.Specs.csproj", "{645164C9-2513-4878-A141-4FA609576191}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Release|Any CPU.Build.0 = Release|Any CPU
{645164C9-2513-4878-A141-4FA609576191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{645164C9-2513-4878-A141-4FA609576191}.Debug|Any CPU.Build.0 = Debug|Any CPU
{645164C9-2513-4878-A141-4FA609576191}.Release|Any CPU.ActiveCfg = Release|Any CPU
{645164C9-2513-4878-A141-4FA609576191}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A86A54F7-0C6A-4389-B16E-37CA68C24A9B}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
using System;
using FluentAssertions;
using Xunit;
using Polly.Caching.Serialization.System.Text.Json;
using System.Text.Json;

namespace Polly.Specs.Caching.Serialization.System.Text.Json.Specs
{
public class JsonSerializerSpecs
{
readonly JsonSerializerOptions StandardSettings = new JsonSerializerOptions
{
WriteIndented = true
};

#region Configuration

[Fact]
public void Should_throw_when_JsonSerializerSettings_is_null()
{
Action configure = () => new JsonSerializer<object>(null);

configure.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("jsonSerializerOptions");
}

[Fact]
public void Should_not_throw_when_configured_with_non_null_JsonSerializerSettings()
{
JsonSerializerOptions settings = new JsonSerializerOptions();

Action configure = () => new JsonSerializer<object>(settings);

configure.ShouldNotThrow();
}

#endregion

#region Serialize

[Fact]
public void Should_serialize_using_configured_JsonSerializerSettings()
{
JsonSerializer<SampleClass> serializer = new JsonSerializer<SampleClass>(StandardSettings);

SampleClass objectToSerialize = new SampleClass()
{
StringProperty = "<html></html>",
IntProperty = 1
};

string serialized = serializer.Serialize(objectToSerialize);

serialized.Should().Be("{\r\n \"StringProperty\": \"\\u003Chtml\\u003E\\u003C/html\\u003E\",\r\n \"IntProperty\": 1\r\n}");
}

#endregion

#region Deserialize

[Fact]
public void Should_deserialize_using_configured_JsonSerializerSettings()
{
JsonSerializer<SampleClass> serializer = new JsonSerializer<SampleClass>(StandardSettings);

string serialized = "{\"StringProperty\":\"\\u003chtml\\u003e\\u003c/html\\u003e\",\"IntProperty\":1}";

SampleClass deserialized = serializer.Deserialize(serialized);

deserialized.ShouldBeEquivalentTo(new
{
IntProperty = 1,
StringProperty = "<html></html>"
});
}

[Fact]
public void Throws_on_deserialize_null()
{
JsonSerializer<object> serializer = new JsonSerializer<object>(StandardSettings);

Action deserializeNull = () => serializer.Deserialize(null);

deserializeNull.ShouldThrow<ArgumentNullException>();
}

#endregion

#region Round-trip

[Theory]
[MemberData(nameof(SampleClassData))]
public void Should_roundtrip_all_variants_of_reference_type(SampleClass testValue)
{
JsonSerializer<SampleClass> serializer = new JsonSerializer<SampleClass>(StandardSettings);

serializer.Deserialize(serializer.Serialize(testValue)).ShouldBeEquivalentTo(testValue);
}

public static TheoryData<SampleClass> SampleClassData =>
new TheoryData<SampleClass>
{
new SampleClass(),
new SampleClass()
{
StringProperty = "<html></html>",
IntProperty = 1
},
(SampleClass)null,
default(SampleClass)
};

public class SampleClass
{
public string StringProperty { get; set; }
public int IntProperty { get; set; }
}

[Theory]
[MemberData(nameof(SampleStringData))]
public void Should_roundtrip_all_variants_of_string(String testValue)
{
JsonSerializer<String> serializer = new JsonSerializer<String>(StandardSettings);

serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
}

public static TheoryData<String> SampleStringData =>
new TheoryData<String>
{
"some string",
"",
null,
default(string),
"null"
};

[Theory]
[MemberData(nameof(SampleNumericData))]
public void Should_roundtrip_all_variants_of_numeric(int testValue)
{
JsonSerializer<int> serializer = new JsonSerializer<int>(StandardSettings);

serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
}


public static TheoryData<int> SampleNumericData =>
new TheoryData<int>
{
-1,
0,
1,
default(int)
};

[Theory]
[MemberData(nameof(SampleEnumData))]
public void Should_roundtrip_all_variants_of_enum(SampleEnum testValue)
{
JsonSerializer<SampleEnum> serializer = new JsonSerializer<SampleEnum>(StandardSettings);

serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
}


public static TheoryData<SampleEnum> SampleEnumData =>
new TheoryData<SampleEnum>
{
SampleEnum.FirstValue,
SampleEnum.SecondValue,
default(SampleEnum),
};

public enum SampleEnum
{
FirstValue,
SecondValue,
}

[Theory]
[MemberData(nameof(SampleBoolData))]
public void Should_roundtrip_all_variants_of_bool(bool testValue)
{
JsonSerializer<bool> serializer = new JsonSerializer<bool>(StandardSettings);

serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
}

public static TheoryData<bool> SampleBoolData =>
new TheoryData<bool>
{
true,
false,
default(bool),
};

[Theory]
[MemberData(nameof(SampleNullableBoolData))]
public void Should_roundtrip_all_variants_of_nullable_bool(bool? testValue)
{
JsonSerializer<bool?> serializer = new JsonSerializer<bool?>(StandardSettings);

serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
}

public static TheoryData<bool?> SampleNullableBoolData =>
new TheoryData<bool?>
{
true,
false,
null,
default(bool?),
};
#endregion
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>Library</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<OutputTypeEx>library</OutputTypeEx>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
<DefineConstants>TRACE;DEBUG;PORTABLE;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE;RELEASE;RELEASE;PORTABLE;NETCOREAPP3_0</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="4.19.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="Polly" Version="7.2.0" />
<PackageReference Include="System.Text.Json" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Polly.Caching.Serialization.System.Text.Json\Polly.Caching.Serialization.System.Text.Json.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using System.Reflection;
using Xunit;

[assembly: AssemblyTitle("Polly.Caching.Serialization.System.Text.Json.Specs")]
[assembly: CollectionBehavior(DisableTestParallelization = true)]
43 changes: 43 additions & 0 deletions src/Polly.Caching.Serialization.System.Text.Json/JsonSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Text.Json;

namespace Polly.Caching.Serialization.System.Text.Json
{
/// <summary>
/// A serializer for serializing items of type <typeparamref name="TResult"/> to JSON, for the Polly <see cref="CachePolicy"/>
/// </summary>
/// <typeparam name="TResult"/>
public class JsonSerializer<TResult> : ICacheItemSerializer<TResult, string>
{
private readonly JsonSerializerOptions _jsonSerializerOptions;

/// <summary>
/// Constructs a new <see cref="JsonSerializer{TResult}"/> using the given <see cref="JsonSerializerOptions"/>.
/// </summary>
/// <param name="jsonSerializerOptions">The <see cref="JsonSerializerOptions"/> to use for serialization and deserialization.</param>
public JsonSerializer(JsonSerializerOptions jsonSerializerOptions)
{
_jsonSerializerOptions = jsonSerializerOptions ?? throw new ArgumentNullException(nameof(jsonSerializerOptions));
}

/// <summary>
/// Deserializes the passed json-serialization of an object, to type <typeparamref name="TResult"/>, using the <see cref="JsonSerializerOptions"/> passed when the <see cref="JsonSerializer{TResult}"/> was constructed.
/// </summary>
/// <param name="objectToDeserialize">The object to deserialize</param>
/// <returns>The deserialized object</returns>
public TResult Deserialize(string objectToDeserialize)
{
return JsonSerializer.Deserialize<TResult>(objectToDeserialize);
}

/// <summary>
/// Serializes the specified object to JSON, using the <see cref="JsonSerializerOptions"/> passed when the <see cref="JsonSerializer{TResult}"/> was constructed.
/// </summary>
/// <param name="objectToSerialize">The object to serialize</param>
/// <returns>The serialized object</returns>
public string Serialize(TResult objectToSerialize)
{
return JsonSerializer.Serialize<TResult>(objectToSerialize, _jsonSerializerOptions);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>Polly.Caching.Serialization.System.Text.Json</AssemblyName>
<AssemblyOriginatorKeyFile>..\Polly.snk</AssemblyOriginatorKeyFile>
<DefineConstants>TRACE;DEBUG;PORTABLE;NETCOREAPP3_0</DefineConstants>
<DefaultLanguage>en-US</DefaultLanguage>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<RootNamespace>Polly.Caching.Serialization.System.Text.Json</RootNamespace>
<TargetFramework>netstandard2.0</TargetFramework>
<NetStandardImplicitPackageVersion>2.0.0</NetStandardImplicitPackageVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<NuSpecFile Include="$(SolutionDir)Polly.Caching.Serialization.System.Text.Json.nuspec">
<Visible>False</Visible>
</NuSpecFile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Polly" Version="7.2.0" />
<PackageReference Include="System.Text.Json" Version="4.7.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyTitle("Polly.Caching.Serialization.System.Text.Json")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]

[assembly: InternalsVisibleTo("Polly.Caching.Serialization.System.Text.Json.Specs")]

0 comments on commit 4afd1cf

Please sign in to comment.