Skip to content

Commit

Permalink
refactor(declarations): move declaration uniqueness check to model fi…
Browse files Browse the repository at this point in the history
…le (#794)

* refactor(declarations): Move unique name check to model file.

Signed-off-by: Ertugrul Karademir <[email protected]>

* refactor(test): move validation checks for duplicate class to model file

Signed-off-by: Ertugrul Karademir <[email protected]>

* test: empty commit to trigger test

Signed-off-by: Ertugrul Karademir <[email protected]>

---------

Signed-off-by: Ertugrul Karademir <[email protected]>
  • Loading branch information
ekarademir authored Jan 29, 2024
1 parent 429a9a8 commit a406c0f
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 53 deletions.
15 changes: 0 additions & 15 deletions packages/concerto-core/lib/introspect/classdeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,21 +190,6 @@ class ClassDeclaration extends Declaration {
validate() {
super.validate();

const declarations = this.getModelFile().getAllDeclarations();
const declarationNames = declarations.map(
d => d.getFullyQualifiedName()
);
const uniqueNames = new Set(declarationNames);

if (uniqueNames.size !== declarations.length) {
const duplicateElements = declarationNames.filter(
(item, index) => declarationNames.indexOf(item) !== index
);
throw new IllegalModelException(
`Duplicate class name ${duplicateElements[0]}`
);
}

// if we have a super type make sure it exists
if (this.superType !== null) {
// and make sure that the class isn't extending itself
Expand Down
16 changes: 16 additions & 0 deletions packages/concerto-core/lib/introspect/modelfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,22 @@ class ModelFile extends Decorated {
});

// Validate all of the types in this model file.
// Check if names of the declarations are unique.
const declarationNames = this.declarations.map(
d => d.getFullyQualifiedName()
);
const uniqueNames = new Set(declarationNames);

if (uniqueNames.size !== this.declarations.length) {
const duplicateElements = declarationNames.filter(
(item, index) => declarationNames.indexOf(item) !== index
);
throw new IllegalModelException(
`Duplicate class name ${duplicateElements[0]}`
);
}

// Run validations on class declarations
for(let n=0; n < this.declarations.length; n++) {
let classDeclaration = this.declarations[n];
classDeclaration.validate();
Expand Down
38 changes: 0 additions & 38 deletions packages/concerto-core/test/introspect/classdeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ const { MetaModelNamespace } = require('@accordproject/concerto-metamodel');
const IllegalModelException = require('../../lib/introspect/illegalmodelexception');
const ClassDeclaration = require('../../lib/introspect/classdeclaration');
const AssetDeclaration = require('../../lib/introspect/assetdeclaration');
const EnumDeclaration = require('../../lib/introspect/enumdeclaration');
const ConceptDeclaration = require('../../lib/introspect/conceptdeclaration');
const ParticipantDeclaration = require('../../lib/introspect/participantdeclaration');
const TransactionDeclaration = require('../../lib/introspect/transactiondeclaration');
const IntrospectUtils = require('./introspectutils');
const ParserUtil = require('./parserutility');

Expand Down Expand Up @@ -87,27 +84,6 @@ describe('ClassDeclaration', () => {
});

describe('#validate', () => {
it('should throw when asset name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadLastDeclaration('test/data/parser/classdeclaration.dupeassetname.cto', AssetDeclaration);
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when transaction name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadLastDeclaration('test/data/parser/classdeclaration.dupetransactionname.cto', TransactionDeclaration);
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when participant name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadLastDeclaration('test/data/parser/classdeclaration.dupeparticipantname.cto', ParticipantDeclaration);
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when an super type identifier is redeclared', () => {
let asset = introspectUtils.loadLastDeclaration('test/data/parser/classdeclaration.identifierextendsfromsupertype.cto', AssetDeclaration);
(() => {
Expand All @@ -123,20 +99,6 @@ describe('ClassDeclaration', () => {
// }).should.throw(/Identifier defined in super class/);
//});

it('should throw when concept name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadLastDeclaration('test/data/parser/classdeclaration.dupeconceptname.cto', ConceptDeclaration);
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when enum name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadLastDeclaration('test/data/parser/classdeclaration.dupeenumname.cto', EnumDeclaration);
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when not abstract, not enum and not concept without an identifier', () => {
let asset = introspectUtils.loadLastDeclaration('test/data/parser/classdeclaration.noidentifier.cto', AssetDeclaration);
asset.superType = null;
Expand Down
38 changes: 38 additions & 0 deletions packages/concerto-core/test/introspect/modelfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const EnumDeclaration = require('../../lib/introspect/enumdeclaration');
const IllegalModelException = require('../../lib/introspect/illegalmodelexception');
const ModelFile = require('../../lib/introspect/modelfile');
const ModelManager = require('../../lib/modelmanager');
const IntrospectUtils = require('./introspectutils');

const fs = require('fs');
const path = require('path');
Expand All @@ -44,10 +45,12 @@ describe('ModelFile', () => {
const carLeaseModel = fs.readFileSync(path.resolve(__dirname, '../data/model/carlease.cto'), 'utf8');
let modelManager;
let sandbox;
let introspectUtils;

beforeEach(() => {
modelManager = new ModelManager();
Util.addComposerModel(modelManager);
introspectUtils = new IntrospectUtils(modelManager);
sandbox = sinon.createSandbox();
});

Expand Down Expand Up @@ -203,6 +206,41 @@ describe('ModelFile', () => {

describe('#validate', () => {

it('should throw when asset name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadModelFile('test/data/parser/classdeclaration.dupeassetname.cto');
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when transaction name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadModelFile('test/data/parser/classdeclaration.dupetransactionname.cto');
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when participant name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadModelFile('test/data/parser/classdeclaration.dupeparticipantname.cto');
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when concept name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadModelFile('test/data/parser/classdeclaration.dupeconceptname.cto');
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw when enum name is duplicted in a modelfile', () => {
let asset = introspectUtils.loadModelFile('test/data/parser/classdeclaration.dupeenumname.cto');
(() => {
asset.validate();
}).should.throw(/Duplicate class/);
});

it('should throw if an import exists for an invalid namespace', () => {
const model = `
namespace org.acme
Expand Down

0 comments on commit a406c0f

Please sign in to comment.