Commit aa9b8167 authored by Romain F. T's avatar Romain F. T
Browse files

Fix #633 and #634

parent ff4dd2b4
<?xml version="1.0" encoding="ASCII"?>
<java:Model xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://www.eclipse.org/MoDisco/Java/0.2.incubation/java" name="j-unit-test-contains-too-many-asserts">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="FooTest633">
<modifier visibility="public"/>
<superClass type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="testWith1Assert">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="testWith3Asserts">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="notATestBut3Asserts">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="FooTest633_2">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="testInvalidClass">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="junit" proxy="true">
<ownedPackages name="framework" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="TestCase" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@superClass">
</ownedElements>
</ownedPackages>
</ownedElements>
<orphanTypes xsi:type="java:PrimitiveTypeInt" name="int"/>
<orphanTypes xsi:type="java:PrimitiveTypeLong" name="long"/>
<orphanTypes xsi:type="java:PrimitiveTypeFloat" name="float"/>
<orphanTypes xsi:type="java:PrimitiveTypeDouble" name="double"/>
<orphanTypes xsi:type="java:PrimitiveTypeBoolean" name="boolean"/>
<orphanTypes xsi:type="java:PrimitiveTypeVoid" name="void" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@returnType"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="FooTest.java" originalFilePath="/home/roschan/Projets/Eclipse/eclipse-workspace3/ATL/j-unit-test-contains-too-many-asserts/src/FooTest.java" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
<?xml version="1.0" encoding="ASCII"?>
<java:Model xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://www.eclipse.org/MoDisco/Java/0.2.incubation/java" name="j-unit-test-should-include-assert">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="FooTest634">
<modifier visibility="public"/>
<superClass type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="testWithAssert">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:AssertStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="testWithoutAssert">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="notATestAndNoAssert">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="FooTest634_2">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="testInvalidClass">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="junit" proxy="true">
<ownedPackages name="framework" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="TestCase" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@superClass">
</ownedElements>
</ownedPackages>
</ownedElements>
<orphanTypes xsi:type="java:PrimitiveTypeInt" name="int"/>
<orphanTypes xsi:type="java:PrimitiveTypeLong" name="long"/>
<orphanTypes xsi:type="java:PrimitiveTypeFloat" name="float"/>
<orphanTypes xsi:type="java:PrimitiveTypeDouble" name="double"/>
<orphanTypes xsi:type="java:PrimitiveTypeBoolean" name="boolean"/>
<orphanTypes xsi:type="java:PrimitiveTypeVoid" name="void" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@returnType"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="FooTest.java" originalFilePath="/home/roschan/Projets/Eclipse/eclipse-workspace3/ATL/j-unit-test-should-include-assert/src/FooTest.java" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
...@@ -158,11 +158,15 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = ...@@ -158,11 +158,15 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
thisModule.avoidReassigningParameters(), thisModule.avoidReassigningParameters(),
thisModule.avoidStringBufferField(), thisModule.avoidStringBufferField(),
thisModule.forLoopVariableCount(), thisModule.forLoopVariableCount(),
thisModule.JUnitTestsShouldIncludeAssert(),
thisModule.JUnitTestContainsTooManyAsserts(1) -- TODO il s'agit d'une
-- règle paramétrée, je ne sais pas du tout où l'utilisateur indiquerait
-- sa préférence donc en attendant je mets 1 (valeur par défaut).
thisModule.oneDeclarationPerLine(), thisModule.oneDeclarationPerLine(),
thisModule.switchDensity(), thisModule.switchDensity(),
-- #FIXME: thisModule.unusedLocalVariable(), -- #FIXME: thisModule.unusedLocalVariable(),
thisModule.useAssertSameInsteadOfAssertTrue(), thisModule.useAssertSameInsteadOfAssertTrue(),
thisModule.useAssertTrueInsteadOfAssertEquals() thisModule.useAssertTrueInsteadOfAssertEquals(),
-- Bugged rules: -- Bugged rules:
-- --
...@@ -179,15 +183,8 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = ...@@ -179,15 +183,8 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
-- thisModule.dontUseFloatTypeForLoopIndices(), -- thisModule.dontUseFloatTypeForLoopIndices(),
-- thisModule.methodWithSameNameAsEnclosingClass(), -- thisModule.methodWithSameNameAsEnclosingClass(),
-- Best practicices rules
--
thisModule.avoidThrowingNewInstanceOfSameException(),
thisModule.switchDensity()
}; };
--- Creates an instance of Measure for the switch statement missing one or more break/return statements --- Creates an instance of Measure for the switch statement missing one or more break/return statements
rule MeasureMissingBreakInSwitch(ss: java!SwitchStatement) { rule MeasureMissingBreakInSwitch(ss: java!SwitchStatement) {
to to
...@@ -219,13 +216,13 @@ rule MeasureAbstractClassWithoutAnyMethod(i : java!ClassDeclaration) { ...@@ -219,13 +216,13 @@ rule MeasureAbstractClassWithoutAnyMethod(i : java!ClassDeclaration) {
), ),
noc: smm!DimensionalMeasure ( noc: smm!DimensionalMeasure (
name <- 'AbstractClassWithoutAnyMethod', name <- 'AbstractClassWithoutAnyMethod',
shortDescription <- 'If an abstract class does not provides any methods, it may be acting as a simple data containerth...' shortDescription <- 'If an abstract class does not provides any methods, it may be acting as a simple data containerth...'
), ),
measurement: smm!DirectMeasurement ( measurement: smm!DirectMeasurement (
error<-'The class anstract' + i.name + ' has not method.' error<-'The class anstract' + i.name + ' has not method.'
) )
do { do {
noc; noc;
} }
} }
...@@ -239,7 +236,7 @@ rule MeasureArrayIsStoredDirectly(s: java!MethodDeclaration){ ...@@ -239,7 +236,7 @@ rule MeasureArrayIsStoredDirectly(s: java!MethodDeclaration){
), ),
noc: smm!DimensionalMeasure ( noc: smm!DimensionalMeasure (
name <- 'ArrayIsStoredDirectly', name <- 'ArrayIsStoredDirectly',
shortDescription <- 'Constructors and methods receiving arrays should clone objects and store the copy' shortDescription <- 'Constructors and methods receiving arrays should clone objects and store the copy'
), ),
measurement: smm!DirectMeasurement ( measurement: smm!DirectMeasurement (
error <- s.name + ' has an array parameter that is not cloned before use' error <- s.name + ' has an array parameter that is not cloned before use'
...@@ -265,7 +262,7 @@ rule MeasureAvoidCallingFinalize(methode : java!MethodInvocation) { ...@@ -265,7 +262,7 @@ rule MeasureAvoidCallingFinalize(methode : java!MethodInvocation) {
error <- 'finalize() is called in class' + methode.originalCompilationUnit.name error <- 'finalize() is called in class' + methode.originalCompilationUnit.name
) )
do { do {
noc; noc;
} }
} }
...@@ -325,11 +322,11 @@ rule MeasureAvoidEnumAsIdentifier(w: java!VariableDeclaration) { ...@@ -325,11 +322,11 @@ rule MeasureAvoidEnumAsIdentifier(w: java!VariableDeclaration) {
error <- ' class '+w.originalCompilationUnit.name+ ' has a variable named to enum witch is a reserved name' error <- ' class '+w.originalCompilationUnit.name+ ' has a variable named to enum witch is a reserved name'
) )
do { do {
noc; noc;
} }
} }
-- ------------------------------------------- AvoidInstantiatingObjectInLoops --------------------------------------------- -- ---------------------------------------- AvoidInstantiatingObjectInLoops -------------------------------------------
--- creates a measure when an object is instantiated in a loop --- creates a measure when an object is instantiated in a loop
rule MeasureAvoidInstantiatingObjectInLoops(s: java!Statement){ rule MeasureAvoidInstantiatingObjectInLoops(s: java!Statement){
to to
...@@ -470,10 +467,10 @@ rule measureAvoidThreadGroup(variable : java!VariableDeclarationStatement) { ...@@ -470,10 +467,10 @@ rule measureAvoidThreadGroup(variable : java!VariableDeclarationStatement) {
} }
} }
-- ------------------------------------------- AvoidThrowingNewInstanceOfSameException --------------------------------------------- -- ------------------------------------- AvoidThrowingNewInstanceOfSameException -----------------------------------------
--- A Measure instance if the class violates the rule 'AvoidThrowingNewInstanceOfSameException'. --- A Measure instance if the class violates the rule 'AvoidThrowingNewInstanceOfSameException'.
rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) { rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) {
to to
om: smm!ObservedMeasure ( om: smm!ObservedMeasure (
measure <- noc, measure <- noc,
measurements <- measurement measurements <- measurement
...@@ -486,7 +483,7 @@ rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) { ...@@ -486,7 +483,7 @@ rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) {
error <-'The class '+ catch.originalCompilationUnit.name + ' has a method that rethrows a caught exception wrapped inside a new instance of the same type.' error <-'The class '+ catch.originalCompilationUnit.name + ' has a method that rethrows a caught exception wrapped inside a new instance of the same type.'
) )
do { do {
noc; noc;
} }
} }
...@@ -533,7 +530,7 @@ rule MeasureAvoidUsingShortType(typeShort : java!VariableDeclarationStatement) { ...@@ -533,7 +530,7 @@ rule MeasureAvoidUsingShortType(typeShort : java!VariableDeclarationStatement) {
} }
} }
-- ----------------------------------------- AvoidUsingNativeCode ------------------------------------------------------------------------------------ -- ---------------------------------------- AvoidUsingNativeCode -------------------------------------------------------
---creates a new Measure when a Java Native Interface (JNI) calls unecessary reliance(s). ---creates a new Measure when a Java Native Interface (JNI) calls unecessary reliance(s).
rule MeasureAvoidUsingNativeCode(classDeclaration : java!ClassDeclaration) { rule MeasureAvoidUsingNativeCode(classDeclaration : java!ClassDeclaration) {
...@@ -673,7 +670,7 @@ rule MeasureCommentRequired(element: java!BodyDeclaration, violatedProperties: S ...@@ -673,7 +670,7 @@ rule MeasureCommentRequired(element: java!BodyDeclaration, violatedProperties: S
} }
} }
-- ------------------------------------------- MeasureCompareObjectsWithEquals --------------------------------------------- -- --------------------------------------- MeasureCompareObjectsWithEquals ---------------------------------------------
--- A measure instance if the class violates the rule MeasureCompareObjectsWithEquals. --- A measure instance if the class violates the rule MeasureCompareObjectsWithEquals.
rule MeasureCompareObjectsWithEquals(expression : java!InfixExpression) { rule MeasureCompareObjectsWithEquals(expression : java!InfixExpression) {
to to
...@@ -686,16 +683,16 @@ rule MeasureCompareObjectsWithEquals(expression : java!InfixExpression) { ...@@ -686,16 +683,16 @@ rule MeasureCompareObjectsWithEquals(expression : java!InfixExpression) {
shortDescription <- 'Use equals() to compare object references; avoid comparing them with ==.' shortDescription <- 'Use equals() to compare object references; avoid comparing them with ==.'
), ),
measurement: smm!DirectMeasurement ( measurement: smm!DirectMeasurement (
error<-'The Class '+ expression.originalCompilationUnit.name + ' is using == instead of equals() to compare objects.' error<-'The Class '+ expression.originalCompilationUnit.name + ' is using == instead of equals() to compare objects.'
) )
do { do {
noc; noc;
} }
} }
-- -----------------------------------------DoNotCallGarbageCollectionExplicitly---------------------------------------------- -- ------------------------------------- DoNotCallGarbageCollectionExplicitly ------------------------------------------
--- A Measure instance if the class violate the rule DoNotCallGarbageCollectionExplicitly --- A Measure instance if the class violate the rule DoNotCallGarbageCollectionExplicitly
rule MeasureDoNotCallGarbageCollectionExplicitly(method : java!MethodInvocation) { rule MeasureDoNotCallGarbageCollectionExplicitly(method : java!MethodInvocation) {
to to
...@@ -715,7 +712,7 @@ rule MeasureDoNotCallGarbageCollectionExplicitly(method : java!MethodInvocation) ...@@ -715,7 +712,7 @@ rule MeasureDoNotCallGarbageCollectionExplicitly(method : java!MethodInvocation)
} }
} }
-- ----------------------------------------- DoNotCallSystemExit---------------------------------------------- -- ----------------------------------------- DoNotCallSystemExit ----------------------------------------------
--- A Measure instance if the class violates the rule DoNotCallSystemExit. --- A Measure instance if the class violates the rule DoNotCallSystemExit.
rule MeasureDoNotCallSystemExit(invocation : java!MethodInvocation) { rule MeasureDoNotCallSystemExit(invocation : java!MethodInvocation) {
to to
...@@ -728,7 +725,7 @@ rule MeasureDoNotCallSystemExit(invocation : java!MethodInvocation) { ...@@ -728,7 +725,7 @@ rule MeasureDoNotCallSystemExit(invocation : java!MethodInvocation) {
shortDescription <- 'Applications should not call System.exit(), since only the web container or the application server should stop the JVM' shortDescription <- 'Applications should not call System.exit(), since only the web container or the application server should stop the JVM'
), ),
measurement: smm!DirectMeasurement ( measurement: smm!DirectMeasurement (
error<- 'Do not call ' + invocation.method.getMethodClassName() + '.' + invocation.method.name + ' in the file ' + invocation.originalCompilationUnit.name error<- 'Do not call ' + invocation.method.getMethodClassName() + '.' + invocation.method.name + ' in the file ' + invocation.originalCompilationUnit.name
) )
do { do {
...@@ -1133,7 +1130,7 @@ rule MeasureFieldDeclarationsShouldBeAtStartOfClass(class: java!ClassDeclaration ...@@ -1133,7 +1130,7 @@ rule MeasureFieldDeclarationsShouldBeAtStartOfClass(class: java!ClassDeclaration
name <- 'FieldDeclarationsShouldBeAtStartOfClass', name <- 'FieldDeclarationsShouldBeAtStartOfClass',
shortDescription <- 'Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.' shortDescription <- 'Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.'
), ),
measurement: smm!DirectMeasurement ( measurement: smm!DirectMeasurement (
error<- 'Some of the fields of the class ' + class.name + ' are not declared at the top' error<- 'Some of the fields of the class ' + class.name + ' are not declared at the top'
) )
do { do {
...@@ -1141,7 +1138,7 @@ rule MeasureFieldDeclarationsShouldBeAtStartOfClass(class: java!ClassDeclaration ...@@ -1141,7 +1138,7 @@ rule MeasureFieldDeclarationsShouldBeAtStartOfClass(class: java!ClassDeclaration
} }
} }
-- ------------------------------------------- MeasureFinalFieldCouldBeStatic --------------------------------------------- -- --------------------------------- MeasureFinalFieldCouldBeStatic ---------------------------------------------
--- A Measure instance if the class violates the rule MeasureFinalFieldCouldBeStatic. --- A Measure instance if the class violates the rule MeasureFinalFieldCouldBeStatic.
rule MeasureFinalFieldCouldBeStatic(field : java!FieldDeclaration) { rule MeasureFinalFieldCouldBeStatic(field : java!FieldDeclaration) {
to to
...@@ -1163,7 +1160,7 @@ rule MeasureFinalFieldCouldBeStatic(field : java!FieldDeclaration) { ...@@ -1163,7 +1160,7 @@ rule MeasureFinalFieldCouldBeStatic(field : java!FieldDeclaration) {
} }
} }
-- ----------------------------------------- ForLoopVariableCount---------------------------------------------- -- ----------------------------------------- ForLoopVariableCount ----------------------------------------------
--- A Measure instance if the class violates the rule ForLoopVariableCount. --- A Measure instance if the class violates the rule ForLoopVariableCount.
rule MeasureForLoopVariableCount(forStatement: java!ForStatement) { rule MeasureForLoopVariableCount(forStatement: java!ForStatement) {
to to
...@@ -1184,7 +1181,7 @@ rule MeasureForLoopVariableCount(forStatement: java!ForStatement) { ...@@ -1184,7 +1181,7 @@ rule MeasureForLoopVariableCount(forStatement: java!ForStatement) {
} }
} }
-- -----------------------------------------GenericsNaming---------------------------------------------- -- ---------------------------------------- GenericsNaming ---------------------------------------------
--- A Measure instance if the class violate the rule GenericsNaming --- A Measure instance if the class violate the rule GenericsNaming
rule MeasureGenericsNaming(type :java!TypeParameter) { rule MeasureGenericsNaming(type :java!TypeParameter) {
to to
...@@ -1314,9 +1311,9 @@ rule MeasureIntegerInstantiation(variable : java!CompilationUnit) { ...@@ -1314,9 +1311,9 @@ rule MeasureIntegerInstantiation(variable : java!CompilationUnit) {
), ),
noc: smm!DimensionalMeasure ( noc: smm!DimensionalMeasure (
name <- 'IntegerInstantiation', name <- 'IntegerInstantiation',
shortDescription <- 'Calling new Integer() causes memory allocation that can be avoided by the static Integer.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Integer() is deprecated since JDK 9 for that reason.' shortDescription <- 'Calling new Integer() causes memory allocation that can be avoided by the static Integer.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Integer() is deprecated since JDK 9 for that reason.'
), ),
measurement: smm!DirectMeasurement ( measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' an instantiation of Integer must be Integer.ValueOf().' error<-'In the Class '+ variable.name + ' an instantiation of Integer must be Integer.ValueOf().'
) )
...@@ -1346,6 +1343,46 @@ rule MeasureJUnitSpelling(i : java!MethodDeclaration) { ...@@ -1346,6 +1343,46 @@ rule MeasureJUnitSpelling(i : java!MethodDeclaration) {
} }
} }
-- --------------------- JUnitTestsShouldIncludeAssert -------------------------
--- A measure instance if a JUnit test class violates the rule JUnitTestsShouldIncludeAssert
rule MeasureJUnitTestsShouldIncludeAssert(m: java!MethodDeclaration, c: java!ClassDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'JUnitTestsShouldIncludeAssert',
shortDescription <- 'JUnit tests should include at least one assertion.'
),
measurement: smm!DirectMeasurement (
error<- 'The JUnit test ' + m.name + ' in the class ' + c.name + ' should include at least one assertion.'
)
do {
noc;
}
}
----------------------- JUnitTestContainsTooManyAsserts ------------------------
-- A measure instance if a JUnit test class violates the rule JUnitTestContainsTooManyAsserts
rule MeasureJUnitTestContainsTooManyAsserts(m: java!MethodDeclaration, c: java!ClassDeclaration, max: Integer) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'JUnitTestContainsTooManyAsserts',
shortDescription <- 'Unit tests should not contain too many asserts.'
),
measurement: smm!DirectMeasurement (
error<- 'The JUnit test ' + m.getName() + ' in the class ' + c.getName() + ' contains more than ' + max + ' assertions.'
)
do {
noc;
}
}
-- ------------------------------------------- LongInstantiation --------------------------------------------- -- ------------------------------------------- LongInstantiation ---------------------------------------------
--- A Measure instance if the class violates the rule 'LongInstantiation'. --- A Measure instance if the class violates the rule 'LongInstantiation'.
rule MeasureLongInstantiation(variable : java!CompilationUnit) { rule MeasureLongInstantiation(variable : java!CompilationUnit) {
......
...@@ -125,16 +125,68 @@ helper context java!VariableDeclarationExpression def: nbLocalVariableDeclaratio ...@@ -125,16 +125,68 @@ helper context java!VariableDeclarationExpression def: nbLocalVariableDeclaratio
self.fragments.size(); -- The fragments collection contains all the variable declarations of an initializer* self.fragments.size(); -- The fragments collection contains all the variable declarations of an initializer*
-- Initializer* : for(int x = 0; ...), "int x = 0" is the initializer part of the for loop -- Initializer* : for(int x = 0; ...), "int x = 0" is the initializer part of the for loop
--- helper for the rule JUnitTestsShouldIncludeAssert
--TODO ne couvre pas du tout tous les cas possibles que fait le vrai PMD (mockito, etc.)
helper def: JUnitTestsShouldIncludeAssert() : Set(smm!Measure) =
java!ClassDeclaration.allInstances()
-> select(cl | cl.isTestClass())
-> iterate(i; res : Set(smm!Measure) = Set{} | i.bodyDeclarations
-> select(mtd |
mtd.oclIsTypeOf(java!MethodDeclaration)
and mtd.isTestMethod()
and mtd.numberOfAsserts() < 1
)
-> collect(mtd | thisModule.MeasureJUnitTestsShouldIncludeAssert(mtd, i))
)
;
-- counts the number of assertions in a method declaration
helper context java!MethodDeclaration def: numberOfAsserts() : Integer =
self.getBody().statements
-> select(sttm | sttm <> OclUndefined) -- utile?
-> select(sttm | sttm.oclIsTypeOf(java!AssertStatement))
-> size()
;
-- tells if a method is a test (assuming its class is a TestCase)
-- XXX we maybe could check the annotation too?
helper context java!MethodDeclaration def: isTestMethod() : Boolean =
self.name.substring(1, 4) = 'test'
;
-- tells if a class extends TestCase
helper context java!ClassDeclaration def: isTestClass() : Boolean =
if self.superClass <> OclUndefined then -- the condition is needed because
-- using "and" doesn't prevent the execution of the rest of the expression
-- for some reason, so an error occurs
self.superClass.type.name = 'junit.framework.TestCase' or self.superClass.type.name = 'TestCase'
else
false
endif
;
--- helper for the rule JUnitTestContainsTooManyAsserts
helper def: JUnitTestContainsTooManyAsserts(maximumAsserts : Integer) : Set(smm!Measure) =
java!ClassDeclaration.allInstances()
-> select(cl | cl.isTestClass())
-> iterate(i; res : Set(smm!Measure) = Set{} | i.bodyDeclarations
-> select(mtd |
mtd.oclIsTypeOf(java!MethodDeclaration)
and mtd.isTestMethod()
and mtd.numberOfAsserts() > maximumAsserts
)
-> collect(mtd | thisModule.MeasureJUnitTestContainsTooManyAsserts(mtd, i, maximumAsserts))
)
;
-- #TODO: Add comment -- #TODO: Add comment
helper def: oneDeclarationPerLine(): Set(smm!Measure) = helper def: oneDeclarationPerLine(): Set(smm!Measure) =
java!VariableDeclarationStatement.allInstances() java!VariableDeclarationStatement.allInstances()
->select(s | s.fragments.size()>1) ->select(s | s.fragments.size()>1)
->collect(s | thisModule.MeasureOneDeclarationPerLine(s)); ->collect(s | thisModule.MeasureOneDeclarationPerLine(s));
--- Rule for metrics SwitchDensity : --- Rule for metrics SwitchDensity :
-- #TODO: Improve comment -- #TODO: Improve comment
helper def: switchDensity() : Set (smm!Measure) = helper def: switchDensity() : Set (smm!Measure) =
-- Browse through all Switch Statements -- Browse through all Switch Statements
java!SwitchStatement.allInstances()->iterate(switchCase; res : Set(smm!Measure) = Set{} | java!SwitchStatement.allInstances()->iterate(switchCase; res : Set(smm!Measure) = Set{} |
...@@ -171,8 +223,6 @@ helper def: useAssertTrueInsteadOfAssertEquals() : Set(smm!Measure) = ...@@ -171,8 +223,6 @@ helper def: useAssertTrueInsteadOfAssertEquals() : Set(smm!Measure) =
->select(assert | thisModule.isWrongUseAssertTrueInsteadOfAssertEquals(assert)) ->select(assert | thisModule.isWrongUseAssertTrueInsteadOfAssertEquals(assert))
->collect(assert | thisModule.MesureUseAssertTrueInsteadOfAssertEquals(assert)); ->collect(assert | thisModule.MesureUseAssertTrueInsteadOfAssertEquals(assert));
-- Attention !!! -- Attention !!!
-- Before adding a rule to the end of file, ensure that you are respecting the -- Before adding a rule to the end of file, ensure that you are respecting the
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment