Skip to content

Commit

Permalink
feat(*): detect field to relationship, scalar to array (contributes to
Browse files Browse the repository at this point in the history
…accordproject#442)

Signed-off-by: Simon Stone <[email protected]>
  • Loading branch information
Simon Stone authored and Simon Stone committed Aug 5, 2022
1 parent b7d6cc7 commit a85f35b
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/concerto-analysis/src/compare-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ export const defaultCompareConfig: CompareConfig = {
'namespace-changed': CompareResult.ERROR,
'enum-value-added': CompareResult.PATCH,
'enum-value-removed': CompareResult.MAJOR,
'property-type-changed': CompareResult.MAJOR,
}
};
38 changes: 37 additions & 1 deletion packages/concerto-analysis/src/comparers/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,40 @@ const propertyRemoved: ComparerFactory = (context) => ({
}
});

export const propertyComparerFactories = [propertyAdded, propertyRemoved];
const propertyTypeChanged: ComparerFactory = (context) => ({
compareProperty: (a, b) => {
if (!a || !b) {
return;
}
const aType = getPropertyType(a);
const bType = getPropertyType(b);
const classDeclarationType = getClassDeclarationType(a.getParent());
if (aType !== bType) {
context.report({
key: 'property-type-changed',
message: `The ${aType} "${a.getName()}" in the ${classDeclarationType} "${a.getParent().getName()}" changed type from ${aType} to ${bType}`,
element: a
});
return;
} else if (a instanceof EnumValueDeclaration || b instanceof EnumValueDeclaration) {
return;
}
const aIsArray = a.isArray();
const bIsArray = b.isArray();
if (aIsArray && !bIsArray) {
context.report({
key: 'property-type-changed',
message: `The array ${aType} "${a.getName()}" in the ${classDeclarationType} "${a.getParent().getName()}" changed type from an array ${aType} to a scalar ${aType}`,
element: a
});
} else if (!aIsArray && bIsArray) {
context.report({
key: 'property-type-changed',
message: `The scalar ${aType} "${a.getName()}" in the ${classDeclarationType} "${a.getParent().getName()}" changed type from a scalar ${aType} to an array ${aType}`,
element: a
});
}
},
});

export const propertyComparerFactories = [propertyAdded, propertyRemoved, propertyTypeChanged];
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace [email protected]

concept Bar {

}

concept Thing {
o Bar bar
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace [email protected]

concept Bar {

}

concept Thing {
--> Bar bar
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace [email protected]

concept Bar {

}

concept Thing {
o Bar bar
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace [email protected]

concept Bar {

}

concept Thing {
o Bar[] bar
}
48 changes: 48 additions & 0 deletions packages/concerto-analysis/test/unit/compare.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,51 @@ test('should detect an enum value being removed', async () => {
]));
expect(results.result).toBe(CompareResult.MAJOR);
});

test('should detect a field changing to a relationship', async () => {
const [a, b] = await getModelFiles('field-to-relationship-a.cto', 'field-to-relationship-b.cto');
const results = new Compare().compare(a, b);
expect(results.findings).toEqual(expect.arrayContaining([
expect.objectContaining({
key: 'property-type-changed',
message: 'The field "bar" in the concept "Thing" changed type from field to relationship'
})
]));
expect(results.result).toBe(CompareResult.MAJOR);
});

test('should detect a relationship changing to a field', async () => {
const [a, b] = await getModelFiles('field-to-relationship-b.cto', 'field-to-relationship-a.cto');
const results = new Compare().compare(a, b);
expect(results.findings).toEqual(expect.arrayContaining([
expect.objectContaining({
key: 'property-type-changed',
message: 'The relationship "bar" in the concept "Thing" changed type from relationship to field'
})
]));
expect(results.result).toBe(CompareResult.MAJOR);
});

test('should detect a scalar changing to an array', async () => {
const [a, b] = await getModelFiles('scalar-to-array-a.cto', 'scalar-to-array-b.cto');
const results = new Compare().compare(a, b);
expect(results.findings).toEqual(expect.arrayContaining([
expect.objectContaining({
key: 'property-type-changed',
message: 'The scalar field "bar" in the concept "Thing" changed type from a scalar field to an array field'
})
]));
expect(results.result).toBe(CompareResult.MAJOR);
});

test('should detect an array changing to a scalar', async () => {
const [a, b] = await getModelFiles('scalar-to-array-b.cto', 'scalar-to-array-a.cto');
const results = new Compare().compare(a, b);
expect(results.findings).toEqual(expect.arrayContaining([
expect.objectContaining({
key: 'property-type-changed',
message: 'The array field "bar" in the concept "Thing" changed type from an array field to a scalar field'
})
]));
expect(results.result).toBe(CompareResult.MAJOR);
});

0 comments on commit a85f35b

Please sign in to comment.