Add/Fix tests for UniJSON. Add ExplicitIgnorableValue option to ignore checks for validations

This commit is contained in:
yutopp
2019-01-08 23:28:02 +09:00
parent 317699ef41
commit 77eaa4bcb0
7 changed files with 152 additions and 17 deletions

View File

@@ -28,7 +28,7 @@ namespace UniJSON
}
struct EnumTest
{
{
public HogeFuga EnumDefault;
[JsonSchema(EnumSerializationType =EnumSerializationType.AsInt)]
@@ -104,6 +104,7 @@ namespace UniJSON
Assert.AreEqual(1, json.GetObjectCount());
Assert.AreEqual(1, json["Vector"][0].GetInt32());
}
#endregion
#region Deserialize

View File

@@ -1,7 +1,6 @@
#pragma warning disable 0649
using NUnit.Framework;
namespace UniJSON
{
public class SchemaTests
@@ -40,6 +39,24 @@ namespace UniJSON
Assert.AreEqual(0, parsed["properties"]["age"]["minimum"].GetInt32());
}
[JsonSchema(Title="MultipleConstraints")]
public class MultipleConstraints
{
[JsonSchema(Required = true, Minimum = 0, Maximum = 100)]
public int ranged;
}
[Test]
public void CreateFromClassWithMultipleConstraints()
{
var s = JsonSchema.FromType<MultipleConstraints>();
var v = s.Validator as JsonObjectValidator;
var rangedV = v.Properties["ranged"].Validator as JsonIntValidator;
Assert.AreEqual(0, rangedV.Minimum);
Assert.AreEqual(100, rangedV.Maximum);
}
public enum ProjectionType
{
Perspective,
@@ -48,7 +65,7 @@ namespace UniJSON
class EnumStringTest
{
[JsonSchema(EnumSerializationType =EnumSerializationType.AsLowerString)]
[JsonSchema(EnumSerializationType = EnumSerializationType.AsLowerString)]
public ProjectionType type;
}
@@ -81,7 +98,7 @@ namespace UniJSON
]
}
}
}
";
@@ -117,7 +134,7 @@ namespace UniJSON
]
}
}
}
";
@@ -129,6 +146,5 @@ namespace UniJSON
Assert.AreEqual(fromJson, fromType);
}
}
}

View File

@@ -34,5 +34,48 @@ namespace UniJSON
Assert.AreEqual(expected, actual);
}
[JsonSchema(Title="ObjectNestedTest")]
public class ObjectNestedTest
{
public CheckConstraintsTest C;
}
[Test]
public void TestObjectNested()
{
var obj = new ObjectNestedTest()
{
C = new CheckConstraintsTest(),
};
var s = JsonSchema.FromType<ObjectNestedTest>();
{
var c = new JsonSchemaValidationContext(obj);
Assert.Null(s.Validator.Validate(c, s));
}
var actual = s.Serialize(obj);
var expected = @"{""C"":{""X"":0}}";
Assert.AreEqual(expected, actual);
}
[Test]
public void TestObjectNestedWithNull()
{
var obj = new ObjectNestedTest();
var s = JsonSchema.FromType<ObjectNestedTest>();
{
var c = new JsonSchemaValidationContext(obj);
Assert.Null(s.Validator.Validate(c, s));
}
var actual = s.Serialize(obj);
var expected = @"{}";
Assert.AreEqual(expected, actual);
}
}
}

View File

@@ -216,7 +216,7 @@ namespace UniJSON
var s = JsonSchema.FromType<NotRequired>();
// An error is not returned because Value is not 'Required' and the diagnosis is not enabled
Assert.Null(s.Validator.Validate(c, new Hoge { Value = 0 }));
Assert.Null(s.Validator.Validate(c, new NotRequired { Value = 0 }));
Assert.True(c.IsEmpty());
}
@@ -228,7 +228,55 @@ namespace UniJSON
};
var s = JsonSchema.FromType<NotRequired>();
Assert.NotNull(s.Validator.Validate(c, new Hoge { Value = 0 }));
Assert.NotNull(s.Validator.Validate(c, new NotRequired { Value = 0 }));
Assert.True(c.IsEmpty());
}
}
class NotRequiredWithIgnorable
{
[JsonSchema(Minimum = 2, ExplicitIgnorableValue = -1)]
public int Value;
}
[Test]
public void ObjectValidatorForNotRequiredWithIgnorable()
{
{
var c = new JsonSchemaValidationContext("test")
{
EnableDiagnosisForNotRequiredFields = false, // Default behaviour
};
var s = JsonSchema.FromType<NotRequiredWithIgnorable>();
// An error is not returned because Value is not 'Required' and the diagnosis is not enabled
Assert.Null(s.Validator.Validate(c, new NotRequiredWithIgnorable { Value = 0 }));
Assert.True(c.IsEmpty());
}
{
var c = new JsonSchemaValidationContext("test")
{
EnableDiagnosisForNotRequiredFields = true,
};
var s = JsonSchema.FromType<NotRequiredWithIgnorable>();
Assert.NotNull(s.Validator.Validate(c, new NotRequiredWithIgnorable { Value = 0 }));
Assert.True(c.IsEmpty());
}
{
var c = new JsonSchemaValidationContext("test")
{
EnableDiagnosisForNotRequiredFields = true,
};
var s = JsonSchema.FromType<NotRequiredWithIgnorable>();
// An error is NOT returned even though diagnosis is enabled because of an ignorable value is matched
Assert.Null(s.Validator.Validate(c, new NotRequiredWithIgnorable { Value = -1 }));
Assert.True(c.IsEmpty());
}

View File

@@ -57,6 +57,8 @@ namespace UniJSON
/// </summary>
public bool SkipComparison { get; set; }
public object ExplicitIgnorableValue { private get; set; }
public override string ToString()
{
return string.Format("<{0}>", Title);
@@ -175,7 +177,8 @@ namespace UniJSON
Title = a.Title,
Description = a.Description,
Validator = validator,
SkipComparison = skipComparison
SkipComparison = skipComparison,
ExplicitIgnorableValue = a.ExplicitIgnorableValue,
};
return schema;
@@ -404,6 +407,16 @@ namespace UniJSON
Validator.ToJsonScheama(f);
f.EndMap();
}
public bool IsExplicitlyIgnorableValue<T>(T obj)
{
if (obj == null)
{
return ExplicitIgnorableValue == null;
}
return obj.Equals(ExplicitIgnorableValue);
}
}
public static class JsonSchemaExtensions

View File

@@ -55,6 +55,12 @@ namespace UniJSON
/// </summary>
public bool SkipSchemaComparison;
/// <summary>
/// Suppress errors if a value of the field which is not required by a schema is matched to this value.
/// This feature will be useful to ignore invalid value which is known.
/// </summary>
public object ExplicitIgnorableValue;
public void Merge(BaseJsonSchemaAttribute rhs)
{
if (rhs == null) return;

View File

@@ -4,7 +4,6 @@ using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace UniJSON
{
/// <summary>
@@ -302,18 +301,26 @@ namespace UniJSON
{
class ObjectValidator
{
delegate JsonSchemaValidationException FieldValidator(IJsonSchemaValidator v,
JsonSchemaValidationContext c, T o);
delegate JsonSchemaValidationException FieldValidator(
JsonSchema s, JsonSchemaValidationContext c, T o, bool isRequired);
Dictionary<string, FieldValidator> m_validators = new Dictionary<string, FieldValidator>();
static FieldValidator CreteFieldValidator<U>(Func<T, U> getter, string name)
{
return (v, c, o) =>
return (s, c, o, isRequired) =>
{
var v = s.Validator;
using (c.Push(name))
{
return v.Validate(c, getter(o));
var field = getter(o);
var ex = v.Validate(c, field);
if (ex != null && !isRequired && s.IsExplicitlyIgnorableValue(field))
{
return null;
}
return ex;
}
};
}
@@ -354,11 +361,12 @@ namespace UniJSON
FieldValidator fv;
if (m_validators.TryGetValue(fieldName, out fv))
{
var ex = fv(schema.Validator, c, o);
var isRequired = required.Contains(fieldName);
var ex = fv(schema, c, o, isRequired);
if (ex != null)
{
if (required.Contains(fieldName) // required fields must be checked
|| c.EnableDiagnosisForNotRequiredFields)
if (isRequired // required fields must be checked
|| c.EnableDiagnosisForNotRequiredFields)
{
return ex;
}