@_linked/core 0.0.1 → 1.0.0-next.20260216062729
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/LICENSE +1 -1
- package/README.md +147 -92
- package/lib/cjs/queries/SelectQuery.d.ts +5 -0
- package/lib/cjs/queries/SelectQuery.js +14 -0
- package/lib/cjs/queries/SelectQuery.js.map +1 -1
- package/lib/cjs/shapes/SHACL.d.ts +1 -0
- package/lib/cjs/shapes/SHACL.js +82 -2
- package/lib/cjs/shapes/SHACL.js.map +1 -1
- package/lib/cjs/shapes/Shape.d.ts +13 -1
- package/lib/cjs/shapes/Shape.js +6 -0
- package/lib/cjs/shapes/Shape.js.map +1 -1
- package/lib/cjs/test-helpers/query-fixtures.d.ts +583 -0
- package/lib/cjs/test-helpers/query-fixtures.js +39 -1
- package/lib/cjs/test-helpers/query-fixtures.js.map +1 -1
- package/lib/esm/queries/SelectQuery.d.ts +5 -0
- package/lib/esm/queries/SelectQuery.js +14 -0
- package/lib/esm/queries/SelectQuery.js.map +1 -1
- package/lib/esm/shapes/SHACL.d.ts +1 -0
- package/lib/esm/shapes/SHACL.js +82 -2
- package/lib/esm/shapes/SHACL.js.map +1 -1
- package/lib/esm/shapes/Shape.d.ts +13 -1
- package/lib/esm/shapes/Shape.js +6 -0
- package/lib/esm/shapes/Shape.js.map +1 -1
- package/lib/esm/test-helpers/query-fixtures.d.ts +583 -0
- package/lib/esm/test-helpers/query-fixtures.js +38 -0
- package/lib/esm/test-helpers/query-fixtures.js.map +1 -1
- package/package.json +17 -1
- package/.context/notes.md +0 -0
- package/.context/todos.md +0 -0
- package/AGENTS.md +0 -59
- package/docs/001-core-extraction.md +0 -305
- package/jest.config.js +0 -25
- package/scripts/dual-package.js +0 -25
- package/src/collections/CoreMap.ts +0 -127
- package/src/collections/CoreSet.ts +0 -171
- package/src/collections/ShapeSet.ts +0 -18
- package/src/index.ts +0 -88
- package/src/interfaces/ICoreIterable.ts +0 -35
- package/src/interfaces/IFileStore.ts +0 -28
- package/src/interfaces/IQuadStore.ts +0 -16
- package/src/interfaces/IQueryParser.ts +0 -51
- package/src/ontologies/lincd.ts +0 -25
- package/src/ontologies/npm.ts +0 -15
- package/src/ontologies/owl.ts +0 -26
- package/src/ontologies/rdf.ts +0 -32
- package/src/ontologies/rdfs.ts +0 -38
- package/src/ontologies/shacl.ts +0 -136
- package/src/ontologies/xsd.ts +0 -47
- package/src/package.ts +0 -11
- package/src/queries/CreateQuery.ts +0 -41
- package/src/queries/DeleteQuery.ts +0 -54
- package/src/queries/MutationQuery.ts +0 -287
- package/src/queries/QueryContext.ts +0 -41
- package/src/queries/QueryFactory.ts +0 -275
- package/src/queries/QueryParser.ts +0 -79
- package/src/queries/SelectQuery.ts +0 -2101
- package/src/queries/UpdateQuery.ts +0 -47
- package/src/shapes/List.ts +0 -52
- package/src/shapes/SHACL.ts +0 -653
- package/src/shapes/Shape.ts +0 -282
- package/src/test-helpers/query-fixtures.ts +0 -313
- package/src/tests/core-utils.test.ts +0 -286
- package/src/tests/metadata.test.ts +0 -65
- package/src/tests/query.test.ts +0 -599
- package/src/tests/query.types.test.ts +0 -606
- package/src/tests/store-routing.test.ts +0 -133
- package/src/utils/LinkedErrorLogging.ts +0 -25
- package/src/utils/LinkedFileStorage.ts +0 -75
- package/src/utils/LinkedStorage.ts +0 -120
- package/src/utils/NameSpace.ts +0 -5
- package/src/utils/NodeReference.ts +0 -16
- package/src/utils/Package.ts +0 -681
- package/src/utils/Prefix.ts +0 -108
- package/src/utils/ShapeClass.ts +0 -335
- package/src/utils/Types.ts +0 -19
- package/src/utils/URI.ts +0 -40
- package/src/utils/cached.ts +0 -53
- package/tsconfig-cjs.json +0 -8
- package/tsconfig-esm.json +0 -9
- package/tsconfig.json +0 -29
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
import {describe, expect, test, jest, beforeEach} from '@jest/globals';
|
|
2
|
-
import {linkedPackage} from '../utils/Package';
|
|
3
|
-
import {Shape} from '../shapes/Shape';
|
|
4
|
-
import {literalProperty, objectProperty} from '../shapes/SHACL';
|
|
5
|
-
import {CoreSet} from '../collections/CoreSet';
|
|
6
|
-
import {
|
|
7
|
-
getLeastSpecificShapeClasses,
|
|
8
|
-
getMostSpecificSubShapes,
|
|
9
|
-
getPropertyShapeByLabel,
|
|
10
|
-
getShapeClass,
|
|
11
|
-
getSubShapesClasses,
|
|
12
|
-
getSuperShapesClasses,
|
|
13
|
-
} from '../utils/ShapeClass';
|
|
14
|
-
import {LinkedStorage} from '../utils/LinkedStorage';
|
|
15
|
-
import {QueryParser} from '../queries/QueryParser';
|
|
16
|
-
import {isWhereEvaluationPath} from '../queries/SelectQuery';
|
|
17
|
-
import {getQueryContext, setQueryContext} from '../queries/QueryContext';
|
|
18
|
-
import {NodeReferenceValue} from '../utils/NodeReference';
|
|
19
|
-
|
|
20
|
-
const makeProp = (base: string) => (suffix: string): NodeReferenceValue => ({
|
|
21
|
-
id: `${base}${suffix}`,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const shapeProp = makeProp('linked://tmp/shapeclass/');
|
|
25
|
-
const contextProp = makeProp('linked://tmp/context/');
|
|
26
|
-
const packageProp = makeProp('linked://tmp/package/');
|
|
27
|
-
|
|
28
|
-
const {linkedShape: linkedShapeClassTest} = linkedPackage('shapeclass-test');
|
|
29
|
-
const {linkedShape: linkedShapeContextTest} = linkedPackage('context-test');
|
|
30
|
-
const {
|
|
31
|
-
linkedShape: linkedShapePackageTest,
|
|
32
|
-
registerPackageExport,
|
|
33
|
-
registerPackageModule,
|
|
34
|
-
packageExports,
|
|
35
|
-
getPackageShape,
|
|
36
|
-
} = linkedPackage('package-test');
|
|
37
|
-
|
|
38
|
-
@linkedShapeClassTest
|
|
39
|
-
class BaseShape extends Shape {
|
|
40
|
-
@literalProperty({path: shapeProp('base')})
|
|
41
|
-
get base(): string {
|
|
42
|
-
return '';
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@linkedShapeClassTest
|
|
47
|
-
class SubShape extends BaseShape {
|
|
48
|
-
@literalProperty({path: shapeProp('sub')})
|
|
49
|
-
get sub(): string {
|
|
50
|
-
return '';
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
@linkedShapeClassTest
|
|
55
|
-
class DeepSubShape extends SubShape {
|
|
56
|
-
@literalProperty({path: shapeProp('deep')})
|
|
57
|
-
get deep(): string {
|
|
58
|
-
return '';
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
@linkedShapeClassTest
|
|
63
|
-
class SiblingSubShape extends BaseShape {
|
|
64
|
-
@literalProperty({path: shapeProp('sibling')})
|
|
65
|
-
get sibling(): string {
|
|
66
|
-
return '';
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
@linkedShapeContextTest
|
|
71
|
-
class ContextPerson extends Shape {
|
|
72
|
-
@literalProperty({path: contextProp('name'), maxCount: 1})
|
|
73
|
-
get name(): string {
|
|
74
|
-
return '';
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
@objectProperty({path: contextProp('bestFriend'), maxCount: 1, shape: ContextPerson})
|
|
78
|
-
get bestFriend(): ContextPerson {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@linkedShapePackageTest
|
|
84
|
-
class PackagePerson extends Shape {
|
|
85
|
-
@literalProperty({path: packageProp('name'), maxCount: 1})
|
|
86
|
-
get name(): string {
|
|
87
|
-
return '';
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const resetLinkedStorage = () => {
|
|
92
|
-
LinkedStorage.setDefaultStore(null as any);
|
|
93
|
-
LinkedStorage.getShapeToStoreMap().clear();
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
describe('ShapeClass utilities', () => {
|
|
97
|
-
test('getShapeClass resolves a class by node shape id', () => {
|
|
98
|
-
expect(getShapeClass(BaseShape.shape.id)).toBe(BaseShape);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
test('getSubShapesClasses returns subclasses', () => {
|
|
102
|
-
const subs = getSubShapesClasses(BaseShape);
|
|
103
|
-
expect(subs).toEqual(
|
|
104
|
-
expect.arrayContaining([SubShape, DeepSubShape, SiblingSubShape]),
|
|
105
|
-
);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
test('getSuperShapesClasses returns superclasses (most specific first)', () => {
|
|
109
|
-
const supers = getSuperShapesClasses(DeepSubShape);
|
|
110
|
-
expect(supers[0]).toBe(SubShape);
|
|
111
|
-
expect(supers).toEqual(expect.arrayContaining([BaseShape, Shape]));
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
test('getPropertyShapeByLabel walks inheritance chain', () => {
|
|
115
|
-
const property = getPropertyShapeByLabel(DeepSubShape, 'base');
|
|
116
|
-
expect(property).toBeDefined();
|
|
117
|
-
expect(property?.parentNodeShape).toBe(BaseShape.shape);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
test('getMostSpecificSubShapes returns only leaves', () => {
|
|
121
|
-
const mostSpecific = getMostSpecificSubShapes(BaseShape);
|
|
122
|
-
expect(mostSpecific).toEqual(
|
|
123
|
-
expect.arrayContaining([DeepSubShape, SiblingSubShape]),
|
|
124
|
-
);
|
|
125
|
-
expect(mostSpecific).not.toEqual(expect.arrayContaining([SubShape]));
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test('getLeastSpecificShapeClasses filters to base shapes', () => {
|
|
129
|
-
const shapes = new CoreSet([new SubShape(), new SiblingSubShape(), new BaseShape()]);
|
|
130
|
-
const leastSpecific = getLeastSpecificShapeClasses(shapes);
|
|
131
|
-
expect(leastSpecific).toEqual(expect.arrayContaining([BaseShape]));
|
|
132
|
-
expect(leastSpecific).not.toEqual(
|
|
133
|
-
expect.arrayContaining([SubShape, SiblingSubShape]),
|
|
134
|
-
);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('LinkedStorage extra behaviors', () => {
|
|
139
|
-
beforeEach(() => resetLinkedStorage());
|
|
140
|
-
|
|
141
|
-
test('setDefaultStore calls init when provided', () => {
|
|
142
|
-
const init = jest.fn();
|
|
143
|
-
LinkedStorage.setDefaultStore({init} as any);
|
|
144
|
-
expect(init).toHaveBeenCalled();
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
test('getStores returns default and shape-specific stores', () => {
|
|
148
|
-
const defaultStore = {selectQuery: jest.fn()} as any;
|
|
149
|
-
const shapeStore = {selectQuery: jest.fn()} as any;
|
|
150
|
-
LinkedStorage.setDefaultStore(defaultStore);
|
|
151
|
-
LinkedStorage.setStoreForShapes(shapeStore, BaseShape);
|
|
152
|
-
const stores = LinkedStorage.getStores();
|
|
153
|
-
expect(stores.has(defaultStore)).toBe(true);
|
|
154
|
-
expect(stores.has(shapeStore)).toBe(true);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test('getStoreForShapeClass falls back to superclass mapping', () => {
|
|
158
|
-
const baseStore = {selectQuery: jest.fn()} as any;
|
|
159
|
-
LinkedStorage.setStoreForShapes(baseStore, BaseShape);
|
|
160
|
-
expect(LinkedStorage.getStoreForShapeClass(SubShape)).toBe(baseStore);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test('selectQuery rejects when no store is configured', async () => {
|
|
164
|
-
await expect(
|
|
165
|
-
LinkedStorage.selectQuery({shape: null} as any),
|
|
166
|
-
).rejects.toThrow('No query store configured');
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
describe('QueryParser delegation', () => {
|
|
171
|
-
beforeEach(() => resetLinkedStorage());
|
|
172
|
-
|
|
173
|
-
test('selectQuery delegates to LinkedStorage', async () => {
|
|
174
|
-
const store = {
|
|
175
|
-
selectQuery: jest.fn(async () => [{id: 'r1'}]),
|
|
176
|
-
} as any;
|
|
177
|
-
LinkedStorage.setDefaultStore(store);
|
|
178
|
-
|
|
179
|
-
const queryFactory = ContextPerson.query((p) => p.name);
|
|
180
|
-
const result = await QueryParser.selectQuery(queryFactory);
|
|
181
|
-
|
|
182
|
-
expect(store.selectQuery).toHaveBeenCalledTimes(1);
|
|
183
|
-
expect(store.selectQuery.mock.calls[0][0]?.type).toBe('select');
|
|
184
|
-
expect(result).toEqual([{id: 'r1'}]);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
test('update/create/delete delegate to LinkedStorage', async () => {
|
|
188
|
-
const store = {
|
|
189
|
-
updateQuery: jest.fn(async () => ({id: 'u1'})),
|
|
190
|
-
createQuery: jest.fn(async () => ({id: 'c1'})),
|
|
191
|
-
deleteQuery: jest.fn(async () => ({deleted: [], count: 0})),
|
|
192
|
-
} as any;
|
|
193
|
-
LinkedStorage.setDefaultStore(store);
|
|
194
|
-
|
|
195
|
-
const updateResult = await QueryParser.updateQuery(
|
|
196
|
-
'u1',
|
|
197
|
-
{name: 'Ada'} as any,
|
|
198
|
-
ContextPerson,
|
|
199
|
-
);
|
|
200
|
-
const createResult = await QueryParser.createQuery(
|
|
201
|
-
{name: 'Tess'} as any,
|
|
202
|
-
ContextPerson,
|
|
203
|
-
);
|
|
204
|
-
const deleteResult = await QueryParser.deleteQuery('d1', ContextPerson);
|
|
205
|
-
|
|
206
|
-
expect(store.updateQuery.mock.calls[0][0]?.type).toBe('update');
|
|
207
|
-
expect(store.createQuery.mock.calls[0][0]?.type).toBe('create');
|
|
208
|
-
expect(store.deleteQuery.mock.calls[0][0]?.type).toBe('delete');
|
|
209
|
-
expect(updateResult).toEqual({id: 'u1'});
|
|
210
|
-
expect(createResult).toEqual({id: 'c1'});
|
|
211
|
-
expect(deleteResult).toEqual({deleted: [], count: 0});
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('QueryContext edge cases', () => {
|
|
216
|
-
test('getQueryContext returns null for unknown names', () => {
|
|
217
|
-
expect(getQueryContext('missing-context')).toBeNull();
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
test('setQueryContext warns and ignores invalid values', () => {
|
|
221
|
-
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
222
|
-
setQueryContext('invalid-context', {foo: 'bar'} as any);
|
|
223
|
-
expect(getQueryContext('invalid-context')).toBeNull();
|
|
224
|
-
expect(warn).toHaveBeenCalled();
|
|
225
|
-
warn.mockRestore();
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
test('setQueryContext warns when QResult provided without shapeType', () => {
|
|
229
|
-
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
230
|
-
setQueryContext('missing-shape', {id: 'ctx-1'} as any);
|
|
231
|
-
expect(getQueryContext('missing-shape')).toBeNull();
|
|
232
|
-
expect(warn).toHaveBeenCalled();
|
|
233
|
-
warn.mockRestore();
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
test('setQueryContext accepts QResult with shapeType and uses latest value', () => {
|
|
237
|
-
setQueryContext('ctx', {id: 'ctx-1'} as any, ContextPerson);
|
|
238
|
-
setQueryContext('ctx', {id: 'ctx-2'} as any, ContextPerson);
|
|
239
|
-
const context = getQueryContext('ctx');
|
|
240
|
-
expect(context.id).toBe('ctx-2');
|
|
241
|
-
|
|
242
|
-
const query = ContextPerson.query((p) => p.name).where((p) =>
|
|
243
|
-
p.bestFriend.equals(context),
|
|
244
|
-
);
|
|
245
|
-
const queryObject = query.getQueryObject();
|
|
246
|
-
const where = queryObject?.where;
|
|
247
|
-
expect(where).toBeDefined();
|
|
248
|
-
if (!where) {
|
|
249
|
-
throw new Error('Expected where clause');
|
|
250
|
-
}
|
|
251
|
-
const evaluation = isWhereEvaluationPath(where) ? where : where.firstPath;
|
|
252
|
-
if (!isWhereEvaluationPath(evaluation)) {
|
|
253
|
-
throw new Error('Expected evaluation where clause');
|
|
254
|
-
}
|
|
255
|
-
expect(evaluation.args[0]).toEqual({
|
|
256
|
-
id: 'ctx-2',
|
|
257
|
-
shape: {id: ContextPerson.shape.id},
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
describe('Package registration helpers', () => {
|
|
263
|
-
test('getPackageShape returns a shape class by name', () => {
|
|
264
|
-
expect(getPackageShape(PackagePerson.name)).toBe(PackagePerson);
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
test('registerPackageExport adds items to packageExports', () => {
|
|
268
|
-
function Helper() {}
|
|
269
|
-
registerPackageExport(Helper);
|
|
270
|
-
expect(packageExports.Helper).toBe(Helper);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
test('registerPackageModule sets names and registers exports', () => {
|
|
274
|
-
const unnamed = {name: '', original: {name: ''}};
|
|
275
|
-
const wrapped = {name: '_wrappedComponent', original: {name: ''}};
|
|
276
|
-
const moduleRef = {exports: {Unnamed: unnamed, Wrapped: wrapped}};
|
|
277
|
-
|
|
278
|
-
registerPackageModule(moduleRef);
|
|
279
|
-
|
|
280
|
-
expect(moduleRef.exports.Unnamed.name).toBe('Unnamed');
|
|
281
|
-
expect(moduleRef.exports.Wrapped.name).toBe('Wrapped');
|
|
282
|
-
expect(moduleRef.exports.Wrapped.original.name).toBe('Wrapped_implementation');
|
|
283
|
-
expect(packageExports.Unnamed).toBe(moduleRef.exports.Unnamed);
|
|
284
|
-
expect(packageExports.Wrapped).toBe(moduleRef.exports.Wrapped);
|
|
285
|
-
});
|
|
286
|
-
});
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import {describe, expect, test} from '@jest/globals';
|
|
2
|
-
import {linkedPackage} from '../utils/Package';
|
|
3
|
-
import {Shape} from '../shapes/Shape';
|
|
4
|
-
import {literalProperty, LINCD_DATA_ROOT} from '../shapes/SHACL';
|
|
5
|
-
import {URI} from '../utils/URI';
|
|
6
|
-
import {lincd} from '../ontologies/lincd';
|
|
7
|
-
import {shacl} from '../ontologies/shacl';
|
|
8
|
-
import {NodeReferenceValue} from '../utils/NodeReference';
|
|
9
|
-
|
|
10
|
-
const packageName = 'meta-test';
|
|
11
|
-
const {linkedShape, packageMetadata} = linkedPackage(packageName);
|
|
12
|
-
|
|
13
|
-
const tmpPropBase = 'linked://tmp/props/';
|
|
14
|
-
const tmpTypeBase = 'linked://tmp/types/';
|
|
15
|
-
|
|
16
|
-
const prop = (suffix: string): NodeReferenceValue => ({
|
|
17
|
-
id: `${tmpPropBase}${suffix}`,
|
|
18
|
-
});
|
|
19
|
-
const type = (suffix: string): NodeReferenceValue => ({
|
|
20
|
-
id: `${tmpTypeBase}${suffix}`,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
@linkedShape
|
|
24
|
-
class MetaPerson extends Shape {
|
|
25
|
-
static targetClass = type('MetaPerson');
|
|
26
|
-
|
|
27
|
-
@literalProperty({path: prop('name'), maxCount: 1})
|
|
28
|
-
get name(): string {
|
|
29
|
-
return '';
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe('Package & Shape Metadata Registration', () => {
|
|
34
|
-
test('registers package metadata with legacy id format', () => {
|
|
35
|
-
expect(packageMetadata).toEqual({
|
|
36
|
-
id: `${LINCD_DATA_ROOT}module/${packageName}`,
|
|
37
|
-
packageName,
|
|
38
|
-
type: lincd.Module,
|
|
39
|
-
});
|
|
40
|
-
expect(globalThis['lincd']._packages[packageName]).toBe(packageMetadata);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('registers node shape metadata with expected id', () => {
|
|
44
|
-
const expectedId = `${LINCD_DATA_ROOT}module/${URI.sanitize(
|
|
45
|
-
packageName,
|
|
46
|
-
)}/shape/${URI.sanitize(MetaPerson.name)}`;
|
|
47
|
-
|
|
48
|
-
expect(MetaPerson.shape).toBeDefined();
|
|
49
|
-
expect(MetaPerson.shape.id).toBe(expectedId);
|
|
50
|
-
expect(MetaPerson.shape.label).toBe(MetaPerson.name);
|
|
51
|
-
expect(MetaPerson.shape.targetClass).toEqual(type('MetaPerson'));
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('registers property shape metadata with expected id', () => {
|
|
55
|
-
const nodeShapeId = MetaPerson.shape.id;
|
|
56
|
-
const propertyShape = MetaPerson.shape.getPropertyShape('name');
|
|
57
|
-
|
|
58
|
-
expect(propertyShape).toBeDefined();
|
|
59
|
-
expect(propertyShape.label).toBe('name');
|
|
60
|
-
expect(propertyShape.id).toBe(`${nodeShapeId}/name`);
|
|
61
|
-
expect(propertyShape.path).toEqual(prop('name'));
|
|
62
|
-
expect(propertyShape.nodeKind).toEqual(shacl.Literal);
|
|
63
|
-
expect(propertyShape.parentNodeShape).toBe(MetaPerson.shape);
|
|
64
|
-
});
|
|
65
|
-
});
|