Skip to content
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

Serialize and deserialize Enum values as strings #64

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/SimpleJson.Tests/PocoDeserializerTests/EnumDeserializeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//-----------------------------------------------------------------------
// <copyright file="<file>.cs" company="The Outercurve Foundation">
// Copyright (c) 2011, The Outercurve Foundation.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.opensource.org/licenses/mit-license.php
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
// <author>Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me)</author>
// <website>https://github.com/facebook-csharp-sdk/simple-json</website>
//-----------------------------------------------------------------------

namespace SimpleJson.Tests.PocoDeserializerTests
{
using System;

#if NUNIT
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
using NUnit.Framework;
#else
#if NETFX_CORE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif
#endif

[TestClass]
public class EnumDeserializeTests
{
[TestMethod]
public void DeserializeEnumStringValue()
{
var json = "{\"Value\":\"Two\"}";

var result = SimpleJson.DeserializeObject<X>(json);
Assert.AreEqual(Values.Two, result.Value);
}

public class X
{
public Values Value { get; set; }
}
}


[TestClass]
public class NullableEnumDeserializeTests
{
[TestMethod]
public void DeserializeNullEnumValue()
{
var json = "{}";

var result = SimpleJson.DeserializeObject<X>(json);

Assert.IsNull(result.Value);
}

[TestMethod]
public void DeserializeNullValue()
{
var json = "{\"Value\":null}";

var result = SimpleJson.DeserializeObject<X>(json);
Assert.IsNull(result.Value);
}

[TestMethod]
public void DeserializeNullableEnumWithValue()
{
var json = "{\"Value\":\"Two\"}";
var result = SimpleJson.DeserializeObject<X>(json);
Assert.AreEqual(Values.Two, result.Value);
}

public class X
{
public Values? Value { get; set; }
}
}

public enum Values
{
One,
Two,
Three
}

}
100 changes: 100 additions & 0 deletions src/SimpleJson.Tests/PocoJsonSerializerTests/EnumSerializeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//-----------------------------------------------------------------------
// <copyright file="<file>.cs" company="The Outercurve Foundation">
// Copyright (c) 2011, The Outercurve Foundation.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.opensource.org/licenses/mit-license.php
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
// <author>Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me)</author>
// <website>https://github.com/facebook-csharp-sdk/simple-json</website>
//-----------------------------------------------------------------------

