Skip to content

Commit

Permalink
Added ReadOnlyAttribute support, merged simple-json/pull/75 the fix f…
Browse files Browse the repository at this point in the history
…or large integers.

[release]
  • Loading branch information
Lakritzator committed Jan 24, 2017
1 parent b5f1c25 commit 01ec439
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 19 deletions.
59 changes: 59 additions & 0 deletions Dapplo.HttpExtensions.Tests/SimpleJsonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#region using

using System;
using System.Globalization;
using Dapplo.HttpExtensions.Tests.Shared.TestEntities;
using Dapplo.Log.XUnit;
using Dapplo.HttpExtensions.Tests.TestEntities;
Expand All @@ -38,6 +39,7 @@ namespace Dapplo.HttpExtensions.Tests
/// </summary>
public class SimpleJsonTests
{
private static readonly LogSource Log = new LogSource();
public SimpleJsonTests(ITestOutputHelper testOutputHelper)
{
LogSettings.RegisterDefaultLogger<XUnitLogger>(LogLevels.Verbose, testOutputHelper);
Expand Down Expand Up @@ -66,6 +68,43 @@ public void TestSerializeObject_EmitDefaultValue()
Assert.Contains("prerelease", jsonString);
}

/// <summary>
/// Test SimpleJson EmitDefaultValue
/// </summary>
[Fact]
public void TestSerializeObject_Readonly()
{
var testObject = new SerializeTestEntity
{
ValueNormal = "normal",
ValueEmitDefaultFalse = null,
ValueReadOnly = "readonly",
ValueNotReadOnly = "notReadonly"
};
var jsonString = SimpleJson.SerializeObject(testObject);
Log.Info().WriteLine("Serialized: "+ jsonString);
Assert.Contains("valueNormal", jsonString);
Assert.Contains("valueNotReadOnly", jsonString);
Assert.DoesNotContain("valueEmitDefaultFalse", jsonString);
Assert.DoesNotContain("valueReadOnly", jsonString);

testObject.ValueEmitDefaultFalse = "something";
jsonString = SimpleJson.SerializeObject(testObject);
Assert.Contains("valueEmitDefaultFalse", jsonString);
}

/// <summary>
/// Test SimpleJson ReadOnly
/// </summary>
[Fact]
public void TestDeserializeObject_Readonly()
{
var jsonString = "{\"valueNormal\":\"normal\",\"valueReadOnly\":\"readonly\"}";
var jsonObject = SimpleJson.DeserializeObject<SerializeTestEntity>(jsonString);
Assert.NotNull(jsonObject.ValueReadOnly);
Assert.NotNull(jsonObject.ValueNormal);
}

[Fact]
public void TestSimpleJson_DeserializeObject()
{
Expand All @@ -75,5 +114,25 @@ public void TestSimpleJson_DeserializeObject()
Assert.True(jsonObject.StringExtensionData.Count == 2);
Assert.True(jsonObject.IntExtensionData.Count == 2);
}

[Fact]
public void GivenNumberWithoutDecimalTooLargeForLongTypeIsDecimal()
{
decimal veryLargeInteger = long.MaxValue + 1M;
var json = veryLargeInteger.ToString(CultureInfo.InvariantCulture);
object result = SimpleJson.DeserializeObject(json);

Assert.IsType<decimal>(result);
}

[Fact]
public void GivenNumberWithoutDecimalTooLargeForDecimalTypeIsDouble()
{
decimal veryVeryLargeInteger = decimal.MaxValue;
var json = veryVeryLargeInteger + "0"; // Tack a zero onto the end -- multiply by 10
object result = SimpleJson.DeserializeObject(json);

Assert.IsType<double>(result);
}
}
}
51 changes: 51 additions & 0 deletions Dapplo.HttpExtensions.Tests/TestEntities/SerializeTestEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Dapplo - building blocks for desktop applications
// Copyright (C) 2016 Dapplo
//
// For more information see: http://dapplo.net/
// Dapplo repositories are hosted on GitHub: https://github.com/dapplo
//
// This file is part of Dapplo.HttpExtensions
//
// Dapplo.HttpExtensions is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Dapplo.HttpExtensions is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have a copy of the GNU Lesser General Public License
// along with Dapplo.HttpExtensions. If not, see <http://www.gnu.org/licenses/lgpl.txt>.

