Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema 2020 12 #52

Merged
merged 8 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 30 additions & 24 deletions JsonPointer.Tests/RelativeJsonPointerParseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,32 @@ public static IEnumerable SpecificationExamples
{
get
{
yield return new TestCaseData("1/foo", 1, new[] {"foo"});
yield return new TestCaseData("2/foo/0", 2, new[] {"foo", "0"});
yield return new TestCaseData("3/", 3, new[] {""});
yield return new TestCaseData("4/a~1b", 4, new[] {"a/b"});
yield return new TestCaseData("5/c%d", 5, new[] {"c%d"});
yield return new TestCaseData("6/e^f", 6, new[] {"e^f"});
yield return new TestCaseData("7/g|h", 7, new[] {"g|h"});
yield return new TestCaseData("8/i\\j", 8, new[] {"i\\j"});
yield return new TestCaseData("9/k\"l", 9, new[] {"k\"l"});
yield return new TestCaseData("10/ ", 10, new[] {" "});
yield return new TestCaseData("11/m~0n", 11, new[] {"m~n"});
yield return new TestCaseData("12/c%25d", 12, new[] {"c%25d"});
yield return new TestCaseData("13/e%5Ef", 13, new[] {"e%5Ef"});
yield return new TestCaseData("14/g%7Ch", 14, new[] {"g%7Ch"});
yield return new TestCaseData("15/i%5Cj", 15, new[] {"i%5Cj"});
yield return new TestCaseData("16/k%22l", 16, new[] {"k%22l"});
yield return new TestCaseData("17/%20", 17, new[] {"%20"});
yield return new TestCaseData("0", 0, new string[] { });
yield return new TestCaseData("1/0", 1, new[] {"0"});
yield return new TestCaseData("2/highly/nested/objects", 2, new[] {"highly", "nested", "objects"});
yield return new TestCaseData("0#", 0, new string[] { });
yield return new TestCaseData("1#", 1, new string[] { });
yield return new TestCaseData("1/foo", 1, 0, new[] {"foo"});
yield return new TestCaseData("2/foo/0", 2, 0, new[] {"foo", "0"});
yield return new TestCaseData("3/", 3, 0, new[] {""});
yield return new TestCaseData("4/a~1b", 4, 0, new[] {"a/b"});
yield return new TestCaseData("5/c%d", 5, 0, new[] {"c%d"});
yield return new TestCaseData("6/e^f", 6, 0, new[] {"e^f"});
yield return new TestCaseData("7/g|h", 7, 0, new[] {"g|h"});
yield return new TestCaseData("8/i\\j", 8, 0, new[] {"i\\j"});
yield return new TestCaseData("9/k\"l", 9, 0, new[] {"k\"l"});
yield return new TestCaseData("10/ ", 10, 0, new[] {" "});
yield return new TestCaseData("11/m~0n", 11, 0, new[] {"m~n"});
yield return new TestCaseData("12/c%25d", 12, 0, new[] {"c%25d"});
yield return new TestCaseData("13/e%5Ef", 13, 0, new[] {"e%5Ef"});
yield return new TestCaseData("14/g%7Ch", 14, 0, new[] {"g%7Ch"});
yield return new TestCaseData("15/i%5Cj", 15, 0, new[] {"i%5Cj"});
yield return new TestCaseData("16/k%22l", 16, 0, new[] {"k%22l"});
yield return new TestCaseData("17/%20", 17, 0, new[] {"%20"});
yield return new TestCaseData("0", 0, 0, new string[] { });
yield return new TestCaseData("1/0", 1, 0, new[] {"0"});
yield return new TestCaseData("2/highly/nested/objects", 2, 0, new[] {"highly", "nested", "objects"});
yield return new TestCaseData("0#", 0, 0, new string[] { });
yield return new TestCaseData("1#", 1, 0, new string[] { });
yield return new TestCaseData("1-1#", 1, -1, new string[] { });
yield return new TestCaseData("1+1#", 1, 1, new string[] { });
yield return new TestCaseData("1-1/path", 1, -1, new[] {"path"});
yield return new TestCaseData("1+1/path", 1, 1, new[] {"path"});
}
}
public static IEnumerable FailureCases
Expand All @@ -51,21 +55,23 @@ public static IEnumerable FailureCases
}

