1071 lines
60 KiB
C#
1071 lines
60 KiB
C#
|
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|||
|
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Globalization;
|
|||
|
using System.IO;
|
|||
|
using System.Reflection;
|
|||
|
using System.Runtime.Serialization.Json;
|
|||
|
using System.Text;
|
|||
|
using Xunit;
|
|||
|
|
|||
|
namespace System.Json
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// JsonPrimitive unit tests
|
|||
|
/// </summary>
|
|||
|
public class JsonPrimitiveTests
|
|||
|
{
|
|||
|
const string DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffK";
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Int16"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromInt16()
|
|||
|
{
|
|||
|
short[] values = new short[] { Int16.MinValue, Int16.MaxValue, 1 };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<short>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Int32"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromInt32()
|
|||
|
{
|
|||
|
int[] values = new int[] { Int32.MinValue, Int32.MaxValue, 12345678 };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<int>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Int64"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromInt64()
|
|||
|
{
|
|||
|
long[] values = new long[] { Int64.MinValue, Int64.MaxValue, 12345678901232L };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<long>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="UInt64"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromUInt64()
|
|||
|
{
|
|||
|
ulong[] values = new ulong[] { UInt64.MinValue, UInt64.MaxValue, 12345678901232L };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<ulong>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="UInt32"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromUInt32()
|
|||
|
{
|
|||
|
uint[] values = new uint[] { UInt32.MinValue, UInt32.MaxValue, 3234567890 };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<uint>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="UInt16"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromUInt16()
|
|||
|
{
|
|||
|
ushort[] values = new ushort[] { UInt16.MinValue, UInt16.MaxValue, 33333 };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<ushort>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Byte"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromByte()
|
|||
|
{
|
|||
|
byte[] values = new byte[] { Byte.MinValue, Byte.MaxValue, 0x83 };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<byte>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="SByte"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromSByte()
|
|||
|
{
|
|||
|
sbyte[] values = new sbyte[] { SByte.MinValue, SByte.MaxValue, -0x33 };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<sbyte>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Single"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromFloat()
|
|||
|
{
|
|||
|
float[] values = new float[] { float.MinValue, float.MaxValue, 1.234f, float.PositiveInfinity, float.NegativeInfinity, float.NaN };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<float>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Double"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromDouble()
|
|||
|
{
|
|||
|
double[] values = new double[] { double.MinValue, double.MaxValue, 1.234, double.PositiveInfinity, double.NegativeInfinity, double.NaN };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<double>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Decimal"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromDecimal()
|
|||
|
{
|
|||
|
decimal[] values = new decimal[] { decimal.MinValue, decimal.MaxValue, 123456789.123456789m };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Number);
|
|||
|
this.TestReadAsRoundtrip<decimal>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Boolean"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromBoolean()
|
|||
|
{
|
|||
|
bool[] values = new bool[] { true, false };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.Boolean);
|
|||
|
this.TestReadAsRoundtrip<bool>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Char"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromChar()
|
|||
|
{
|
|||
|
char[] values = new char[] { 'H', '\0', '\uffff' };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.String);
|
|||
|
this.TestReadAsRoundtrip<char>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="String"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromString()
|
|||
|
{
|
|||
|
string[] values = new string[] { "Hello", "abcdef", "\r\t123\n32" };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.String);
|
|||
|
this.TestReadAsRoundtrip<string>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="DateTime"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromDateTime()
|
|||
|
{
|
|||
|
DateTime[] values = new DateTime[]
|
|||
|
{
|
|||
|
new DateTime(2000, 10, 16, 8, 0, 0, DateTimeKind.Utc),
|
|||
|
new DateTime(2000, 10, 16, 8, 0, 0, DateTimeKind.Local),
|
|||
|
};
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.String);
|
|||
|
this.TestReadAsRoundtrip<DateTime>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Uri"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromUri()
|
|||
|
{
|
|||
|
Uri[] values = new Uri[] { new Uri("http://tempuri.org"), new Uri("foo/bar", UriKind.Relative) };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.String);
|
|||
|
this.TestReadAsRoundtrip<Uri>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from <see cref="Guid"/> values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromGuid()
|
|||
|
{
|
|||
|
Guid[] values = new Guid[] { Guid.NewGuid(), Guid.Empty, Guid.NewGuid() };
|
|||
|
for (int i = 0; i < values.Length; i++)
|
|||
|
{
|
|||
|
this.ValidateJson(new JsonPrimitive(values[i]), GetExpectedRepresentation(values[i]), JsonType.String);
|
|||
|
this.TestReadAsRoundtrip<Guid>(new JsonPrimitive(values[i]), values[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Validates round-trip of <see cref="JsonPrimitive"/> values created from different types of values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void JsonPrimitiveFromObject()
|
|||
|
{
|
|||
|
List<KeyValuePair<object, JsonType>> values = new List<KeyValuePair<object, JsonType>>
|
|||
|
{
|
|||
|
new KeyValuePair<object, JsonType>(true, JsonType.Boolean),
|
|||
|
new KeyValuePair<object, JsonType>((short)1, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(234, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(3435434233443L, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(UInt64.MaxValue, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(UInt32.MaxValue, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(UInt16.MaxValue, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(Byte.MaxValue, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(SByte.MinValue, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(double.MaxValue, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(float.Epsilon, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>(decimal.MinusOne, JsonType.Number),
|
|||
|
new KeyValuePair<object, JsonType>("hello", JsonType.String),
|
|||
|
new KeyValuePair<object, JsonType>(Guid.NewGuid(), JsonType.String),
|
|||
|
new KeyValuePair<object, JsonType>(DateTime.UtcNow, JsonType.String),
|
|||
|
new KeyValuePair<object, JsonType>(new Uri("http://www.microsoft.com"), JsonType.String),
|
|||
|
};
|
|||
|
|
|||
|
foreach (var value in values)
|
|||
|
{
|
|||
|
string json = GetExpectedRepresentation(value.Key);
|
|||
|
JsonValue jsonValue = JsonValue.Parse(json);
|
|||
|
Assert.IsType(typeof(JsonPrimitive), jsonValue);
|
|||
|
this.ValidateJson((JsonPrimitive)jsonValue, json, value.Value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Negative tests for <see cref="JsonPrimitive"/> constructors with null values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void NullChecks()
|
|||
|
{
|
|||
|
ExpectException<ArgumentNullException>(() => new JsonPrimitive((string)null));
|
|||
|
ExpectException<ArgumentNullException>(() => new JsonPrimitive((Uri)null));
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for casting string values into non-string values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void CastingFromStringTests()
|
|||
|
{
|
|||
|
int seed = MethodBase.GetCurrentMethod().Name.GetHashCode();
|
|||
|
Random rndGen = new Random(seed);
|
|||
|
|
|||
|
Assert.Equal(false, (bool)(new JsonPrimitive("false")));
|
|||
|
Assert.Equal(false, (bool)(new JsonPrimitive("False")));
|
|||
|
Assert.Equal(true, (bool)(new JsonPrimitive("true")));
|
|||
|
Assert.Equal(true, (bool)(new JsonPrimitive("True")));
|
|||
|
|
|||
|
byte b = PrimitiveCreator.CreateInstanceOfByte(rndGen);
|
|||
|
Assert.Equal(b, (byte)(new JsonPrimitive(b.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
decimal dec = PrimitiveCreator.CreateInstanceOfDecimal(rndGen);
|
|||
|
Assert.Equal(dec, (decimal)(new JsonPrimitive(dec.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
double dbl = rndGen.NextDouble() * rndGen.Next();
|
|||
|
Assert.Equal(dbl, (double)(new JsonPrimitive(dbl.ToString("R", CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
Assert.Equal(Double.PositiveInfinity, (double)(new JsonPrimitive("Infinity")));
|
|||
|
Assert.Equal(Double.NegativeInfinity, (double)(new JsonPrimitive("-Infinity")));
|
|||
|
Assert.Equal(Double.NaN, (double)(new JsonPrimitive("NaN")));
|
|||
|
|
|||
|
ExpectException<InvalidCastException>(delegate { var d = (double)(new JsonPrimitive("INF")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var d = (double)(new JsonPrimitive("-INF")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var d = (double)(new JsonPrimitive("infinity")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var d = (double)(new JsonPrimitive("INFINITY")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var d = (double)(new JsonPrimitive("nan")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var d = (double)(new JsonPrimitive("Nan")); });
|
|||
|
|
|||
|
float flt = (float)(rndGen.NextDouble() * rndGen.Next());
|
|||
|
Assert.Equal(flt, (float)(new JsonPrimitive(flt.ToString("R", CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
Assert.Equal(Single.PositiveInfinity, (float)(new JsonPrimitive("Infinity")));
|
|||
|
Assert.Equal(Single.NegativeInfinity, (float)(new JsonPrimitive("-Infinity")));
|
|||
|
Assert.Equal(Single.NaN, (float)(new JsonPrimitive("NaN")));
|
|||
|
|
|||
|
ExpectException<InvalidCastException>(delegate { var f = (float)(new JsonPrimitive("INF")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var f = (float)(new JsonPrimitive("-INF")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var f = (float)(new JsonPrimitive("infinity")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var f = (float)(new JsonPrimitive("INFINITY")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var f = (float)(new JsonPrimitive("nan")); });
|
|||
|
ExpectException<InvalidCastException>(delegate { var f = (float)(new JsonPrimitive("Nan")); });
|
|||
|
|
|||
|
int i = PrimitiveCreator.CreateInstanceOfInt32(rndGen);
|
|||
|
Assert.Equal(i, (int)(new JsonPrimitive(i.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
long l = PrimitiveCreator.CreateInstanceOfInt64(rndGen);
|
|||
|
Assert.Equal(l, (long)(new JsonPrimitive(l.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
sbyte sb = PrimitiveCreator.CreateInstanceOfSByte(rndGen);
|
|||
|
Assert.Equal(sb, (sbyte)(new JsonPrimitive(sb.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
short s = PrimitiveCreator.CreateInstanceOfInt16(rndGen);
|
|||
|
Assert.Equal(s, (short)(new JsonPrimitive(s.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
ushort ui16 = PrimitiveCreator.CreateInstanceOfUInt16(rndGen);
|
|||
|
Assert.Equal(ui16, (ushort)(new JsonPrimitive(ui16.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
uint ui32 = PrimitiveCreator.CreateInstanceOfUInt32(rndGen);
|
|||
|
Assert.Equal(ui32, (uint)(new JsonPrimitive(ui32.ToString(CultureInfo.InvariantCulture))));
|
|||
|
|
|||
|
ulong ui64 = PrimitiveCreator.CreateInstanceOfUInt64(rndGen);
|
|||
|
Assert.Equal(ui64, (ulong)(new JsonPrimitive(ui64.ToString(CultureInfo.InvariantCulture))));
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for casting <see cref="JsonPrimitive"/> created from special floating point values (infinity, NaN).
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void CastingNumbersTest()
|
|||
|
{
|
|||
|
Assert.Equal(float.PositiveInfinity, (float)(new JsonPrimitive(double.PositiveInfinity)));
|
|||
|
Assert.Equal(float.NegativeInfinity, (float)(new JsonPrimitive(double.NegativeInfinity)));
|
|||
|
Assert.Equal(float.NaN, (float)(new JsonPrimitive(double.NaN)));
|
|||
|
|
|||
|
Assert.Equal(double.PositiveInfinity, (double)(new JsonPrimitive(float.PositiveInfinity)));
|
|||
|
Assert.Equal(double.NegativeInfinity, (double)(new JsonPrimitive(float.NegativeInfinity)));
|
|||
|
Assert.Equal(double.NaN, (double)(new JsonPrimitive(float.NaN)));
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for the many formats which can be cast to a <see cref="DateTime"/>.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void CastingDateTimeTest()
|
|||
|
{
|
|||
|
int seed = MethodBase.GetCurrentMethod().Name.GetHashCode();
|
|||
|
Random rndGen = new Random(seed);
|
|||
|
DateTime dt = new DateTime(
|
|||
|
rndGen.Next(1000, 3000), // year
|
|||
|
rndGen.Next(1, 13), // month
|
|||
|
rndGen.Next(1, 28), // day
|
|||
|
rndGen.Next(0, 24), // hour
|
|||
|
rndGen.Next(0, 60), // minute
|
|||
|
rndGen.Next(0, 60), // second
|
|||
|
DateTimeKind.Utc);
|
|||
|
Log.Info("dt = {0}", dt);
|
|||
|
|
|||
|
const string JsonDateFormat = "yyyy-MM-ddTHH:mm:ssZ";
|
|||
|
string dateString = dt.ToString(JsonDateFormat, CultureInfo.InvariantCulture);
|
|||
|
JsonValue jv = dateString;
|
|||
|
DateTime dt2 = (DateTime)jv;
|
|||
|
Assert.Equal(dt.ToUniversalTime(), dt2.ToUniversalTime());
|
|||
|
|
|||
|
const string DateTimeLocalFormat = "yyyy-MM-ddTHH:mm:ss";
|
|||
|
const string DateLocalFormat = "yyyy-MM-dd";
|
|||
|
const string TimeLocalFormat = "HH:mm:ss";
|
|||
|
|
|||
|
for (int i = 0; i < 100; i++)
|
|||
|
{
|
|||
|
DateTime dateLocal = PrimitiveCreator.CreateInstanceOfDateTime(rndGen).ToLocalTime();
|
|||
|
dateLocal = new DateTime(dateLocal.Year, dateLocal.Month, dateLocal.Day, dateLocal.Hour, dateLocal.Minute, dateLocal.Second, DateTimeKind.Local);
|
|||
|
string localDateTime = dateLocal.ToString(DateTimeLocalFormat, CultureInfo.InvariantCulture);
|
|||
|
string localDate = dateLocal.ToString(DateLocalFormat, CultureInfo.InvariantCulture);
|
|||
|
string localTime = dateLocal.ToString(TimeLocalFormat, CultureInfo.InvariantCulture);
|
|||
|
|
|||
|
Assert.Equal(dateLocal, new JsonPrimitive(localDateTime).ReadAs<DateTime>());
|
|||
|
Assert.Equal(dateLocal.Date, new JsonPrimitive(localDate).ReadAs<DateTime>());
|
|||
|
DateTime timeOnly = new JsonPrimitive(localTime).ReadAs<DateTime>();
|
|||
|
Assert.Equal(dateLocal.Hour, timeOnly.Hour);
|
|||
|
Assert.Equal(dateLocal.Minute, timeOnly.Minute);
|
|||
|
Assert.Equal(dateLocal.Second, timeOnly.Second);
|
|||
|
|
|||
|
DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(DateTime));
|
|||
|
using (MemoryStream ms = new MemoryStream())
|
|||
|
{
|
|||
|
dcjs.WriteObject(ms, dateLocal);
|
|||
|
ms.Position = 0;
|
|||
|
JsonValue jvFromString = JsonValue.Load(ms);
|
|||
|
Assert.Equal(dateLocal, jvFromString.ReadAs<DateTime>());
|
|||
|
}
|
|||
|
|
|||
|
using (MemoryStream ms = new MemoryStream())
|
|||
|
{
|
|||
|
DateTime dateUtc = dateLocal.ToUniversalTime();
|
|||
|
dcjs.WriteObject(ms, dateUtc);
|
|||
|
ms.Position = 0;
|
|||
|
JsonValue jvFromString = JsonValue.Load(ms);
|
|||
|
Assert.Equal(dateUtc, jvFromString.ReadAs<DateTime>());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for date parsing form the RFC2822 format.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void Rfc2822DateTimeFormatTest()
|
|||
|
{
|
|||
|
string[] localFormats = new string[]
|
|||
|
{
|
|||
|
"ddd, d MMM yyyy HH:mm:ss zzz",
|
|||
|
"d MMM yyyy HH:mm:ss zzz",
|
|||
|
"ddd, dd MMM yyyy HH:mm:ss zzz",
|
|||
|
"ddd, dd MMM yyyy HH:mm zzz",
|
|||
|
};
|
|||
|
|
|||
|
string[] utcFormats = new string[]
|
|||
|
{
|
|||
|
@"ddd, d MMM yyyy HH:mm:ss \U\T\C",
|
|||
|
"d MMM yyyy HH:mm:ssZ",
|
|||
|
@"ddd, dd MMM yyyy HH:mm:ss \U\T\C",
|
|||
|
"ddd, dd MMM yyyy HH:mmZ",
|
|||
|
};
|
|||
|
|
|||
|
DateTime today = DateTime.Today;
|
|||
|
int seed = today.Year * 10000 + today.Month * 100 + today.Day;
|
|||
|
Log.Info("Seed: {0}", seed);
|
|||
|
Random rndGen = new Random(seed);
|
|||
|
const int DatesToTry = 100;
|
|||
|
const string DateTraceFormat = "ddd yyyy/MM/dd HH:mm:ss.fffZ";
|
|||
|
|
|||
|
for (int i = 0; i < DatesToTry; i++)
|
|||
|
{
|
|||
|
DateTime dt = PrimitiveCreator.CreateInstanceOfDateTime(rndGen);
|
|||
|
dt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Kind);
|
|||
|
Log.Info("Test with date: {0} ({1})", dt.ToString(DateTraceFormat, CultureInfo.InvariantCulture), dt.Kind);
|
|||
|
string[] formatsToTest = dt.Kind == DateTimeKind.Utc ? utcFormats : localFormats;
|
|||
|
foreach (string format in formatsToTest)
|
|||
|
{
|
|||
|
string strDate = dt.ToString(format, CultureInfo.InvariantCulture);
|
|||
|
Log.Info("As string: {0} (format = {1})", strDate, format);
|
|||
|
JsonPrimitive jp = new JsonPrimitive(strDate);
|
|||
|
DateTime parsedDate = jp.ReadAs<DateTime>();
|
|||
|
Log.Info("Parsed date: {0} ({1})", parsedDate.ToString(DateTraceFormat, CultureInfo.InvariantCulture), parsedDate.Kind);
|
|||
|
|
|||
|
DateTime dtExpected = dt;
|
|||
|
DateTime dtActual = parsedDate;
|
|||
|
|
|||
|
if (dt.Kind != parsedDate.Kind)
|
|||
|
{
|
|||
|
dtExpected = dtExpected.ToUniversalTime();
|
|||
|
dtActual = dtActual.ToUniversalTime();
|
|||
|
}
|
|||
|
|
|||
|
Assert.Equal(dtExpected.Year, dtActual.Year);
|
|||
|
Assert.Equal(dtExpected.Month, dtActual.Month);
|
|||
|
Assert.Equal(dtExpected.Day, dtActual.Day);
|
|||
|
Assert.Equal(dtExpected.Hour, dtActual.Hour);
|
|||
|
Assert.Equal(dtExpected.Minute, dtActual.Minute);
|
|||
|
if (format.Contains(":ss"))
|
|||
|
{
|
|||
|
Assert.Equal(dtExpected.Second, dtActual.Second);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Assert.Equal(0, parsedDate.Second);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Log.Info("");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for the <see cref="System.Json.JsonValue.ReadAs{T}()"/> function from string values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void ReadAsFromStringTests()
|
|||
|
{
|
|||
|
int seed = MethodBase.GetCurrentMethod().Name.GetHashCode();
|
|||
|
Random rndGen = new Random(seed);
|
|||
|
|
|||
|
TestReadAsFromStringRoundtrip<bool>(false, "false");
|
|||
|
TestReadAsFromStringRoundtrip<bool>(false, "False");
|
|||
|
TestReadAsFromStringRoundtrip<bool>(true, "true");
|
|||
|
TestReadAsFromStringRoundtrip<bool>(true, "True");
|
|||
|
TestReadAsFromStringRoundtrip<byte>(PrimitiveCreator.CreateInstanceOfByte(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<char>(PrimitiveCreator.CreateInstanceOfChar(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<decimal>(PrimitiveCreator.CreateInstanceOfDecimal(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<int>(PrimitiveCreator.CreateInstanceOfInt32(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<long>(PrimitiveCreator.CreateInstanceOfInt64(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<sbyte>(PrimitiveCreator.CreateInstanceOfSByte(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<short>(PrimitiveCreator.CreateInstanceOfInt16(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<ushort>(PrimitiveCreator.CreateInstanceOfUInt16(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<uint>(PrimitiveCreator.CreateInstanceOfUInt32(rndGen));
|
|||
|
TestReadAsFromStringRoundtrip<ulong>(PrimitiveCreator.CreateInstanceOfUInt64(rndGen));
|
|||
|
double dbl = rndGen.NextDouble() * rndGen.Next();
|
|||
|
TestReadAsFromStringRoundtrip<double>(dbl, dbl.ToString("R", CultureInfo.InvariantCulture));
|
|||
|
TestReadAsFromStringRoundtrip<double>(double.PositiveInfinity, "Infinity");
|
|||
|
TestReadAsFromStringRoundtrip<double>(double.NegativeInfinity, "-Infinity");
|
|||
|
TestReadAsFromStringRoundtrip<double>(double.NaN, "NaN");
|
|||
|
float flt = (float)(rndGen.NextDouble() * rndGen.Next());
|
|||
|
TestReadAsFromStringRoundtrip<float>(flt, flt.ToString("R", CultureInfo.InvariantCulture));
|
|||
|
TestReadAsFromStringRoundtrip<float>(float.PositiveInfinity, "Infinity");
|
|||
|
TestReadAsFromStringRoundtrip<float>(float.NegativeInfinity, "-Infinity");
|
|||
|
TestReadAsFromStringRoundtrip<float>(float.NaN, "NaN");
|
|||
|
Guid guid = PrimitiveCreator.CreateInstanceOfGuid(rndGen);
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("N", CultureInfo.InvariantCulture));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("D", CultureInfo.InvariantCulture));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("B", CultureInfo.InvariantCulture));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("P", CultureInfo.InvariantCulture));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("X", CultureInfo.InvariantCulture));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("X", CultureInfo.InvariantCulture).Replace("0x", "0X"));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("X", CultureInfo.InvariantCulture).Replace("{", " { "));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("X", CultureInfo.InvariantCulture).Replace("}", " } "));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("X", CultureInfo.InvariantCulture).Replace(",", " , "));
|
|||
|
TestReadAsFromStringRoundtrip<Guid>(guid, guid.ToString("X", CultureInfo.InvariantCulture).Replace("0x", "0x0000"));
|
|||
|
Uri uri = null;
|
|||
|
do
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
uri = PrimitiveCreator.CreateInstanceOfUri(rndGen);
|
|||
|
}
|
|||
|
catch (UriFormatException)
|
|||
|
{
|
|||
|
}
|
|||
|
} while (uri == null);
|
|||
|
|
|||
|
TestReadAsFromStringRoundtrip<Uri>(uri);
|
|||
|
TestReadAsFromStringRoundtrip<string>(PrimitiveCreator.CreateInstanceOfString(rndGen));
|
|||
|
|
|||
|
// Roundtrip reference DateTime to remove some of the precision in the ticks. Otherwise, value is too precise.
|
|||
|
DateTimeOffset dateTimeOffset = PrimitiveCreator.CreateInstanceOfDateTimeOffset(rndGen);
|
|||
|
const string ISO8601Format = "yyyy-MM-ddTHH:mm:sszzz";
|
|||
|
dateTimeOffset = DateTimeOffset.ParseExact(dateTimeOffset.ToString(ISO8601Format, CultureInfo.InvariantCulture), ISO8601Format, CultureInfo.InvariantCulture);
|
|||
|
DateTime dateTime = dateTimeOffset.UtcDateTime;
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime, dateTimeOffset.ToUniversalTime().ToString(@"ddd, d MMM yyyy HH:mm:ss \U\T\C"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime, dateTimeOffset.ToUniversalTime().ToString(@"ddd, d MMM yyyy HH:mm:ss \G\M\T"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime.ToLocalTime(), dateTimeOffset.ToString(@"ddd, d MMM yyyy HH:mm:ss zzz"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime, dateTime.ToString("yyyy-MM-ddTHH:mm:ssK"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime.ToLocalTime(), dateTimeOffset.ToString(@"ddd, d MMM yyyy HH:mm:ss zzz"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime.ToLocalTime(), dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:sszzz"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset.UtcDateTime, dateTimeOffset.ToUniversalTime().ToString(@"ddd, d MMM yyyy HH:mm:ss \U\T\C"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset.UtcDateTime, dateTimeOffset.ToUniversalTime().ToString(@"ddd, d MMM yyyy HH:mm:ss \G\M\T"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset, dateTimeOffset.ToUniversalTime().ToString(@"ddd, d MMM yyyy HH:mm:ss zzz"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset, dateTime.ToString("yyyy-MM-ddTHH:mm:ssK"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset, dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:sszzz"));
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset, dateTimeOffset.ToString(@"ddd, d MMM yyyy HH:mm:ss zzz"));
|
|||
|
|
|||
|
// Create ASPNetFormat DateTime
|
|||
|
long unixEpochMilliseconds = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000;
|
|||
|
long millisecondsFromUnixEpoch = dateTime.Ticks / 10000 - unixEpochMilliseconds;
|
|||
|
string AspNetFormattedDateTime = String.Format("/Date({0})/", millisecondsFromUnixEpoch);
|
|||
|
string AspNetFormattedDateTimeWithValidTZ = String.Format("/Date({0}+0700)/", millisecondsFromUnixEpoch);
|
|||
|
string AspNetFormattedDateTimeInvalid1 = String.Format("/Date({0}+99999)/", millisecondsFromUnixEpoch);
|
|||
|
string AspNetFormattedDateTimeInvalid2 = String.Format("/Date({0}+07z0)/", millisecondsFromUnixEpoch);
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime, AspNetFormattedDateTime);
|
|||
|
TestReadAsFromStringRoundtrip<DateTime>(dateTime.ToLocalTime(), AspNetFormattedDateTimeWithValidTZ);
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset, AspNetFormattedDateTime);
|
|||
|
TestReadAsFromStringRoundtrip<DateTimeOffset>(dateTimeOffset, AspNetFormattedDateTimeWithValidTZ);
|
|||
|
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive(AspNetFormattedDateTimeInvalid1).ReadAs<DateTime>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive(AspNetFormattedDateTimeInvalid2).ReadAs<DateTime>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive(AspNetFormattedDateTimeInvalid1).ReadAs<DateTimeOffset>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive(AspNetFormattedDateTimeInvalid2).ReadAs<DateTimeOffset>(); });
|
|||
|
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("INF").ReadAs<float>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("-INF").ReadAs<float>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("infinity").ReadAs<float>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("INFINITY").ReadAs<float>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("nan").ReadAs<float>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("Nan").ReadAs<float>(); });
|
|||
|
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("INF").ReadAs<double>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("-INF").ReadAs<double>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("infinity").ReadAs<double>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("INFINITY").ReadAs<double>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("nan").ReadAs<double>(); });
|
|||
|
ExpectException<FormatException>(delegate { new JsonPrimitive("Nan").ReadAs<double>(); });
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for the <see cref="System.Json.JsonValue.ReadAs{T}()">JsonValue.ReadAs<string></see> method from number values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void TestReadAsStringFromNumbers()
|
|||
|
{
|
|||
|
int seed = MethodBase.GetCurrentMethod().Name.GetHashCode();
|
|||
|
Random rndGen = new Random(seed);
|
|||
|
|
|||
|
int intValue = PrimitiveCreator.CreateInstanceOfInt32(rndGen);
|
|||
|
JsonValue jv = intValue;
|
|||
|
Assert.Equal(intValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(intValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
uint uintValue = PrimitiveCreator.CreateInstanceOfUInt32(rndGen);
|
|||
|
jv = uintValue;
|
|||
|
Assert.Equal(uintValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(uintValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
long longValue = PrimitiveCreator.CreateInstanceOfInt64(rndGen);
|
|||
|
jv = longValue;
|
|||
|
Assert.Equal(longValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(longValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
ulong ulongValue = PrimitiveCreator.CreateInstanceOfUInt64(rndGen);
|
|||
|
jv = ulongValue;
|
|||
|
Assert.Equal(ulongValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(ulongValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
short shortValue = PrimitiveCreator.CreateInstanceOfInt16(rndGen);
|
|||
|
jv = shortValue;
|
|||
|
Assert.Equal(shortValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(shortValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
ushort ushortValue = PrimitiveCreator.CreateInstanceOfUInt16(rndGen);
|
|||
|
jv = ushortValue;
|
|||
|
Assert.Equal(ushortValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(ushortValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
byte byteValue = PrimitiveCreator.CreateInstanceOfByte(rndGen);
|
|||
|
jv = byteValue;
|
|||
|
Assert.Equal(byteValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(byteValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
sbyte sbyteValue = PrimitiveCreator.CreateInstanceOfSByte(rndGen);
|
|||
|
jv = sbyteValue;
|
|||
|
Assert.Equal(sbyteValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(sbyteValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
decimal decValue = PrimitiveCreator.CreateInstanceOfDecimal(rndGen);
|
|||
|
jv = decValue;
|
|||
|
Assert.Equal(decValue.ToString(CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(decValue.ToString(CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
float fltValue = PrimitiveCreator.CreateInstanceOfSingle(rndGen);
|
|||
|
jv = fltValue;
|
|||
|
Assert.Equal(fltValue.ToString("R", CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(fltValue.ToString("R", CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
|
|||
|
double dblValue = PrimitiveCreator.CreateInstanceOfDouble(rndGen);
|
|||
|
jv = dblValue;
|
|||
|
Assert.Equal(dblValue.ToString("R", CultureInfo.InvariantCulture), jv.ToString());
|
|||
|
Assert.Equal(dblValue.ToString("R", CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for the <see cref="System.Json.JsonValue.ReadAs{T}()">JsonValue.ReadAs<string></see> method from date values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void TestReadAsStringFromDates()
|
|||
|
{
|
|||
|
int seed = MethodBase.GetCurrentMethod().Name.GetHashCode();
|
|||
|
Random rndGen = new Random(seed);
|
|||
|
|
|||
|
DateTime dateTimeValue = PrimitiveCreator.CreateInstanceOfDateTime(rndGen);
|
|||
|
JsonValue jv = dateTimeValue;
|
|||
|
Assert.Equal("\"" + dateTimeValue.ToString(DateTimeFormat, CultureInfo.InvariantCulture) + "\"", jv.ToString());
|
|||
|
Assert.Equal(dateTimeValue.ToString(DateTimeFormat, CultureInfo.InvariantCulture), jv.ReadAs<string>());
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for the <see cref="System.Json.JsonValue.ReadAs{T}()">JsonValue.ReadAs<string></see> method from char values.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void TestReadAsStringFromChar()
|
|||
|
{
|
|||
|
char[] chars = "abc\u0000\b\f\r\n\t\ufedc".ToCharArray();
|
|||
|
|
|||
|
foreach (char c in chars)
|
|||
|
{
|
|||
|
string expected = new string(c, 1);
|
|||
|
JsonValue jv = c;
|
|||
|
string actual1 = jv.ReadAs<string>();
|
|||
|
string actual2 = (string)jv;
|
|||
|
|
|||
|
Assert.Equal(expected, actual1);
|
|||
|
Assert.Equal(expected, actual2);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for the <see cref="System.Json.JsonValue.ReadAs{T}()"/> method where T is a number type and the value is created from a string.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void TestReadAsNumberFromStrings()
|
|||
|
{
|
|||
|
Dictionary<object, List<Type>> valuesToNonOverflowingTypesMapping = new Dictionary<object, List<Type>>
|
|||
|
{
|
|||
|
{ double.NaN.ToString("R", CultureInfo.InvariantCulture), new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ double.NegativeInfinity.ToString("R", CultureInfo.InvariantCulture), new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ double.PositiveInfinity.ToString("R", CultureInfo.InvariantCulture), new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ double.MaxValue.ToString("R", CultureInfo.InvariantCulture), new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ double.MinValue.ToString("R", CultureInfo.InvariantCulture), new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ float.MaxValue.ToString("R", CultureInfo.InvariantCulture), new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ float.MinValue.ToString("R", CultureInfo.InvariantCulture), new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ Int64.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(ulong) } },
|
|||
|
{ Int64.MinValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long) } },
|
|||
|
{ Int32.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(ulong), typeof(uint) } },
|
|||
|
{ Int32.MinValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int) } },
|
|||
|
{ Int16.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(ulong), typeof(uint), typeof(ushort) } },
|
|||
|
{ Int16.MinValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short) } },
|
|||
|
{ SByte.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ SByte.MinValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte) } },
|
|||
|
{ UInt64.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(ulong) } },
|
|||
|
{ UInt32.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(ulong), typeof(uint) } },
|
|||
|
{ UInt16.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(ulong), typeof(uint), typeof(ushort) } },
|
|||
|
{ Byte.MaxValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ Byte.MinValue.ToString(), new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "1", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "+01", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "01.1e+01", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "1e1", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "1.0", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "01.0", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "-1", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte) } },
|
|||
|
{ "-1.0", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte) } },
|
|||
|
{ "-01.0", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte) } },
|
|||
|
{ "-01.0e+01", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte) } },
|
|||
|
{ "-01.0e-01", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "-.1", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ "-0100.0e-1", new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte) } },
|
|||
|
};
|
|||
|
|
|||
|
foreach (KeyValuePair<object, List<Type>> mapping in valuesToNonOverflowingTypesMapping)
|
|||
|
{
|
|||
|
ConvertValueToNumber<double>(mapping);
|
|||
|
ConvertValueToNumber<float>(mapping);
|
|||
|
ConvertValueToNumber<decimal>(mapping);
|
|||
|
ConvertValueToNumber<long>(mapping);
|
|||
|
ConvertValueToNumber<int>(mapping);
|
|||
|
ConvertValueToNumber<short>(mapping);
|
|||
|
ConvertValueToNumber<sbyte>(mapping);
|
|||
|
ConvertValueToNumber<ulong>(mapping);
|
|||
|
ConvertValueToNumber<uint>(mapping);
|
|||
|
ConvertValueToNumber<ushort>(mapping);
|
|||
|
ConvertValueToNumber<byte>(mapping);
|
|||
|
}
|
|||
|
|
|||
|
Dictionary<object, List<Type>> valuesThatAreInvalidNumber = new Dictionary<object, List<Type>>
|
|||
|
{
|
|||
|
{ "1L", new List<Type> { } },
|
|||
|
{ "0x1", new List<Type> { } },
|
|||
|
{ "1e309", new List<Type> { } },
|
|||
|
{ "", new List<Type> { } },
|
|||
|
{ "-", new List<Type> { } },
|
|||
|
{ "e10", new List<Type> { } },
|
|||
|
};
|
|||
|
|
|||
|
foreach (KeyValuePair<object, List<Type>> mapping in valuesThatAreInvalidNumber)
|
|||
|
{
|
|||
|
ConvertValueToNumber<double, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<float, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<decimal, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<long, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<int, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<short, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<sbyte, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<ulong, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<uint, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<ushort, FormatException>(mapping);
|
|||
|
ConvertValueToNumber<byte, FormatException>(mapping);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Tests for the <see cref="System.Json.JsonValue.ReadAs{T}()"/> method where T is a number type and the value is created from a number.
|
|||
|
/// This is essentially a number conversion test.
|
|||
|
/// </summary>
|
|||
|
[Fact]
|
|||
|
public void TestReadAsNumberFromNumber()
|
|||
|
{
|
|||
|
Dictionary<object, List<Type>> valuesToNonOverflowingTypesMapping = new Dictionary<object, List<Type>>
|
|||
|
{
|
|||
|
{ double.NaN, new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ double.NegativeInfinity, new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ double.PositiveInfinity, new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ float.NaN, new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ float.NegativeInfinity, new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ float.PositiveInfinity, new List<Type> { typeof(float), typeof(double) } },
|
|||
|
{ double.MaxValue, new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ double.MinValue, new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ float.MaxValue, new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ float.MinValue, new List<Type> { typeof(double), typeof(float) } },
|
|||
|
{ Int64.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(ulong) } },
|
|||
|
{ Int64.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long) } },
|
|||
|
{ Int32.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(ulong), typeof(uint) } },
|
|||
|
{ Int32.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int) } },
|
|||
|
{ Int16.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(ulong), typeof(uint), typeof(ushort) } },
|
|||
|
{ Int16.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short) } },
|
|||
|
{ SByte.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ SByte.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte) } },
|
|||
|
{ UInt64.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(ulong) } },
|
|||
|
{ UInt64.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ UInt32.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(ulong), typeof(uint) } },
|
|||
|
{ UInt32.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ UInt16.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(ulong), typeof(uint), typeof(ushort) } },
|
|||
|
{ UInt16.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ Byte.MaxValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ Byte.MinValue, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (double)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (float)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (decimal)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (long)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (int)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (short)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (sbyte)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (ulong)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (uint)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (ushort)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
{ (byte)1, new List<Type> { typeof(double), typeof(float), typeof(decimal), typeof(long), typeof(int), typeof(short), typeof(sbyte), typeof(ulong), typeof(uint), typeof(ushort), typeof(byte) } },
|
|||
|
};
|
|||
|
|
|||
|
foreach (KeyValuePair<object, List<Type>> mapping in valuesToNonOverflowingTypesMapping)
|
|||
|
{
|
|||
|
ConvertValueToNumber<double>(mapping);
|
|||
|
ConvertValueToNumber<float>(mapping);
|
|||
|
ConvertValueToNumber<decimal>(mapping);
|
|||
|
ConvertValueToNumber<long>(mapping);
|
|||
|
ConvertValueToNumber<int>(mapping);
|
|||
|
ConvertValueToNumber<short>(mapping);
|
|||
|
ConvertValueToNumber<sbyte>(mapping);
|
|||
|
ConvertValueToNumber<ulong>(mapping);
|
|||
|
ConvertValueToNumber<uint>(mapping);
|
|||
|
ConvertValueToNumber<ushort>(mapping);
|
|||
|
ConvertValueToNumber<byte>(mapping);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void ConvertValueToNumber<T>(KeyValuePair<object, List<Type>> mapping)
|
|||
|
{
|
|||
|
ConvertValueToNumber<T, OverflowException>(mapping);
|
|||
|
}
|
|||
|
|
|||
|
static void ConvertValueToNumber<T, TException>(KeyValuePair<object, List<Type>> mapping)
|
|||
|
where TException : Exception
|
|||
|
{
|
|||
|
JsonValue jsonValue = CastToJsonValue(mapping.Key);
|
|||
|
|
|||
|
Log.Info("Converting value {0} of type {1} to type {2}.", mapping.Key, mapping.Key.GetType().Name, typeof(T).Name);
|
|||
|
|
|||
|
if (mapping.Value.Contains(typeof(T)))
|
|||
|
{
|
|||
|
Console.Write("Conversion should work... ");
|
|||
|
T valueOfT;
|
|||
|
Assert.True(jsonValue.TryReadAs<T>(out valueOfT));
|
|||
|
if (mapping.Key.GetType() != typeof(string))
|
|||
|
{
|
|||
|
Console.Write("and original value casted to {0} should be the same as the retrieved value... ", typeof(T).Name);
|
|||
|
T castValue = (T)Convert.ChangeType(mapping.Key, typeof(T), CultureInfo.InvariantCulture);
|
|||
|
Assert.Equal<T>(castValue, valueOfT);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Console.Write("Conversion should fail... ");
|
|||
|
T valueOfT;
|
|||
|
Assert.False(jsonValue.TryReadAs<T>(out valueOfT), String.Format("It was possible to read the value as {0}", valueOfT));
|
|||
|
ExpectException<TException>(delegate
|
|||
|
{
|
|||
|
jsonValue.ReadAs<T>();
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
Log.Info("Success!");
|
|||
|
}
|
|||
|
|
|||
|
static JsonValue CastToJsonValue(object o)
|
|||
|
{
|
|||
|
switch (Type.GetTypeCode(o.GetType()))
|
|||
|
{
|
|||
|
case TypeCode.Boolean:
|
|||
|
return (JsonValue)(bool)o;
|
|||
|
case TypeCode.Byte:
|
|||
|
return (JsonValue)(byte)o;
|
|||
|
case TypeCode.Char:
|
|||
|
return (JsonValue)(char)o;
|
|||
|
case TypeCode.DateTime:
|
|||
|
return (JsonValue)(DateTime)o;
|
|||
|
case TypeCode.Decimal:
|
|||
|
return (JsonValue)(decimal)o;
|
|||
|
case TypeCode.Double:
|
|||
|
return (JsonValue)(double)o;
|
|||
|
case TypeCode.Int16:
|
|||
|
return (JsonValue)(short)o;
|
|||
|
case TypeCode.Int32:
|
|||
|
return (JsonValue)(int)o;
|
|||
|
case TypeCode.Int64:
|
|||
|
return (JsonValue)(long)o;
|
|||
|
case TypeCode.SByte:
|
|||
|
return (JsonValue)(sbyte)o;
|
|||
|
case TypeCode.Single:
|
|||
|
return (JsonValue)(float)o;
|
|||
|
case TypeCode.String:
|
|||
|
return (JsonValue)(string)o;
|
|||
|
case TypeCode.UInt16:
|
|||
|
return (JsonValue)(ushort)o;
|
|||
|
case TypeCode.UInt32:
|
|||
|
return (JsonValue)(uint)o;
|
|||
|
case TypeCode.UInt64:
|
|||
|
return (JsonValue)(ulong)o;
|
|||
|
default:
|
|||
|
if (o.GetType() == typeof(DateTimeOffset))
|
|||
|
{
|
|||
|
return (JsonValue)(DateTimeOffset)o;
|
|||
|
}
|
|||
|
|
|||
|
if (o.GetType() == typeof(Guid))
|
|||
|
{
|
|||
|
return (JsonValue)(Guid)o;
|
|||
|
}
|
|||
|
|
|||
|
if (o.GetType() == typeof(Uri))
|
|||
|
{
|
|||
|
return (JsonValue)(Uri)o;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return (JsonObject)o;
|
|||
|
}
|
|||
|
|
|||
|
static void ExpectException<T>(Action action) where T : Exception
|
|||
|
{
|
|||
|
JsonValueTests.ExpectException<T>(action);
|
|||
|
}
|
|||
|
|
|||
|
static string GetExpectedRepresentation(object obj)
|
|||
|
{
|
|||
|
if (obj is double)
|
|||
|
{
|
|||
|
double dbl = (double)obj;
|
|||
|
if (Double.IsPositiveInfinity(dbl))
|
|||
|
{
|
|||
|
return "Infinity";
|
|||
|
}
|
|||
|
else if (Double.IsNegativeInfinity(dbl))
|
|||
|
{
|
|||
|
return "-Infinity";
|
|||
|
}
|
|||
|
}
|
|||
|
else if (obj is float)
|
|||
|
{
|
|||
|
float flt = (float)obj;
|
|||
|
if (Single.IsPositiveInfinity(flt))
|
|||
|
{
|
|||
|
return "Infinity";
|
|||
|
}
|
|||
|
else if (Single.IsNegativeInfinity(flt))
|
|||
|
{
|
|||
|
return "-Infinity";
|
|||
|
}
|
|||
|
}
|
|||
|
else if (obj is DateTime)
|
|||
|
{
|
|||
|
DateTime dt = (DateTime)obj;
|
|||
|
return "\"" + dt.ToString(DateTimeFormat, CultureInfo.InvariantCulture) + "\"";
|
|||
|
}
|
|||
|
|
|||
|
using (MemoryStream ms = new MemoryStream())
|
|||
|
{
|
|||
|
DataContractJsonSerializer dcjs = new DataContractJsonSerializer(obj.GetType());
|
|||
|
dcjs.WriteObject(ms, obj);
|
|||
|
return Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Position);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ValidateJson(JsonPrimitive jsonPrim, string expectedJson, JsonType expectedJsonType)
|
|||
|
{
|
|||
|
Assert.Equal(expectedJson, jsonPrim.ToString());
|
|||
|
Assert.Equal(expectedJsonType, jsonPrim.JsonType);
|
|||
|
}
|
|||
|
|
|||
|
void TestReadAsRoundtrip<T>(JsonPrimitive jsonPrim, T myOriginalObjectOfT)
|
|||
|
{
|
|||
|
T myReadObjectOfT = jsonPrim.ReadAs<T>();
|
|||
|
T myTryReadObjectOfT;
|
|||
|
Assert.True(jsonPrim.TryReadAs<T>(out myTryReadObjectOfT));
|
|||
|
Assert.Equal(myOriginalObjectOfT, myReadObjectOfT);
|
|||
|
Assert.Equal(myOriginalObjectOfT, myTryReadObjectOfT);
|
|||
|
|
|||
|
string stringValue;
|
|||
|
Assert.True(jsonPrim.TryReadAs<string>(out stringValue));
|
|||
|
if (typeof(T) == typeof(bool))
|
|||
|
{
|
|||
|
// bool returns a lowercase version. make sure we get something usable by doing another roundtrip of the value in .NET
|
|||
|
Assert.Equal(String.Format(CultureInfo.InvariantCulture, "{0}", myOriginalObjectOfT), bool.Parse(stringValue).ToString(CultureInfo.InvariantCulture));
|
|||
|
}
|
|||
|
else if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
|
|||
|
{
|
|||
|
Assert.Equal(String.Format(CultureInfo.InvariantCulture, "{0:R}", myOriginalObjectOfT), stringValue);
|
|||
|
}
|
|||
|
else if (typeof(T) == typeof(DateTime))
|
|||
|
{
|
|||
|
Assert.Equal(String.Format(CultureInfo.InvariantCulture, "{0:" + DateTimeFormat + "}", myOriginalObjectOfT), stringValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Assert.Equal(String.Format(CultureInfo.InvariantCulture, "{0}", myOriginalObjectOfT), stringValue);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void TestReadAsFromStringRoundtrip<T>(T value)
|
|||
|
{
|
|||
|
TestReadAsFromStringRoundtrip<T>(value, String.Format(CultureInfo.InvariantCulture, "{0}", value));
|
|||
|
}
|
|||
|
|
|||
|
void TestReadAsFromStringRoundtrip<T>(T value, string valueString)
|
|||
|
{
|
|||
|
T tempOfT;
|
|||
|
JsonPrimitive jsonPrim = new JsonPrimitive(valueString);
|
|||
|
Assert.True(jsonPrim.TryReadAs<T>(out tempOfT));
|
|||
|
Assert.Equal<T>(value, tempOfT);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|