From ea667639085a39bd63eed1ea9dc0910caba05a05 Mon Sep 17 00:00:00 2001 From: Guillaume Dufour Date: Mon, 31 Oct 2016 21:45:47 +0100 Subject: [PATCH 1/2] #221 Support Package --- lib/editors/genmymodel_parser.js | 31 ++++++++----- lib/editors/modelio_parser.js | 33 ++++++++------ lib/editors/parser_helper.js | 18 +++++++- lib/editors/umldesigner_parser.js | 48 +++++++++++--------- test/editors/genmymodel_parser_test.js | 18 ++++++++ test/editors/modelio_parser_test.js | 2 +- test/editors/umldesigner_parser_test.js | 17 +++++++- test/xmi/genmymodel_package.xmi | 58 +++++++++++++++++++++++++ test/xmi/umldesigner_package.uml | 33 ++++++++++++++ 9 files changed, 210 insertions(+), 48 deletions(-) create mode 100644 test/xmi/genmymodel_package.xmi create mode 100644 test/xmi/umldesigner_package.uml diff --git a/lib/editors/genmymodel_parser.js b/lib/editors/genmymodel_parser.js index 1478059..66bbea8 100644 --- a/lib/editors/genmymodel_parser.js +++ b/lib/editors/genmymodel_parser.js @@ -49,22 +49,31 @@ function initParser(args) { parsedData = new ParsedData(); } + function findElements() { - for (let i = 0; i < root.packagedElement.length; i++) { - let element = root.packagedElement[i]; + findElementsInNode(root, []); +} + +function findElementsInNode(node, path) { + for (let i = 0; i < node.packagedElement.length; i++) { + let element = node.packagedElement[i]; + var indexInfo = {index: i, path: path}; switch (element.$['xsi:type']) { case 'uml:PrimitiveType': case 'uml:DataType': - rawObjects.rawTypesIndexes.push(i); + rawObjects.rawTypesIndexes.push(indexInfo); break; case 'uml:Enumeration': - rawObjects.rawEnumsIndexes.push(i); + rawObjects.rawEnumsIndexes.push(indexInfo); break; case 'uml:Class': - rawObjects.rawClassesIndexes.push(i); + rawObjects.rawClassesIndexes.push(indexInfo); break; case 'uml:Association': - rawObjects.rawAssociationsIndexes.push(i); + rawObjects.rawAssociationsIndexes.push(indexInfo); + break; + case 'uml:Package': + findElementsInNode(element, _.concat(path,i)); break; default: } @@ -73,7 +82,7 @@ function findElements() { function fillTypes() { for (let i = 0; i < rawObjects.rawTypesIndexes.length; i++) { - addType(root.packagedElement[rawObjects.rawTypesIndexes[i]]); + addType(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawTypesIndexes, i)); } } @@ -96,7 +105,7 @@ function addType(typeElement) { function fillEnums() { for (let i = 0; i < rawObjects.rawEnumsIndexes.length; i++) { - addEnum(root.packagedElement[rawObjects.rawEnumsIndexes[i]]); + addEnum(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawEnumsIndexes, i)); } } @@ -130,7 +139,7 @@ function getEnumValues(enumElement) { function fillAssociations() { for (let i = 0; i < rawObjects.rawAssociationsIndexes.length; i++) { - addAssociation(root.packagedElement[rawObjects.rawAssociationsIndexes[i]]); + addAssociation(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawAssociationsIndexes, i)); } } @@ -181,7 +190,7 @@ function getAssociationComments(association) { commentInTo: '' }; for (let i = 0; i < association.ownedEnd.length; i++) { - comments[(i === 0) ? 'commentInTo' : 'commentInFrom'] = + comments[(i === 0) ? 'commentInTo' : 'commentInFrom'] = getComment(association.ownedEnd[i]); } return comments; @@ -201,7 +210,7 @@ function getComment(ownedEnd) { function fillClassesAndFields() { for (let i = 0; i < rawObjects.rawClassesIndexes.length; i++) { - addClassAndFields(root.packagedElement[rawObjects.rawClassesIndexes[i]]); + addClassAndFields(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawClassesIndexes, i)); } } diff --git a/lib/editors/modelio_parser.js b/lib/editors/modelio_parser.js index c78e2e2..670f8f9 100644 --- a/lib/editors/modelio_parser.js +++ b/lib/editors/modelio_parser.js @@ -46,30 +46,35 @@ function initParser(args) { rawClassesIndexes: [], rawAssociationsIndexes: [], rawValidationRulesIndexes: [], - rawPackagesIndexes: [] }; parsedData = new ParsedData(); } + function findElements() { - for (let i = 0; i < root.packagedElement.length; i++) { - let element = root.packagedElement[i]; + findElementsInNode(root, []); +} + +function findElementsInNode(node, path) { + for (let i = 0; i < node.packagedElement.length; i++) { + let element = node.packagedElement[i]; + var indexInfo = {index: i, path: path}; switch (element.$['xmi:type']) { case 'uml:PrimitiveType': - rawObjects.rawTypesIndexes.push(i); + rawObjects.rawTypesIndexes.push(indexInfo); break; case 'uml:Enumeration': - rawObjects.rawEnumsIndexes.push(i); + rawObjects.rawEnumsIndexes.push(indexInfo); break; case 'uml:Class': - rawObjects.rawClassesIndexes.push(i); + rawObjects.rawClassesIndexes.push(indexInfo); break; case 'uml:Association': - rawObjects.rawAssociationsIndexes.push(i); - break; - case 'uml:Package': - rawObjects.rawPackagesIndexes.push(i); + rawObjects.rawAssociationsIndexes.push(indexInfo); break; + case 'uml:Package': + findElementsInNode(element, _.concat(path,i)); + break; default: } } @@ -90,7 +95,7 @@ function findConstraints() { function fillTypes() { for (let i = 0; i < rawObjects.rawTypesIndexes.length; i++) { - addType(root.packagedElement[rawObjects.rawTypesIndexes[i]]); + addType(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawTypesIndexes, i)); } } @@ -113,7 +118,7 @@ function addType(typeElement) { function fillEnums() { for (let i = 0; i < rawObjects.rawEnumsIndexes.length; i++) { - addEnum(root.packagedElement[rawObjects.rawEnumsIndexes[i]]); + addEnum(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawEnumsIndexes, i)); } } @@ -147,7 +152,7 @@ function getEnumValues(enumElement) { function fillAssociations() { for (let i = 0; i < rawObjects.rawAssociationsIndexes.length; i++) { - addAssociation(root.packagedElement[rawObjects.rawAssociationsIndexes[i]]); + addAssociation(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawAssociationsIndexes, i)); } } @@ -176,7 +181,7 @@ function addAssociation(associationElement) { function fillClassesAndFields() { for (let i = 0; i < rawObjects.rawClassesIndexes.length; i++) { - addClassAndFields(root.packagedElement[rawObjects.rawClassesIndexes[i]]); + addClassAndFields(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawClassesIndexes, i)); } } diff --git a/lib/editors/parser_helper.js b/lib/editors/parser_helper.js index 243907c..0c71a27 100644 --- a/lib/editors/parser_helper.js +++ b/lib/editors/parser_helper.js @@ -5,7 +5,8 @@ const _ = require('lodash'); module.exports = { isAnId: isAnId, getTypeNameFromURL: getTypeNameFromURL, - extractClassName: extractClassName + extractClassName: extractClassName, + getXmlElementFromRawIndexes : getXmlElementFromRawIndexes }; @@ -47,3 +48,18 @@ function extractClassName(name) { ).toLowerCase() }; } + +/** + * Extract indexInfo in rawIndexes array and use it to get the referenced element + * @param rawIndexes array of index info with path and the index in the leaf parent element to access to the element + * @param i index of element in rawIndexes + * @returns {Object} the xml element + */ +function getXmlElementFromRawIndexes(root, rawIndexes, i) { + var indexInfo = rawIndexes[i]; + var parentPackage = root; + for (let j = 0; j < indexInfo.path.length; j++) { + parentPackage = parentPackage.packagedElement[indexInfo.path[j]]; + } + return parentPackage.packagedElement[indexInfo.index]; +} diff --git a/lib/editors/umldesigner_parser.js b/lib/editors/umldesigner_parser.js index 214280c..fbc6b17 100644 --- a/lib/editors/umldesigner_parser.js +++ b/lib/editors/umldesigner_parser.js @@ -49,30 +49,38 @@ function initParser(args) { } function findElements() { - for (let i = 0; i < root.packagedElement.length; i++) { - let element = root.packagedElement[i]; + findElementsInNode(root, []); +} + +function findElementsInNode(node, path) { + for (let i = 0; i < node.packagedElement.length; i++) { + let element = node.packagedElement[i]; + var indexInfo = {index: i, path: path}; switch (element.$['xmi:type']) { - case 'uml:PrimitiveType': - case 'uml:DataType': - rawObjects.rawTypesIndexes.push(i); - break; - case 'uml:Enumeration': - rawObjects.rawEnumsIndexes.push(i); - break; - case 'uml:Class': - rawObjects.rawClassesIndexes.push(i); - break; - case 'uml:Association': - rawObjects.rawAssociationsIndexes.push(i); - break; - default: + case 'uml:PrimitiveType': + case 'uml:DataType': + rawObjects.rawTypesIndexes.push(indexInfo); + break; + case 'uml:Enumeration': + rawObjects.rawEnumsIndexes.push(indexInfo); + break; + case 'uml:Class': + rawObjects.rawClassesIndexes.push(indexInfo); + break; + case 'uml:Association': + rawObjects.rawAssociationsIndexes.push(indexInfo); + break; + case 'uml:Package': + findElementsInNode(element, _.concat(path,i)); + break; + default: } } } function fillTypes() { for (let i = 0; i < rawObjects.rawTypesIndexes.length; i++) { - addType(root.packagedElement[rawObjects.rawTypesIndexes[i]]); + addType(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawTypesIndexes, i)); } } @@ -95,7 +103,7 @@ function addType(typeElement) { function fillEnums() { for (let i = 0; i < rawObjects.rawEnumsIndexes.length; i++) { - addEnum(root.packagedElement[rawObjects.rawEnumsIndexes[i]]); + addEnum(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawEnumsIndexes, i)); } } @@ -129,7 +137,7 @@ function getEnumValues(enumElement) { function fillClassesAndFields() { for (let i = 0; i < rawObjects.rawClassesIndexes.length; i++) { - addClassAndFields(root.packagedElement[rawObjects.rawClassesIndexes[i]]); + addClassAndFields(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawClassesIndexes, i)); } } @@ -223,7 +231,7 @@ function addRegularField(element, classId) { function fillAssociations() { for (let i = 0; i < rawObjects.rawAssociationsIndexes.length; i++) { - addAssociation(root.packagedElement[rawObjects.rawAssociationsIndexes[i]]); + addAssociation(parser_helper.getXmlElementFromRawIndexes(root, rawObjects.rawAssociationsIndexes, i)); } } diff --git a/test/editors/genmymodel_parser_test.js b/test/editors/genmymodel_parser_test.js index 6884391..7f134ae 100644 --- a/test/editors/genmymodel_parser_test.js +++ b/test/editors/genmymodel_parser_test.js @@ -272,6 +272,24 @@ describe('GenMyModelParser', () => { }); }); }); + describe('with package', () => { + var parserData = ParserFactory.createParser({ + file: './test/xmi/genmymodel_package.xmi', + databaseType: 'sql' + }); + var parser = parserData.parser; + var parsedData = parser.parse(parserData.data); + + it('parses it', () => { + expect(parsedData).not.to.be.null; + }); + it('includes classes in package', () => { + expect(parsedData.classes['_54pHLZ-oEeawbN_F_HFDxg']).not.to.be.null; + expect(parsedData.classes['_54pHQJ-oEeawbN_F_HFDxg']).not.to.be.null; + expect(parsedData.classNames).to.deep.eq(['A','B']); + }); + }); + }); describe('when passing an invalid diagram', () => { describe('as a class has no name', () => { diff --git a/test/editors/modelio_parser_test.js b/test/editors/modelio_parser_test.js index f5c6205..0296ed1 100644 --- a/test/editors/modelio_parser_test.js +++ b/test/editors/modelio_parser_test.js @@ -290,7 +290,7 @@ describe('ModelioParser', () => { expect(parsedData).not.to.be.null; }); it('works by adding all the classes', () => { - expect(parsedData.classNames).to.deep.eq(['Class2']); + expect(parsedData.classNames).to.deep.eq(['Class1', 'Class3', 'Class2']); }); }); }); diff --git a/test/editors/umldesigner_parser_test.js b/test/editors/umldesigner_parser_test.js index caebba0..82591e2 100644 --- a/test/editors/umldesigner_parser_test.js +++ b/test/editors/umldesigner_parser_test.js @@ -19,7 +19,7 @@ describe('UMLDesignerParser', () => { root: getRootElement(readFileContent('./test/xmi/umldesigner.uml')), databaseTypes: initDatabaseTypeHolder(DatabaseTypes.sql) }); - + it('parses it', () => { expect(parsedData).not.to.be.null; }); @@ -356,6 +356,21 @@ This sucks.` } }); }); + describe('with a user package', () => { + var parsedData = UMLDesignerParser.parse({ + root: getRootElement(readFileContent('./test/xmi/umldesigner_package.uml')), + databaseTypes: initDatabaseTypeHolder(DatabaseTypes.sql) + }); + + it('parses it', () => { + expect(parsedData).not.to.be.null; + }); + it('includes classes in package', () => { + expect(parsedData.classes['_wx0Db4PVEeaFY_lPQPbINQ']).not.to.be.null; + expect(parsedData.classes['_wx0DdoPVEeaFY_lPQPbINQ']).not.to.be.null; + expect(parsedData.classNames).to.deep.eq(['A','B']); + }); + }); }); }); diff --git a/test/xmi/genmymodel_package.xmi b/test/xmi/genmymodel_package.xmi new file mode 100644 index 0000000..356b1a9 --- /dev/null +++ b/test/xmi/genmymodel_package.xmi @@ -0,0 +1,58 @@ + + + +
+
+ + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + +
+ + + + + + +
+ + + + + + + +
+ + + +
+ + + + + diff --git a/test/xmi/umldesigner_package.uml b/test/xmi/umldesigner_package.uml new file mode 100644 index 0000000..3adb1fa --- /dev/null +++ b/test/xmi/umldesigner_package.uml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From fe33c71c11e90f4fdffaa7dafec34730143cf7ee Mon Sep 17 00:00:00 2001 From: Guillaume Dufour Date: Thu, 3 Nov 2016 00:32:28 +0100 Subject: [PATCH 2/2] #221 Support Package add unit test --- test/editors/genmymodel_parser_test.js | 7 +- test/editors/modelio_parser_test.js | 51 +++++++++++--- test/editors/parser_helper_test.js | 14 +++- test/editors/umldesigner_parser_test.js | 5 +- test/xmi/genmymodel_package.xmi | 90 +++++++++++++++---------- test/xmi/modelio_packages2.xmi | 39 +++++++++++ test/xmi/umldesigner_package.uml | 56 +++++++-------- 7 files changed, 184 insertions(+), 78 deletions(-) create mode 100644 test/xmi/modelio_packages2.xmi diff --git a/test/editors/genmymodel_parser_test.js b/test/editors/genmymodel_parser_test.js index 7f134ae..4cfd47f 100644 --- a/test/editors/genmymodel_parser_test.js +++ b/test/editors/genmymodel_parser_test.js @@ -284,12 +284,13 @@ describe('GenMyModelParser', () => { expect(parsedData).not.to.be.null; }); it('includes classes in package', () => { - expect(parsedData.classes['_54pHLZ-oEeawbN_F_HFDxg']).not.to.be.null; - expect(parsedData.classes['_54pHQJ-oEeawbN_F_HFDxg']).not.to.be.null; + expect(parsedData.classes['_z3DqLaFTEeawbN_F_HFDxg']).not.to.be.null; + expect(parsedData.classes['_z3DqQ6FTEeawbN_F_HFDxg']).not.to.be.null; expect(parsedData.classNames).to.deep.eq(['A','B']); + expect(parsedData.enums['_z3DqRqFTEeawbN_F_HFDxg']).not.to.be.null; + expect(parsedData.associations['_z3DqM6FTEeawbN_F_HFDxg']).not.to.be.null; }); }); - }); describe('when passing an invalid diagram', () => { describe('as a class has no name', () => { diff --git a/test/editors/modelio_parser_test.js b/test/editors/modelio_parser_test.js index 0296ed1..29b9444 100644 --- a/test/editors/modelio_parser_test.js +++ b/test/editors/modelio_parser_test.js @@ -279,18 +279,49 @@ describe('ModelioParser', () => { }); }); describe('with packages', () => { - var parserData = ParserFactory.createParser({ - file: './test/xmi/modelio_packages.xmi', - databaseType: 'sql' - }); - var parser = parserData.parser; - var parsedData = parser.parse(parserData.data); + describe('simple model', () => { + var parserData = ParserFactory.createParser({ + file: './test/xmi/modelio_packages.xmi', + databaseType: 'sql' + }); + var parser = parserData.parser; + var parsedData = parser.parse(parserData.data); - it('parses it', () => { - expect(parsedData).not.to.be.null; + it('parses it', () => { + expect(parsedData).not.to.be.null; + }); + it('works by adding all the classes', () => { + expect(parsedData.classNames).to.deep.eq(['Class1', 'Class3', 'Class2']); + expect(parsedData.classes['_vC4sxHdfEeaWkfx80xqrTw']).not.to.be.null; + expect(parsedData.classes['_vC4syndfEeaWkfx80xqrTw']).not.to.be.null; + expect(parsedData.classes['_vC4sz3dfEeaWkfx80xqrTw']).not.to.be.null; + expect(parsedData.associations['_vC4sx3dfEeaWkfx80xqrTw']).not.to.be.null; + expect(parsedData.associations['_vC4szXdfEeaWkfx80xqrTw']).not.to.be.null; + + }); }); - it('works by adding all the classes', () => { - expect(parsedData.classNames).to.deep.eq(['Class1', 'Class3', 'Class2']); + describe('more complex model', () => { + var parserData = ParserFactory.createParser({ + file: './test/xmi/modelio_packages2.xmi', + databaseType: 'sql' + }); + var parser = parserData.parser; + var parsedData = parser.parse(parserData.data); + + it('parses it', () => { + expect(parsedData).not.to.be.null; + }); + it('works by adding all the classes', () => { + expect(parsedData.classNames).to.deep.eq(['Class1', 'Class3', 'Class2']); + expect(parsedData.classes['_bYuIdaFSEeaVvapPODu8lg']).not.to.be.null; + expect(parsedData.classes['_bYuviqFSEeaVvapPODu8lg']).not.to.be.null; + expect(parsedData.classes['_bYuvj6FSEeaVvapPODu8lg']).not.to.be.null; + expect(parsedData.enums['_bYuvi6FSEeaVvapPODu8lg']).not.to.be.null; + expect(parsedData.associations['_bYuvhaFSEeaVvapPODu8lg']).not.to.be.null; + expect(parsedData.associations['_bYuvg6FSEeaVvapPODu8lg']).not.to.be.null; + expect(parsedData.associations['_bYuvh6FSEeaVvapPODu8lg']).not.to.be.null; + + }); }); }); }); diff --git a/test/editors/parser_helper_test.js b/test/editors/parser_helper_test.js index 4fb4817..0eaa3e7 100644 --- a/test/editors/parser_helper_test.js +++ b/test/editors/parser_helper_test.js @@ -2,7 +2,8 @@ var expect = require('chai').expect, isAnId = require('../../lib/editors/parser_helper').isAnId, - extractClassName = require('../../lib/editors/parser_helper').extractClassName; + extractClassName = require('../../lib/editors/parser_helper').extractClassName, + getXmlElementFromRawIndexes = require('../../lib/editors/parser_helper').getXmlElementFromRawIndexes; describe('ParserHelper', () => { describe('#isAnId', () => { @@ -37,4 +38,15 @@ describe('ParserHelper', () => { }); }); }); + describe('#getXmlElementFromRawIndexes', () => { + var root = { packagedElement : [{dumb: 'dumb'}, { packagedElement: [{dumb: 'dumb'},{dumb: 'dumb'},{dumb: 'good'}]}]}; + var rawIndexes = [{index: 2, path: [1]}]; + var i = 0; + var xmlElt = getXmlElementFromRawIndexes(root, rawIndexes, i); + + it('returns the right element', () => { + expect(xmlElt.dumb).to.eq('good'); + }); + }); + }); diff --git a/test/editors/umldesigner_parser_test.js b/test/editors/umldesigner_parser_test.js index 82591e2..764d177 100644 --- a/test/editors/umldesigner_parser_test.js +++ b/test/editors/umldesigner_parser_test.js @@ -368,7 +368,10 @@ This sucks.` it('includes classes in package', () => { expect(parsedData.classes['_wx0Db4PVEeaFY_lPQPbINQ']).not.to.be.null; expect(parsedData.classes['_wx0DdoPVEeaFY_lPQPbINQ']).not.to.be.null; - expect(parsedData.classNames).to.deep.eq(['A','B']); + expect(parsedData.classNames).to.deep.eq(['B','A']); + expect(parsedData.enums['_dRpdIKFLEeaWHdu8QjKipg']).not.to.be.null; + expect(parsedData.associations['_vB6ZwKFLEeaWHdu8QjKipg']).not.to.be.null; + expect(parsedData.associations['_9ZrJgKFLEeaWHdu8QjKipg']).not.to.be.null; }); }); }); diff --git a/test/xmi/genmymodel_package.xmi b/test/xmi/genmymodel_package.xmi index 356b1a9..2aad860 100644 --- a/test/xmi/genmymodel_package.xmi +++ b/test/xmi/genmymodel_package.xmi @@ -1,58 +1,78 @@ - - -
-
+ + +
+
- - -
+ + +
- - -
+ + +
- - -
+ + +
- - -
+ + +
+ + +
+ + - - -
+ + +
- - -
+ + +
- - + + - - -
+ + +
- - + + - - -
+ + +
- - -
+ + +
+ + +
+ + + +
+ + + + +
+ + + diff --git a/test/xmi/modelio_packages2.xmi b/test/xmi/modelio_packages2.xmi new file mode 100644 index 0000000..35a8ca8 --- /dev/null +++ b/test/xmi/modelio_packages2.xmi @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/xmi/umldesigner_package.uml b/test/xmi/umldesigner_package.uml index 3adb1fa..ae004dc 100644 --- a/test/xmi/umldesigner_package.uml +++ b/test/xmi/umldesigner_package.uml @@ -1,33 +1,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + +