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) =
thisModule.avoidReassigningParameters(),
thisModule.avoidStringBufferField(),
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.switchDensity(),
-- #FIXME: thisModule.unusedLocalVariable(),
thisModule.useAssertSameInsteadOfAssertTrue(),
thisModule.useAssertTrueInsteadOfAssertEquals()
thisModule.useAssertTrueInsteadOfAssertEquals(),
-- Bugged rules:
--
......@@ -179,15 +183,8 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
-- thisModule.dontUseFloatTypeForLoopIndices(),
-- 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
rule MeasureMissingBreakInSwitch(ss: java!SwitchStatement) {
to
......@@ -329,7 +326,7 @@ rule MeasureAvoidEnumAsIdentifier(w: java!VariableDeclaration) {
}
}
-- ------------------------------------------- AvoidInstantiatingObjectInLoops ---------------------------------------------
-- ---------------------------------------- AvoidInstantiatingObjectInLoops -------------------------------------------
--- creates a measure when an object is instantiated in a loop
rule MeasureAvoidInstantiatingObjectInLoops(s: java!Statement){
to
......@@ -470,7 +467,7 @@ rule measureAvoidThreadGroup(variable : java!VariableDeclarationStatement) {
}
}
-- ------------------------------------------- AvoidThrowingNewInstanceOfSameException ---------------------------------------------
-- ------------------------------------- AvoidThrowingNewInstanceOfSameException -----------------------------------------
--- A Measure instance if the class violates the rule 'AvoidThrowingNewInstanceOfSameException'.
rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) {
to
......@@ -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).
rule MeasureAvoidUsingNativeCode(classDeclaration : java!ClassDeclaration) {
......@@ -673,7 +670,7 @@ rule MeasureCommentRequired(element: java!BodyDeclaration, violatedProperties: S
}
}
-- ------------------------------------------- MeasureCompareObjectsWithEquals ---------------------------------------------
-- --------------------------------------- MeasureCompareObjectsWithEquals ---------------------------------------------
--- A measure instance if the class violates the rule MeasureCompareObjectsWithEquals.
rule MeasureCompareObjectsWithEquals(expression : java!InfixExpression) {
to
......@@ -695,7 +692,7 @@ rule MeasureCompareObjectsWithEquals(expression : java!InfixExpression) {
}
}
-- -----------------------------------------DoNotCallGarbageCollectionExplicitly----------------------------------------------
-- ------------------------------------- DoNotCallGarbageCollectionExplicitly ------------------------------------------
--- A Measure instance if the class violate the rule DoNotCallGarbageCollectionExplicitly
rule MeasureDoNotCallGarbageCollectionExplicitly(method : java!MethodInvocation) {
to
......@@ -715,7 +712,7 @@ rule MeasureDoNotCallGarbageCollectionExplicitly(method : java!MethodInvocation)
}
}
-- ----------------------------------------- DoNotCallSystemExit----------------------------------------------
-- ----------------------------------------- DoNotCallSystemExit ----------------------------------------------
--- A Measure instance if the class violates the rule DoNotCallSystemExit.
rule MeasureDoNotCallSystemExit(invocation : java!MethodInvocation) {
to
......@@ -1141,7 +1138,7 @@ rule MeasureFieldDeclarationsShouldBeAtStartOfClass(class: java!ClassDeclaration
}
}
-- ------------------------------------------- MeasureFinalFieldCouldBeStatic ---------------------------------------------
-- --------------------------------- MeasureFinalFieldCouldBeStatic ---------------------------------------------
--- A Measure instance if the class violates the rule MeasureFinalFieldCouldBeStatic.
rule MeasureFinalFieldCouldBeStatic(field : java!FieldDeclaration) {
to
......@@ -1163,7 +1160,7 @@ rule MeasureFinalFieldCouldBeStatic(field : java!FieldDeclaration) {
}
}
-- ----------------------------------------- ForLoopVariableCount----------------------------------------------
-- ----------------------------------------- ForLoopVariableCount ----------------------------------------------
--- A Measure instance if the class violates the rule ForLoopVariableCount.
rule MeasureForLoopVariableCount(forStatement: java!ForStatement) {
to
......@@ -1184,7 +1181,7 @@ rule MeasureForLoopVariableCount(forStatement: java!ForStatement) {
}
}
-- -----------------------------------------GenericsNaming----------------------------------------------
-- ---------------------------------------- GenericsNaming ---------------------------------------------
--- A Measure instance if the class violate the rule GenericsNaming
rule MeasureGenericsNaming(type :java!TypeParameter) {
to
......@@ -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 ---------------------------------------------
--- A Measure instance if the class violates the rule 'LongInstantiation'.
rule MeasureLongInstantiation(variable : java!CompilationUnit) {
......
......@@ -125,6 +125,59 @@ helper context java!VariableDeclarationExpression def: nbLocalVariableDeclaratio
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
--- 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
helper def: oneDeclarationPerLine(): Set(smm!Measure) =
......@@ -132,7 +185,6 @@ helper def: oneDeclarationPerLine(): Set(smm!Measure) =
->select(s | s.fragments.size()>1)
->collect(s | thisModule.MeasureOneDeclarationPerLine(s));
--- Rule for metrics SwitchDensity :
-- #TODO: Improve comment
helper def: switchDensity() : Set (smm!Measure) =
......@@ -172,8 +224,6 @@ helper def: useAssertTrueInsteadOfAssertEquals() : Set(smm!Measure) =
->collect(assert | thisModule.MesureUseAssertTrueInsteadOfAssertEquals(assert));
-- Attention !!!
-- Before adding a rule to the end of file, ensure that you are respecting the
-- alphabetical order for rule declarations.
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