diff --git a/packages/composer-common/lib/modelmanager.js b/packages/composer-common/lib/modelmanager.js index 62604f1020..cd40f39949 100644 --- a/packages/composer-common/lib/modelmanager.js +++ b/packages/composer-common/lib/modelmanager.js @@ -134,8 +134,13 @@ class ModelManager { throw new Error('Cannot add a model file with the reserved system namspace: ' + m.getNamespace() ); } - m.validate(); - this.modelFiles[m.getNamespace()] = m; + if (!this.modelFiles[m.getNamespace()]) { + m.validate(); + this.modelFiles[m.getNamespace()] = m; + } else { + throw new Error('namespace already exists'); + } + return m; } @@ -221,14 +226,26 @@ class ModelManager { if (m.isSystemModelFile()){ throw new Error('System namespace can not be updated'); } - this.modelFiles[m.getNamespace()] = m; - newModelFiles.push(m); + + if (!this.modelFiles[m.getNamespace()]) { + this.modelFiles[m.getNamespace()] = m; + newModelFiles.push(m); + } + else { + throw new Error('namespace already exists'); + } } else { if (modelFile.isSystemModelFile()){ throw new Error('System namespace can not be updated'); } - this.modelFiles[modelFile.getNamespace()] = modelFile; - newModelFiles.push(modelFile); + + if (!this.modelFiles[modelFile.getNamespace()]) { + this.modelFiles[modelFile.getNamespace()] = modelFile; + newModelFiles.push(modelFile); + } + else { + throw new Error('namespace already exists'); + } } } diff --git a/packages/composer-common/test/codegen/loopbackvisitor.js b/packages/composer-common/test/codegen/loopbackvisitor.js index 25730fecb0..f31c696a9c 100644 --- a/packages/composer-common/test/codegen/loopbackvisitor.js +++ b/packages/composer-common/test/codegen/loopbackvisitor.js @@ -918,7 +918,7 @@ describe('LoopbackVisitor', () => { }); it('should use the model file of the referencing type to resolve enumeration types', () => { - modelManager.addModelFile(` + modelManager.updateModelFile(` namespace org.acme.base enum Enum { o SOME_VALUE @@ -1021,7 +1021,7 @@ describe('LoopbackVisitor', () => { }); it('should use the model file of the referencing type to resolve other types', () => { - modelManager.addModelFile(` + modelManager.updateModelFile(` namespace org.acme.base asset MyInlineAsset identified by assetId { o String assetId diff --git a/packages/composer-common/test/introspect/classdeclaration.js b/packages/composer-common/test/introspect/classdeclaration.js index 8a83f3e808..a0637c9511 100644 --- a/packages/composer-common/test/introspect/classdeclaration.js +++ b/packages/composer-common/test/introspect/classdeclaration.js @@ -55,7 +55,7 @@ describe('ClassDeclaration', () => { const modelFile = new ModelFile(modelManager, modelDefinitions); modelFiles.push(modelFile); } - modelManager.addModelFiles(modelFiles, modelFileNames); + //modelManager.addModelFiles(modelFiles, modelFileNames); return modelFiles; }; diff --git a/packages/composer-common/test/modelmanager.js b/packages/composer-common/test/modelmanager.js index 88ce2e5e9c..49c5a6b4f7 100644 --- a/packages/composer-common/test/modelmanager.js +++ b/packages/composer-common/test/modelmanager.js @@ -126,6 +126,24 @@ describe('ModelManager', () => { }).should.throw(); }); + it('should return error for duplicate namespaces for a string', () => { + modelManager.addModelFile(modelBase); + let mf1 = sinon.createStubInstance(ModelFile); + mf1.getNamespace.returns('org.acme.base'); + (() => { + modelManager.addModelFile(modelBase); + }).should.throw(/namespace already exists/); + }); + + it('should return error for duplicate namespaces from an object', () => { + modelManager.addModelFile(modelBase); + let mf1 = sinon.createStubInstance(ModelFile); + mf1.getNamespace.returns('org.acme.base'); + (() => { + modelManager.addModelFile(mf1); + }).should.throw(/namespace already exists/); + }); + }); describe('#addModelFiles', () => { @@ -157,7 +175,7 @@ describe('ModelManager', () => { it('should add to existing model files from strings', () => { modelManager.addModelFile(modelBase); modelManager.getModelFile('org.acme.base').getNamespace().should.equal('org.acme.base'); - modelManager.addModelFiles([modelBase, concertoModel, farm2fork]); + modelManager.addModelFiles([concertoModel, farm2fork]); modelManager.getModelFile('org.acme.base').getNamespace().should.equal('org.acme.base'); modelManager.getModelFile('org.acme').getNamespace().should.equal('org.acme'); }); @@ -215,6 +233,24 @@ describe('ModelManager', () => { modelManager.addModelFiles([mockSystemModelFile]); }).should.throw(); }); + + it('should return an error for duplicate namespace from strings', () => { + (() => { + modelManager.addModelFiles([concertoModel, modelBase, farm2fork, modelBase]); + }).should.throw(/namespace already exists/); + }); + + it('should return an error for duplicate namespace from objects', () => { + let mf1 = sinon.createStubInstance(ModelFile); + mf1.getNamespace.returns('org.doge'); + let mf2 = sinon.createStubInstance(ModelFile); + mf2.getNamespace.returns('org.doge.base'); + modelManager.addModelFiles([mf1,mf2]); + (() => { + modelManager.addModelFiles([mf1]); + }).should.throw(/namespace already exists/); + }); + }); describe('#updateModelFile', () => {