[TestCaseSource(nameof(SpecificationExamples))]
public void Parse(string pointerString, int parentSteps, string[] segments)
public void Parse(string pointerString, int parentSteps, int indexManipulation, string[] segments)
{
var pointer = RelativeJsonPointer.Parse(pointerString);

pointer.ParentSteps.Should().Be((uint) parentSteps);
pointer.ArrayIndexManipulator.Should().Be(indexManipulation);
pointer.Pointer.Segments.Length.Should().Be(segments.Length);
pointer.Pointer.Segments.Select(s => s.Value).Should().BeEquivalentTo(segments);
}

[TestCaseSource(nameof(SpecificationExamples))]
public void TryParse(string pointerString, int parentSteps, string[] segments)
public void TryParse(string pointerString, int parentSteps, int indexManipulation, string[] segments)
{
Assert.IsTrue(RelativeJsonPointer.TryParse(pointerString, out var pointer));

pointer.ParentSteps.Should().Be((uint) parentSteps);
pointer.ArrayIndexManipulator.Should().Be(indexManipulation);
pointer.Pointer.Segments.Length.Should().Be(segments.Length);
pointer.Pointer.Segments.Select(s => s.Value).Should().BeEquivalentTo(segments);
}
Expand Down
2 changes: 2 additions & 0 deletions JsonPointer.Tests/RelativeJsonPointerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ public static IEnumerable SpecificationExamples
{
yield return new TestCaseData("0", "\"baz\"");
yield return new TestCaseData("1/0", "\"bar\"");
yield return new TestCaseData("0-1", "\"bar\"");
yield return new TestCaseData("2/highly/nested/objects", "true");
yield return new TestCaseData("0#", "1");
yield return new TestCaseData("0-1#", "0");
yield return new TestCaseData("1#", "\"foo\"");
}
}
Expand Down
22 changes: 22 additions & 0 deletions JsonPointer/JsonPointer.Net.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions JsonPointer/JsonPointer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<RootNamespace>Json.Pointer</RootNamespace>
<Version>1.1.2</Version>
<Version>1.2.0</Version>
<PackageId>JsonPointer.Net</PackageId>
<Authors>Greg Dennis</Authors>
<Product>JsonPointer.Net</Product>
Expand All @@ -18,7 +18,7 @@
<PackageIcon>json-logo-256.png</PackageIcon>
<PackageReleaseNotes>https://gregsdennis.github.io/json-everything/release-notes/json-pointer.html</PackageReleaseNotes>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.1.2.0</FileVersion>
<FileVersion>1.2.0.0</FileVersion>
<DocumentationFile>JsonPointer.Net.xml</DocumentationFile>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
Expand Down
82 changes: 73 additions & 9 deletions JsonPointer/RelativeJsonPointer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ namespace Json.Pointer
/// </summary>
public uint ParentSteps { get; }
/// <summary>
/// Gets the number of lateral steps to take. Applicable only for arrays.
/// </summary>
public int ArrayIndexManipulator { get; }
/// <summary>
/// Gets the pointer to follow after taking <see cref="ParentSteps"/> steps upward.
/// </summary>
public JsonPointer Pointer { get; }
Expand All @@ -32,12 +36,28 @@ private RelativeJsonPointer(uint parentSteps)
{
IsIndexQuery = true;
ParentSteps = parentSteps;
ArrayIndexManipulator = 0;
Pointer = JsonPointer.Empty;
}
private RelativeJsonPointer(uint parentSteps, int arrayIndexManipulator)
{
IsIndexQuery = true;
ParentSteps = parentSteps;
ArrayIndexManipulator = arrayIndexManipulator ;
Pointer = JsonPointer.Empty;
}
private RelativeJsonPointer(uint parentSteps, JsonPointer pointer)
{
IsIndexQuery = false;
ParentSteps = parentSteps;
ArrayIndexManipulator = 0;
Pointer = pointer;
}
private RelativeJsonPointer(uint parentSteps, int arrayIndexManipulator, JsonPointer pointer)
{
IsIndexQuery = false;
ParentSteps = parentSteps;
ArrayIndexManipulator = arrayIndexManipulator;
Pointer = pointer;
}

Expand All @@ -49,6 +69,15 @@ private RelativeJsonPointer(uint parentSteps, JsonPointer pointer)
public static RelativeJsonPointer IndexQuery(uint parentSteps) =>
new RelativeJsonPointer(parentSteps);

/// <summary>
/// Creates an index query pointer.
/// </summary>
/// <param name="parentSteps"></param>
/// <param name="arrayIndexManipulator">The index manipulator.</param>
/// <returns>A Relative JSON Pointer.</returns>
public static RelativeJsonPointer IndexQuery(uint parentSteps, int arrayIndexManipulator) =>
new RelativeJsonPointer(parentSteps, arrayIndexManipulator);

