Skip to content

Commit

Permalink
fix infinite loop in new datetime converter. fix missing sqlite lib i…
Browse files Browse the repository at this point in the history
…n unit tests. (#465)
  • Loading branch information
softlion authored and glennawatson committed Feb 19, 2019
1 parent c91993c commit 7a11834
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 7 deletions.
17 changes: 10 additions & 7 deletions src/Akavache.Core/JsonDateTimeContractResolver.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Serialization;

namespace Akavache
Expand All @@ -18,15 +16,20 @@ public JsonDateTimeContractResolver(IContractResolver contractResolver)
existingContractResolver = contractResolver;
}

protected override JsonContract CreateContract(Type objectType)
public override JsonContract ResolveContract(Type type)
{
var contract = existingContractResolver?.ResolveContract(objectType) ?? base.CreateContract(objectType);
if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
var contract = existingContractResolver?.ResolveContract(type);
if (contract?.Converter != null)
return contract;

if (contract == null)
contract = base.ResolveContract(type);

if (type == typeof(DateTime) || type == typeof(DateTime?))
{
contract.Converter = JsonDateTimeTickConverter.Default;
}

if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?))
else if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
{
contract.Converter = JsonDateTimeOffsetTickConverter.Default;
}
Expand Down
1 change: 1 addition & 0 deletions src/Akavache.Tests/Akavache.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Microsoft.Reactive.Testing" Version="4.0.0" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="1.1.13" />
</ItemGroup>

<ItemGroup>
Expand Down
71 changes: 71 additions & 0 deletions src/Akavache.Tests/DateTimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,83 @@
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Xunit;

namespace Akavache.Tests
{
public class DateTimeTests
{
public DateTimeTests()
{
SQLitePCL.Batteries_V2.Init();
}

[Fact]
public void JsonDateTimeContractResolver_ValidateConverter()
{
//Verify our converter used
var cr = (IContractResolver)new JsonDateTimeContractResolver(null);
var c = cr.ResolveContract(typeof(DateTime));
Assert.True(c.Converter == JsonDateTimeTickConverter.Default);
c = cr.ResolveContract(typeof(DateTime));
Assert.True(c.Converter == JsonDateTimeTickConverter.Default);
c = cr.ResolveContract(typeof(DateTime?));
Assert.True(c.Converter == JsonDateTimeTickConverter.Default);
c = cr.ResolveContract(typeof(DateTime?));
Assert.True(c.Converter == JsonDateTimeTickConverter.Default);

//Verify the other converter is used
cr = new JsonDateTimeContractResolver(new FakeDateTimeHighPrecisionContractResolver());
c = cr.ResolveContract(typeof(DateTime));
Assert.True(c.Converter is FakeDateTimeHighPrecisionJsonConverter);
c = cr.ResolveContract(typeof(DateTimeOffset));
Assert.True(c.Converter == JsonDateTimeOffsetTickConverter.Default);
}

class FakeDateTimeHighPrecisionContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
var contract = base.CreateContract(objectType);
if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
contract.Converter = new FakeDateTimeHighPrecisionJsonConverter();
return contract;
}
}

class FakeDateTimeHighPrecisionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.Integer && reader.TokenType != JsonToken.Date)
return null;

// If you need to deserialize already-serialized DateTimeOffsets, it would come in as JsonToken.Date, uncomment to handle
// Newly serialized values will come in as JsonToken.Integer
if (reader.TokenType == JsonToken.Date)
return (DateTime)reader.Value;

var ticks = (long)reader.Value;
return new DateTime(ticks, DateTimeKind.Utc);
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value != null) {
var dateTime = value is DateTime dt ? dt : ((DateTime?)value).Value;
serializer.Serialize(writer, dateTime.ToUniversalTime().Ticks);
}
}
}


[Theory]
[MemberData(nameof(DateTimeOffsetData))]
public async Task GetOrFetchAsync_DateTimeOffsetShouldBeEqualEveryTime(TestObjectDateTimeOffset data)
Expand Down

0 comments on commit 7a11834

Please sign in to comment.