-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SemanticQuery frontend model (#486)
- Loading branch information
1 parent
e6d7e94
commit 26fff8e
Showing
2 changed files
with
158 additions
and
0 deletions.
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,117 @@ | ||
import { map } from 'lodash'; | ||
|
||
import { startStore, endStore } from '../test-util'; | ||
import mockOntology from '../mock-data/mock-ontology'; | ||
|
||
import Model from '../core/model'; | ||
import Collection from '../core/collection'; | ||
import Graph from '../common-rdf/graph'; | ||
import abstractDeepEqual from '../utilities/abstractDeepEqual'; | ||
|
||
import { logic, filters } from './dropdown-constants'; | ||
import SemanticQuery from './model'; | ||
|
||
describe('semantic search model', function() { | ||
beforeAll(startStore); | ||
beforeAll(function() { | ||
this.ontology = new Graph(mockOntology); | ||
this.model = new SemanticQuery({ | ||
id: '1', | ||
label: 'test 123', | ||
query: new Model({ | ||
chain: new Collection([{ | ||
range: this.ontology, | ||
assertion: true, | ||
selection: this.ontology.at(0), | ||
}, { | ||
range: new Graph([this.ontology.at(0)]), | ||
precedent: this.ontology.at(0), | ||
selection: logic.get('logic:and'), | ||
}, { | ||
range: new Graph([this.ontology.at(0)]), | ||
precedent: this.ontology.at(0), | ||
scheme: 'logic', | ||
action: 'and', | ||
branches: new Collection([{ | ||
chain: new Collection([{ | ||
range: new Graph([this.ontology.at(0)]), | ||
precedent: this.ontology.at(0), | ||
traversal: true, | ||
selection: this.ontology.at(3), | ||
}, { | ||
range: this.ontology, | ||
precedent: this.ontology.at(3), | ||
selection: filters.get('filter:isIRI'), | ||
}, { | ||
filter: filters.get('filter:isIRI'), | ||
}]), | ||
}, { | ||
chain: new Collection([{ | ||
range: this.ontology, | ||
precedent: this.ontology.at(3), | ||
selection: filters.get('filter:equals'), | ||
}, { | ||
filter: filters.get('filter:equals'), | ||
value: 'https://example.example', | ||
}]), | ||
}]), | ||
}]), | ||
}), | ||
}); | ||
const idOnlyOntology = this.ontology.map(m => ({ '@id': m.id })); | ||
this.minimalJSON = { | ||
id: '1', | ||
label: 'test 123', | ||
query: { | ||
chain: [{ | ||
range: idOnlyOntology, | ||
assertion: true, | ||
selection: idOnlyOntology[0], | ||
}, { | ||
range: [idOnlyOntology[0]], | ||
precedent: idOnlyOntology[0], | ||
selection: { id: 'logic:and' }, | ||
}, { | ||
range: [idOnlyOntology[0]], | ||
precedent: idOnlyOntology[0], | ||
scheme: 'logic', | ||
action: 'and', | ||
branches: [{ | ||
chain: [{ | ||
range: [idOnlyOntology[0]], | ||
precedent: idOnlyOntology[0], | ||
traversal: true, | ||
selection: idOnlyOntology[3], | ||
}, { | ||
range: idOnlyOntology, | ||
precedent: idOnlyOntology[3], | ||
selection: { id: 'filter:isIRI' }, | ||
}, { | ||
filter: { id: 'filter:isIRI' }, | ||
}], | ||
}, { | ||
chain: [{ | ||
range: idOnlyOntology, | ||
precedent: idOnlyOntology[3], | ||
selection: { id: 'filter:equals' }, | ||
}, { | ||
filter: { id: 'filter:equals' }, | ||
value: 'https://example.example', | ||
}], | ||
}], | ||
}], | ||
}, | ||
}; | ||
}); | ||
afterAll(endStore); | ||
|
||
it('sends a lean representation to the backend', function() { | ||
const json = this.model.toJSON(); | ||
expect(abstractDeepEqual(json, this.minimalJSON)).toBe(true); | ||
}); | ||
|
||
it('can reconstruct the full representation from lean JSON', function() { | ||
const parsed = this.model.parse(this.minimalJSON); | ||
expect(abstractDeepEqual(parsed, this.model.attributes)).toBe(true); | ||
}); | ||
}); |
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,41 @@ | ||
import { pick, extend, map, mapValues, has, isArray, isObject } from 'lodash'; | ||
|
||
import Model from '../core/model'; | ||
import Collection from '../core/collection'; | ||
import ldChannel from '../common-rdf/radio'; | ||
import Graph from '../common-rdf/graph'; | ||
|
||
import { logic, filters } from './dropdown-constants'; | ||
|
||
function pruneResources(json: any): any { | ||
if (!isObject(json)) return json; | ||
if (isArray(json)) return map(json, pruneResources); | ||
if (has(json, '@id')) return pick(json, '@id'); | ||
if (has(json, 'id')) return pick(json, 'id'); | ||
return mapValues(json, pruneResources); | ||
} | ||
|
||
function parseQuery(json: any, key?: string | number): any { | ||
if (!isObject(json)) return json; | ||
if (isArray(json)) { | ||
const data = map(json, parseQuery); | ||
if (key === 'range') return new Graph(data); | ||
return new Collection(data); | ||
} | ||
if (has(json, '@id')) return ldChannel.request('obtain', json); | ||
if (has(json, 'id')) { | ||
return logic.get(json as Model) || filters.get(json as Model); | ||
} | ||
return new Model(mapValues(json, parseQuery)); | ||
} | ||
|
||
export default class SemanticQuery extends Model { | ||
toJSON(options?: any): any { | ||
const json = super.toJSON(options); | ||
return mapValues(json, pruneResources); | ||
} | ||
|
||
parse(json: any): any { | ||
return mapValues(json, parseQuery); | ||
} | ||
} |