Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
hlaueriksson committed Jul 11, 2024
1 parent 18283d5 commit 39443d6
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 110 deletions.
40 changes: 0 additions & 40 deletions src/CommandQuery.SystemTextJson/Internal/DictionaryExtensions.cs

This file was deleted.

37 changes: 35 additions & 2 deletions src/CommandQuery.SystemTextJson/Internal/JsonExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,52 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace CommandQuery.SystemTextJson
{
internal static class JsonExtensions
{
internal static object? SafeDeserialize(this string json, Type type, JsonSerializerOptions? options)
private static readonly JsonSerializerOptions _options = GetJsonSerializerOptions();

internal static object? SafeDeserialize(this string json, Type type, JsonSerializerOptions? options = null)
{
try
{
return JsonSerializer.Deserialize(json, type, options ?? _options);
}
catch
{
return null;
}
}

internal static object? SafeDeserialize(this IDictionary<string, object>? dictionary, Type type)
{
if (dictionary is null)
{
return null;
}

try
{
return JsonSerializer.Deserialize(json, type, options);
return JsonSerializer.Deserialize(JsonSerializer.Serialize(dictionary), type, _options);
}
catch
{
return null;
}
}

private static JsonSerializerOptions GetJsonSerializerOptions()
{
var result = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString,
};
result.Converters.Add(new JsonStringEnumConverter());
result.Converters.Add(new BooleanConverter());

return result;
}
}
}
4 changes: 2 additions & 2 deletions tests/CommandQuery.Benchmark/JsonBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ public void GlobalSetup()
// SystemTextJson

[Benchmark]
public object SystemTextJson_JsonExtensions_SafeDeserialize() => SystemTextJson.JsonExtensions.SafeDeserialize(_systemTextJsonString, typeof(FakeComplexObject), null);
public object SystemTextJson_string_SafeDeserialize() => SystemTextJson.JsonExtensions.SafeDeserialize(_systemTextJsonString, typeof(FakeComplexObject), null);

[Benchmark]
public object SystemTextJson_DictionaryExtensions_SafeDeserialize() => SystemTextJson.DictionaryExtensions.SafeDeserialize(_dictionary, typeof(FakeComplexObject));
public object SystemTextJson_Dictionary_SafeDeserialize() => SystemTextJson.JsonExtensions.SafeDeserialize(_dictionary, typeof(FakeComplexObject));
}

public class FakeComplexObject
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,89 @@ namespace CommandQuery.Tests.SystemTextJson.Internal
public class JsonExtensionsTests
{
[LoFu, Test]
public void SafeDeserialize()
public void SafeDeserialize_string()
{
void should_return_an_object()
{
"{}".SafeDeserialize(typeof(object), null).Should().NotBeNull();
"{}".SafeDeserialize(typeof(object)).Should().NotBeNull();

JsonSerializer.Serialize(TestData.FakeComplexQuery)
.SafeDeserialize(typeof(FakeComplexQuery), null)
.SafeDeserialize(typeof(FakeComplexQuery))
.Should().BeEquivalentTo(TestData.FakeComplexQuery);

JsonSerializer.Serialize(TestData.FakeDateTimeQuery)
.SafeDeserialize(typeof(FakeDateTimeQuery), null)
.SafeDeserialize(typeof(FakeDateTimeQuery))
.Should().BeEquivalentTo(TestData.FakeDateTimeQuery);

JsonSerializer.Serialize(TestData.FakeNestedQuery)
.SafeDeserialize(typeof(FakeNestedQuery), null)
.SafeDeserialize(typeof(FakeNestedQuery))
.Should().BeEquivalentTo(TestData.FakeNestedQuery);
}

void should_return_null_if_deserialization_fails() => ((string)null).SafeDeserialize(typeof(object), null).Should().BeNull();
void should_have_sane_defaults()
{
var result = "{\"int32\":\"1\"}".SafeDeserialize(typeof(FakeComplexQuery)) as FakeComplexQuery;
result.Int32.Should().Be(1);
}

void should_use_options_when_provided()
{
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
var result = "{\"int32\":\"1\"}".SafeDeserialize(typeof(FakeComplexQuery), options) as FakeComplexQuery;
result.Int32.Should().Be(1);
}

void should_return_null_if_deserialization_fails() => ((string)null).SafeDeserialize(typeof(object)).Should().BeNull();
}

[LoFu, Test]
public void SafeDeserialize_Dictionary()
{
void should_set_the_property_values()
{
var subject = TestData.FakeComplexQuery_As_Dictionary_Of_String_Object;
var result = subject.SafeDeserialize(typeof(FakeComplexQuery)) as FakeComplexQuery;
result.Should().BeEquivalentTo(TestData.FakeComplexQuery);

subject = TestData.FakeComplexQuery_As_Dictionary_Of_String_Object.ToDictionary(x => x.Key.ToLower(), x => x.Value);
result = subject.SafeDeserialize(typeof(FakeComplexQuery)) as FakeComplexQuery;
result.Should().BeEquivalentTo(TestData.FakeComplexQuery);
}

void should_set_the_property_values_of_DateTime_kinds()
{
var subject = TestData.FakeDateTimeQuery_As_Dictionary_Of_String_Object;

var result = subject.SafeDeserialize(typeof(FakeDateTimeQuery)) as FakeDateTimeQuery;

result.Should().BeEquivalentTo(TestData.FakeDateTimeQuery);
}

void should_not_set_the_property_values_of_nested_objects()
{
var subject = TestData.FakeNestedQuery_As_Dictionary_Of_String_Object;

var result = subject.SafeDeserialize(typeof(FakeNestedQuery)) as FakeNestedQuery;

result.Should().BeEquivalentTo(TestData.FakeNestedQuery);
}

void should_return_null_if_dictionary_is_null()
{
IDictionary<string, object> subject = null;

subject.SafeDeserialize(typeof(FakeComplexQuery)).Should().BeNull();
}

void should_return_null_if_conversion_fails()
{
var subject = new Dictionary<string, object>
{
{ "Guid", "fail" }
};

subject.SafeDeserialize(typeof(FakeComplexQuery)).Should().BeNull();
}
}
}
}

0 comments on commit 39443d6

Please sign in to comment.