#region using

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;

#endregion

namespace Dapplo.HttpExtensions.Tests.TestEntities
{
/// <summary>
/// Container for the release information from GitHub
/// </summary>
[DataContract]
public class SerializeTestEntity
{
[DataMember(Name = "valueNormal")]
public string ValueNormal { get; set; }

[DataMember(Name = "valueEmitDefaultFalse", EmitDefaultValue = false)]
public string ValueEmitDefaultFalse { get; set; }

[DataMember(Name = "valueReadOnly"), ReadOnly(true)]
public string ValueReadOnly { get; set; }

[DataMember(Name = "valueNotReadOnly"), ReadOnly(false)]
public string ValueNotReadOnly { get; set; }
}
}
4 changes: 2 additions & 2 deletions Dapplo.HttpExtensions.Tests/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"xunit": "2.1.0",
"xunit.runner.console": "2.1.0",
"xunit.runner.visualstudio": "2.1.0",
"Dapplo.Log": "1.0.22",
"Dapplo.Log.XUnit": "1.0.22"
"Dapplo.Log": "1.0.23",
"Dapplo.Log.XUnit": "1.0.23"
},
"frameworks": {
"net45": {
Expand Down
82 changes: 66 additions & 16 deletions Dapplo.HttpExtensions/SimpleJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -899,20 +899,30 @@ static object ParseNumber(char[] json, ref int index, out bool success)
{
EatWhitespace(json, ref index);
int lastIndex = GetLastIndexOfNumber(json, index);
int charLength = lastIndex - index + 1;
object returnNumber;
string str = new string(json, index, charLength);
if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1)
int charLength = (lastIndex - index) + 1;
object returnNumber = null;
string numberAsString = new string(json, index, charLength);
if ((numberAsString.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1)
|| (numberAsString.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1))
{
double number;
success = double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number);
success = double.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out number);
returnNumber = number;
}
else
{
long number;
success = long.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number);
returnNumber = number;
long longNumber;
decimal decimalNumber;
double doubleNumber;

if (long.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out longNumber))
returnNumber = longNumber;
else if (decimal.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalNumber))
returnNumber = decimalNumber;
else if (double.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleNumber))
returnNumber = doubleNumber;

success = (returnNumber != null);
}
index = lastIndex + 1;
return returnNumber;
Expand Down Expand Up @@ -1670,19 +1680,31 @@ private static object Default(Type type)
DataContractAttribute dataContractAttribute = (DataContractAttribute)ReflectionUtils.GetAttribute(type, typeof(DataContractAttribute));
if (dataContractAttribute == null)
return result;
DataMemberAttribute dataMemberAttribute;
foreach (PropertyInfo propertyInfo in ReflectionUtils.GetProperties(type))
{
DataMemberAttribute dataMemberAttribute;
if (CanAdd(propertyInfo, out dataMemberAttribute))
if (CanWrite(propertyInfo, out dataMemberAttribute))
{
var jsonKey = JsonKey(dataMemberAttribute, propertyInfo);
if (dataMemberAttribute?.EmitDefaultValue == false)
{
var jsonKey = JsonKey(dataMemberAttribute, propertyInfo);
var def = Default(propertyInfo.PropertyType);
result[jsonKey] = value => !Equals(def, value);
}
}
}
foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type))
{
if (!fieldInfo.IsStatic && CanWrite(fieldInfo, out dataMemberAttribute))
{
if (dataMemberAttribute?.EmitDefaultValue == false)
{
var jsonKey = JsonKey(dataMemberAttribute, fieldInfo);
var def = Default(fieldInfo.FieldType);
result[jsonKey] = value => !Equals(def, value);
}
}
}
return result;
}

