mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
546 lines
18 KiB
546 lines
18 KiB
// ==========================================================================
|
|
// Squidex Headless CMS
|
|
// ==========================================================================
|
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
// All rights reserved. Licensed under the MIT license.
|
|
// ==========================================================================
|
|
|
|
using NodaTime;
|
|
using Xunit;
|
|
|
|
#pragma warning disable xUnit2004 // Do not use equality check to test for boolean conditions
|
|
|
|
namespace Squidex.Infrastructure.Json.Objects
|
|
{
|
|
public class JsonObjectTests
|
|
{
|
|
[Fact]
|
|
public void Should_make_correct_object_equal_comparisons()
|
|
{
|
|
var obj1a = new JsonObject().Add("key1", 1);
|
|
var obj1b = new JsonObject().Add("key1", 1);
|
|
|
|
var objOtherValue = new JsonObject().Add("key1", 2);
|
|
var objOtherKey = new JsonObject().Add("key2", 1);
|
|
var objOtherSize = new JsonObject().Add("key1", 1).Add("key2", 2);
|
|
|
|
var number = JsonValue.Create(1);
|
|
|
|
Assert.Equal(obj1a, obj1b);
|
|
Assert.Equal(obj1a.GetHashCode(), obj1b.GetHashCode());
|
|
Assert.True(obj1a.Equals((object)obj1b));
|
|
|
|
Assert.NotEqual(obj1a, objOtherValue);
|
|
Assert.NotEqual(obj1a.GetHashCode(), objOtherValue.GetHashCode());
|
|
Assert.False(obj1a.Equals((object)objOtherValue));
|
|
|
|
Assert.NotEqual(obj1a, objOtherKey);
|
|
Assert.NotEqual(obj1a.GetHashCode(), objOtherKey.GetHashCode());
|
|
Assert.False(obj1a.Equals((object)objOtherKey));
|
|
|
|
Assert.NotEqual(obj1a, objOtherSize);
|
|
Assert.NotEqual(obj1a.GetHashCode(), objOtherSize.GetHashCode());
|
|
Assert.False(obj1a.Equals((object)objOtherSize));
|
|
|
|
Assert.NotEqual(obj1a, number);
|
|
Assert.NotEqual(obj1a.GetHashCode(), number.GetHashCode());
|
|
Assert.False(obj1a.Equals((object)number));
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_make_correct_array_equal_comparisons()
|
|
{
|
|
var array1a = JsonValue.Array(1);
|
|
var array1b = JsonValue.Array(1);
|
|
|
|
var arrayOtherValue = JsonValue.Array(2);
|
|
var arrayOtherSize = JsonValue.Array(1, 2);
|
|
|
|
var number = JsonValue.Create(1);
|
|
|
|
Assert.Equal(array1a, array1b);
|
|
Assert.Equal(array1a.GetHashCode(), array1b.GetHashCode());
|
|
Assert.True(array1a.Equals((object)array1b));
|
|
|
|
Assert.NotEqual(array1a, arrayOtherValue);
|
|
Assert.NotEqual(array1a.GetHashCode(), arrayOtherValue.GetHashCode());
|
|
Assert.False(array1a.Equals((object)arrayOtherValue));
|
|
|
|
Assert.NotEqual(array1a, arrayOtherSize);
|
|
Assert.NotEqual(array1a.GetHashCode(), arrayOtherSize.GetHashCode());
|
|
Assert.False(array1a.Equals((object)arrayOtherSize));
|
|
|
|
Assert.NotEqual(array1a, number);
|
|
Assert.NotEqual(array1a.GetHashCode(), number.GetHashCode());
|
|
Assert.False(array1a.Equals((object)number));
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_make_correct_scalar_comparisons()
|
|
{
|
|
var number1a = JsonValue.Create(1);
|
|
var number1b = JsonValue.Create(1);
|
|
|
|
var number2 = JsonValue.Create(2);
|
|
|
|
var boolean = JsonValue.True;
|
|
|
|
Assert.Equal(number1a, number1b);
|
|
Assert.Equal(number1a.GetHashCode(), number1b.GetHashCode());
|
|
Assert.True(number1a.Equals((object)number1b));
|
|
|
|
Assert.NotEqual(number1a, number2);
|
|
Assert.NotEqual(number1a.GetHashCode(), number2.GetHashCode());
|
|
Assert.False(number1a.Equals((object)number2));
|
|
|
|
Assert.NotEqual(number1a, boolean);
|
|
Assert.NotEqual(number1a.GetHashCode(), boolean.GetHashCode());
|
|
Assert.False(number1a.Equals((object)boolean));
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_make_correct_null_comparisons()
|
|
{
|
|
var null1 = JsonValue.Null;
|
|
var null2 = JsonValue.Null;
|
|
|
|
var boolean = JsonValue.True;
|
|
|
|
Assert.Equal(null1, null2);
|
|
Assert.Equal(null1.GetHashCode(), null2.GetHashCode());
|
|
Assert.True(null1.Equals((object)null2));
|
|
|
|
Assert.NotEqual(null1, boolean);
|
|
Assert.NotEqual(null1.GetHashCode(), boolean.GetHashCode());
|
|
Assert.False(null1.Equals((object)boolean));
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_null()
|
|
{
|
|
var jsons = new[]
|
|
{
|
|
new JsonValue((string?)null),
|
|
JsonValue.Create((string?)null),
|
|
JsonValue.Create((object?)null),
|
|
default
|
|
};
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Null(json.Value);
|
|
Assert.Equal(JsonValueType.Null, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsNumber);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsString);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_booleans()
|
|
{
|
|
var jsons = new[]
|
|
{
|
|
new JsonValue(true),
|
|
JsonValue.Create(true),
|
|
JsonValue.Create((object?)true),
|
|
true
|
|
};
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal(true, json.Value);
|
|
Assert.Equal(true, json.AsBoolean);
|
|
Assert.Equal(JsonValueType.Boolean, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsNumber);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsString);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_floats()
|
|
{
|
|
var jsons = new[]
|
|
{
|
|
new JsonValue(12.5),
|
|
JsonValue.Create(12.5),
|
|
JsonValue.Create((object?)12.5),
|
|
JsonValue.Create((object?)12.5f),
|
|
12.5
|
|
};
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal(12.5, json.Value);
|
|
Assert.Equal(12.5, json.AsNumber);
|
|
Assert.Equal(JsonValueType.Number, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsString);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_more_integers()
|
|
{
|
|
var jsons = new[]
|
|
{
|
|
new JsonValue(12),
|
|
JsonValue.Create(12),
|
|
JsonValue.Create((object?)12L),
|
|
JsonValue.Create((object?)12),
|
|
12
|
|
};
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal(12d, json.Value);
|
|
Assert.Equal(12d, json.AsNumber);
|
|
Assert.Equal(JsonValueType.Number, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsString);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_strings()
|
|
{
|
|
var jsons = new[]
|
|
{
|
|
new JsonValue("text"),
|
|
JsonValue.Create("text"),
|
|
JsonValue.Create((object?)"text"),
|
|
"text"
|
|
};
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal("text", json.Value);
|
|
Assert.Equal("text", json.AsString);
|
|
Assert.Equal(JsonValueType.String, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsNumber);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_instants()
|
|
{
|
|
var instant = Instant.FromUnixTimeSeconds(4123125455);
|
|
|
|
var jsons = new[]
|
|
{
|
|
JsonValue.Create(instant),
|
|
JsonValue.Create((object?)instant),
|
|
instant
|
|
};
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal(instant.ToString(), json.Value);
|
|
Assert.Equal(instant.ToString(), json.AsString);
|
|
Assert.Equal(JsonValueType.String, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsNumber);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_ids()
|
|
{
|
|
var id = DomainId.NewGuid();
|
|
|
|
var jsons = new[]
|
|
{
|
|
JsonValue.Create(id),
|
|
JsonValue.Create((object?)id),
|
|
id
|
|
};
|
|
|
|
var actual = id.ToString();
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal(actual, json.Value);
|
|
Assert.Equal(actual, json.AsString);
|
|
Assert.Equal(JsonValueType.String, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsNumber);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_arrays()
|
|
{
|
|
var input = new JsonArray { 1, 2 };
|
|
|
|
var jsons = new[]
|
|
{
|
|
new JsonValue(input),
|
|
JsonValue.Array(1, 2),
|
|
JsonValue.Array(new int[] { 1, 2 }),
|
|
JsonValue.Create(input),
|
|
JsonValue.Create((object?)input),
|
|
JsonValue.Create(new object[] { 1, 2 }),
|
|
input
|
|
};
|
|
|
|
var actual = new JsonArray { 1, 2 };
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal(actual, json.Value);
|
|
Assert.Equal(actual, json.AsArray);
|
|
Assert.Equal(JsonValueType.Array, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsNumber);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsString);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsObject);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_create_objects()
|
|
{
|
|
var input = new JsonObject().Add("1", 1).Add("2", 2);
|
|
|
|
var jsons = new[]
|
|
{
|
|
new JsonValue(input),
|
|
JsonValue.Create(input),
|
|
JsonValue.Create((object?)input),
|
|
JsonValue.Create(input.ToDictionary(x => x.Key, x => x.Value.Value)),
|
|
input
|
|
};
|
|
|
|
var actual = new JsonObject().Add("1", 1).Add("2", 2);
|
|
|
|
foreach (var json in jsons)
|
|
{
|
|
Assert.Equal(actual, json.Value);
|
|
Assert.Equal(actual, json.AsObject);
|
|
Assert.Equal(JsonValueType.Object, json.Type);
|
|
|
|
Assert.Throws<InvalidOperationException>(() => json.AsBoolean);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsNumber);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsString);
|
|
Assert.Throws<InvalidOperationException>(() => json.AsArray);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_clone_number_and_return_same()
|
|
{
|
|
var source = JsonValue.Create(1);
|
|
|
|
var clone = source.Clone();
|
|
|
|
Assert.Same(source.Value, clone.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_clone_string_and_return_same()
|
|
{
|
|
var source = JsonValue.Create("test");
|
|
|
|
var clone = source.Clone();
|
|
|
|
Assert.Same(source.Value, clone.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_clone_boolean_and_return_same()
|
|
{
|
|
var source = JsonValue.Create(true);
|
|
|
|
var clone = source.Clone();
|
|
|
|
Assert.Same(source.Value, clone.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_clone_null_and_return_same()
|
|
{
|
|
var source = JsonValue.Null;
|
|
|
|
var clone = source.Clone();
|
|
|
|
Assert.Same(source.Value, clone.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_clone_array_and_also_children()
|
|
{
|
|
var source = JsonValue.Array(new JsonArray(), new JsonArray()).AsArray;
|
|
|
|
var clone = ((JsonValue)source).Clone().AsArray;
|
|
|
|
Assert.NotSame(source, clone);
|
|
|
|
for (var i = 0; i < source.Count; i++)
|
|
{
|
|
Assert.NotSame(clone[i].Value, source[i].Value);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_clone_object_and_also_children()
|
|
{
|
|
var source = new JsonObject().Add("1", new JsonArray()).Add("2", new JsonArray());
|
|
|
|
var clone = ((JsonValue)source).Clone().AsObject;
|
|
|
|
Assert.NotSame(source, clone);
|
|
|
|
foreach (var (key, value) in clone)
|
|
{
|
|
Assert.NotSame(value.Value, source[key].Value);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_throw_exception_if_creation_value_from_invalid_type()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => JsonValue.Create(default(TimeSpan)));
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_null_if_getting_value_by_path_segment_from_null()
|
|
{
|
|
var json = JsonValue.Null;
|
|
|
|
var found = json.TryGetByPath("path", out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(default, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_null_if_getting_value_by_path_segment_from_string()
|
|
{
|
|
var json = JsonValue.Create("string");
|
|
|
|
var found = json.TryGetByPath("path", out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(default, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_null_if_getting_value_by_path_segment_from_boolean()
|
|
{
|
|
var json = JsonValue.True;
|
|
|
|
var found = json.TryGetByPath("path", out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(default, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_null_if_getting_value_by_path_segment_from_number()
|
|
{
|
|
var json = JsonValue.Create(12);
|
|
|
|
var found = json.TryGetByPath("path", out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(default, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_same_object_if_path_is_null()
|
|
{
|
|
JsonValue json = new JsonObject().Add("property", 12);
|
|
|
|
var found = json.TryGetByPath((string?)null, out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(json, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_same_object_if_path_is_empty()
|
|
{
|
|
JsonValue json = new JsonObject().Add("property", 12);
|
|
|
|
var found = json.TryGetByPath(string.Empty, out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(json, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_from_nested_array()
|
|
{
|
|
JsonValue json =
|
|
new JsonObject()
|
|
.Add("property",
|
|
JsonValue.Array(
|
|
JsonValue.Create(12),
|
|
new JsonObject()
|
|
.Add("nested", 13)));
|
|
|
|
var found = json.TryGetByPath("property[1].nested", out var actual);
|
|
|
|
Assert.True(found);
|
|
Assert.Equal(JsonValue.Create(13), actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_null_if_property_not_found()
|
|
{
|
|
JsonValue json =
|
|
new JsonObject()
|
|
.Add("property", 12);
|
|
|
|
var found = json.TryGetByPath("notfound", out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(default, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_null_if_out_of_index1()
|
|
{
|
|
JsonValue json = JsonValue.Array(12, 14);
|
|
|
|
var found = json.TryGetByPath("-1", out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(default, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void Should_return_null_if_out_of_index2()
|
|
{
|
|
JsonValue json = JsonValue.Array(12, 14);
|
|
|
|
var found = json.TryGetByPath("2", out var actual);
|
|
|
|
Assert.False(found);
|
|
Assert.Equal(default, actual);
|
|
}
|
|
}
|
|
}
|
|
|