Skip to content

Commit d78747d

Browse files
committed
Use events for language value warnings.
1 parent 2595ab0 commit d78747d

File tree

4 files changed

+149
-11
lines changed

4 files changed

+149
-11
lines changed

lib/expand.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ const {
3939
validateTypeValue: _validateTypeValue
4040
} = require('./util');
4141

42+
const {
43+
handleEvent: _handleEvent
44+
} = require('./events');
45+
4246
const api = {};
4347
module.exports = api;
4448
const REGEX_BCP47 = /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/;
@@ -591,9 +595,19 @@ async function _expandObject({
591595
value = _asArray(value).map(v => _isString(v) ? v.toLowerCase() : v);
592596

593597
// ensure language tag matches BCP47
594-
for(const lang of value) {
595-
if(_isString(lang) && !lang.match(REGEX_BCP47)) {
596-
console.warn(`@language must be valid BCP47: ${lang}`);
598+
for(const language of value) {
599+
if(_isString(language) && !language.match(REGEX_BCP47)) {
600+
_handleEvent({
601+
event: {
602+
code: 'invalid @language value',
603+
level: 'warning',
604+
message: '@language value must be valid BCP47.',
605+
details: {
606+
language
607+
}
608+
},
609+
options
610+
});
597611
}
598612
}
599613

lib/fromRdf.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ const graphTypes = require('./graphTypes');
88
const types = require('./types');
99
const util = require('./util');
1010

11+
const {
12+
handleEvent: _handleEvent
13+
} = require('./events');
14+
1115
// constants
1216
const {
1317
// RDF,
@@ -44,15 +48,16 @@ module.exports = api;
4448
*/
4549
api.fromRDF = async (
4650
dataset,
47-
{
48-
useRdfType = false,
49-
useNativeTypes = false,
50-
rdfDirection = null
51-
}
51+
options
5252
) => {
5353
const defaultGraph = {};
5454
const graphMap = {'@default': defaultGraph};
5555
const referencedOnce = {};
56+
const {
57+
useRdfType = false,
58+
useNativeTypes = false,
59+
rdfDirection = null
60+
} = options;
5661

5762
for(const quad of dataset) {
5863
// TODO: change 'name' to 'graph'
@@ -87,7 +92,7 @@ api.fromRDF = async (
8792
continue;
8893
}
8994

90-
const value = _RDFToObject(o, useNativeTypes, rdfDirection);
95+
const value = _RDFToObject(o, useNativeTypes, rdfDirection, options);
9196
util.addValue(node, p, value, {propertyIsArray: true});
9297

9398
// object may be an RDF list/partial list node but we can't know easily
@@ -275,10 +280,12 @@ api.fromRDF = async (
275280
*
276281
* @param o the RDF triple object to convert.
277282
* @param useNativeTypes true to output native types, false not to.
283+
* @param rdfDirection text direction mode [null, i18n-datatype]
284+
* @param options top level API options
278285
*
279286
* @return the JSON-LD object.
280287
*/
281-
function _RDFToObject(o, useNativeTypes, rdfDirection) {
288+
function _RDFToObject(o, useNativeTypes, rdfDirection, options) {
282289
// convert NamedNode/BlankNode object to JSON-LD
283290
if(o.termType.endsWith('Node')) {
284291
return {'@id': o.value};
@@ -335,7 +342,17 @@ function _RDFToObject(o, useNativeTypes, rdfDirection) {
335342
if(language.length > 0) {
336343
rval['@language'] = language;
337344
if(!language.match(REGEX_BCP47)) {
338-
console.warn(`@language must be valid BCP47: ${language}`);
345+
_handleEvent({
346+
event: {
347+
code: 'invalid @language value',
348+
level: 'warning',
349+
message: '@language value must be valid BCP47.',
350+
details: {
351+
language
352+
}
353+
},
354+
options
355+
});
339356
}
340357
}
341358
rval['@direction'] = direction;

lib/jsonld.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,8 @@ jsonld.normalize = jsonld.canonize = async function(input, options) {
600600
* (default: false).
601601
* [useNativeTypes] true to convert XSD types into native types
602602
* (boolean, integer, double), false not to (default: false).
603+
* [rdfDirection] 'i18n-datatype' to support RDF transformation of
604+
* @direction (default: null).
603605
* [handleEvent] handler for events such as warnings.
604606
*
605607
* @return a Promise that resolves to the JSON-LD document.

tests/misc.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,4 +651,109 @@ describe('events', () => {
651651
assert.equal(ranHandler3, true, 'ran handler 3');
652652
assert.equal(handled, true, 'handled');
653653
});
654+
it('handle known warning events', async () => {
655+
const d =
656+
{
657+
"@context": {
658+
"id-at": {"@id": "@test"},
659+
"@RESERVED": "ex:test"
660+
},
661+
"@RESERVED": "test",
662+
"ex:language": {
663+
"@value": "test",
664+
"@language": "!"
665+
}
666+
}
667+
;
668+
const ex =
669+
[
670+
{
671+
"ex:language": [
672+
{
673+
"@value": "test",
674+
"@language": "!"
675+
}
676+
]
677+
}
678+
]
679+
;
680+
681+
let handledReservedTerm = false;
682+
let handledReservedValue = false;
683+
let handledLanguage = false;
684+
const e = await jsonld.expand(d, {
685+
handleEvent: {
686+
'invalid reserved term': () => {
687+
handledReservedTerm = true;
688+
},
689+
'invalid reserved value': () => {
690+
handledReservedValue = true;
691+
},
692+
'invalid @language value': () => {
693+
handledLanguage = true;
694+
}
695+
}
696+
});
697+
assert.deepStrictEqual(e, ex);
698+
assert.equal(handledReservedTerm, true);
699+
assert.equal(handledReservedValue, true);
700+
assert.equal(handledLanguage, true);
701+
702+
// dataset with invalid language tag
703+
// Equivalent N-Quads:
704+
// <ex:s> <ex:p> "..."^^<https://www.w3.org/ns/i18n#!_rtl> .'
705+
// Using JSON dataset to bypass N-Quads parser checks.
706+
const d2 =
707+
[
708+
{
709+
"subject": {
710+
"termType": "NamedNode",
711+
"value": "ex:s"
712+
},
713+
"predicate": {
714+
"termType": "NamedNode",
715+
"value": "ex:p"
716+
},
717+
"object": {
718+
"termType": "Literal",
719+
"value": "invalid @language value",
720+
"datatype": {
721+
"termType": "NamedNode",
722+
"value": "https://www.w3.org/ns/i18n#!_rtl"
723+
}
724+
},
725+
"graph": {
726+
"termType": "DefaultGraph",
727+
"value": ""
728+
}
729+
}
730+
]
731+
;
732+
const ex2 =
733+
[
734+
{
735+
"@id": "ex:s",
736+
"ex:p": [
737+
{
738+
"@value": "invalid @language value",
739+
"@language": "!",
740+
"@direction": "rtl"
741+
}
742+
]
743+
}
744+
]
745+
;
746+
747+
let handledLanguage2 = false;
748+
const e2 = await jsonld.fromRDF(d2, {
749+
rdfDirection: 'i18n-datatype',
750+
handleEvent: {
751+
'invalid @language value': () => {
752+
handledLanguage2 = true;
753+
}
754+
}
755+
});
756+
assert.deepStrictEqual(e2, ex2);
757+
assert.equal(handledLanguage2, true);
758+
});
654759
});

0 commit comments

Comments
 (0)