diff --git a/lib/codegen/fromcto/plantuml/plantumlvisitor.js b/lib/codegen/fromcto/plantuml/plantumlvisitor.js index d3b9614b..dbcb207c 100644 --- a/lib/codegen/fromcto/plantuml/plantumlvisitor.js +++ b/lib/codegen/fromcto/plantuml/plantumlvisitor.js @@ -57,6 +57,22 @@ class PlantUMLVisitor extends DiagramVisitor { this.writeDeclaration(classDeclaration, parameters, '(A,green)' ); } + /** + * Visitor design pattern + * @param {MapDeclaration} mapDeclaration - the object being visited + * @param {Object} parameters - the parameter + * @protected + */ + visitMapDeclaration(mapDeclaration, parameters) { + const fqn = this.escapeString(mapDeclaration.getFullyQualifiedName()); + const keyType = mapDeclaration.getKey().getType(); + const valueType = mapDeclaration.getValue().getType(); + + parameters.fileWriter.writeLine(0, `map "${fqn}: Map<${keyType}, ${valueType}>" as ${fqn} {`); + parameters.fileWriter.writeLine(0, '}' ); + } + + /** * Visitor design pattern * @param {ClassDeclaration} classDeclaration - the object being visited diff --git a/test/codegen/__snapshots__/codegen.js.snap b/test/codegen/__snapshots__/codegen.js.snap index dd92e2f9..3425c333 100644 --- a/test/codegen/__snapshots__/codegen.js.snap +++ b/test/codegen/__snapshots__/codegen.js.snap @@ -3799,6 +3799,8 @@ class org.acme.hr.base.TShirtSizeType << (E,grey) >> { + LARGE } org.acme.hr.base.TShirtSizeType --|> concerto_1_0_0.Concept +map "org.acme.hr.base.EmployeeTShirtSizes: Map" as org.acme.hr.base.EmployeeTShirtSizes { +} class org.acme.hr.base.Address { + String street + String city @@ -3807,6 +3809,18 @@ class org.acme.hr.base.Address { + String country } org.acme.hr.base.Address --|> concerto_1_0_0.Concept +map "org.acme.hr.CompanyProperties: Map" as org.acme.hr.CompanyProperties { +} +map "org.acme.hr.EmployeeLoginTimes: Map" as org.acme.hr.EmployeeLoginTimes { +} +map "org.acme.hr.EmployeeSocialSecurityNumbers: Map" as org.acme.hr.EmployeeSocialSecurityNumbers { +} +map "org.acme.hr.NextOfKin: Map" as org.acme.hr.NextOfKin { +} +map "org.acme.hr.EmployeeProfiles: Map" as org.acme.hr.EmployeeProfiles { +} +map "org.acme.hr.EmployeeDirectory: Map" as org.acme.hr.EmployeeDirectory { +} class org.acme.hr.Company { + String name + Address headquarters @@ -5800,6 +5814,8 @@ class org.acme.hr.base_1_0_0.TShirtSizeType << (E,grey) >> { + MEDIUM + LARGE } +map "org.acme.hr.base_1_0_0.EmployeeTShirtSizes: Map" as org.acme.hr.base_1_0_0.EmployeeTShirtSizes { +} class org.acme.hr.base_1_0_0.Address { + String street + String city @@ -5808,6 +5824,18 @@ class org.acme.hr.base_1_0_0.Address { + String country } org.acme.hr.base_1_0_0.Address "1" *-- "1" org.acme.hr.base_1_0_0.State : state +map "org.acme.hr_1_0_0.CompanyProperties: Map" as org.acme.hr_1_0_0.CompanyProperties { +} +map "org.acme.hr_1_0_0.EmployeeLoginTimes: Map" as org.acme.hr_1_0_0.EmployeeLoginTimes { +} +map "org.acme.hr_1_0_0.EmployeeSocialSecurityNumbers: Map" as org.acme.hr_1_0_0.EmployeeSocialSecurityNumbers { +} +map "org.acme.hr_1_0_0.NextOfKin: Map" as org.acme.hr_1_0_0.NextOfKin { +} +map "org.acme.hr_1_0_0.EmployeeProfiles: Map" as org.acme.hr_1_0_0.EmployeeProfiles { +} +map "org.acme.hr_1_0_0.EmployeeDirectory: Map" as org.acme.hr_1_0_0.EmployeeDirectory { +} class org.acme.hr_1_0_0.Company { + String name + Address headquarters @@ -9717,6 +9745,8 @@ class org.acme.hr.base_1_0_0.TShirtSizeType << (E,grey) >> { + LARGE } org.acme.hr.base_1_0_0.TShirtSizeType --|> concerto_1_0_0.Concept +map "org.acme.hr.base_1_0_0.EmployeeTShirtSizes: Map" as org.acme.hr.base_1_0_0.EmployeeTShirtSizes { +} class org.acme.hr.base_1_0_0.Address { + String street + String city @@ -9726,6 +9756,18 @@ class org.acme.hr.base_1_0_0.Address { } org.acme.hr.base_1_0_0.Address "1" *-- "1" org.acme.hr.base_1_0_0.State : state org.acme.hr.base_1_0_0.Address --|> concerto_1_0_0.Concept +map "org.acme.hr_1_0_0.CompanyProperties: Map" as org.acme.hr_1_0_0.CompanyProperties { +} +map "org.acme.hr_1_0_0.EmployeeLoginTimes: Map" as org.acme.hr_1_0_0.EmployeeLoginTimes { +} +map "org.acme.hr_1_0_0.EmployeeSocialSecurityNumbers: Map" as org.acme.hr_1_0_0.EmployeeSocialSecurityNumbers { +} +map "org.acme.hr_1_0_0.NextOfKin: Map" as org.acme.hr_1_0_0.NextOfKin { +} +map "org.acme.hr_1_0_0.EmployeeProfiles: Map" as org.acme.hr_1_0_0.EmployeeProfiles { +} +map "org.acme.hr_1_0_0.EmployeeDirectory: Map" as org.acme.hr_1_0_0.EmployeeDirectory { +} class org.acme.hr_1_0_0.Company { + String name + Address headquarters diff --git a/test/codegen/fromcto/plantuml/plantumlvisitor.js b/test/codegen/fromcto/plantuml/plantumlvisitor.js index c97b0de5..34e2ddcd 100644 --- a/test/codegen/fromcto/plantuml/plantumlvisitor.js +++ b/test/codegen/fromcto/plantuml/plantumlvisitor.js @@ -25,6 +25,7 @@ const ModelManager = require('@accordproject/concerto-core').ModelManager; const AssetDeclaration = require('@accordproject/concerto-core').AssetDeclaration; const ParticipantDeclaration = require('@accordproject/concerto-core').ParticipantDeclaration; const ClassDeclaration = require('@accordproject/concerto-core').ClassDeclaration; +const {MapDeclaration, MapKeyType, MapValueType } = require('@accordproject/concerto-core'); const EnumDeclaration = require('@accordproject/concerto-core').EnumDeclaration; const EnumValueDeclaration = require('@accordproject/concerto-core').EnumValueDeclaration; const Field = require('@accordproject/concerto-core').Field; @@ -440,6 +441,31 @@ describe('PlantUMLVisitor', function () { }); }); + describe('visitMapDeclaration', () => { + it('should write the map declaration for a map', () => { + let param = { + fileWriter: mockFileWriter + }; + + let mockMapDeclaration = sinon.createStubInstance(MapDeclaration); + let mockMapKey = sinon.createStubInstance(MapKeyType); + let mockMapValue = sinon.createStubInstance(MapValueType); + + mockMapDeclaration.getKey.returns(mockMapKey); + mockMapDeclaration.getValue.returns(mockMapValue); + mockMapKey.getType.returns('String'); + mockMapValue.getType.returns('String'); + + mockMapDeclaration.getFullyQualifiedName.returns('org.acme.NextOfKin'); + + plantUMLvisitor.visitMapDeclaration(mockMapDeclaration, param); + + param.fileWriter.writeLine.callCount.should.deep.equal(2); + param.fileWriter.writeLine.getCall(0).args.should.deep.equal([0, 'map "org.acme.NextOfKin: Map" as org.acme.NextOfKin {']); + param.fileWriter.writeLine.getCall(1).args.should.deep.equal([0, '}']); + }); + }); + describe('visitClassDeclaration', () => { it('should write the class declaration for a class', () => { let acceptSpy = sinon.spy();