diff --git a/src/models/ConstrainedMetaModel.ts b/src/models/ConstrainedMetaModel.ts index 928b24ca65..eaca070f9c 100644 --- a/src/models/ConstrainedMetaModel.ts +++ b/src/models/ConstrainedMetaModel.ts @@ -55,6 +55,9 @@ export class ConstrainedTupleModel extends ConstrainedMetaModel { ).map((tupleModel) => { return tupleModel.value = tupleModel.value as ConstrainedReferenceModel; }); + //Ensure no duplicate references + dependencyModels = [...new Set(dependencyModels)]; + //Ensure no self references dependencyModels = dependencyModels.filter((referenceModel) => { return referenceModel.name !== this.name; @@ -104,6 +107,9 @@ export class ConstrainedUnionModel extends ConstrainedMetaModel { ).map((unionModel) => { return unionModel as ConstrainedReferenceModel; }); + //Ensure no duplicate references + dependencyModels = [...new Set(dependencyModels)]; + //Ensure no self references dependencyModels = dependencyModels.filter((referenceModel) => { return referenceModel.name !== this.name; @@ -125,21 +131,6 @@ export class ConstrainedEnumModel extends ConstrainedMetaModel { public values: ConstrainedEnumValueModel[]) { super(name, originalInput, type); } - - getNearestDependencies(): ConstrainedReferenceModel[] { - let dependencyModels = Object.values(this.values).filter( - (enumModel) => { - return enumModel.value instanceof ConstrainedReferenceModel; - } - ).map((enumModel) => { - return enumModel.value as ConstrainedReferenceModel; - }); - //Ensure no self references - dependencyModels = dependencyModels.filter((referenceModel) => { - return referenceModel.name !== this.name; - }); - return dependencyModels; - } } export class ConstrainedDictionaryModel extends ConstrainedMetaModel { constructor( @@ -161,6 +152,9 @@ export class ConstrainedDictionaryModel extends ConstrainedMetaModel { ).map((model) => { return model as ConstrainedReferenceModel; }); + //Ensure no duplicate references + dependencyModels = [...new Set(dependencyModels)]; + //Ensure no self references dependencyModels = dependencyModels.filter((referenceModel) => { return referenceModel.name !== this.name; @@ -186,6 +180,9 @@ export class ConstrainedObjectModel extends ConstrainedMetaModel { ).map((modelProperty) => { return modelProperty.property as ConstrainedReferenceModel; }); + //Ensure no duplicate references + dependencyModels = [...new Set(dependencyModels)]; + //Ensure no self references dependencyModels = dependencyModels.filter((referenceModel) => { return referenceModel.name !== this.name; diff --git a/test/blackbox/blackbox.spec.ts b/test/blackbox/blackbox.spec.ts index ff8ed0ca4c..0dd09c4d63 100644 --- a/test/blackbox/blackbox.spec.ts +++ b/test/blackbox/blackbox.spec.ts @@ -45,6 +45,9 @@ const filesToTest = [ }).filter(({ file }) => { // Related to https://github.com/asyncapi/modelina/issues/389 return !file.includes('jenkins-config.json'); + }).filter(({file}) => { + // Related to https://github.com/asyncapi/modelina/issues/840 + // Related to https://github.com/asyncapi/modelina/issues/841 }).filter(({ file }) => { // Related to https://github.com/asyncapi/modelina/issues/825 return !file.includes('circleci-config.json'); diff --git a/test/models/ConstrainedMetaModel.spec.ts b/test/models/ConstrainedMetaModel.spec.ts index 438a7bcb23..08d1e18b1e 100644 --- a/test/models/ConstrainedMetaModel.spec.ts +++ b/test/models/ConstrainedMetaModel.spec.ts @@ -99,6 +99,23 @@ describe('ConstrainedMetaModel', () => { expect(dependencies).toHaveLength(1); expect(dependencies[0]).toEqual(model.tuple[0].value); }); + + test('should not return duplicate dependencies', () => { + const stringModel = new StringModel('', undefined); + const referenceModel = new ReferenceModel('', undefined, stringModel); + const referenceTupleModel = new TupleValueModel(0, referenceModel); + const reference2TupleModel = new TupleValueModel(1, referenceModel); + const rawModel = new TupleModel('test', undefined, [referenceTupleModel, reference2TupleModel]); + + const model = constrainMetaModel(mockedTypeMapping, mockedConstraints, { + metaModel: rawModel, + constrainedName: '', + options: undefined + }) as ConstrainedTupleModel; + const dependencies = model.getNearestDependencies(); + expect(dependencies).toHaveLength(1); + expect(dependencies[0]).toEqual(model.tuple[0].value); + }); }); describe('ObjectModel', () => { test('should return all reference dependencies', () => { @@ -121,6 +138,26 @@ describe('ConstrainedMetaModel', () => { expect(dependencies[0]).toEqual(model.properties['reference'].property); }); + test('should not return duplicate dependencies', () => { + const stringModel = new StringModel('string', undefined); + const referenceModel = new ReferenceModel('reference', undefined, stringModel); + const referenceObjectPropertyModel = new ObjectPropertyModel('reference', false, referenceModel); + const reference2ObjectPropertyModel = new ObjectPropertyModel('reference2', false, referenceModel); + const rawModel = new ObjectModel('test', undefined, { + reference: referenceObjectPropertyModel, + reference2: reference2ObjectPropertyModel + }); + + const model = constrainMetaModel(mockedTypeMapping, mockedConstraints, { + metaModel: rawModel, + constrainedName: '', + options: undefined + }) as ConstrainedObjectModel; + const dependencies = model.getNearestDependencies(); + expect(dependencies).toHaveLength(1); + expect(dependencies[0]).toEqual(model.properties['reference'].property); + }); + describe('containsPropertyType', () => { test('should find present property type and those who are not', () => { const stringModel = new ConstrainedStringModel('', undefined, ''); @@ -154,6 +191,20 @@ describe('ConstrainedMetaModel', () => { const referenceModel = new ReferenceModel('', undefined, stringModel); const rawModel = new DictionaryModel('test', undefined, referenceModel, stringModel); + const model = constrainMetaModel(mockedTypeMapping, mockedConstraints, { + metaModel: rawModel, + constrainedName: '', + options: undefined + }) as ConstrainedDictionaryModel; + const dependencies = model.getNearestDependencies(); + expect(dependencies).toHaveLength(1); + expect(dependencies[0]).toEqual(model.key); + }); + test('should not return duplicate dependencies', () => { + const stringModel = new StringModel('', undefined); + const referenceModel = new ReferenceModel('', undefined, stringModel); + const rawModel = new DictionaryModel('test', undefined, referenceModel, referenceModel); + const model = constrainMetaModel(mockedTypeMapping, mockedConstraints, { metaModel: rawModel, constrainedName: '', @@ -207,5 +258,20 @@ describe('ConstrainedMetaModel', () => { expect(dependencies).toHaveLength(1); expect(dependencies[0]).toEqual(model.union[0]); }); + + test('should not return duplicate dependencies', () => { + const stringModel = new StringModel('', undefined); + const referenceModel = new ReferenceModel('', undefined, stringModel); + const rawModel = new UnionModel('test', undefined, [referenceModel, referenceModel]); + + const model = constrainMetaModel(mockedTypeMapping, mockedConstraints, { + metaModel: rawModel, + constrainedName: '', + options: undefined + }) as ConstrainedUnionModel; + const dependencies = model.getNearestDependencies(); + expect(dependencies).toHaveLength(1); + expect(dependencies[0]).toEqual(model.union[0]); + }); }); });