Skip to content

Commit 2ea4613

Browse files
committed
Add and test fromRDF event support.
- Add another langage check. - Add tests.
1 parent 91a25c6 commit 2ea4613

File tree

2 files changed

+131
-8
lines changed

2 files changed

+131
-8
lines changed

lib/fromRdf.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
const JsonLdError = require('./JsonLdError');
77
const graphTypes = require('./graphTypes');
88
const types = require('./types');
9-
const util = require('./util');
9+
10+
const {
11+
REGEX_BCP47,
12+
addValue: _addValue
13+
} = require('./util');
1014

1115
const {
1216
handleEvent: _handleEvent
@@ -33,8 +37,6 @@ const {
3337
XSD_STRING,
3438
} = require('./constants');
3539

36-
const REGEX_BCP47 = /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/;
37-
3840
const api = {};
3941
module.exports = api;
4042

@@ -88,12 +90,12 @@ api.fromRDF = async (
8890
}
8991

9092
if(p === RDF_TYPE && !useRdfType && objectIsNode) {
91-
util.addValue(node, '@type', o.value, {propertyIsArray: true});
93+
_addValue(node, '@type', o.value, {propertyIsArray: true});
9294
continue;
9395
}
9496

9597
const value = _RDFToObject(o, useNativeTypes, rdfDirection, options);
96-
util.addValue(node, p, value, {propertyIsArray: true});
98+
_addValue(node, p, value, {propertyIsArray: true});
9799

98100
// object may be an RDF list/partial list node but we can't know easily
99101
// until all triples are read
@@ -152,12 +154,12 @@ api.fromRDF = async (
152154
}
153155
154156
if(p === RDF_TYPE && !useRdfType && objectIsId) {
155-
util.addValue(node, '@type', o.value, {propertyIsArray: true});
157+
_addValue(node, '@type', o.value, {propertyIsArray: true});
156158
continue;
157159
}
158160
159161
const value = _RDFToObject(o, useNativeTypes);
160-
util.addValue(node, p, value, {propertyIsArray: true});
162+
_addValue(node, p, value, {propertyIsArray: true});
161163
162164
// object may be an RDF list/partial list node but we can't know easily
163165
// until all triples are read
@@ -296,6 +298,22 @@ function _RDFToObject(o, useNativeTypes, rdfDirection, options) {
296298

297299
// add language
298300
if(o.language) {
301+
if(!o.language.match(REGEX_BCP47)) {
302+
if(options.eventHandler) {
303+
_handleEvent({
304+
event: {
305+
type: ['JsonLdEvent'],
306+
code: 'invalid @language value',
307+
level: 'warning',
308+
message: '@language value must be valid BCP47.',
309+
details: {
310+
language: o.language
311+
}
312+
},
313+
options
314+
});
315+
}
316+
}
299317
rval['@language'] = o.language;
300318
} else {
301319
let type = o.datatype.value;

tests/misc.js

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,13 +601,16 @@ describe('events', () => {
601601
if(eventCounts || eventLog) {
602602
opts.eventHandler = eventHandler;
603603
}
604-
if(!['expand'].includes(type)) {
604+
if(!['expand', 'fromRDF'].includes(type)) {
605605
throw new Error(`Unknown test type: "${type}"`);
606606
}
607607
try {
608608
if(type === 'expand') {
609609
result = await jsonld.expand(input, opts);
610610
}
611+
if(type === 'fromRDF') {
612+
result = await jsonld.fromRDF(input, opts);
613+
}
611614
} catch(e) {
612615
error = e;
613616
}
@@ -2765,4 +2768,106 @@ describe('events', () => {
27652768
});
27662769
});
27672770
});
2771+
2772+
describe('fromRDF', () => {
2773+
it('should emit for invalid N-Quads @language value', async () => {
2774+
// N-Quads with invalid language tag (too long)
2775+
// FIXME: should N-Quads parser catch this instead?
2776+
const input =
2777+
'_:b0 <urn:property> "test"@abcdefghi .'
2778+
;
2779+
const expected =
2780+
[
2781+
{
2782+
"@id": "_:b0",
2783+
"urn:property": [
2784+
{
2785+
"@language": "abcdefghi",
2786+
"@value": "test"
2787+
}
2788+
]
2789+
}
2790+
]
2791+
;
2792+
2793+
console.error('FIXME');
2794+
await _test({
2795+
type: 'fromRDF',
2796+
input,
2797+
expected,
2798+
mapCounts: {},
2799+
eventCounts: {
2800+
codes: {
2801+
'invalid @language value': 1
2802+
},
2803+
events: 1
2804+
},
2805+
testNotSafe: true
2806+
});
2807+
});
2808+
2809+
it('should emit for invalid Dataset @language value', async () => {
2810+
// dataset with invalid language tag (too long)
2811+
// Equivalent N-Quads:
2812+
// '<ex:s> <ex:p> "test"^^<https://www.w3.org/ns/i18n#abcdefghi_rtl> .'
2813+
// Using JSON dataset to bypass N-Quads parser checks.
2814+
const input =
2815+
[
2816+
{
2817+
"subject": {
2818+
"termType": "NamedNode",
2819+
"value": "ex:s"
2820+
},
2821+
"predicate": {
2822+
"termType": "NamedNode",
2823+
"value": "ex:p"
2824+
},
2825+
"object": {
2826+
"termType": "Literal",
2827+
"value": "test",
2828+
"datatype": {
2829+
"termType": "NamedNode",
2830+
"value": "https://www.w3.org/ns/i18n#abcdefghi_rtl"
2831+
}
2832+
},
2833+
"graph": {
2834+
"termType": "DefaultGraph",
2835+
"value": ""
2836+
}
2837+
}
2838+
]
2839+
;
2840+
const expected =
2841+
[
2842+
{
2843+
"@id": "ex:s",
2844+
"ex:p": [
2845+
{
2846+
"@value": "test",
2847+
"@language": "abcdefghi",
2848+
"@direction": "rtl"
2849+
}
2850+
]
2851+
}
2852+
]
2853+
;
2854+
2855+
await _test({
2856+
type: 'fromRDF',
2857+
input,
2858+
options: {
2859+
rdfDirection: 'i18n-datatype',
2860+
},
2861+
expected,
2862+
mapCounts: {},
2863+
eventCounts: {
2864+
codes: {
2865+
'invalid @language value': 1
2866+
},
2867+
events: 1
2868+
},
2869+
testNotSafe: true
2870+
});
2871+
});
2872+
});
27682873
});

0 commit comments

Comments
 (0)