Skip to content

Commit

Permalink
Add spec tests and fix issue with pruneBlankNodeIdentifiers
Browse files Browse the repository at this point in the history
- Add tests p010, p020, p021, and p046 (thanks for the pointer @eroux)
- Update test data for test 0021 from https://json-ld.org/test-suite/
- Fix issue with `pruneBlankNodeIdentifiers` exposed by test p021
  • Loading branch information
fsteeg committed Aug 21, 2017
1 parent 46cd7f2 commit 437e709
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 31 deletions.
24 changes: 11 additions & 13 deletions core/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java
Expand Up @@ -326,30 +326,28 @@ public static Map<String, Object> frame(Object input, Object frame, JsonLdOption
final Map<String, Object> rval = activeCtx.serialize();
rval.put(alias, compacted);

Set<Object> toPrune = opts.getPruneBlankNodeIdentifiers() ?
blankNodeIdsToPrune(rval, new HashSet<>()) : Collections.emptySet();
Set<Object> toPrune = opts.getPruneBlankNodeIdentifiers() ? blankNodeIdsToPrune(rval) : Collections.emptySet();
JsonLdUtils.removePreserveAndPrune(activeCtx, rval, opts, toPrune);
return rval;
}

private static Set<Object> blankNodeIdsToPrune(Object input, Set<Object> set) {
private static Set<Object> blankNodeIdsToPrune(final Map<String, Object> rval) {
return countBlankNodeIds(rval, new HashMap<>()).entrySet().stream().filter(e -> e.getValue() == 1)
.map(e -> e.getKey()).collect(Collectors.toSet());
}

private static Map<Object, Integer> countBlankNodeIds(Object input, Map<Object, Integer> frequencies) {
if (input instanceof List) {
((List<?>) input).forEach(e -> blankNodeIdsToPrune(e, set));
((List<?>) input).forEach(e -> countBlankNodeIds(e, frequencies));
} else if (input instanceof Map) {
((Map<?, ?>) input).entrySet().forEach(e -> blankNodeIdsToPrune(e.getValue(), set));
((Map<?, ?>) input).entrySet().forEach(e -> countBlankNodeIds(e.getValue(), frequencies));
} else if (input instanceof String) {
String p = (String) input;
if (p.startsWith("_:")) {
if(set.contains(p)){
// more than 1, don't prune
set.remove(p);
} else {
// exactly 1, prune
set.add(p);
}
frequencies.put(p, frequencies.containsKey(p) ? frequencies.get(p) + 1 : 1);
}
}
return set;
return frequencies;
}

/**
Expand Down
Expand Up @@ -419,6 +419,9 @@ public void runTest() throws URISyntaxException, IOException, JsonLdError {
if (test_opts.containsKey("produceGeneralizedRdf")) {
options.setProduceGeneralizedRdf((Boolean) test_opts.get("produceGeneralizedRdf"));
}
if (test_opts.containsKey("pruneBlankNodeIdentifiers")) {
options.setPruneBlankNodeIdentifiers((Boolean) test_opts.get("pruneBlankNodeIdentifiers"));
}
if (test_opts.containsKey("redirectTo")) {
testLoader.setRedirectTo((String) test_opts.get("redirectTo"));
}
Expand Down
Expand Up @@ -2,6 +2,6 @@
"@context": {
"dc": "http://purl.org/dc/elements/1.1/",
"ex": "http://example.org/vocab#",
"dc:list": {"@container": "@list"}
"ex:list": {"@container": "@list"}
}
}
6 changes: 3 additions & 3 deletions core/src/test/resources/json-ld.org/frame-0021-in.jsonld
Expand Up @@ -6,12 +6,12 @@
"ex:contains": {
"@type": "@id"
},
"dc:list": {"@container": "@list"}
"ex:list": {"@container": "@list"}
},
"@graph": [
{
"@id": "_:Book",
"dc:label": "Book type"
"dc:title": "Book type"
}, {
"@id": "http://example.org/library",
"@type": "ex:Library",
Expand All @@ -27,6 +27,6 @@
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:title": "The Introduction",
"dc:list": [1, 2, 3, 4, 4, 4, 5]
"ex:list": [1, 2, 3, 4, 4, 4, 5]
}]
}
10 changes: 5 additions & 5 deletions core/src/test/resources/json-ld.org/frame-0021-out.jsonld
Expand Up @@ -2,12 +2,12 @@
"@context": {
"dc": "http://purl.org/dc/elements/1.1/",
"ex": "http://example.org/vocab#",
"dc:list": {"@container": "@list"}
"ex:list": {"@container": "@list"}
},
"@graph": [
{
"@id": "_:b0",
"dc:label": "Book type"
"dc:title": "Book type"
}, {
"@id": "http://example.org/library",
"@type": "ex:Library",
Expand All @@ -21,7 +21,7 @@
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:title": "The Introduction",
"dc:list": [1, 2, 3, 4, 4, 4, 5]
"ex:list": [1, 2, 3, 4, 4, 4, 5]
}
}
}, {
Expand All @@ -32,15 +32,15 @@
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:title": "The Introduction",
"dc:list": [1, 2, 3, 4, 4, 4, 5]
"ex:list": [1, 2, 3, 4, 4, 4, 5]
},
"dc:creator": "Plato",
"dc:title": "The Republic"
}, {
"@id": "http://example.org/library/the-republic#introduction",
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:list": [1, 2, 3, 4, 4, 4, 5],
"ex:list": [1, 2, 3, 4, 4, 4, 5],
"dc:title": "The Introduction"
}]
}
4 changes: 4 additions & 0 deletions core/src/test/resources/json-ld.org/frame-0046-frame.jsonld
@@ -0,0 +1,4 @@
{
"@context": {"@vocab": "urn:"},
"@type": "Class"
}
11 changes: 11 additions & 0 deletions core/src/test/resources/json-ld.org/frame-0046-in.jsonld
@@ -0,0 +1,11 @@
{
"@context": {"@vocab": "urn:"},
"@id": "urn:id-1",
"@type": "Class",
"preserve": {
"@graph": {
"@id": "urn:id-2",
"term": "data"
}
}
}
49 changes: 40 additions & 9 deletions core/src/test/resources/json-ld.org/frame-manifest.jsonld
Expand Up @@ -152,13 +152,44 @@
"input": "frame-0021-in.jsonld",
"frame": "frame-0021-frame.jsonld",
"expect": "frame-0021-out.jsonld"
}
, {
"@id": "#t0022",
"@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"],
"name": "Default inside sets",
"input": "frame-0022-in.jsonld",
"frame": "frame-0022-frame.jsonld",
"expect": "frame-0022-out.jsonld"
}]
}, {
"@id": "#t0022",
"@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"],
"name": "Default inside sets",
"input": "frame-0022-in.jsonld",
"frame": "frame-0022-frame.jsonld",
"expect": "frame-0022-out.jsonld"
}, {
"@id": "p0010",
"@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"],
"name": "Property CURIE conflict (prune bnodes)",
"option" : {"pruneBlankNodeIdentifiers" : true},
"input": "frame-0010-in.jsonld",
"frame": "frame-0010-frame.jsonld",
"expect": "frame-p010-out.jsonld"
}, {
"@id": "p0020",
"@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"],
"name": "Blank nodes in an array (prune bnodes)",
"option" : {"pruneBlankNodeIdentifiers" : true},
"input": "frame-0020-in.jsonld",
"frame": "frame-0020-frame.jsonld",
"expect": "frame-p020-out.jsonld"
}, {
"@id": "p0021",
"@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"],
"name": "Blank nodes in @type (prune bnodes)",
"option" : {"pruneBlankNodeIdentifiers" : true},
"input": "frame-0021-in.jsonld",
"frame": "frame-0021-frame.jsonld",
"expect": "frame-p021-out.jsonld"
}, {
"@id": "p0046",
"@type": ["jld:PositiveEvaluationTest", "jld:FrameTest"],
"name": "Merge graphs if no outer @graph is used (prune bnodes)",
"option" : {"pruneBlankNodeIdentifiers" : true},
"input": "frame-0046-in.jsonld",
"frame": "frame-0046-frame.jsonld",
"expect": "frame-p046-out.jsonld"
}]
}
17 changes: 17 additions & 0 deletions core/src/test/resources/json-ld.org/frame-p010-out.jsonld
@@ -0,0 +1,17 @@
{
"@context": {
"dc": "http://purl.org/dc/terms/",
"dc:creator": {
"@type": "@id"
},
"foaf": "http://xmlns.com/foaf/0.1/",
"ps": "http://purl.org/payswarm#"
},
"@graph": [{
"@id": "http://example.com/asset",
"@type": "ps:Asset",
"dc:creator": {
"foaf:name": "John Doe"
}
}]
}
79 changes: 79 additions & 0 deletions core/src/test/resources/json-ld.org/frame-p020-out.jsonld
@@ -0,0 +1,79 @@
{
"@graph": [
{
"http://rdf.data-vocabulary.org/#ingredients": ["12 fresh mint leaves", "1/2 lime, juiced with pulp", "1 tablespoons white sugar", "1 cup ice cubes", "2 fluid ounces white rum", "1/2 cup club soda"],
"http://rdf.data-vocabulary.org/#instructions": [{
"@id": "_:b1",
"http://rdf.data-vocabulary.org/#description": "Crush lime juice, mint and sugar together in glass.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 1
}
}, {
"@id": "_:b2",
"http://rdf.data-vocabulary.org/#description": "Fill glass to top with ice cubes.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 2
}
}, {
"@id": "_:b3",
"http://rdf.data-vocabulary.org/#description": "Pour white rum over ice.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 3
}
}, {
"@id": "_:b4",
"http://rdf.data-vocabulary.org/#description": "Fill the rest of glass with club soda, stir.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 4
}
}, {
"@id": "_:b5",
"http://rdf.data-vocabulary.org/#description": "Garnish with a lime wedge.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 5
}
}],
"http://rdf.data-vocabulary.org/#name": "Mojito",
"http://rdf.data-vocabulary.org/#yield": "1 cocktail"
}, {
"@id": "_:b1",
"http://rdf.data-vocabulary.org/#description": "Crush lime juice, mint and sugar together in glass.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 1
}
}, {
"@id": "_:b2",
"http://rdf.data-vocabulary.org/#description": "Fill glass to top with ice cubes.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 2
}
}, {
"@id": "_:b3",
"http://rdf.data-vocabulary.org/#description": "Pour white rum over ice.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 3
}
}, {
"@id": "_:b4",
"http://rdf.data-vocabulary.org/#description": "Fill the rest of glass with club soda, stir.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 4
}
}, {
"@id": "_:b5",
"http://rdf.data-vocabulary.org/#description": "Garnish with a lime wedge.",
"http://rdf.data-vocabulary.org/#step": {
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": 5
}
}]
}
46 changes: 46 additions & 0 deletions core/src/test/resources/json-ld.org/frame-p021-out.jsonld
@@ -0,0 +1,46 @@
{
"@context": {
"dc": "http://purl.org/dc/elements/1.1/",
"ex": "http://example.org/vocab#",
"ex:list": {"@container": "@list"}
},
"@graph": [
{
"@id": "_:b0",
"dc:title": "Book type"
}, {
"@id": "http://example.org/library",
"@type": "ex:Library",
"ex:contains": {
"@id": "http://example.org/library/the-republic",
"@type": "_:b0",
"dc:creator": "Plato",
"dc:title": "The Republic",
"ex:contains": {
"@id": "http://example.org/library/the-republic#introduction",
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:title": "The Introduction",
"ex:list": [1, 2, 3, 4, 4, 4, 5]
}
}
}, {
"@id": "http://example.org/library/the-republic",
"@type": "_:b0",
"ex:contains": {
"@id": "http://example.org/library/the-republic#introduction",
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:title": "The Introduction",
"ex:list": [1, 2, 3, 4, 4, 4, 5]
},
"dc:creator": "Plato",
"dc:title": "The Republic"
}, {
"@id": "http://example.org/library/the-republic#introduction",
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"ex:list": [1, 2, 3, 4, 4, 4, 5],
"dc:title": "The Introduction"
}]
}
8 changes: 8 additions & 0 deletions core/src/test/resources/json-ld.org/frame-p046-out.jsonld
@@ -0,0 +1,8 @@
{
"@context": {"@vocab": "urn:"},
"@graph": [{
"@id": "urn:id-1",
"@type": "Class",
"preserve": {}
}]
}

0 comments on commit 437e709

Please sign in to comment.