Skip to content

Commit 5abbcf2

Browse files
committed
Fix indexed field names appearing twice in IRIs
1 parent 5b75b78 commit 5abbcf2

2 files changed

Lines changed: 129 additions & 30 deletions

File tree

lib/serialize/ComponentConstructor.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,24 @@ export class ComponentConstructor {
248248
fieldId: string,
249249
scope: FieldScope,
250250
): ConstructorArgumentDefinition {
251+
// Append the current field name to the scope
252+
if (parameterData.type === 'field') {
253+
scope = {
254+
...scope,
255+
parentFieldNames: [ ...scope.parentFieldNames, parameterData.name ],
256+
};
257+
}
258+
251259
if (parameterData.range.type === 'nested') {
252260
// Create a hash object with `fields` entries.
253261
// Each entry's value is (indirectly) recursively handled by this method again.
254262
const fields = parameterData.range.value.map(subParamData => this.constructFieldDefinitionNested(
255263
context,
256264
classReference,
257-
<ParameterData<ParameterRangeResolved> & { range: { type: 'nested' } }> parameterData,
265+
<ParameterData<ParameterRangeResolved> & { range: { type: 'nested' } }>parameterData,
258266
parameters,
259267
subParamData,
268+
fieldId,
260269
scope,
261270
));
262271
return { fields };
@@ -277,6 +286,7 @@ export class ComponentConstructor {
277286
* @param parameterData Parameter data with nested range.
278287
* @param parameters The array of parameters of the owning class, which will be appended to.
279288
* @param subParamData The sub-parameter of the parameter with nested range.
289+
* @param fieldId The @id of the field.
280290
* @param scope The current field scope.
281291
*/
282292
public constructFieldDefinitionNested(
@@ -285,13 +295,10 @@ export class ComponentConstructor {
285295
parameterData: ParameterData<ParameterRangeResolved> & { range: { type: 'nested' } },
286296
parameters: ParameterDefinition[],
287297
subParamData: ParameterData<ParameterRangeResolved>,
298+
fieldId: string,
288299
scope: FieldScope,
289300
): ConstructorFieldDefinition {
290301
if (subParamData.type === 'field') {
291-
const subScope: FieldScope = {
292-
parentFieldNames: [ ...scope.parentFieldNames, subParamData.name ],
293-
fieldIdsHash: scope.fieldIdsHash,
294-
};
295302
return {
296303
keyRaw: subParamData.name,
297304
value: this.parameterDataToConstructorArgument(
@@ -300,7 +307,7 @@ export class ComponentConstructor {
300307
subParamData,
301308
parameters,
302309
this.fieldNameToId(context, classReference, subParamData.name, scope),
303-
subScope,
310+
scope,
304311
),
305312
};
306313
}
@@ -313,8 +320,15 @@ export class ComponentConstructor {
313320
classReference.localName} at ${classReference.fileName}`);
314321
}
315322

323+
// Remove the last element of the parent field names when we're in an indexed field,
324+
// to avoid the field name to be in the IRI twice.
325+
scope = {
326+
...scope,
327+
parentFieldNames: scope.parentFieldNames.slice(0, -1),
328+
};
329+
316330
// Determine parameter id's
317-
const idCollectEntries = this.fieldNameToId(context, classReference, parameterData.name, scope);
331+
const idCollectEntries = fieldId;
318332
const idKey = this.fieldNameToId(context, classReference, `${parameterData.name}_key`, scope);
319333
const idValue = this.fieldNameToId(context, classReference, `${parameterData.name}_value`, scope);
320334

test/serialize/ComponentConstructor.test.ts

Lines changed: 108 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -611,28 +611,110 @@ describe('ComponentConstructor', () => {
611611
}, parameters)).toEqual([
612612
{
613613
fields: [
614-
{ keyRaw: 'fieldA', value: { '@id': 'mp:a/b/file-param#MyClass_fieldA' }},
615-
{ keyRaw: 'fieldB', value: { '@id': 'mp:a/b/file-param#MyClass_fieldB' }},
614+
{ keyRaw: 'fieldA', value: { '@id': 'mp:a/b/file-param#MyClass_field_fieldA' }},
615+
{ keyRaw: 'fieldB', value: { '@id': 'mp:a/b/file-param#MyClass_field_fieldB' }},
616616
],
617617
},
618618
]);
619619
expect(parameters).toEqual([
620620
{
621-
'@id': 'mp:a/b/file-param#MyClass_fieldA',
621+
'@id': 'mp:a/b/file-param#MyClass_field_fieldA',
622622
comment: 'Hi1',
623623
range: 'xsd:boolean',
624624
required: true,
625625
unique: true,
626626
},
627627
{
628-
'@id': 'mp:a/b/file-param#MyClass_fieldB',
628+
'@id': 'mp:a/b/file-param#MyClass_field_fieldB',
629629
comment: 'Hi2',
630630
range: 'xsd:string',
631631
required: true,
632632
unique: true,
633633
},
634634
]);
635635
});
636+
637+
it('should handle a constructor with a nested param with a hash', () => {
638+
const parameters: ParameterDefinition[] = [];
639+
expect(ctor.constructParameters(context, classReference, {
640+
parameters: [
641+
{
642+
type: 'field',
643+
name: 'field',
644+
range: {
645+
type: 'nested',
646+
value: [
647+
{
648+
type: 'field',
649+
name: 'fieldA',
650+
range: {
651+
type: 'nested',
652+
value: [
653+
{
654+
type: 'index',
655+
domain: 'string',
656+
range: { type: 'raw', value: 'boolean' },
657+
comment: 'Hi1',
658+
},
659+
],
660+
},
661+
required: true,
662+
unique: true,
663+
comment: 'Hi1',
664+
},
665+
],
666+
},
667+
required: true,
668+
unique: true,
669+
comment: 'Hi',
670+
},
671+
],
672+
}, parameters)).toEqual([
673+
{
674+
fields: [
675+
{
676+
keyRaw: 'fieldA',
677+
value: {
678+
fields: [
679+
{
680+
collectEntries: 'mp:a/b/file-param#MyClass_field_fieldA',
681+
key: 'mp:a/b/file-param#MyClass_field_fieldA_key',
682+
value: {
683+
'@id': 'mp:a/b/file-param#MyClass_field_fieldA_value',
684+
},
685+
},
686+
],
687+
},
688+
},
689+
],
690+
},
691+
]);
692+
expect(parameters).toEqual([
693+
{
694+
'@id': 'mp:a/b/file-param#MyClass_field_fieldA',
695+
comment: 'Hi1',
696+
range: {
697+
'@type': 'mp:a/b/file-param#MyClass_field_fieldA_range',
698+
parameters: [
699+
{
700+
'@id': 'mp:a/b/file-param#MyClass_field_fieldA_key',
701+
required: true,
702+
unique: true,
703+
},
704+
{
705+
'@id': 'mp:a/b/file-param#MyClass_field_fieldA_value',
706+
comment: 'Hi1',
707+
range: 'xsd:boolean',
708+
required: true,
709+
unique: true,
710+
},
711+
],
712+
},
713+
required: true,
714+
unique: true,
715+
},
716+
]);
717+
});
636718
});
637719

638720
describe('parameterDataToConstructorArgument', () => {
@@ -738,12 +820,12 @@ describe('ComponentConstructor', () => {
738820
comment: 'Hi',
739821
}, parameters, 'mp:a/b/file-param#MyClass_field', scope)).toEqual({
740822
fields: [
741-
{ keyRaw: 'field', value: { '@id': 'mp:a/b/file-param#MyClass_field' }},
823+
{ keyRaw: 'field', value: { '@id': 'mp:a/b/file-param#MyClass_field_field' }},
742824
],
743825
});
744826
expect(parameters).toEqual([
745827
{
746-
'@id': 'mp:a/b/file-param#MyClass_field',
828+
'@id': 'mp:a/b/file-param#MyClass_field_field',
747829
comment: 'Hi',
748830
range: 'xsd:boolean',
749831
required: true,
@@ -783,20 +865,20 @@ describe('ComponentConstructor', () => {
783865
comment: 'Hi',
784866
}, parameters, 'mp:a/b/file-param#MyClass_field', scope)).toEqual({
785867
fields: [
786-
{ keyRaw: 'fieldA', value: { '@id': 'mp:a/b/file-param#MyClass_fieldA' }},
787-
{ keyRaw: 'fieldB', value: { '@id': 'mp:a/b/file-param#MyClass_fieldB' }},
868+
{ keyRaw: 'fieldA', value: { '@id': 'mp:a/b/file-param#MyClass_field_fieldA' }},
869+
{ keyRaw: 'fieldB', value: { '@id': 'mp:a/b/file-param#MyClass_field_fieldB' }},
788870
],
789871
});
790872
expect(parameters).toEqual([
791873
{
792-
'@id': 'mp:a/b/file-param#MyClass_fieldA',
874+
'@id': 'mp:a/b/file-param#MyClass_field_fieldA',
793875
comment: 'Hi1',
794876
range: 'xsd:boolean',
795877
required: true,
796878
unique: true,
797879
},
798880
{
799-
'@id': 'mp:a/b/file-param#MyClass_fieldB',
881+
'@id': 'mp:a/b/file-param#MyClass_field_fieldB',
800882
comment: 'Hi2',
801883
range: 'xsd:string',
802884
required: true,
@@ -848,27 +930,27 @@ describe('ComponentConstructor', () => {
848930
comment: 'Hi',
849931
}, parameters, 'mp:a/b/file-param#MyClass_field', scope)).toEqual({
850932
fields: [
851-
{ keyRaw: 'fieldA', value: { '@id': 'mp:a/b/file-param#MyClass_fieldA' }},
933+
{ keyRaw: 'fieldA', value: { '@id': 'mp:a/b/file-param#MyClass_field_fieldA' }},
852934
{
853935
keyRaw: 'fieldSub',
854936
value: {
855937
fields: [
856-
{ keyRaw: 'fieldB', value: { '@id': 'mp:a/b/file-param#MyClass_fieldSub_fieldB' }},
938+
{ keyRaw: 'fieldB', value: { '@id': 'mp:a/b/file-param#MyClass_field_fieldSub_fieldB' }},
857939
],
858940
},
859941
},
860942
],
861943
});
862944
expect(parameters).toEqual([
863945
{
864-
'@id': 'mp:a/b/file-param#MyClass_fieldA',
946+
'@id': 'mp:a/b/file-param#MyClass_field_fieldA',
865947
comment: 'Hi1',
866948
range: 'xsd:boolean',
867949
required: true,
868950
unique: true,
869951
},
870952
{
871-
'@id': 'mp:a/b/file-param#MyClass_fieldSub_fieldB',
953+
'@id': 'mp:a/b/file-param#MyClass_field_fieldSub_fieldB',
872954
comment: 'Hi2',
873955
range: 'xsd:string',
874956
required: true,
@@ -920,27 +1002,27 @@ describe('ComponentConstructor', () => {
9201002
comment: 'Hi',
9211003
}, parameters, 'mp:a/b/file-param#MyClass_field', scope)).toEqual({
9221004
fields: [
923-
{ keyRaw: 'field', value: { '@id': 'mp:a/b/file-param#MyClass_field' }},
1005+
{ keyRaw: 'field', value: { '@id': 'mp:a/b/file-param#MyClass_field_field' }},
9241006
{
9251007
keyRaw: 'value',
9261008
value: {
9271009
fields: [
928-
{ keyRaw: 'field', value: { '@id': 'mp:a/b/file-param#MyClass_value_field' }},
1010+
{ keyRaw: 'field', value: { '@id': 'mp:a/b/file-param#MyClass_field_value_field' }},
9291011
],
9301012
},
9311013
},
9321014
],
9331015
});
9341016
expect(parameters).toEqual([
9351017
{
936-
'@id': 'mp:a/b/file-param#MyClass_field',
1018+
'@id': 'mp:a/b/file-param#MyClass_field_field',
9371019
comment: 'Hi1',
9381020
range: 'xsd:boolean',
9391021
required: true,
9401022
unique: true,
9411023
},
9421024
{
943-
'@id': 'mp:a/b/file-param#MyClass_value_field',
1025+
'@id': 'mp:a/b/file-param#MyClass_field_value_field',
9441026
comment: 'Hi2',
9451027
range: 'xsd:string',
9461028
required: true,
@@ -968,7 +1050,7 @@ describe('ComponentConstructor', () => {
9681050
required: true,
9691051
unique: true,
9701052
comment: 'Hi',
971-
}, parameters, 'mp:a/b/file-param#MyClass_field', scope)).toEqual({
1053+
}, parameters, 'mp:a/b/file-param#MyClass_fieldA', scope)).toEqual({
9721054
fields: [
9731055
{
9741056
collectEntries: 'mp:a/b/file-param#MyClass_fieldA',
@@ -1031,7 +1113,7 @@ describe('ComponentConstructor', () => {
10311113
required: true,
10321114
unique: true,
10331115
comment: 'Hi',
1034-
}, parameters, 'mp:a/b/file-param#MyClass_field', scope)).toEqual({
1116+
}, parameters, 'mp:a/b/file-param#MyClass_fieldA', scope)).toEqual({
10351117
fields: [
10361118
{
10371119
collectEntries: 'mp:a/b/file-param#MyClass_fieldA',
@@ -1040,7 +1122,7 @@ describe('ComponentConstructor', () => {
10401122
},
10411123
{
10421124
keyRaw: 'fieldB',
1043-
value: { '@id': 'mp:a/b/file-param#MyClass_fieldB' },
1125+
value: { '@id': 'mp:a/b/file-param#MyClass_fieldA_fieldB' },
10441126
},
10451127
],
10461128
});
@@ -1069,7 +1151,7 @@ describe('ComponentConstructor', () => {
10691151
},
10701152
},
10711153
{
1072-
'@id': 'mp:a/b/file-param#MyClass_fieldB',
1154+
'@id': 'mp:a/b/file-param#MyClass_fieldA_fieldB',
10731155
comment: 'Hi1',
10741156
range: 'xsd:boolean',
10751157
required: true,
@@ -1113,6 +1195,7 @@ describe('ComponentConstructor', () => {
11131195
parameterData,
11141196
parameters,
11151197
subParamData,
1198+
'',
11161199
scope,
11171200
))
11181201
.toEqual({ keyRaw: 'fieldA', value: { '@id': 'mp:a/b/file-param#MyClass_fieldA' }});
@@ -1167,6 +1250,7 @@ describe('ComponentConstructor', () => {
11671250
parameterData,
11681251
parameters,
11691252
subParamData,
1253+
'',
11701254
scope,
11711255
))
11721256
.toEqual({
@@ -1219,6 +1303,7 @@ describe('ComponentConstructor', () => {
12191303
parameterData,
12201304
parameters,
12211305
subParamData,
1306+
'mp:a/b/file-param#MyClass_fieldA',
12221307
scope,
12231308
))
12241309
.toEqual({
@@ -1271,7 +1356,7 @@ describe('ComponentConstructor', () => {
12711356
};
12721357
const subParamData: ParameterData<ParameterRangeResolved> = (<any> parameterData).range.value[0];
12731358
expect(() => ctor
1274-
.constructFieldDefinitionNested(context, classReference, parameterData, parameters, subParamData, scope))
1359+
.constructFieldDefinitionNested(context, classReference, parameterData, parameters, subParamData, '', scope))
12751360
.toThrow(new Error(`Detected illegal indexed element inside a non-field in MyClass at /docs/package/src/a/b/file-param`));
12761361
});
12771362
});

0 commit comments

Comments
 (0)