Files
acceptance-tests
data
debian
docs
external
Newtonsoft.Json
api-doc-tools
api-snapshot
aspnetwebstack
packages
src
test
Microsoft.TestCommon
Microsoft.Web.Helpers.Test
Microsoft.Web.Http.Data.Test
Microsoft.Web.Mvc.Test
Microsoft.Web.WebPages.OAuth.Test
SPA.Test
System.Json.Test.Integration
System.Json.Test.Unit
Common
Extensions
Properties
JsonArrayTest.cs
JsonDefaultTest.cs
JsonObjectTest.cs
JsonPrimitiveTest.cs
JsonTypeTest.cs
JsonValueDynamicMetaObjectTest.cs
JsonValueDynamicTest.cs
JsonValueLinqExtensionsTest.cs
JsonValueTest.cs
System.Json.Test.Unit.csproj
packages.config
System.Net.Http.Formatting.Test.Integration
System.Net.Http.Formatting.Test.Unit
System.Web.Helpers.Test
System.Web.Http.Integration.Test
System.Web.Http.SelfHost.Test
System.Web.Http.Test
System.Web.Http.WebHost.Test
System.Web.Mvc.Test
System.Web.Razor.Test
System.Web.WebPages.Administration.Test
System.Web.WebPages.Deployment.Test
System.Web.WebPages.Razor.Test
System.Web.WebPages.Test
WebMatrix.Data.Test
WebMatrix.WebData.Test
Settings.StyleCop
tools
.gitattributes
.gitignore
License.txt
README.md
Runtime.msbuild
Runtime.sln
Runtime.xunit
Settings.StyleCop
build.cmd
binary-reference-assemblies
bockbuild
boringssl
cecil
cecil-legacy
corefx
corert
ikdasm
ikvm
linker
nuget-buildtasks
nunit-lite
roslyn-binaries
rx
xunit-binaries
ikvm-native
libgc
llvm
m4
man
mcs
mk
mono
msvc
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
linux-packaging-mono/external/aspnetwebstack/test/System.Json.Test.Unit/JsonValueDynamicTest.cs