namespace SimpleJson.Tests.PocoJsonSerializerTests
{
using System;

#if NUNIT
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
using NUnit.Framework;
#else
#if NETFX_CORE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif
#endif

[TestClass]
public class EnumSerializeTests
{
[TestMethod]
public void SerializeEnumAsStringValue()
{
var obj = new SerializeEnumClass()
{
Value = Values.Two
};

var json = SimpleJson.SerializeObject(obj);

Assert.AreEqual("{\"Value\":\"Two\"}", json);
}

public class SerializeEnumClass
{
public Values Value { get; set; }
}
}

[TestClass]
public class NullableEnumSerializeTest
{
[TestMethod]
public void SerializeNullableEnumWithNoValue()
{
var obj = new SerializeNullableEnumClass();

var json = SimpleJson.SerializeObject(obj);

Assert.AreEqual("{\"Value\":null}", json);
}

[TestMethod]
public void SerializeNullableEnumWithValue()
{
var obj = new SerializeNullableEnumClass
{
Value = Values.Two
};

var json = SimpleJson.SerializeObject(obj);

Assert.AreEqual("{\"Value\":\"Two\"}", json);
}

public class SerializeNullableEnumClass
{
public Values? Value { get; set; }
}
}

public enum Values
{
One,
Two,
Three
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void GuidSerialization()
public void EnumSerialization()
{
string json = SimpleJson.SerializeObject(StringComparison.CurrentCultureIgnoreCase);
Assert.AreEqual("1", json);
Assert.AreEqual("\"CurrentCultureIgnoreCase\"", json);
}

[TestMethod]
Expand Down
2 changes: 2 additions & 0 deletions src/SimpleJson.Tests/SimpleJson.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,13 @@
<Compile Include="JsonDecodeTypeTests.cs" />
<Compile Include="JsonDataContractSerializeObjectTests.cs" />
<Compile Include="PocoDeserializerTests\ArrayTests.cs" />
<Compile Include="PocoDeserializerTests\EnumDeserializeTests.cs" />
<Compile Include="PocoDeserializerTests\NullableTypeDeserializeTests.cs" />
<Compile Include="PocoDeserializerTests\DateTimeDeserializeTests.cs" />
<Compile Include="PocoDeserializerTests\DictionaryDeserializeTests.cs" />
<Compile Include="PocoDeserializerTests\ListOfPocoDeserializeTests.cs" />
<Compile Include="PocoJsonSerializerTests\DateTimeSerializeTests.cs" />
<Compile Include="PocoJsonSerializerTests\EnumSerializeTests.cs" />
<Compile Include="PocoJsonSerializerTests\NullableSerializeTests.cs" />
<Compile Include="PocoJsonSerializerTests\PrivateFieldsDeserializeTests.cs" />
<Compile Include="PocoJsonSerializerTests\PrivateFieldsSerializeTests.cs" />
Expand Down
49 changes: 30 additions & 19 deletions src/SimpleJson/SimpleJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ static class SimpleJson
static SimpleJson()
{
EscapeTable = new char[93];
EscapeTable['"'] = '"';
EscapeTable['"'] = '"';
EscapeTable['\\'] = '\\';
EscapeTable['\b'] = 'b';
EscapeTable['\f'] = 'f';
Expand Down Expand Up @@ -556,7 +556,7 @@ public static object DeserializeObject(string json)
/// <returns>
/// Returns true if successfull otherwise false.
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")]
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")]
public static bool TryDeserializeObject(string json, out object obj)
{
bool success = true;
Expand Down Expand Up @@ -1222,7 +1222,7 @@ public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrat

#endif
}

[GeneratedCode("simple-json", "1.0.0")]
#if SIMPLE_JSON_INTERNAL
internal
Expand All @@ -1231,7 +1231,7 @@ public static DataContractJsonSerializerStrategy DataContractJsonSerializerStrat
#endif
interface IJsonSerializerStrategy
{
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")]
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")]
bool TrySerializeNonPrimitiveObject(object input, out object output);
object DeserializeObject(object value, Type type);
}
Expand Down Expand Up @@ -1330,12 +1330,12 @@ public virtual object DeserializeObject(object value, Type type)
if (type == null) throw new ArgumentNullException("type");
string str = value as string;

if (type == typeof (Guid) && string.IsNullOrEmpty(str))
if (type == typeof(Guid) && string.IsNullOrEmpty(str))
return default(Guid);

if (value == null)
return null;

object obj = null;

if (str != null)
Expand All @@ -1350,19 +1350,19 @@ public virtual object DeserializeObject(object value, Type type)
return new Guid(str);
if (type == typeof(Uri))
{
bool isValid = Uri.IsWellFormedUriString(str, UriKind.RelativeOrAbsolute);
bool isValid = Uri.IsWellFormedUriString(str, UriKind.RelativeOrAbsolute);

Uri result;
if (isValid && Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out result))
return result;

return null;
return null;
}

if (type == typeof(string))
return str;

return Convert.ChangeType(str, type, CultureInfo.InvariantCulture);
if (type == typeof(string))
return str;

return Convert.ChangeType(str, type, CultureInfo.InvariantCulture);
}
else
{
Expand All @@ -1379,9 +1379,20 @@ public virtual object DeserializeObject(object value, Type type)
}
else if (value is bool)
return value;

bool valueIsLong = value is long;
bool valueIsDouble = value is double;
if (type.IsEnum)
{
if (value is double || value is int || value is long)
{
return Enum.ToObject(type, Convert.ToInt32(value.ToString()));
}
else if (value is string)
{
return Enum.Parse(type, value.ToString());
}
}
if ((valueIsLong && type == typeof(long)) || (valueIsDouble && type == typeof(double)))
return value;
if ((valueIsDouble && type != typeof(double)) || (valueIsLong && type != typeof(long)))
Expand Down Expand Up @@ -1466,10 +1477,10 @@ public virtual object DeserializeObject(object value, Type type)

protected virtual object SerializeEnum(Enum p)
{
return Convert.ToDouble(p, CultureInfo.InvariantCulture);
return p.ToString();
}

[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")]
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")]
protected virtual bool TrySerializeKnownTypes(object input, out object output)
{
bool returnValue = true;
Expand All @@ -1494,7 +1505,7 @@ protected virtual bool TrySerializeKnownTypes(object input, out object output)
}
return returnValue;
}
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification="Need to support .NET 2")]
[SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")]
protected virtual bool TrySerializeUnknownTypes(object input, out object output)
{
if (input == null) throw new ArgumentNullException("input");
Expand Down Expand Up @@ -1596,7 +1607,7 @@ private static bool CanAdd(MemberInfo info, out string jsonKey)
namespace Reflection
{
// This class is meant to be copied into other libraries. So we want to exclude it from Code Analysis rules
// that might be in place in the target project.
// that might be in place in the target project.
[GeneratedCode("reflection-utils", "1.0.0")]
#if SIMPLE_JSON_REFLECTION_UTILS_PUBLIC
public
Expand Down Expand Up @@ -1649,7 +1660,7 @@ public static Type GetGenericListElementType(Type type)
foreach (Type implementedInterface in interfaces)
{
if (IsTypeGeneric(implementedInterface) &&
implementedInterface.GetGenericTypeDefinition() == typeof (IList<>))
implementedInterface.GetGenericTypeDefinition() == typeof(IList<>))
{
return GetGenericTypeArguments(implementedInterface)[0];
}
Expand Down Expand Up @@ -1699,7 +1710,7 @@ public static bool IsTypeGenericeCollectionInterface(Type type)
|| genericDefinition == typeof(IReadOnlyCollection<>)
|| genericDefinition == typeof(IReadOnlyList<>)
#endif
);
);
}

public static bool IsAssignableFrom(Type type1, Type type2)
Expand Down