Skip to content

Commit

Permalink
fix(core) Root hierarchy should have proper inheritance
Browse files Browse the repository at this point in the history
Signed-off-by: Jerome Simeon <[email protected]>
  • Loading branch information
jeromesimeon committed Mar 19, 2021
1 parent c2ecad3 commit b941281
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 25 deletions.
2 changes: 1 addition & 1 deletion packages/concerto-core/lib/introspect/classdeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ class ClassDeclaration extends Decorated {
* @returns {Boolean} true if the class declaration includes an explicit identifier
*/
isExplicitlyIdentified() {
return this.idField && this.idField !== '$identifier';
return (!!this.idField && this.idField !== '$identifier');
}

/**
Expand Down
20 changes: 20 additions & 0 deletions packages/concerto-core/lib/introspect/modelfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ class ModelFile {

if(this.namespace !== 'concerto' && this.ast.imports) {
this.ast.imports.push( { namespace: 'concerto.Concept'} );
this.ast.imports.push( { namespace: 'concerto.Asset'} );
this.ast.imports.push( { namespace: 'concerto.Transaction'} );
this.ast.imports.push( { namespace: 'concerto.Participant'} );
this.ast.imports.push( { namespace: 'concerto.Event'} );
}

if(this.ast.imports) {
Expand All @@ -106,15 +110,31 @@ class ModelFile {
let thing = this.ast.body[n];

if(thing.type === 'AssetDeclaration') {
// Default super type for asset
if (!thing.classExtension) {
thing.classExtension = { class: { name: 'Asset' } };
}
this.declarations.push( new AssetDeclaration(this, thing) );
}
else if(thing.type === 'TransactionDeclaration') {
// Default super type for transaction
if (!thing.classExtension) {
thing.classExtension = { class: { name: 'Transaction' } };
}
this.declarations.push( new TransactionDeclaration(this, thing) );
}
else if(thing.type === 'EventDeclaration') {
// Default super type for event
if (!thing.classExtension) {
thing.classExtension = { class: { name: 'Event' } };
}
this.declarations.push( new EventDeclaration(this, thing) );
}
else if(thing.type === 'ParticipantDeclaration') {
// Default super type for participant
if (!thing.classExtension) {
thing.classExtension = { class: { name: 'Participant' } };
}
this.declarations.push( new ParticipantDeclaration(this, thing) );
}
else if(thing.type === 'EnumDeclaration') {
Expand Down
8 changes: 4 additions & 4 deletions packages/concerto-core/lib/modelmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ class ModelManager {
addRootModel() {
this.addModelFile( `namespace concerto
abstract concept Concept {}
abstract asset Asset {}
abstract transaction Transaction {}
abstract participant Participant {}
abstract event Event {}`, 'concerto.cto');
abstract concept Asset {}
abstract concept Transaction { o DateTime timestamp }
abstract concept Participant {}
abstract concept Event { o DateTime timestamp }`, 'concerto.cto');
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/concerto-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@
],
"all": true,
"check-coverage": true,
"statements": 99,
"branches": 98,
"statements": 98,
"branches": 97,
"functions": 99,
"lines": 98
}
Expand Down
16 changes: 8 additions & 8 deletions packages/concerto-core/test/introspect/classdeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,16 @@ describe('ClassDeclaration', () => {
superclassName.should.equal('com.testing.parent.Super');
});

it('should return concerto.Concept when no super type exists', function() {
it('should return concerto.Participant when no super type exists', function() {
const baseclass = modelManager.getType('com.testing.parent.Base');
should.exist(baseclass);
const superclassName = baseclass.getSuperType();
should.equal(superclassName,'concerto.Concept');
should.equal(superclassName,'concerto.Participant');
});

it('toString',()=>{
const baseclass = modelManager.getType('com.testing.parent.Base');
baseclass.toString().should.equal('ClassDeclaration {id=com.testing.parent.Base super=Concept enum=false abstract=true}');
baseclass.toString().should.equal('ClassDeclaration {id=com.testing.parent.Base super=Participant enum=false abstract=true}');
});
});

Expand Down Expand Up @@ -280,7 +280,7 @@ describe('ClassDeclaration', () => {

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

it('should return Concept if no super type', () => {
it('should return Asset if no super type', () => {
let classDecl = modelManager.getType('system.Asset');
classDecl._resolveSuperType().should.not.be.null;
});
Expand All @@ -290,7 +290,7 @@ describe('ClassDeclaration', () => {
asset TestAsset identified by assetId { o String assetId }`);
let classDecl = modelManager.getType('org.acme.TestAsset');
let superClassDecl = classDecl._resolveSuperType();
should.equal(superClassDecl.getName(), 'Concept');
should.equal(superClassDecl.getName(), 'Asset');
});

it('should return the super class declaration for a super class in the same file', () => {
Expand Down Expand Up @@ -362,20 +362,20 @@ describe('ClassDeclaration', () => {
modelManager.addModelFiles(modelFiles);
});

it('should return an array with Concept if there are no superclasses', function() {
it('should return an array with Concept and Participant if there are no superclasses', function() {
const testClass = modelManager.getType('com.testing.parent.Base');
should.exist(testClass);
const superclasses = testClass.getAllSuperTypeDeclarations();
const superclassNames = superclasses.map(classDef => classDef.getName());
superclassNames.should.have.length(1);
superclassNames.should.have.length(2);
});

it('should return all superclass definitions', function() {
const testClass = modelManager.getType('com.testing.child.Sub');
should.exist(testClass);
const superclasses = testClass.getAllSuperTypeDeclarations();
const superclassNames = superclasses.map(classDef => classDef.getName());
superclassNames.should.have.same.members(['Base', 'Super', 'Concept']);
superclassNames.should.have.same.members(['Base', 'Super', 'Participant', 'Concept']);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ asset Order {
mm.addModelFile( `
namespace test
asset Order {
asset Order identified {
o Double price
}
`, 'test.cto');
Expand Down Expand Up @@ -205,10 +205,9 @@ asset Order identified by sku {

const order = mm.getType('test.Order');
order.should.not.be.null;
order.getProperties().length.should.equal(2);
order.isSystemIdentified().should.be.true;
order.getProperties().length.should.equal(1); // XXX Without an identified means it should have only a price property
order.isSystemIdentified().should.be.false;
order.isExplicitlyIdentified().should.be.false;
order.getIdentifierFieldName().should.equal('$identifier');
});

});
Expand Down
4 changes: 2 additions & 2 deletions packages/concerto-core/test/introspect/modelfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('ModelFile', () => {
};
sandbox.stub(parser, 'parse').returns(ast);
let mf = new ModelFile(modelManager, 'fake definitions');
mf.imports.should.deep.equal(['org.freddos', 'org.doge', 'concerto.Concept']);
mf.imports.should.deep.equal(['org.freddos', 'org.doge', 'concerto.Concept', 'concerto.Asset', 'concerto.Transaction', 'concerto.Participant', 'concerto.Event']);
});

it('should call the parser with the definitions and save imports with uris', () => {
Expand All @@ -101,7 +101,7 @@ describe('ModelFile', () => {
};
sandbox.stub(parser, 'parse').returns(ast);
let mf = new ModelFile(modelManager, 'fake definitions');
mf.imports.should.deep.equal(['org.doge', 'org.freddos.*', 'concerto.Concept']);
mf.imports.should.deep.equal(['org.doge', 'org.freddos.*', 'concerto.Concept', 'concerto.Asset', 'concerto.Transaction', 'concerto.Participant', 'concerto.Event']);
mf.getImportURI('org.freddos.*').should.equal('https://freddos.org/model.cto');
(mf.getImportURI('org.doge') === null).should.be.true;
});
Expand Down
2 changes: 1 addition & 1 deletion packages/concerto-core/test/models/farm2fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('Farm2Fork Model', function() {
let txDecl = modelFile.getTransactionDeclaration('MoveAnimalToHolding');
txDecl.should.not.be.null;
txDecl.getName().should.equal('MoveAnimalToHolding');
txDecl.getProperties().length.should.equal(4);
txDecl.getProperties().length.should.equal(3); // XXX Should not have an identifier, but farmer + holding + timestamp
let holdingField = txDecl.getProperty('holding');
(holdingField !== null).should.be.true;
holdingField.getName().should.equal('holding');
Expand Down
6 changes: 3 additions & 3 deletions packages/concerto-core/test/models/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ describe('Test Model', function(){
let txDecl = modelFile.getTransactionDeclaration('VehicleTransferredToScrapMerchant');
txDecl.should.not.be.null;
txDecl.getName().should.equal('VehicleTransferredToScrapMerchant');
txDecl.getProperties().length.should.equal(4);
txDecl.getProperties().length.should.equal(3); // Should have 3: scarpMerchant, vehicle, timestamp
let scrapMerchantField = txDecl.getProperty('scrapMerchant');
(scrapMerchantField !== null).should.be.true;
scrapMerchantField.getName().should.equal('scrapMerchant');
Expand Down Expand Up @@ -340,7 +340,7 @@ describe('Test Model', function(){
const importNamespace = ModelUtil.getNamespace(element);
return modelManager.getModelFile(importNamespace);
});
imprts.length.should.equal(2);
imprts.length.should.equal(6); // XXX Now includes all concerto.* classes
modelFile.getImports().includes('composer.MyParticipant').should.equal(true);
});
});
Expand Down Expand Up @@ -379,7 +379,7 @@ describe('Test Model', function(){
const importNamespace = ModelUtil.getNamespace(element);
return modelManager.getModelFile(importNamespace);
});
imprts.length.should.equal(3);
imprts.length.should.equal(7); // XXX Now includes all concerto.* classes
});
});
});

0 comments on commit b941281

Please sign in to comment.