471 lines
20 KiB
C#
Raw Normal View History

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Dynamic;
using System.Runtime.Serialization.Json;
using Xunit;
namespace System.Json
{
public class JsonValueDynamicTest
{
const string InvalidIndexType = "Invalid '{0}' index type; only 'System.String' and non-negative 'System.Int32' types are supported.";
const string NonSingleNonNullIndexNotSupported = "Null index or multidimensional indexing is not supported by this indexer; use 'System.Int32' or 'System.String' for array and object indexing respectively.";
[Fact]
public void SettingDifferentValueTypes()
{
dynamic dyn = new JsonObject();
dyn.boolean = AnyInstance.AnyBool;
dyn.int16 = AnyInstance.AnyShort;
dyn.int32 = AnyInstance.AnyInt;
dyn.int64 = AnyInstance.AnyLong;
dyn.uint16 = AnyInstance.AnyUShort;
dyn.uint32 = AnyInstance.AnyUInt;
dyn.uint64 = AnyInstance.AnyULong;
dyn.@char = AnyInstance.AnyChar;
dyn.dbl = AnyInstance.AnyDouble;
dyn.flt = AnyInstance.AnyFloat;
dyn.dec = AnyInstance.AnyDecimal;
dyn.str = AnyInstance.AnyString;
dyn.uri = AnyInstance.AnyUri;
dyn.@byte = AnyInstance.AnyByte;
dyn.@sbyte = AnyInstance.AnySByte;
dyn.guid = AnyInstance.AnyGuid;
dyn.dateTime = AnyInstance.AnyDateTime;
dyn.dateTimeOffset = AnyInstance.AnyDateTimeOffset;
dyn.JsonArray = AnyInstance.AnyJsonArray;
dyn.JsonPrimitive = AnyInstance.AnyJsonPrimitive;
dyn.JsonObject = AnyInstance.AnyJsonObject;
JsonObject jo = (JsonObject)dyn;
Assert.Equal(AnyInstance.AnyBool, (bool)jo["boolean"]);
Assert.Equal(AnyInstance.AnyShort, (short)jo["int16"]);
Assert.Equal(AnyInstance.AnyUShort, (ushort)jo["uint16"]);
Assert.Equal(AnyInstance.AnyInt, (int)jo["int32"]);
Assert.Equal(AnyInstance.AnyUInt, (uint)jo["uint32"]);
Assert.Equal(AnyInstance.AnyLong, (long)jo["int64"]);
Assert.Equal(AnyInstance.AnyULong, (ulong)jo["uint64"]);
Assert.Equal(AnyInstance.AnySByte, (sbyte)jo["sbyte"]);
Assert.Equal(AnyInstance.AnyByte, (byte)jo["byte"]);
Assert.Equal(AnyInstance.AnyChar, (char)jo["char"]);
Assert.Equal(AnyInstance.AnyDouble, (double)jo["dbl"]);
Assert.Equal(AnyInstance.AnyFloat, (float)jo["flt"]);
Assert.Equal(AnyInstance.AnyDecimal, (decimal)jo["dec"]);
Assert.Equal(AnyInstance.AnyString, (string)jo["str"]);
Assert.Equal(AnyInstance.AnyUri, (Uri)jo["uri"]);
Assert.Equal(AnyInstance.AnyGuid, (Guid)jo["guid"]);
Assert.Equal(AnyInstance.AnyDateTime, (DateTime)jo["dateTime"]);
Assert.Equal(AnyInstance.AnyDateTimeOffset, (DateTimeOffset)jo["dateTimeOffset"]);
Assert.Same(AnyInstance.AnyJsonArray, jo["JsonArray"]);
Assert.Equal(AnyInstance.AnyJsonPrimitive, jo["JsonPrimitive"]);
Assert.Same(AnyInstance.AnyJsonObject, jo["JsonObject"]);
Assert.Equal(AnyInstance.AnyBool, (bool)dyn.boolean);
Assert.Equal(AnyInstance.AnyShort, (short)dyn.int16);
Assert.Equal(AnyInstance.AnyUShort, (ushort)dyn.uint16);
Assert.Equal(AnyInstance.AnyInt, (int)dyn.int32);
Assert.Equal(AnyInstance.AnyUInt, (uint)dyn.uint32);
Assert.Equal(AnyInstance.AnyLong, (long)dyn.int64);
Assert.Equal(AnyInstance.AnyULong, (ulong)dyn.uint64);
Assert.Equal(AnyInstance.AnySByte, (sbyte)dyn.@sbyte);
Assert.Equal(AnyInstance.AnyByte, (byte)dyn.@byte);
Assert.Equal(AnyInstance.AnyChar, (char)dyn.@char);
Assert.Equal(AnyInstance.AnyDouble, (double)dyn.dbl);
Assert.Equal(AnyInstance.AnyFloat, (float)dyn.flt);
Assert.Equal(AnyInstance.AnyDecimal, (decimal)dyn.dec);
Assert.Equal(AnyInstance.AnyString, (string)dyn.str);
Assert.Equal(AnyInstance.AnyUri, (Uri)dyn.uri);
Assert.Equal(AnyInstance.AnyGuid, (Guid)dyn.guid);
Assert.Equal(AnyInstance.AnyDateTime, (DateTime)dyn.dateTime);
Assert.Equal(AnyInstance.AnyDateTimeOffset, (DateTimeOffset)dyn.dateTimeOffset);
Assert.Same(AnyInstance.AnyJsonArray, dyn.JsonArray);
Assert.Equal(AnyInstance.AnyJsonPrimitive, dyn.JsonPrimitive);
Assert.Same(AnyInstance.AnyJsonObject, dyn.JsonObject);
ExceptionHelper.Throws<ArgumentException>(delegate { dyn.other = Console.Out; });
ExceptionHelper.Throws<ArgumentException>(delegate { dyn.other = dyn.NonExistentProp; });
}
[Fact]
public void NullTests()
{
dynamic dyn = new JsonObject();
JsonObject jo = (JsonObject)dyn;
dyn.@null = null;
Assert.Same(dyn.@null, AnyInstance.DefaultJsonValue);
jo["@null"] = null;
Assert.Null(jo["@null"]);
}
[Fact]
public void DynamicNotationTest()
{
bool boolValue;
JsonValue jsonValue;
Person person = Person.CreateSample();
dynamic jo = JsonValueExtensions.CreateFrom(person);
dynamic target = jo;
Assert.Equal<int>(person.Age, target.Age.ReadAs<int>()); // JsonPrimitive
Assert.Equal<string>(person.Address.ToString(), ((JsonObject)target.Address).ReadAsType<Address>().ToString()); // JsonObject
target = jo.Address.City; // JsonPrimitive
Assert.NotNull(target);
Assert.Equal<string>(target.ReadAs<string>(), person.Address.City);
target = jo.Friends; // JsonArray
Assert.NotNull(target);
jsonValue = target as JsonValue;
Assert.Equal<int>(person.Friends.Count, jsonValue.ReadAsType<List<Person>>().Count);
target = jo.Friends[1].Address.City;
Assert.NotNull(target);
Assert.Equal<string>(target.ReadAs<string>(), person.Address.City);
target = jo.Address.NonExistentProp.NonExistentProp2; // JsonObject (default)
Assert.NotNull(target);
Assert.True(jo is JsonObject);
Assert.False(target.TryReadAs<bool>(out boolValue));
Assert.True(target.TryReadAs<JsonValue>(out jsonValue));
Assert.Same(target, jsonValue);
Assert.Same(jo.Address.NonExistent, AnyInstance.DefaultJsonValue);
Assert.Same(jo.Friends[1000], AnyInstance.DefaultJsonValue);
Assert.Same(jo.Age.NonExistentProp, AnyInstance.DefaultJsonValue);
Assert.Same(jo.Friends.NonExistentProp, AnyInstance.DefaultJsonValue);
}
[Fact]
public void PropertyAccessTest()
{
Person p = AnyInstance.AnyPerson;
JsonObject jo = JsonValueExtensions.CreateFrom(p) as JsonObject;
JsonArray ja = JsonValueExtensions.CreateFrom(p.Friends) as JsonArray;
JsonPrimitive jp = AnyInstance.AnyJsonPrimitive;
JsonValue jv = AnyInstance.DefaultJsonValue;
dynamic jod = jo;
dynamic jad = ja;
dynamic jpd = jp;
dynamic jvd = jv;
Assert.Equal(jo.Count, jod.Count);
Assert.Equal(jo.JsonType, jod.JsonType);
Assert.Equal(jo.Keys.Count, jod.Keys.Count);
Assert.Equal(jo.Values.Count, jod.Values.Count);
Assert.Equal(p.Age, (int)jod.Age);
Assert.Equal(p.Age, (int)jod["Age"]);
Assert.Equal(p.Age, (int)jo["Age"]);
Assert.Equal(p.Address.City, (string)jo["Address"]["City"]);
Assert.Equal(p.Address.City, (string)jod["Address"]["City"]);
Assert.Equal(p.Address.City, (string)jod.Address.City);
Assert.Equal(p.Friends.Count, ja.Count);
Assert.Equal(ja.Count, jad.Count);
Assert.Equal(ja.IsReadOnly, jad.IsReadOnly);
Assert.Equal(ja.JsonType, jad.JsonType);
Assert.Equal(p.Friends[0].Age, (int)ja[0]["Age"]);
Assert.Equal(p.Friends[0].Age, (int)jad[0].Age);
Assert.Equal(jp.JsonType, jpd.JsonType);
}
[Fact]
public void ConcatDynamicAssignmentTest()
{
string value = "MyValue";
dynamic dynArray = JsonValue.Parse(AnyInstance.AnyJsonArray.ToString());
dynamic dynObj = JsonValue.Parse(AnyInstance.AnyJsonObject.ToString());
JsonValue target;
target = dynArray[0] = dynArray[1] = dynArray[2] = value;
Assert.Equal((string)target, value);
Assert.Equal((string)dynArray[0], value);
Assert.Equal((string)dynArray[1], value);
Assert.Equal((string)dynArray[2], value);
target = dynObj["key0"] = dynObj["key1"] = dynObj["key2"] = value;
Assert.Equal((string)target, value);
Assert.Equal((string)dynObj["key0"], value);
Assert.Equal((string)dynObj["key1"], value);
Assert.Equal((string)dynObj["key2"], value);
foreach (KeyValuePair<string, JsonValue> pair in AnyInstance.AnyJsonObject)
{
Assert.Equal<string>(AnyInstance.AnyJsonObject[pair.Key].ToString(), dynObj[pair.Key].ToString());
}
}
[Fact]
public void IndexConversionTest()
{
dynamic target = AnyInstance.AnyJsonArray;
dynamic expected = AnyInstance.AnyJsonArray[0];
dynamic result;
dynamic[] zero_indexes =
{
(short)0,
(ushort)0,
(byte)0,
(sbyte)0,
(char)0,
(int)0
};
result = target[(short)0];
Assert.Same(expected, result);
result = target[(ushort)0];
Assert.Same(expected, result);
result = target[(byte)0];
Assert.Same(expected, result);
result = target[(sbyte)0];
Assert.Same(expected, result);
result = target[(char)0];
Assert.Same(expected, result);
foreach (dynamic zero_index in zero_indexes)
{
result = target[zero_index];
Assert.Same(expected, result);
}
}
[Fact]
public void InvalidIndexTest()
{
object index1 = new object();
bool index2 = true;
Person index3 = AnyInstance.AnyPerson;
JsonObject jo = AnyInstance.AnyJsonObject;
dynamic target;
object ret;
JsonValue[] values = { AnyInstance.AnyJsonObject, AnyInstance.AnyJsonArray };
foreach (JsonValue value in values)
{
target = value;
ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[index1]; }, String.Format(InvalidIndexType, index1.GetType().FullName));
ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[index2]; }, String.Format(InvalidIndexType, index2.GetType().FullName));
ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[index3]; }, String.Format(InvalidIndexType, index3.GetType().FullName));
ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[null]; }, NonSingleNonNullIndexNotSupported);
ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[0, 1]; }, NonSingleNonNullIndexNotSupported);
ExceptionHelper.Throws<ArgumentException>(delegate { ret = target["key1", "key2"]; }, NonSingleNonNullIndexNotSupported);
ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[true]; }, String.Format(InvalidIndexType, true.GetType().FullName));
ExceptionHelper.Throws<ArgumentException>(delegate { target[index1] = jo; }, String.Format(InvalidIndexType, index1.GetType().FullName));
ExceptionHelper.Throws<ArgumentException>(delegate { target[index2] = jo; }, String.Format(InvalidIndexType, index2.GetType().FullName));
ExceptionHelper.Throws<ArgumentException>(delegate { target[index3] = jo; }, String.Format(InvalidIndexType, index3.GetType().FullName));
ExceptionHelper.Throws<ArgumentException>(delegate { target[null] = jo; }, NonSingleNonNullIndexNotSupported);
ExceptionHelper.Throws<ArgumentException>(delegate { target[0, 1] = jo; }, NonSingleNonNullIndexNotSupported);
ExceptionHelper.Throws<ArgumentException>(delegate { target["key1", "key2"] = jo; }, NonSingleNonNullIndexNotSupported);
ExceptionHelper.Throws<ArgumentException>(delegate { target[true] = jo; }, String.Format(InvalidIndexType, true.GetType().FullName));
}
}
[Fact]
public void InvalidCastingTests()
{
dynamic dyn;
string value = "NameValue";
dyn = AnyInstance.AnyJsonPrimitive;
ExceptionHelper.Throws<InvalidOperationException>(delegate { dyn.name = value; });
dyn = AnyInstance.AnyJsonArray;
ExceptionHelper.Throws<InvalidOperationException>(delegate { dyn.name = value; });
dyn = new JsonObject(AnyInstance.AnyJsonObject);
dyn.name = value;
Assert.Equal((string)dyn.name, value);
dyn = AnyInstance.DefaultJsonValue;
ExceptionHelper.Throws<InvalidOperationException>(delegate { dyn.name = value; });
}
[Fact]
public void CastTests()
{
dynamic dyn = JsonValueExtensions.CreateFrom(AnyInstance.AnyPerson) as JsonObject;
string city = dyn.Address.City;
Assert.Equal<string>(AnyInstance.AnyPerson.Address.City, dyn.Address.City.ReadAs<string>());
Assert.Equal<string>(AnyInstance.AnyPerson.Address.City, city);
JsonValue[] values =
{
AnyInstance.AnyInt,
AnyInstance.AnyString,
AnyInstance.AnyDateTime,
AnyInstance.AnyJsonObject,
AnyInstance.AnyJsonArray,
AnyInstance.DefaultJsonValue
};
int loopCount = 2;
bool explicitCast = true;
while (loopCount > 0)
{
loopCount--;
foreach (JsonValue jv in values)
{
EvaluateNoExceptions<JsonValue>(null, explicitCast);
EvaluateNoExceptions<JsonValue>(jv, explicitCast);
EvaluateNoExceptions<object>(jv, explicitCast);
EvaluateNoExceptions<IDynamicMetaObjectProvider>(jv, explicitCast);
EvaluateNoExceptions<IEnumerable<KeyValuePair<string, JsonValue>>>(jv, explicitCast);
EvaluateNoExceptions<string>(null, explicitCast);
EvaluateExpectExceptions<int>(null, explicitCast);
EvaluateExpectExceptions<Person>(jv, explicitCast);
EvaluateExpectExceptions<Exception>(jv, explicitCast);
EvaluateIgnoreExceptions<JsonObject>(jv, explicitCast);
EvaluateIgnoreExceptions<int>(jv, explicitCast);
EvaluateIgnoreExceptions<string>(jv, explicitCast);
EvaluateIgnoreExceptions<DateTime>(jv, explicitCast);
EvaluateIgnoreExceptions<JsonArray>(jv, explicitCast);
EvaluateIgnoreExceptions<JsonPrimitive>(jv, explicitCast);
}
explicitCast = false;
}
EvaluateNoExceptions<IDictionary<string, JsonValue>>(AnyInstance.AnyJsonObject, false);
EvaluateNoExceptions<IList<JsonValue>>(AnyInstance.AnyJsonArray, false);
}
static void EvaluateNoExceptions<T>(JsonValue value, bool cast)
{
Evaluate<T>(value, cast, false, true);
}
static void EvaluateExpectExceptions<T>(JsonValue value, bool cast)
{
Evaluate<T>(value, cast, true, true);
}
static void EvaluateIgnoreExceptions<T>(JsonValue value, bool cast)
{
Evaluate<T>(value, cast, true, false);
}
static void Evaluate<T>(JsonValue value, bool cast, bool throwExpected, bool assertExceptions)
{
T ret2;
object obj = null;
bool exceptionThrown = false;
string retstr2, retstr1;
Console.WriteLine("Test info: expected:[{0}], explicitCast type:[{1}]", value, typeof(T));
try
{
if (typeof(int) == typeof(T))
{
obj = ((int)value);
}
else if (typeof(string) == typeof(T))
{
obj = ((string)value);
}
else if (typeof(DateTime) == typeof(T))
{
obj = ((DateTime)value);
}
else if (typeof(IList<JsonValue>) == typeof(T))
{
obj = (IList<JsonValue>)value;
}
else if (typeof(IDictionary<string, JsonValue>) == typeof(T))
{
obj = (IDictionary<string, JsonValue>)value;
}
else if (typeof(JsonValue) == typeof(T))
{
obj = (JsonValue)value;
}
else if (typeof(JsonObject) == typeof(T))
{
obj = (JsonObject)value;
}
else if (typeof(JsonArray) == typeof(T))
{
obj = (JsonArray)value;
}
else if (typeof(JsonPrimitive) == typeof(T))
{
obj = (JsonPrimitive)value;
}
else
{
obj = (T)(object)value;
}
retstr1 = obj == null ? "null" : obj.ToString();
}
catch (Exception ex)
{
exceptionThrown = true;
retstr1 = ex.Message;
}
if (assertExceptions)
{
Assert.Equal<bool>(throwExpected, exceptionThrown);
}
exceptionThrown = false;
try
{
dynamic dyn = value as dynamic;
if (cast)
{
ret2 = (T)dyn;
}
else
{
ret2 = dyn;
}
retstr2 = ret2 != null ? ret2.ToString() : "null";
}
catch (Exception ex)
{
exceptionThrown = true;
retstr2 = ex.Message;
}
if (assertExceptions)
{
Assert.Equal<bool>(throwExpected, exceptionThrown);
}
// fixup string
retstr1 = retstr1.Replace("\'Person\'", String.Format("\'{0}\'", typeof(Person).FullName));
if (retstr1.EndsWith(".")) retstr1 = retstr1.Substring(0, retstr1.Length - 1);
// fixup string
retstr2 = retstr2.Replace("\'string\'", String.Format("\'{0}\'", typeof(string).FullName));
retstr2 = retstr2.Replace("\'int\'", String.Format("\'{0}\'", typeof(int).FullName));
if (retstr2.EndsWith(".")) retstr2 = retstr2.Substring(0, retstr2.Length - 1);
Assert.Equal<string>(retstr1, retstr2);
}
}
}