/// <summary>
/// Creates a Relative JSON Pointer from a JSON Pointer and a number of parent steps.
/// </summary>
Expand All @@ -58,6 +87,16 @@ private RelativeJsonPointer(uint parentSteps, JsonPointer pointer)
public static RelativeJsonPointer FromPointer(uint parentSteps, JsonPointer pointer) =>
new RelativeJsonPointer(parentSteps, pointer);

/// <summary>
/// Creates a Relative JSON Pointer from a JSON Pointer and a number of parent steps.
/// </summary>
/// <param name="parentSteps">The number of parent steps.</param>
/// <param name="arrayIndexManipulator">The index manipulator.</param>
/// <param name="pointer">The JSON Pointer.</param>
/// <returns>A Relative JSON Pointer.</returns>
public static RelativeJsonPointer FromPointer(uint parentSteps, int arrayIndexManipulator, JsonPointer pointer) =>
new RelativeJsonPointer(parentSteps, arrayIndexManipulator, pointer);

/// <summary>
/// Parses a JSON Pointer segment from a string.
/// </summary>
Expand All @@ -73,22 +112,32 @@ public static RelativeJsonPointer Parse(string source)
var span = source.AsSpan();
int i = 0;
while (i < span.Length && char.IsDigit(span[i])) i++;

if (i == 0) throw new PointerParseException($"`{nameof(source)}` must start with a non-negative integer");

var number = uint.Parse(span.Slice(0, i).ToString());
if (i == span.Length) return new RelativeJsonPointer(number, JsonPointer.Empty);
var parentSteps = uint.Parse(span.Slice(0, i).ToString());
if (i == span.Length) return new RelativeJsonPointer(parentSteps, JsonPointer.Empty);

int indexManipulation = 0;
if (span[i] == '+' || span[i] == '-')
{
var sign = span[i] == '+' ? 1 : -1;
i++;
var start = i;
while (i < span.Length && char.IsDigit(span[i])) i++;
indexManipulation = sign * int.Parse(span.Slice(start, i - start).ToString());
if (i == span.Length) return new RelativeJsonPointer(parentSteps, indexManipulation, JsonPointer.Empty);
}
if (span[i] == '#')
{
if (i+1 < span.Length) throw new PointerParseException($"{nameof(source)} cannot contain data after a `#`");
return new RelativeJsonPointer(number);
return new RelativeJsonPointer(parentSteps, indexManipulation);
}

if (span[i] != '/') throw new PointerParseException($"{nameof(source)} must contain either a `#` or a pointer after the initial number");

var pointer = JsonPointer.Parse(span.Slice(i).ToString());

return new RelativeJsonPointer(number, pointer);
return new RelativeJsonPointer(parentSteps, indexManipulation, pointer);
}

/// <summary>
Expand Down Expand Up @@ -117,20 +166,35 @@ public static bool TryParse(string source, out RelativeJsonPointer relativePoint
return false;
}

var number = uint.Parse(span.Slice(0, i).ToString());
var parentSteps = uint.Parse(span.Slice(0, i).ToString());
if (i == span.Length)
{
relativePointer = new RelativeJsonPointer(number, JsonPointer.Empty);
relativePointer = new RelativeJsonPointer(parentSteps, JsonPointer.Empty);
return true;
}

int indexManipulation = 0;
if (span[i] == '+' || span[i] == '-')
{
var sign = span[i] == '+' ? 1 : -1;
i++;
var start = i;
while (i < span.Length && char.IsDigit(span[i])) i++;
indexManipulation = sign * int.Parse(span.Slice(start, i - start).ToString());
if (i == span.Length)
{
relativePointer = new RelativeJsonPointer(parentSteps, indexManipulation, JsonPointer.Empty);
return true;
}
}
if (span[i] == '#')
{
if (i + 1 < span.Length)
{
relativePointer = default;
return false;
}
relativePointer = new RelativeJsonPointer(number);
relativePointer = new RelativeJsonPointer(parentSteps, indexManipulation);
return true;
}

Expand All @@ -146,7 +210,7 @@ public static bool TryParse(string source, out RelativeJsonPointer relativePoint
return false;
}

relativePointer = new RelativeJsonPointer(number, pointer);
relativePointer = new RelativeJsonPointer(parentSteps, indexManipulation, pointer);
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions JsonSchema.Tests/FormatTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void Ipv4_Pass()

var value = JsonDocument.Parse("\"100.2.54.3\"");

