-
Notifications
You must be signed in to change notification settings - Fork 400
Rework of UnitsNetJsonConverter #746
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
Merged
angularsen
merged 4 commits into
angularsen:master
from
dschuermans:feature/732-UnitsNetJsonConverter
Feb 9, 2020
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
UnitsNet.Serialization.JsonNet.Tests/Infrastructure/TestObject.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Licensed under MIT No Attribution, see LICENSE file at the root. | ||
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet. | ||
|
||
namespace UnitsNet.Serialization.JsonNet.Tests.Infrastructure | ||
{ | ||
public sealed class TestObject | ||
{ | ||
public Frequency? NullableFrequency { get; set; } | ||
public Frequency NonNullableFrequency { get; set; } | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
UnitsNet.Serialization.JsonNet.Tests/Infrastructure/TestObjectWithIComparable.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Licensed under MIT No Attribution, see LICENSE file at the root. | ||
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet. | ||
|
||
using System; | ||
|
||
namespace UnitsNet.Serialization.JsonNet.Tests.Infrastructure | ||
{ | ||
public sealed class TestObjectWithIComparable | ||
{ | ||
public IComparable Value { get; set; } | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
UnitsNet.Serialization.JsonNet.Tests/Infrastructure/TestObjectWithThreeIComparable.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Licensed under MIT No Attribution, see LICENSE file at the root. | ||
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet. | ||
|
||
using System; | ||
|
||
namespace UnitsNet.Serialization.JsonNet.Tests.Infrastructure | ||
{ | ||
public sealed class TestObjectWithThreeIComparable | ||
{ | ||
public IComparable Value1 { get; set; } | ||
|
||
public IComparable Value2 { get; set; } | ||
|
||
public IComparable Value3 { get; set; } | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...Net.Serialization.JsonNet.Tests/Infrastructure/TestObjectWithValueAndUnitAsIComparable.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Licensed under MIT No Attribution, see LICENSE file at the root. | ||
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet. | ||
|
||
using System; | ||
|
||
namespace UnitsNet.Serialization.JsonNet.Tests.Infrastructure | ||
{ | ||
public sealed class TestObjectWithValueAndUnitAsIComparable : IComparable | ||
{ | ||
public double Value { get; set; } | ||
public string Unit { get; set; } | ||
|
||
public int CompareTo(object obj) | ||
{ | ||
return ((IComparable)Value).CompareTo(obj); | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
UnitsNet.Serialization.JsonNet.Tests/Infrastructure/TestObjectWithValueAsIComparable.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Licensed under MIT No Attribution, see LICENSE file at the root. | ||
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet. | ||
|
||
using System; | ||
|
||
namespace UnitsNet.Serialization.JsonNet.Tests.Infrastructure | ||
{ | ||
public sealed class TestObjectWithValueAsIComparable : IComparable | ||
{ | ||
public int Value { get; set; } | ||
|
||
public int CompareTo(object obj) | ||
{ | ||
return ((IComparable)Value).CompareTo(obj); | ||
} | ||
|
||
// Needed for verifying that the deserialized object is the same, should not affect the serialization code | ||
public override bool Equals(object obj) | ||
{ | ||
if (obj == null || GetType() != obj.GetType()) | ||
{ | ||
return false; | ||
} | ||
return Value.Equals(((TestObjectWithValueAsIComparable)obj).Value); | ||
} | ||
|
||
public override int GetHashCode() | ||
{ | ||
return Value.GetHashCode(); | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
UnitsNet.Serialization.JsonNet.Tests/Infrastructure/UnitsNetJsonBaseTest.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Licensed under MIT No Attribution, see LICENSE file at the root. | ||
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet. | ||
|
||
using Newtonsoft.Json; | ||
|
||
namespace UnitsNet.Serialization.JsonNet.Tests.Infrastructure | ||
{ | ||
public abstract class UnitsNetJsonBaseTest | ||
{ | ||
private readonly JsonSerializerSettings _jsonSerializerSettings; | ||
|
||
protected UnitsNetJsonBaseTest() | ||
{ | ||
_jsonSerializerSettings = new JsonSerializerSettings {Formatting = Formatting.Indented}; | ||
_jsonSerializerSettings.Converters.Add(new UnitsNetIQuantityJsonConverter()); | ||
_jsonSerializerSettings.Converters.Add(new UnitsNetIComparableJsonConverter()); | ||
} | ||
|
||
protected string SerializeObject(object obj, TypeNameHandling typeNameHandling = TypeNameHandling.None) | ||
{ | ||
_jsonSerializerSettings.TypeNameHandling = typeNameHandling; | ||
|
||
return JsonConvert.SerializeObject(obj, _jsonSerializerSettings).Replace("\r\n", "\n"); | ||
} | ||
|
||
protected T DeserializeObject<T>(string json, TypeNameHandling typeNameHandling = TypeNameHandling.None) | ||
{ | ||
_jsonSerializerSettings.TypeNameHandling = typeNameHandling; | ||
|
||
return JsonConvert.DeserializeObject<T>(json, _jsonSerializerSettings); | ||
} | ||
} | ||
} |
209 changes: 209 additions & 0 deletions
209
UnitsNet.Serialization.JsonNet.Tests/UnitsNetBaseJsonConverterTest.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
// Licensed under MIT No Attribution, see LICENSE file at the root. | ||
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Converters; | ||
using Newtonsoft.Json.Linq; | ||
using Newtonsoft.Json.Serialization; | ||
using Xunit; | ||
|
||
namespace UnitsNet.Serialization.JsonNet.Tests | ||
{ | ||
public sealed class UnitsNetBaseJsonConverterTest | ||
{ | ||
private TestConverter _sut; | ||
|
||
public UnitsNetBaseJsonConverterTest() | ||
{ | ||
_sut = new TestConverter(); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ConvertIQuantity_works_as_expected() | ||
{ | ||
var result = _sut.Test_ConvertIQuantity(Power.FromWatts(10.2365D)); | ||
|
||
Assert.Equal("PowerUnit.Watt", result.Unit); | ||
Assert.Equal(10.2365D, result.Value); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ConvertIQuantity_throws_ArgumentNullException_when_quantity_is_NULL() | ||
{ | ||
var result = Assert.Throws<ArgumentNullException>(() => _sut.Test_ConvertIQuantity(null)); | ||
|
||
Assert.Equal("Value cannot be null.\r\nParameter name: quantity", result.Message); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ConvertValueUnit_works_as_expected() | ||
{ | ||
var result = _sut.Test_ConvertValueUnit("PowerUnit.Watt", 10.2365D); | ||
|
||
Assert.NotNull(result); | ||
Assert.IsType<Power>(result); | ||
Assert.True(Power.FromWatts(10.2365D).Equals((Power)result, 1E-5, ComparisonType.Absolute)); | ||
|
||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ConvertValueUnit_works_with_NULL_value() | ||
{ | ||
var result = _sut.Test_ConvertValueUnit(); | ||
|
||
Assert.Null(result); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ConvertValueUnit_throws_UnitsNetException_when_unit_does_not_exist() | ||
{ | ||
var result = Assert.Throws<UnitsNetException>(() => _sut.Test_ConvertValueUnit("SomeImaginaryUnit.Watt", 10.2365D)); | ||
|
||
Assert.Equal("Unable to find enum type.", result.Message); | ||
Assert.True(result.Data.Contains("type")); | ||
Assert.Equal("UnitsNet.Units.SomeImaginaryUnit,UnitsNet", result.Data["type"]); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ConvertValueUnit_throws_UnitsNetException_when_unit_is_in_unexpected_format() | ||
{ | ||
var result = Assert.Throws<UnitsNetException>(() => _sut.Test_ConvertValueUnit("PowerUnit Watt", 10.2365D)); | ||
|
||
Assert.Equal("\"PowerUnit Watt\" is not a valid unit.", result.Message); | ||
Assert.True(result.Data.Contains("type")); | ||
Assert.Equal("PowerUnit Watt", result.Data["type"]); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_CreateLocalSerializer_works_as_expected() | ||
{ | ||
//Possible improvement: Set all possible settings and test each one. But the main goal of CreateLocalSerializer is that the current serializer is left out. | ||
var serializer = JsonSerializer.Create(new JsonSerializerSettings() | ||
{ | ||
TypeNameHandling = TypeNameHandling.Arrays, | ||
Converters = new List<JsonConverter>() | ||
{ | ||
|
||
new BinaryConverter(), | ||
_sut, | ||
new DataTableConverter() | ||
}, | ||
ContractResolver = new CamelCasePropertyNamesContractResolver() | ||
}); | ||
|
||
var result = _sut.Test_CreateLocalSerializer(serializer); | ||
|
||
Assert.Equal(TypeNameHandling.Arrays, result.TypeNameHandling); | ||
Assert.Equal(2, result.Converters.Count); | ||
Assert.Collection(result.Converters, | ||
(converter) => Assert.IsType<BinaryConverter>(converter), | ||
(converter) => Assert.IsType<DataTableConverter>(converter)); | ||
Assert.IsType<CamelCasePropertyNamesContractResolver>(result.ContractResolver); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ReadValueUnit_work_as_expected() | ||
{ | ||
var token = new JObject(); | ||
|
||
token.Add("Unit", "PowerUnit.Watt"); | ||
token.Add("Value", 10.2365D); | ||
|
||
var result = _sut.Test_ReadValueUnit(token); | ||
|
||
Assert.NotNull(result); | ||
Assert.Equal("PowerUnit.Watt", result?.Unit); | ||
Assert.Equal(10.2365D, result?.Value); | ||
} | ||
|
||
[Fact] | ||
public void UnitsNetBaseJsonConverter_ReadValueUnit_works_with_empty_token() | ||
{ | ||
var token = new JObject(); | ||
|
||
var result = _sut.Test_ReadValueUnit(token); | ||
|
||
Assert.Null(result); | ||
} | ||
|
||
[Theory] | ||
[InlineData(false, true)] | ||
[InlineData(true, false)] | ||
public void UnitsNetBaseJsonConverter_ReadValueUnit_returns_null_when_unit_or_value_is_missing(bool withUnit, bool withValue) | ||
{ | ||
var token = new JObject(); | ||
|
||
if (withUnit) | ||
{ | ||
token.Add("Unit", "PowerUnit.Watt"); | ||
} | ||
|
||
if (withValue) | ||
{ | ||
token.Add("Value", 10.2365D); | ||
} | ||
|
||
var result = _sut.Test_ReadValueUnit(token); | ||
|
||
Assert.Null(result); | ||
} | ||
|
||
[Theory] | ||
[InlineData("Unit", "Value")] | ||
[InlineData("unit", "Value")] | ||
[InlineData("Unit", "value")] | ||
[InlineData("unit", "value")] | ||
[InlineData("unIT", "vAlUe")] | ||
public void UnitsNetBaseJsonConverter_ReadValueUnit_works_case_insensitive(string unitPropertyName, string valuePropertyName) | ||
{ | ||
var token = new JObject(); | ||
|
||
token.Add(unitPropertyName, "PowerUnit.Watt"); | ||
token.Add(valuePropertyName, 10.2365D); | ||
|
||
var result = _sut.Test_ReadValueUnit(token); | ||
|
||
Assert.NotNull(result); | ||
Assert.Equal("PowerUnit.Watt", result?.Unit); | ||
Assert.Equal(10.2365D, result?.Value); | ||
} | ||
|
||
/// <summary> | ||
/// Dummy converter, used to access protected methods on abstract UnitsNetBaseJsonConverter{T} | ||
/// </summary> | ||
private class TestConverter : UnitsNetBaseJsonConverter<string> | ||
{ | ||
public override bool CanRead => false; | ||
public override bool CanWrite => false; | ||
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer) => throw new NotImplementedException(); | ||
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer) => throw new NotImplementedException(); | ||
|
||
public (string Unit, double Value) Test_ConvertIQuantity(IQuantity value) | ||
{ | ||
var result = ConvertIQuantity(value); | ||
|
||
return (result.Unit, result.Value); | ||
} | ||
|
||
public IQuantity Test_ConvertValueUnit(string unit, double value) => Test_ConvertValueUnit(new ValueUnit() {Unit = unit, Value = value}); | ||
public IQuantity Test_ConvertValueUnit() => Test_ConvertValueUnit(null); | ||
private IQuantity Test_ConvertValueUnit(ValueUnit valueUnit) => ConvertValueUnit(valueUnit); | ||
|
||
public JsonSerializer Test_CreateLocalSerializer(JsonSerializer serializer) => CreateLocalSerializer(serializer, this); | ||
|
||
public (string Unit, double Value)? Test_ReadValueUnit(JToken jsonToken) | ||
{ | ||
var result = ReadValueUnit(jsonToken); | ||
|
||
if (result == null) | ||
{ | ||
return null; | ||
} | ||
|
||
return (result.Unit, result.Value); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.