Expand All @@ -1700,7 +1722,7 @@ private static object Default(Type type)
if (propertyInfo.CanRead)
{
MethodInfo getMethod = ReflectionUtils.GetGetterMethodInfo(propertyInfo);
if (!getMethod.IsStatic && CanAdd(propertyInfo, out dataMemberAttribute))
if (!getMethod.IsStatic && CanWrite(propertyInfo, out dataMemberAttribute))
{
jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? propertyInfo.Name : dataMemberAttribute.Name;
result[jsonKey] = ReflectionUtils.GetGetMethod(propertyInfo);
Expand All @@ -1709,7 +1731,7 @@ private static object Default(Type type)
}
foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type))
{
if (!fieldInfo.IsStatic && CanAdd(fieldInfo, out dataMemberAttribute))
if (!fieldInfo.IsStatic && CanWrite(fieldInfo, out dataMemberAttribute))
{
jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? fieldInfo.Name : dataMemberAttribute.Name;
result[jsonKey] = ReflectionUtils.GetGetMethod(fieldInfo);
Expand All @@ -1731,7 +1753,7 @@ private static object Default(Type type)
if (propertyInfo.CanWrite)
{
MethodInfo setMethod = ReflectionUtils.GetSetterMethodInfo(propertyInfo);
if (!setMethod.IsStatic && CanAdd(propertyInfo, out dataMemberAttribute))
if (!setMethod.IsStatic && CanRead(propertyInfo, out dataMemberAttribute))
{
jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? propertyInfo.Name : dataMemberAttribute.Name;
result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(propertyInfo.PropertyType, ReflectionUtils.GetSetMethod(propertyInfo));
Expand All @@ -1741,7 +1763,7 @@ private static object Default(Type type)
}
foreach (FieldInfo fieldInfo in ReflectionUtils.GetFields(type))
{
if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanAdd(fieldInfo, out dataMemberAttribute))
if (!fieldInfo.IsInitOnly && !fieldInfo.IsStatic && CanRead(fieldInfo, out dataMemberAttribute))
{
jsonKey = string.IsNullOrEmpty(dataMemberAttribute.Name) ? fieldInfo.Name : dataMemberAttribute.Name;
result[jsonKey] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(fieldInfo.FieldType, ReflectionUtils.GetSetMethod(fieldInfo));
Expand All @@ -1751,12 +1773,40 @@ private static object Default(Type type)
return result;
}

private static bool CanAdd(MemberInfo info, out DataMemberAttribute dataMemberAttribute)
/// <summary>
/// Check if we should read the member
/// </summary>
/// <param name="info"></param>
/// <param name="dataMemberAttribute"></param>
/// <returns></returns>
private static bool CanRead(MemberInfo info, out DataMemberAttribute dataMemberAttribute)
{
dataMemberAttribute = null;

if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null)
return false;
dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute));
if (dataMemberAttribute == null)
return false;
return true;
}

/// <summary>
/// Check if we should write the member
/// </summary>
/// <param name="info"></param>
/// <param name="dataMemberAttribute"></param>
/// <returns>bool</returns>
private static bool CanWrite(MemberInfo info, out DataMemberAttribute dataMemberAttribute)
{
dataMemberAttribute = null;

if (ReflectionUtils.GetAttribute(info, typeof(IgnoreDataMemberAttribute)) != null)
return false;
// check if the member has a ReadOnlyAttribute set to true, this means we wont emit
ReadOnlyAttribute readOnlyAttribute = (ReadOnlyAttribute)ReflectionUtils.GetAttribute(info, typeof(ReadOnlyAttribute));
if (readOnlyAttribute != null && readOnlyAttribute.IsReadOnly)
return false;
dataMemberAttribute = (DataMemberAttribute)ReflectionUtils.GetAttribute(info, typeof(DataMemberAttribute));
if (dataMemberAttribute == null)
return false;
Expand Down
2 changes: 1 addition & 1 deletion Dapplo.HttpExtensions/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"supports": {},
"dependencies": {
"Dapplo.Log": "1.0.22"
"Dapplo.Log": "1.0.23"
},
"frameworks": {
"netstandard1.3": {
Expand Down

0 comments on commit 01ec439

Please sign in to comment.