var result = schema.Validate(value.RootElement, new ValidationOptions{ValidateFormat = true});
var result = schema.Validate(value.RootElement, new ValidationOptions{RequireFormatValidation = true});

Assert.True(result.IsValid);
}
Expand All @@ -25,7 +25,7 @@ public void Ipv4_Fail()

var value = JsonDocument.Parse("\"100.2.5444.3\"");

var result = schema.Validate(value.RootElement, new ValidationOptions {ValidateFormat = true});
var result = schema.Validate(value.RootElement, new ValidationOptions {RequireFormatValidation = true});

Assert.False(result.IsValid);
}
Expand Down
2 changes: 1 addition & 1 deletion JsonSchema.Tests/GithubTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public void Issue19_Draft4ShouldInvalidateAsUnrecognizedSchema_NoOption()

var result = schema.Validate(instance.RootElement, new ValidationOptions{OutputFormat = OutputFormat.Detailed});

result.AssertValid();
result.AssertInvalid();
}

[Test]
Expand Down
6 changes: 5 additions & 1 deletion JsonSchema.Tests/Suite/Suite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public static IEnumerable<TestCaseData> TestCases()
return GetTests("draft6")
.Concat(GetTests("draft7"))
.Concat(GetTests("draft2019-09"));
//.Concat(GetTests("draft2020-12"));
}

private static IEnumerable<TestCaseData> GetTests(string draftFolder)
Expand All @@ -41,8 +42,11 @@ private static IEnumerable<TestCaseData> GetTests(string draftFolder)
options.ValidateAs = Draft.Draft7;
break;
case "draft2019-09":
options.ValidateAs = Draft.Draft201909;
break;
case "draft2020-12":
// will set this when implementing the next draft
//options.ValidateAs = Draft.Draft2019_09;
//options.ValidateAs = Draft.Draft202012;
break;
}

Expand Down
2 changes: 2 additions & 0 deletions JsonSchema/AdditionalPropertiesKeyword.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ namespace Json.Schema
[SchemaDraft(Draft.Draft6)]
[SchemaDraft(Draft.Draft7)]
[SchemaDraft(Draft.Draft201909)]
[SchemaDraft(Draft.Draft202012)]
[Vocabulary(Vocabularies.Applicator201909Id)]
[Vocabulary(Vocabularies.Applicator202012Id)]
[JsonConverter(typeof(AdditionalPropertiesKeywordJsonConverter))]
public class AdditionalPropertiesKeyword : IJsonSchemaKeyword, IRefResolvable, ISchemaContainer, IEquatable<AdditionalPropertiesKeyword>
{
Expand Down
2 changes: 2 additions & 0 deletions JsonSchema/AllOfKeyword.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ namespace Json.Schema
[SchemaDraft(Draft.Draft6)]
[SchemaDraft(Draft.Draft7)]
[SchemaDraft(Draft.Draft201909)]
[SchemaDraft(Draft.Draft202012)]
[Vocabulary(Vocabularies.Applicator201909Id)]
[Vocabulary(Vocabularies.Applicator202012Id)]
[JsonConverter(typeof(AllOfKeywordJsonConverter))]
public class AllOfKeyword : IJsonSchemaKeyword, IRefResolvable, ISchemaCollector, IEquatable<AllOfKeyword>
{
Expand Down
2 changes: 2 additions & 0 deletions JsonSchema/AnchorKeyword.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ namespace Json.Schema
[SchemaKeyword(Name)]
[SchemaPriority(long.MinValue + 2)]
[SchemaDraft(Draft.Draft201909)]
[SchemaDraft(Draft.Draft202012)]
[Vocabulary(Vocabularies.Core201909Id)]
[Vocabulary(Vocabularies.Core202012Id)]
[JsonConverter(typeof(AnchorKeywordJsonConverter))]
public class AnchorKeyword : IJsonSchemaKeyword, IEquatable<AnchorKeyword>
{
Expand Down
2 changes: 2 additions & 0 deletions JsonSchema/AnyOfKeyword.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ namespace Json.Schema
[SchemaDraft(Draft.Draft6)]
[SchemaDraft(Draft.Draft7)]
[SchemaDraft(Draft.Draft201909)]
[SchemaDraft(Draft.Draft202012)]
[Vocabulary(Vocabularies.Applicator201909Id)]
[Vocabulary(Vocabularies.Applicator202012Id)]
[JsonConverter(typeof(AnyOfKeywordJsonConverter))]
public class AnyOfKeyword : IJsonSchemaKeyword, IRefResolvable, ISchemaCollector, IEquatable<AnyOfKeyword>
{
Expand Down