diff --git a/lib/codegen/fromcto/odata/odatavisitor.js b/lib/codegen/fromcto/odata/odatavisitor.js
index c003ae52..b3c5bc33 100644
--- a/lib/codegen/fromcto/odata/odatavisitor.js
+++ b/lib/codegen/fromcto/odata/odatavisitor.js
@@ -63,7 +63,7 @@ class ODataVisitor {
} else if (thing.isClassDeclaration?.()) {
return this.visitClassDeclaration(thing, parameters);
} else if (thing.isMapDeclaration?.()) {
- return;
+ return this.visitMapDeclaration(thing, parameters);
} else if (thing.isTypeScalar?.()) {
return this.visitField(thing.getScalarField(), parameters);
} else if (thing.isField?.()) {
@@ -280,6 +280,43 @@ class ODataVisitor {
return null;
}
+ /**
+ * Visitor design pattern
+ * @param {MapDeclaration} mapDeclaration - the object being visited
+ * @param {Object} parameters - the parameter
+ * @return {Object} the result of visiting or null
+ * @private
+ */
+ visitMapDeclaration(mapDeclaration, parameters) {
+ let keyType = mapDeclaration.getKey().getType();
+ let valueType = mapDeclaration.getValue().getType();
+
+ if (ModelUtil.isPrimitiveType(keyType)) {
+ keyType = this.toODataType(keyType);
+ } else if (ModelUtil.isScalar(mapDeclaration.getKey())) {
+ const scalarDeclaration = mapDeclaration.getModelFile().getType(mapDeclaration.getKey().getType());
+ const scalarType = scalarDeclaration.getType();
+ keyType = this.toODataType(scalarType);
+ }
+
+ if (ModelUtil.isPrimitiveType(valueType)) {
+ valueType = this.toODataType(valueType);
+ } else if (ModelUtil.isScalar(mapDeclaration.getValue())) {
+ const scalarDeclaration = mapDeclaration.getModelFile().getType(mapDeclaration.getValue().getType());
+ const scalarType = scalarDeclaration.getType();
+ valueType = this.toODataType(scalarType);
+ } else {
+ valueType = ModelUtil.removeNamespaceVersionFromFullyQualifiedName(mapDeclaration.getModelFile().getFullyQualifiedTypeName(valueType));
+ }
+
+ parameters.fileWriter.writeLine(1, ``);
+ parameters.fileWriter.writeLine(2, ``);
+ parameters.fileWriter.writeLine(2, ``);
+ parameters.fileWriter.writeLine(1, '');
+
+ return null;
+ }
+
/**
* Visitor design pattern
* @param {Relationship} relationship - the object being visited
diff --git a/test/codegen/__snapshots__/codegen.js.snap b/test/codegen/__snapshots__/codegen.js.snap
index 27f4b951..75ce707b 100644
--- a/test/codegen/__snapshots__/codegen.js.snap
+++ b/test/codegen/__snapshots__/codegen.js.snap
@@ -2686,6 +2686,10 @@ exports[`codegen #formats check we can convert all formats from namespace unvers
+
+
+
+
@@ -2723,6 +2727,30 @@ exports[`codegen #formats check we can convert all formats from namespace unvers
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8660,6 +8688,10 @@ exports[`codegen #formats check we can convert all formats from namespace versio
+
+
+
+
@@ -8697,6 +8729,30 @@ exports[`codegen #formats check we can convert all formats from namespace versio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/codegen/fromcto/odata/odatavisitor.js b/test/codegen/fromcto/odata/odatavisitor.js
index a329c2a6..8694bbf1 100644
--- a/test/codegen/fromcto/odata/odatavisitor.js
+++ b/test/codegen/fromcto/odata/odatavisitor.js
@@ -19,9 +19,13 @@ chai.should();
const sinon = require('sinon');
const ODataVisitor = require('../../../../lib/codegen/fromcto/odata/odatavisitor.js');
+const { ConceptDeclaration } = require('@accordproject/concerto-core');
const ClassDeclaration = require('@accordproject/concerto-core').ClassDeclaration;
+const ScalarDeclaration = require('@accordproject/concerto-core').ScalarDeclaration;
const EnumDeclaration = require('@accordproject/concerto-core').EnumDeclaration;
+const MapDeclaration = require('@accordproject/concerto-core').MapDeclaration;
+const ModelUtil = require('@accordproject/concerto-core').ModelUtil;
const EnumValueDeclaration = require('@accordproject/concerto-core').EnumValueDeclaration;
const Field = require('@accordproject/concerto-core').Field;
const ModelFile = require('@accordproject/concerto-core').ModelFile;
@@ -30,6 +34,8 @@ const RelationshipDeclaration = require('@accordproject/concerto-core').Relation
const Decorator = require('@accordproject/concerto-core').Decorator;
const FileWriter = require('@accordproject/concerto-util').FileWriter;
+let sandbox = sinon.createSandbox();
+
describe('ODataVisitor', function () {
let oDataVisitor;
let mockFileWriter;
@@ -326,6 +332,164 @@ describe('ODataVisitor', function () {
});
});
+ describe('visitMapDeclaration', () => {
+ it('should write the map ', () => {
+ let param = {
+ fileWriter: mockFileWriter
+ };
+
+ let mockModelFile = sinon.createStubInstance(ModelFile);
+ let mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
+
+ const getKeyType = sinon.stub();
+ const getValueType = sinon.stub();
+
+ getKeyType.returns('String');
+ getValueType.returns('String');
+
+ mockModelFile.getType.returns(mockMapDeclaration);
+ mockMapDeclaration.getName.returns('MockMap');
+ mockMapDeclaration.getKey.returns({getType: getKeyType});
+ mockMapDeclaration.getValue.returns({getType: getValueType});
+
+ const isPrimitiveTypeStub = sandbox.stub(ModelUtil, 'isPrimitiveType');
+
+ isPrimitiveTypeStub.onCall(0).returns(true);
+ isPrimitiveTypeStub.onCall(1).returns(true);
+
+ oDataVisitor.visitMapDeclaration(mockMapDeclaration, param);
+
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ isPrimitiveTypeStub.restore();
+ });
+
+ it('should write the map ', () => {
+ let param = {
+ fileWriter: mockFileWriter
+ };
+
+ let mockModelFile = sinon.createStubInstance(ModelFile);
+ let mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
+ let mockScalarDeclaration = sinon.createStubInstance(ScalarDeclaration);
+
+
+ const getKeyType = sinon.stub();
+ const getValueType = sinon.stub();
+
+ getKeyType.returns('SSN');
+ getValueType.returns('String');
+
+ mockMapDeclaration.getName.returns('MockMap');
+ mockMapDeclaration.getKey.returns({getType: getKeyType});
+ mockMapDeclaration.getValue.returns({getType: getValueType});
+ mockMapDeclaration.getModelFile.returns(mockModelFile);
+ mockModelFile.getType.returns(mockScalarDeclaration);
+ mockScalarDeclaration.getType.returns('String');
+
+ const isPrimitiveTypeStub = sandbox.stub(ModelUtil, 'isPrimitiveType');
+ const isScalarStub = sandbox.stub(ModelUtil, 'isScalar');
+
+ isPrimitiveTypeStub.onCall(0).returns(false);
+ isPrimitiveTypeStub.onCall(1).returns(true);
+
+ isScalarStub.onCall(0).returns(true);
+ isScalarStub.onCall(1).returns(false);
+
+ oDataVisitor.visitMapDeclaration(mockMapDeclaration, param);
+
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ isPrimitiveTypeStub.restore();
+ isScalarStub.restore();
+ });
+
+ it('should write the map ', () => {
+ let param = {
+ fileWriter: mockFileWriter
+ };
+
+ let mockModelFile = sinon.createStubInstance(ModelFile);
+ let mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
+ let mockScalarDeclaration = sinon.createStubInstance(ScalarDeclaration);
+
+ const getKeyType = sinon.stub();
+ const getValueType = sinon.stub();
+
+ getKeyType.returns('SSN');
+ getValueType.returns('SSN');
+
+ mockMapDeclaration.getName.returns('MockMap');
+ mockMapDeclaration.getKey.returns({getType: getKeyType});
+ mockMapDeclaration.getValue.returns({getType: getValueType});
+ mockMapDeclaration.getModelFile.returns(mockModelFile);
+ mockModelFile.getType.returns(mockScalarDeclaration);
+ mockScalarDeclaration.getType.returns('String');
+
+ const isPrimitiveTypeStub = sandbox.stub(ModelUtil, 'isPrimitiveType');
+ const isScalarStub = sandbox.stub(ModelUtil, 'isScalar');
+
+ isPrimitiveTypeStub.onCall(0).returns(false);
+ isPrimitiveTypeStub.onCall(1).returns(false);
+
+ isScalarStub.onCall(0).returns(true);
+ isScalarStub.onCall(1).returns(true);
+
+ oDataVisitor.visitMapDeclaration(mockMapDeclaration, param);
+
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ isPrimitiveTypeStub.restore();
+ isScalarStub.restore();
+ });
+
+ it('should write the map ', () => {
+ let param = {
+ fileWriter: mockFileWriter
+ };
+
+ let mockModelFile = sinon.createStubInstance(ModelFile);
+ let mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
+ let mockConceptDeclaration = sinon.createStubInstance(ConceptDeclaration);
+
+ const getKeyType = sinon.stub();
+ const getValueType = sinon.stub();
+
+ getKeyType.returns('String');
+ getValueType.returns('Person');
+
+ mockMapDeclaration.getName.returns('MockMap');
+ mockMapDeclaration.getKey.returns({getType: getKeyType});
+ mockMapDeclaration.getValue.returns({getType: getValueType});
+ mockMapDeclaration.getModelFile.returns(mockModelFile);
+ mockModelFile.getType.returns(mockConceptDeclaration);
+ mockModelFile.getFullyQualifiedTypeName.returns('com.acme@1.0.0.Person');
+
+ const isPrimitiveTypeStub = sandbox.stub(ModelUtil, 'isPrimitiveType');
+ const isScalarStub = sandbox.stub(ModelUtil, 'isScalar');
+
+ isPrimitiveTypeStub.onCall(0).returns(true);
+ isPrimitiveTypeStub.onCall(1).returns(false);
+
+ isScalarStub.onCall(0).returns(false);
+
+ oDataVisitor.visitMapDeclaration(mockMapDeclaration, param);
+
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(2, '').calledOnce.should.be.ok;
+ param.fileWriter.writeLine.withArgs(1, '').calledOnce.should.be.ok;
+ isPrimitiveTypeStub.restore();
+ isScalarStub.restore();
+ });
+ });
+
describe('visitClassDeclaration', () => {
let param;
beforeEach(() => {