diff --git a/lib/fromRdf.js b/lib/fromRdf.js index fb3567c8..e4cf0bad 100644 --- a/lib/fromRdf.js +++ b/lib/fromRdf.js @@ -47,7 +47,8 @@ api.fromRDF = async ( { useRdfType = false, useNativeTypes = false, - rdfDirection = null + rdfDirection = null, + preserveOrder = false, } ) => { const defaultGraph = {}; @@ -246,13 +247,13 @@ api.fromRDF = async ( } const result = []; - const subjects = Object.keys(defaultGraph).sort(); + const subjects = preserveOrder ? Object.keys(defaultGraph): Object.keys(defaultGraph).sort(); for(const subject of subjects) { const node = defaultGraph[subject]; if(subject in graphMap) { const graph = node['@graph'] = []; const graphObject = graphMap[subject]; - const graphSubjects = Object.keys(graphObject).sort(); + const graphSubjects = preserveOrder ? Object.keys(graphObject) : Object.keys(graphObject).sort(); for(const graphSubject of graphSubjects) { const node = graphObject[graphSubject]; // only add full subjects to top-level diff --git a/tests/misc.js b/tests/misc.js index 1c3758e0..5d23c441 100644 --- a/tests/misc.js +++ b/tests/misc.js @@ -250,6 +250,156 @@ describe('other fromRDF tests', () => { done(); }); }); + + it('should preserve object and property order when specified', done => { + const nq = ` + "3" .\n + "1" .\n + "2" .\n + + "3" .\n + "1" .\n + "2" .\n + + "3" .\n + "1" .\n + "2" .\n + `; + const p = jsonld.fromRDF(nq, {preserveOrder: true}); + assert(p instanceof Promise); + p.catch(e => { + assert.ifError(e); + }).then(output => { + assert.deepEqual( + output, + [ + {"@id": "http://example.com/Subject3", + "@graph": [ + { + "@id": "http://example.com/Subject3/Property3", + "http://example.com/value": [{"@value": "3"}] + }, + { + "@id": "http://example.com/Subject3/Property1", + "http://example.com/value": [{"@value": "1"}] + }, + { + "@id": "http://example.com/Subject3/Property2", + "http://example.com/value": [{"@value": "2"}] + } + ] + }, + {"@id": "http://example.com/Subject1", + "@graph": [ + { + "@id": "http://example.com/Subject1/Property3", + "http://example.com/value": [{"@value": "3"}] + }, + { + "@id": "http://example.com/Subject1/Property1", + "http://example.com/value": [{"@value": "1"}] + }, + { + "@id": "http://example.com/Subject1/Property2", + "http://example.com/value": [{"@value": "2"}] + } + ] + }, + {"@id": "http://example.com/Subject2", + "@graph": [ + { + "@id": "http://example.com/Subject2/Property3", + "http://example.com/value": [{"@value": "3"}] + }, + { + "@id": "http://example.com/Subject2/Property1", + "http://example.com/value": [{"@value": "1"}] + }, + { + "@id": "http://example.com/Subject2/Property2", + "http://example.com/value": [{"@value": "2"}] + } + ] + } + ]); + done(); + }); + }); + + it('orders objects and properties by default or when specified', done => { + const nq = ` + "3" .\n + "1" .\n + "2" .\n + + "3" .\n + "1" .\n + "2" .\n + + "3" .\n + "1" .\n + "2" .\n + `; + const p = jsonld.fromRDF(nq); + assert(p instanceof Promise); + p.catch(e => { + assert.ifError(e); + }).then(output => { + assert.deepEqual( + output, + [ + {"@id": "http://example.com/Subject1", + "@graph": [ + { + "@id": "http://example.com/Subject1/Property1", + "http://example.com/value": [{"@value": "1"}] + }, + { + "@id": "http://example.com/Subject1/Property2", + "http://example.com/value": [{"@value": "2"}] + }, + { + "@id": "http://example.com/Subject1/Property3", + "http://example.com/value": [{"@value": "3"}] + } + ] + }, + {"@id": "http://example.com/Subject2", + "@graph": [ + { + "@id": "http://example.com/Subject2/Property1", + "http://example.com/value": [{"@value": "1"}] + }, + { + "@id": "http://example.com/Subject2/Property2", + "http://example.com/value": [{"@value": "2"}] + }, + { + "@id": "http://example.com/Subject2/Property3", + "http://example.com/value": [{"@value": "3"}] + } + ] + }, + {"@id": "http://example.com/Subject3", + "@graph": [ + { + "@id": "http://example.com/Subject3/Property1", + "http://example.com/value": [{"@value": "1"}] + }, + { + "@id": "http://example.com/Subject3/Property2", + "http://example.com/value": [{"@value": "2"}] + }, + { + "@id": "http://example.com/Subject3/Property3", + "http://example.com/value": [{"@value": "3"}] + } + ] + } + ]); + done(); + }); + }); }); describe('loading multiple levels of contexts', () => {