-
Notifications
You must be signed in to change notification settings - Fork 46
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
Extract dependency free API and tests #71
Closed
Closed
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
ba30621
wip
b836f84
Merge branch 'master' into issues/16
goofballLogic 91d7a18
reading in json and parsing for test cases without newtonsoft
c90deec
Conformance tests now passing
6b96556
oops
98dd4aa
oops
268d2e3
Update json-ld.net.csproj
goofballLogic ff415c8
Update json-ld.net.csproj
goofballLogic 4f287ce
Merge branch 'master' into issues/16
goofballLogic f9b2e4b
restore try catch to verify errors properly
4552955
Merge branch 'master' into issues/16
goofballLogic c3ae91a
moved string-based API out into an infrastructure project
97bce7e
Merge branch 'issues/16' of github.com:linked-data-dotnet/json-ld.net…
3062504
to normalise namespace for tinyjson
425a3c8
We should use the same version of the microsoft test sdk across all t…
ee37cb0
undo unintentional whitespace changes
aa28180
remove redundant Raw file from testing project
c444ca0
rejigged JsonFetcher so internal dependencies no longer needed betwee…
d7012ff
undo changes
c5d1e0b
whitespace
45382d9
other unintentional file changes
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
using Xunit; | ||
using System.IO; | ||
using JsonLD.Core; | ||
using JsonLD.Util; | ||
using JsonLD.Test; | ||
|
||
namespace JsonLD.Infrastructure.Text.Tests | ||
{ | ||
public class ConformanceTests | ||
{ | ||
[Theory, ClassData(typeof(ConformanceCases))] | ||
public void ConformanceTestPasses(string id, ConformanceCase conformanceCase) | ||
{ | ||
string result; | ||
try | ||
{ | ||
result = conformanceCase.run(); | ||
if (!JsonLdUtils.DeepCompareStrings(result, conformanceCase.output)) | ||
{ | ||
#if DEBUG | ||
Console.WriteLine(id); | ||
Console.WriteLine("Actual:"); | ||
Console.Write(JSONUtils.ToPrettyString(result)); | ||
Console.WriteLine("--------------------------"); | ||
Console.WriteLine("Expected:"); | ||
Console.Write(JSONUtils.ToPrettyString(conformanceCase.output)); | ||
Console.WriteLine("--------------------------"); | ||
#endif | ||
|
||
Assert.True(false, "Returned JSON doesn't match expectations."); | ||
} | ||
|
||
} | ||
catch (Exception ex) | ||
{ | ||
if (conformanceCase.error == default) throw; // unexpected error | ||
Assert.True(ex.Message.StartsWith(conformanceCase.error), "Resulting error doesn't match expectations."); | ||
} | ||
} | ||
} | ||
|
||
public class ConformanceCase | ||
{ | ||
public string input { get; set; } | ||
public string context { get; set; } | ||
public string frame { get; set; } | ||
public string output { get; set; } | ||
public string error { get; set; } | ||
public Func<string> run { get; set; } | ||
} | ||
|
||
public class ConformanceCases : IEnumerable<object[]> | ||
{ | ||
string[] manifests = new[] { | ||
"compact-manifest.jsonld", | ||
"expand-manifest.jsonld", | ||
"flatten-manifest.jsonld", | ||
"frame-manifest.jsonld", | ||
"toRdf-manifest.jsonld", | ||
"fromRdf-manifest.jsonld", | ||
"normalize-manifest.jsonld", | ||
// Test tests are not supported on CORE CLR | ||
#if !PORTABLE && !IS_CORECLR | ||
"error-manifest.jsonld", | ||
"remote-doc-manifest.jsonld", | ||
#endif | ||
}; | ||
|
||
public ConformanceCases() | ||
{ | ||
|
||
} | ||
|
||
public IEnumerator<object[]> GetEnumerator() | ||
{ | ||
var rootDirectory = "W3C"; | ||
|
||
foreach (string manifest in manifests) | ||
{ | ||
var testCases = JsonFetcher.GetTestCases(manifest, rootDirectory); | ||
|
||
foreach (var testCase in testCases.Sequence) | ||
{ | ||
Func<string> run; | ||
ConformanceCase newCase = new ConformanceCase(); | ||
|
||
try | ||
{ | ||
newCase.input = testCase.GetInputJson(); | ||
newCase.context = testCase.GetContextJson(); | ||
newCase.frame = testCase.GetFrameJson(); | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new Exception($"{testCase.Id} in {testCases.Name}", ex); | ||
} | ||
|
||
var options = new JsonLD.Infrastructure.Text.JsonLdOptions("http://json-ld.org/test-suite/tests/" + testCase.Input); | ||
|
||
var testType = testCase.Type; | ||
|
||
if (testType.Any((s) => s == "jld:NegativeEvaluationTest")) | ||
{ | ||
newCase.error = testCase.Expect; | ||
} | ||
else if (testType.Any((s) => s == "jld:PositiveEvaluationTest")) | ||
{ | ||
if (testType.Any((s) => new List<string> { "jld:ToRDFTest", "jld:NormalizeTest" }.Contains(s))) | ||
{ | ||
newCase.output = File.ReadAllText(Path.Combine("W3C", testCase.Expect)); | ||
} | ||
else if (testType.Any((s) => s == "jld:FromRDFTest")) | ||
{ | ||
newCase.input = File.ReadAllText(Path.Combine("W3C", testCase.Input)); | ||
newCase.output = testCase.GetExpectJson(); | ||
} | ||
else | ||
{ | ||
newCase.output = testCase.GetExpectJson(); | ||
} | ||
} | ||
else | ||
{ | ||
throw new Exception("Expecting either positive or negative evaluation test."); | ||
} | ||
|
||
if (testCase.Options != null) | ||
{ | ||
if (testCase.Options.CompactArrays.HasValue) | ||
{ | ||
options.SetCompactArrays(testCase.Options.CompactArrays.Value); | ||
} | ||
if (testCase.Options.Base != default) | ||
{ | ||
options.SetBase(testCase.Options.Base); | ||
} | ||
if (testCase.Options.ExpandContext != default) | ||
{ | ||
newCase.context = testCase.GetExpandContextJson(); | ||
options.SetExpandContext(newCase.context); | ||
} | ||
if (testCase.Options.ProduceGeneralizedRdf.HasValue) | ||
{ | ||
options.SetProduceGeneralizedRdf(testCase.Options.ProduceGeneralizedRdf.Value); | ||
} | ||
if (testCase.Options.UseNativeTypes.HasValue) | ||
{ | ||
options.SetUseNativeTypes(testCase.Options.UseNativeTypes.Value); | ||
} | ||
if (testCase.Options.UseRdfType.HasValue) | ||
{ | ||
options.SetUseRdfType(testCase.Options.UseRdfType.Value); | ||
} | ||
} | ||
|
||
if (testType.Any((s) => s == "jld:CompactTest")) | ||
{ | ||
run = () => Infrastructure.Text.JsonLdProcessor.Compact(newCase.input, newCase.context, options); | ||
} | ||
else if (testType.Any((s) => s == "jld:ExpandTest")) | ||
{ | ||
run = () => Infrastructure.Text.JsonLdProcessor.Expand(newCase.input, options); | ||
} | ||
else if (testType.Any((s) => s == "jld:FlattenTest")) | ||
{ | ||
run = () => Infrastructure.Text.JsonLdProcessor.Flatten(newCase.input, newCase.context, options); | ||
} | ||
else if (testType.Any((s) => s == "jld:FrameTest")) | ||
{ | ||
run = () => Infrastructure.Text.JsonLdProcessor.Frame(newCase.input, newCase.frame, options); | ||
} | ||
else if (testType.Any((s) => s == "jld:NormalizeTest")) | ||
{ | ||
run = () => RDFDatasetUtils.ToNQuads((RDFDataset)Infrastructure.Text.JsonLdProcessor.Normalize(newCase.input, options)).Replace("\n", "\r\n"); | ||
} | ||
else if (testType.Any((s) => s == "jld:ToRDFTest")) | ||
{ | ||
options.format = "application/nquads"; | ||
run = () => Infrastructure.Text.JsonLdProcessor.ToRDF(newCase.input, options).Replace("\n", "\r\n"); | ||
|
||
} | ||
else if (testType.Any((s) => s == "jld:FromRDFTest")) | ||
{ | ||
options.format = "application/nquads"; | ||
run = () => Infrastructure.Text.JsonLdProcessor.FromRDF(newCase.input, options); | ||
} | ||
else | ||
{ | ||
run = () => { throw new Exception("Couldn't find a test type, apparently."); }; | ||
} | ||
|
||
if (testCases.AreRemoteDocumentTests) | ||
{ | ||
Func<string> innerRun = run; | ||
run = () => | ||
{ | ||
var remoteDoc = options.documentLoader.LoadDocument("https://json-ld.org/test-suite/tests/" + testCase.Input); | ||
newCase.input = remoteDoc.Document; | ||
options.SetBase(remoteDoc.DocumentUrl); | ||
options.SetExpandContext(remoteDoc.Context); | ||
return innerRun(); | ||
}; | ||
} | ||
|
||
newCase.run = run; | ||
|
||
yield return new object[] { manifest + testCase.Id, newCase }; | ||
} | ||
} | ||
} | ||
|
||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() | ||
{ | ||
throw new Exception("auggh"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
namespace JsonLD.Infrastructure.Text.Tests | ||
{ | ||
internal static class DictionaryExtensions | ||
{ | ||
public static T Required<T>(this Dictionary<string, object> dictionary, string propertyName) => Extract<T>(dictionary, propertyName, true); | ||
|
||
public static T Optional<T>(this Dictionary<string, object> dictionary, string propertyName) => Extract<T>(dictionary, propertyName, false); | ||
|
||
private static T Extract<T>(Dictionary<string, object> dictionary, string propertyName, bool isRequired) | ||
{ | ||
if (!dictionary.ContainsKey(propertyName)) | ||
{ | ||
if (isRequired) | ||
{ | ||
var message = $"Expected top-level property {propertyName} but only found {string.Join(", ", dictionary.Keys)}"; | ||
throw new Exception(message); | ||
} | ||
else | ||
{ | ||
return default; | ||
} | ||
} | ||
var value = dictionary[propertyName]; | ||
if (typeof(T).IsGenericType) { | ||
var genericType = typeof(T).GetGenericTypeDefinition(); | ||
if (genericType == typeof(List<>)) | ||
{ | ||
var list = Activator.CreateInstance<T>(); | ||
var addMethod = typeof(T).GetMethod("Add"); | ||
foreach(var item in (IEnumerable)value) | ||
{ | ||
addMethod.Invoke(list, new[] { item }); | ||
} | ||
return list; | ||
} | ||
} | ||
return (T)value; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
|
||
namespace JsonLD.Infrastructure.Text.Tests | ||
{ | ||
internal static class JsonFetcher | ||
{ | ||
public static JsonTestCases GetTestCases(string manifest, string rootDirectory) | ||
{ | ||
var json = GetJsonAsString(rootDirectory, manifest); | ||
var parsed = TinyJson.JSONParser.FromJson<Dictionary<string, object>>(json); | ||
var sequence = parsed.Required<List<object>>("sequence"); | ||
var name = parsed.Required<string>("name"); | ||
return new JsonTestCases(name, sequence, rootDirectory); | ||
} | ||
|
||
internal static string GetJsonAsString(string folderPath, string fileName) | ||
{ | ||
if (string.IsNullOrWhiteSpace(fileName)) throw new ArgumentOutOfRangeException(nameof(fileName), "Empty or whitespace"); | ||
var filePath = Path.Combine(folderPath, fileName); | ||
using (var manifestStream = File.OpenRead(filePath)) | ||
using (var reader = new StreamReader(manifestStream)) | ||
{ | ||
return reader.ReadToEnd(); | ||
} | ||
} | ||
|
||
internal static string GetRemoteJsonAsString(string input) => throw new NotImplementedException("Not even sure if this should be implemented. Need to double check whether remote test cases are supposed to use the core library to resolve the remote document or whether it's valid for the test case itself to retrieve it"); | ||
|
||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
JsonLD.Infrastructure.Text.Tests/JsonLD.Infrastructure.Text.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\JsonLD.Infrastructure.Text\JsonLD.Infrastructure.Text.csproj" /> | ||
<ProjectReference Include="..\test\json-ld.net.tests\json-ld.net.tests.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace JsonLD.Infrastructure.Text.Tests | ||
{ | ||
internal class JsonTestCase | ||
{ | ||
private readonly string _dataPath; | ||
private readonly bool _isRemoteDocumentTest; | ||
|
||
internal JsonTestCase(Dictionary<string, object> dictionary, string dataPath, bool isRemoteDocumentTest) | ||
{ | ||
Id = dictionary.Required<string>("@id"); | ||
Type = dictionary.Optional<List<string>>("@type"); | ||
Input = dictionary.Required<string>("input"); | ||
Expect = dictionary.Required<string>("expect"); | ||
Context = dictionary.Optional<string>("context"); | ||
Frame = dictionary.Optional<string>("frame"); | ||
var options = dictionary.Optional<Dictionary<string, object>>("option"); | ||
if (options != null) Options = new JsonTestCaseOptions(options); | ||
_dataPath = dataPath; | ||
_isRemoteDocumentTest = isRemoteDocumentTest; | ||
} | ||
|
||
internal string Context { get; } | ||
|
||
internal string Expect { get; } | ||
|
||
internal string Frame { get; } | ||
|
||
internal string Id { get; } | ||
|
||
internal string Input { get; } | ||
|
||
internal JsonTestCaseOptions Options { get; } | ||
|
||
internal IEnumerable<string> Type { get; } | ||
|
||
internal string GetContextJson() => Context == null ? null : JsonFetcher.GetJsonAsString(_dataPath, Context); | ||
|
||
internal string GetExpandContextJson() => Options?.ExpandContext == null ? null : JsonFetcher.GetJsonAsString(_dataPath, Options.ExpandContext); | ||
|
||
internal string GetExpectJson() => Expect == null ? null : JsonFetcher.GetJsonAsString(_dataPath, Expect); | ||
|
||
internal string GetFrameJson() => Frame == null ? null : JsonFetcher.GetJsonAsString(_dataPath, Frame); | ||
|
||
internal string GetInputJson() => _isRemoteDocumentTest | ||
? JsonFetcher.GetRemoteJsonAsString(Input) | ||
: JsonFetcher.GetJsonAsString(_dataPath, Input); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would prefer netstandard, but for now not wanting to change the core test project which is netcoreapp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's have
netstandard
as a goal, but we'll get there when we'll get there.