Skip to content

Commit 4afd1cf

Browse files
authored
Merge pull request #1 from bryanjhogan/SystemTextJson
Added System.Text.Json
2 parents 25fdc82 + 5d5133b commit 4afd1cf

File tree

7 files changed

+363
-0
lines changed

7 files changed

+363
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.29613.14
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
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}"
7+
EndProject
8+
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}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{C9D59F30-246F-4BA6-B999-1B51BC8FA304}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{645164C9-2513-4878-A141-4FA609576191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{645164C9-2513-4878-A141-4FA609576191}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{645164C9-2513-4878-A141-4FA609576191}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{645164C9-2513-4878-A141-4FA609576191}.Release|Any CPU.Build.0 = Release|Any CPU
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {A86A54F7-0C6A-4389-B16E-37CA68C24A9B}
30+
EndGlobalSection
31+
EndGlobal
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
using System;
2+
using FluentAssertions;
3+
using Xunit;
4+
using Polly.Caching.Serialization.System.Text.Json;
5+
using System.Text.Json;
6+
7+
namespace Polly.Specs.Caching.Serialization.System.Text.Json.Specs
8+
{
9+
public class JsonSerializerSpecs
10+
{
11+
readonly JsonSerializerOptions StandardSettings = new JsonSerializerOptions
12+
{
13+
WriteIndented = true
14+
};
15+
16+
#region Configuration
17+
18+
[Fact]
19+
public void Should_throw_when_JsonSerializerSettings_is_null()
20+
{
21+
Action configure = () => new JsonSerializer<object>(null);
22+
23+
configure.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("jsonSerializerOptions");
24+
}
25+
26+
[Fact]
27+
public void Should_not_throw_when_configured_with_non_null_JsonSerializerSettings()
28+
{
29+
JsonSerializerOptions settings = new JsonSerializerOptions();
30+
31+
Action configure = () => new JsonSerializer<object>(settings);
32+
33+
configure.ShouldNotThrow();
34+
}
35+
36+
#endregion
37+
38+
#region Serialize
39+
40+
[Fact]
41+
public void Should_serialize_using_configured_JsonSerializerSettings()
42+
{
43+
JsonSerializer<SampleClass> serializer = new JsonSerializer<SampleClass>(StandardSettings);
44+
45+
SampleClass objectToSerialize = new SampleClass()
46+
{
47+
StringProperty = "<html></html>",
48+
IntProperty = 1
49+
};
50+
51+
string serialized = serializer.Serialize(objectToSerialize);
52+
53+
serialized.Should().Be("{\r\n \"StringProperty\": \"\\u003Chtml\\u003E\\u003C/html\\u003E\",\r\n \"IntProperty\": 1\r\n}");
54+
}
55+
56+
#endregion
57+
58+
#region Deserialize
59+
60+
[Fact]
61+
public void Should_deserialize_using_configured_JsonSerializerSettings()
62+
{
63+
JsonSerializer<SampleClass> serializer = new JsonSerializer<SampleClass>(StandardSettings);
64+
65+
string serialized = "{\"StringProperty\":\"\\u003chtml\\u003e\\u003c/html\\u003e\",\"IntProperty\":1}";
66+
67+
SampleClass deserialized = serializer.Deserialize(serialized);
68+
69+
deserialized.ShouldBeEquivalentTo(new
70+
{
71+
IntProperty = 1,
72+
StringProperty = "<html></html>"
73+
});
74+
}
75+
76+
[Fact]
77+
public void Throws_on_deserialize_null()
78+
{
79+
JsonSerializer<object> serializer = new JsonSerializer<object>(StandardSettings);
80+
81+
Action deserializeNull = () => serializer.Deserialize(null);
82+
83+
deserializeNull.ShouldThrow<ArgumentNullException>();
84+
}
85+
86+
#endregion
87+
88+
#region Round-trip
89+
90+
[Theory]
91+
[MemberData(nameof(SampleClassData))]
92+
public void Should_roundtrip_all_variants_of_reference_type(SampleClass testValue)
93+
{
94+
JsonSerializer<SampleClass> serializer = new JsonSerializer<SampleClass>(StandardSettings);
95+
96+
serializer.Deserialize(serializer.Serialize(testValue)).ShouldBeEquivalentTo(testValue);
97+
}
98+
99+
public static TheoryData<SampleClass> SampleClassData =>
100+
new TheoryData<SampleClass>
101+
{
102+
new SampleClass(),
103+
new SampleClass()
104+
{
105+
StringProperty = "<html></html>",
106+
IntProperty = 1
107+
},
108+
(SampleClass)null,
109+
default(SampleClass)
110+
};
111+
112+
public class SampleClass
113+
{
114+
public string StringProperty { get; set; }
115+
public int IntProperty { get; set; }
116+
}
117+
118+
[Theory]
119+
[MemberData(nameof(SampleStringData))]
120+
public void Should_roundtrip_all_variants_of_string(String testValue)
121+
{
122+
JsonSerializer<String> serializer = new JsonSerializer<String>(StandardSettings);
123+
124+
serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
125+
}
126+
127+
public static TheoryData<String> SampleStringData =>
128+
new TheoryData<String>
129+
{
130+
"some string",
131+
"",
132+
null,
133+
default(string),
134+
"null"
135+
};
136+
137+
[Theory]
138+
[MemberData(nameof(SampleNumericData))]
139+
public void Should_roundtrip_all_variants_of_numeric(int testValue)
140+
{
141+
JsonSerializer<int> serializer = new JsonSerializer<int>(StandardSettings);
142+
143+
serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
144+
}
145+
146+
147+
public static TheoryData<int> SampleNumericData =>
148+
new TheoryData<int>
149+
{
150+
-1,
151+
0,
152+
1,
153+
default(int)
154+
};
155+
156+
[Theory]
157+
[MemberData(nameof(SampleEnumData))]
158+
public void Should_roundtrip_all_variants_of_enum(SampleEnum testValue)
159+
{
160+
JsonSerializer<SampleEnum> serializer = new JsonSerializer<SampleEnum>(StandardSettings);
161+
162+
serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
163+
}
164+
165+
166+
public static TheoryData<SampleEnum> SampleEnumData =>
167+
new TheoryData<SampleEnum>
168+
{
169+
SampleEnum.FirstValue,
170+
SampleEnum.SecondValue,
171+
default(SampleEnum),
172+
};
173+
174+
public enum SampleEnum
175+
{
176+
FirstValue,
177+
SecondValue,
178+
}
179+
180+
[Theory]
181+
[MemberData(nameof(SampleBoolData))]
182+
public void Should_roundtrip_all_variants_of_bool(bool testValue)
183+
{
184+
JsonSerializer<bool> serializer = new JsonSerializer<bool>(StandardSettings);
185+
186+
serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
187+
}
188+
189+
public static TheoryData<bool> SampleBoolData =>
190+
new TheoryData<bool>
191+
{
192+
true,
193+
false,
194+
default(bool),
195+
};
196+
197+
[Theory]
198+
[MemberData(nameof(SampleNullableBoolData))]
199+
public void Should_roundtrip_all_variants_of_nullable_bool(bool? testValue)
200+
{
201+
JsonSerializer<bool?> serializer = new JsonSerializer<bool?>(StandardSettings);
202+
203+
serializer.Deserialize(serializer.Serialize(testValue)).Should().Be(testValue);
204+
}
205+
206+
public static TheoryData<bool?> SampleNullableBoolData =>
207+
new TheoryData<bool?>
208+
{
209+
true,
210+
false,
211+
null,
212+
default(bool?),
213+
};
214+
#endregion
215+
}
216+
217+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
4+
<OutputType>Library</OutputType>
5+
<TargetFramework>netcoreapp2.0</TargetFramework>
6+
<OutputTypeEx>library</OutputTypeEx>
7+
</PropertyGroup>
8+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
9+
<DebugType>full</DebugType>
10+
<DefineConstants>TRACE;DEBUG;PORTABLE;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
11+
</PropertyGroup>
12+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
13+
<DebugType>pdbonly</DebugType>
14+
<Optimize>true</Optimize>
15+
<DefineConstants>TRACE;RELEASE;RELEASE;PORTABLE;NETCOREAPP3_0</DefineConstants>
16+
</PropertyGroup>
17+
<ItemGroup>
18+
<PackageReference Include="FluentAssertions" Version="4.19.3" />
19+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
20+
<PackageReference Include="xunit" Version="2.2.0" />
21+
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
22+
<PackageReference Include="Polly" Version="7.2.0" />
23+
<PackageReference Include="System.Text.Json" Version="4.7.0" />
24+
</ItemGroup>
25+
<ItemGroup>
26+
<ProjectReference Include="..\Polly.Caching.Serialization.System.Text.Json\Polly.Caching.Serialization.System.Text.Json.csproj" />
27+
</ItemGroup>
28+
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
using System.Reflection;
2+
using Xunit;
3+
4+
[assembly: AssemblyTitle("Polly.Caching.Serialization.System.Text.Json.Specs")]
5+
[assembly: CollectionBehavior(DisableTestParallelization = true)]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Text.Json;
3+
4+
namespace Polly.Caching.Serialization.System.Text.Json
5+
{
6+
/// <summary>
7+
/// A serializer for serializing items of type <typeparamref name="TResult"/> to JSON, for the Polly <see cref="CachePolicy"/>
8+
/// </summary>
9+
/// <typeparam name="TResult"/>
10+
public class JsonSerializer<TResult> : ICacheItemSerializer<TResult, string>
11+
{
12+
private readonly JsonSerializerOptions _jsonSerializerOptions;
13+
14+
/// <summary>
15+
/// Constructs a new <see cref="JsonSerializer{TResult}"/> using the given <see cref="JsonSerializerOptions"/>.
16+
/// </summary>
17+
/// <param name="jsonSerializerOptions">The <see cref="JsonSerializerOptions"/> to use for serialization and deserialization.</param>
18+
public JsonSerializer(JsonSerializerOptions jsonSerializerOptions)
19+
{
20+
_jsonSerializerOptions = jsonSerializerOptions ?? throw new ArgumentNullException(nameof(jsonSerializerOptions));
21+
}
22+
23+
/// <summary>
24+
/// 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.
25+
/// </summary>
26+
/// <param name="objectToDeserialize">The object to deserialize</param>
27+
/// <returns>The deserialized object</returns>
28+
public TResult Deserialize(string objectToDeserialize)
29+
{
30+
return JsonSerializer.Deserialize<TResult>(objectToDeserialize);
31+
}
32+
33+
/// <summary>
34+
/// Serializes the specified object to JSON, using the <see cref="JsonSerializerOptions"/> passed when the <see cref="JsonSerializer{TResult}"/> was constructed.
35+
/// </summary>
36+
/// <param name="objectToSerialize">The object to serialize</param>
37+
/// <returns>The serialized object</returns>
38+
public string Serialize(TResult objectToSerialize)
39+
{
40+
return JsonSerializer.Serialize<TResult>(objectToSerialize, _jsonSerializerOptions);
41+
}
42+
}
43+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<AssemblyName>Polly.Caching.Serialization.System.Text.Json</AssemblyName>
4+
<AssemblyOriginatorKeyFile>..\Polly.snk</AssemblyOriginatorKeyFile>
5+
<DefineConstants>TRACE;DEBUG;PORTABLE;NETCOREAPP3_0</DefineConstants>
6+
<DefaultLanguage>en-US</DefaultLanguage>
7+
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
8+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
9+
<RootNamespace>Polly.Caching.Serialization.System.Text.Json</RootNamespace>
10+
<TargetFramework>netstandard2.0</TargetFramework>
11+
<NetStandardImplicitPackageVersion>2.0.0</NetStandardImplicitPackageVersion>
12+
</PropertyGroup>
13+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
14+
<DebugType>full</DebugType>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
17+
<DebugType>pdbonly</DebugType>
18+
<Optimize>true</Optimize>
19+
</PropertyGroup>
20+
<ItemGroup>
21+
<NuSpecFile Include="$(SolutionDir)Polly.Caching.Serialization.System.Text.Json.nuspec">
22+
<Visible>False</Visible>
23+
</NuSpecFile>
24+
</ItemGroup>
25+
<ItemGroup>
26+
<PackageReference Include="Polly" Version="7.2.0" />
27+
<PackageReference Include="System.Text.Json" Version="4.7.0" />
28+
</ItemGroup>
29+
</Project>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
using System.Reflection;
3+
using System.Runtime.CompilerServices;
4+
5+
[assembly: AssemblyTitle("Polly.Caching.Serialization.System.Text.Json")]
6+
[assembly: AssemblyVersion("1.0.0.0")]
7+
[assembly: AssemblyFileVersion("1.0.0.0")]
8+
[assembly: AssemblyInformationalVersion("1.0.0.0")]
9+
10+
[assembly: InternalsVisibleTo("Polly.Caching.Serialization.System.Text.Json.Specs")]

0 commit comments

Comments
 (0)