Skip to content

Commit 0033b49

Browse files
nikkufake-join[bot]
authored andcommitted
feat: support old style <idref> referencing
1 parent 85ed905 commit 0033b49

File tree

5 files changed

+143
-7
lines changed

5 files changed

+143
-7
lines changed

lib/read.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,19 @@ ReferenceHandler.prototype.handleNode = function(node) {
215215
this.element = this.createReference(node);
216216
}
217217

218+
const property = this.property;
219+
220+
const idAttr = property.xml && property.xml.idAttr;
221+
222+
if (idAttr && node.attributes[idAttr]) {
223+
this.element.id = node.attributes[idAttr];
224+
}
225+
218226
return this;
219227
};
220228

221229
ReferenceHandler.prototype.handleEnd = function() {
222-
this.element.id = this.body;
230+
this.element.id = this.element.id || this.body;
223231
};
224232

225233
ReferenceHandler.prototype.createReference = function(node) {

lib/write.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,16 +245,31 @@ function ReferenceSerializer(tagName) {
245245
this.tagName = tagName;
246246
}
247247

248-
ReferenceSerializer.prototype.build = function(element) {
248+
ReferenceSerializer.prototype.build = function(property, element) {
249+
this.property = property;
249250
this.element = element;
251+
250252
return this;
251253
};
252254

253255
ReferenceSerializer.prototype.serializeTo = function(writer) {
254-
writer
255-
.appendIndent()
256-
.append('<' + this.tagName + '>' + this.element.id + '</' + this.tagName + '>')
257-
.appendNewLine();
256+
257+
const property = this.property;
258+
259+
const idAttr = property.xml && property.xml.idAttr;
260+
261+
const id = this.element.id;
262+
const tagName = this.tagName;
263+
264+
writer.appendIndent();
265+
266+
if (idAttr) {
267+
writer.append('<' + tagName + ' ' + idAttr + '="' + id + '" />');
268+
} else {
269+
writer.append('<' + tagName + '>' + id + '</' + tagName + '>');
270+
}
271+
272+
writer.appendNewLine();
258273
};
259274

260275
function BodySerializer() {}
@@ -532,7 +547,7 @@ ElementSerializer.prototype.parseContainments = function(properties) {
532547
} else
533548
if (isReference) {
534549
forEach(value, function(v) {
535-
body.push(new ReferenceSerializer(self.addTagName(self.nsPropertyTagName(p))).build(v));
550+
body.push(new ReferenceSerializer(self.addTagName(self.nsPropertyTagName(p))).build(p, v));
536551
});
537552
} else {
538553

test/fixtures/model/properties.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,20 @@
177177
}
178178
]
179179
},
180+
{
181+
"name": "ReferencingNestedRef",
182+
"superClass": [ "BaseWithId" ],
183+
"properties": [
184+
{
185+
"name": "referencedComplex",
186+
"type": "Complex",
187+
"isReference": true,
188+
"xml": {
189+
"idAttr": "idref"
190+
}
191+
}
192+
]
193+
},
180194
{
181195
"name": "ReferencingCollection",
182196
"superClass": [ "BaseWithId" ],

test/spec/reader.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,53 @@ describe('Reader', function() {
878878
});
879879

880880

881+
it('single (attribute / idAttr)', async function() {
882+
883+
// given
884+
var reader = new Reader(extendedModel);
885+
var rootHandler = reader.handler('props:Root');
886+
887+
var xml =
888+
'<props:root xmlns:props="http://properties">' +
889+
'<props:containedCollection id="C_5">' +
890+
'<props:complex id="C_1" />' +
891+
'<props:complex id="C_2" />' +
892+
'</props:containedCollection>' +
893+
'<props:referencingNestedRef id="C_4">' +
894+
'<props:referencedComplex idref="C_1" />' +
895+
'</props:referencingNestedRef>' +
896+
'<props:referencingNestedRef id="C_6" referencedComplex="C_1" />' +
897+
'</props:root>';
898+
899+
// when
900+
var {
901+
rootElement
902+
} = await reader.fromXML(xml, rootHandler);
903+
904+
// then
905+
expect(rootElement).to.jsonEqual({
906+
$type: 'props:Root',
907+
any: [
908+
{
909+
$type: 'props:ContainedCollection',
910+
id: 'C_5',
911+
children: [
912+
{ $type: 'props:Complex', id: 'C_1' },
913+
{ $type: 'props:Complex', id: 'C_2' }
914+
]
915+
},
916+
{ $type: 'props:ReferencingNestedRef', id: 'C_4' },
917+
{ $type: 'props:ReferencingNestedRef', id: 'C_6' }
918+
]
919+
});
920+
921+
var referenced = rootElement.any[0].children[0];
922+
923+
expect(rootElement.any[1].referencedComplex).to.equal(referenced);
924+
expect(rootElement.any[2].referencedComplex).to.equal(referenced);
925+
});
926+
927+
881928
it('collection', async function() {
882929

883930
// given

test/spec/rountrip.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,58 @@ describe('Roundtrip', function() {
455455
});
456456

457457

458+
describe('references (idAttr)', function() {
459+
460+
var refsModel = createModel([ 'properties', 'properties-extended' ]);
461+
462+
463+
it('single (attribute / idAttr)', async function() {
464+
465+
// given
466+
var reader = new Reader(refsModel);
467+
var rootHandler = reader.handler('props:Root');
468+
469+
var input =
470+
'<props:root xmlns:props="http://properties">' +
471+
'<props:containedCollection id="C_5">' +
472+
'<props:complex id="C_1" />' +
473+
'<props:complex id="C_2" />' +
474+
'</props:containedCollection>' +
475+
'<props:referencingNestedRef id="C_4">' +
476+
'<props:referencedComplex idref="C_1" />' +
477+
'</props:referencingNestedRef>' +
478+
'<props:referencingNestedRef id="C_6" referencedComplex="C_1" />' +
479+
'</props:root>';
480+
481+
var {
482+
rootElement
483+
} = await reader.fromXML(input, rootHandler);
484+
485+
// when
486+
var writer = createWriter(refsModel);
487+
488+
var output = writer.toXML(rootElement);
489+
490+
// then
491+
expect(output).to.eql(
492+
'<props:root xmlns:props="http://properties">' +
493+
'<props:containedCollection id="C_5">' +
494+
'<props:complex id="C_1" />' +
495+
'<props:complex id="C_2" />' +
496+
'</props:containedCollection>' +
497+
'<props:referencingNestedRef id="C_4">' +
498+
'<props:referencedComplex idref="C_1" />' +
499+
'</props:referencingNestedRef>' +
500+
'<props:referencingNestedRef id="C_6">' +
501+
'<props:referencedComplex idref="C_1" />' +
502+
'</props:referencingNestedRef>' +
503+
'</props:root>'
504+
);
505+
});
506+
507+
});
508+
509+
458510
describe('package owned xml -> serialize property', function() {
459511

460512
it('should roundtrip', async function() {

0 commit comments

Comments
 (0)