+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2009 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-
-package org.sonar.java.ast.check;
-
-import org.sonar.check.IsoCategory;
-import org.sonar.check.Rule;
-import org.sonar.check.RuleProperty;
-import org.sonar.java.ast.visitor.ClassVisitor;
-import org.sonar.squid.api.CheckMessage;
-import org.sonar.squid.api.SourceCode;
-import org.sonar.squid.api.SourceFile;
-import org.sonar.squid.measures.Metric;
-
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
-
-import java.util.List;
-
-@Rule(key = "ClassComplexityCheck", name = "ClassComplexityCheck", isoCategory = IsoCategory.Maintainability)
-public class ClassComplexityCheck extends JavaAstCheck {
-
- @RuleProperty(description = "Threshold.")
- private Integer threshold;
-
- @Override
- public List<Integer> getWantedTokens() {
- return ClassVisitor.wantedTokens;
- }
-
- @Override
- public void leaveToken(DetailAST ast) {
- SourceCode currentResource = peekSourceCode();
- int complexity = calculateComplexity(currentResource);
- if (complexity > threshold) {
- CheckMessage message = new CheckMessage(this, "Class complexity exceeds " + threshold + ".");
- message.setLine(ast.getLineNo());
- message.setCost(complexity - threshold);
- SourceFile sourceFile = currentResource.getParent(SourceFile.class);
- sourceFile.log(message);
- }
- }
-
- private int calculateComplexity(SourceCode sourceCode) {
- int result = 0;
- if (sourceCode.getChildren() != null) {
- for (SourceCode child : sourceCode.getChildren()) {
- result += calculateComplexity(child);
- }
- }
- result += sourceCode.getInt(Metric.COMPLEXITY);
- return result;
- }
-
- public void setThreshold(int threshold) {
- this.threshold = threshold;
- }
-
-}
+++ /dev/null
-package org.sonar.java.ast.check;
-
-import org.sonar.check.IsoCategory;
-import org.sonar.check.Rule;
-import org.sonar.check.RuleProperty;
-import org.sonar.java.ast.visitor.MethodVisitor;
-import org.sonar.squid.api.CheckMessage;
-import org.sonar.squid.api.SourceCode;
-import org.sonar.squid.api.SourceFile;
-import org.sonar.squid.measures.Metric;
-
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
-
-import java.util.List;
-
-@Rule(key = "MethodComplexityCheck", name = "MethodComplexityCheck", isoCategory = IsoCategory.Maintainability)
-public class MethodComplexityCheck extends JavaAstCheck {
-
- @RuleProperty(description = "Threshold.")
- private Integer threshold;
-
- @Override
- public List<Integer> getWantedTokens() {
- return MethodVisitor.wantedTokens;
- }
-
- @Override
- public void leaveToken(DetailAST ast) {
- SourceCode currentResource = peekSourceCode();
- int complexity = currentResource.getInt(Metric.COMPLEXITY) + currentResource.getInt(Metric.BRANCHES) + 1;
- if (complexity > threshold) {
- CheckMessage message = new CheckMessage(this, "Method complexity exceeds " + threshold + ".");
- message.setLine(ast.getLineNo());
- message.setCost(complexity - threshold);
- SourceFile sourceFile = currentResource.getParent(SourceFile.class);
- sourceFile.log(message);
- }
- }
-
- public void setThreshold(int threshold) {
- this.threshold = threshold;
- }
-
-}
+++ /dev/null
-package org.sonar.java.bytecode.check;
-
-import org.sonar.check.IsoCategory;
-import org.sonar.check.Priority;
-import org.sonar.check.Rule;
-import org.sonar.check.RuleProperty;
-import org.sonar.java.bytecode.asm.AsmClass;
-import org.sonar.squid.api.CheckMessage;
-import org.sonar.squid.api.SourceClass;
-import org.sonar.squid.measures.Metric;
-
-@Rule(key = "MaximumInheritanceDepth", name = "Avoid too deep inheritance tree", isoCategory = IsoCategory.Maintainability,
- priority = Priority.MAJOR, description = "<p>Inheritance is certainly one of the most valuable concept of object-oriented "
- + "programming. It's a way to compartmentalize and reuse code by creating collections of attributes and behaviors called "
- + "classes which can be based on previously created classes. But abusing of this concept by creating a deep inheritance tree "
- + "can lead to very complex and unmaintainable source code.</p>"
- + "<p>Most of the time a too deep inheritance tree is due to bad object oriented design which has led to systematically use "
- + "'inheritance' when 'composition' would suit better.</p>")
-public class DITCheck extends BytecodeCheck {
-
- @RuleProperty(description = "Maximum depth of the inheritance tree.", defaultValue = "5")
- private Integer max;
-
- @Override
- public void visitClass(AsmClass asmClass) {
- SourceClass sourceClass = getSourceClass(asmClass);
- int dit = sourceClass.getInt(Metric.DIT);
- if (dit > max) {
- CheckMessage message = new CheckMessage(this, "This class has " + dit
- + " parents which makes it complex to understand and to maintain.");
- message.setLine(sourceClass.getStartAtLine());
- message.setCost(dit - max);
- getSourceFile(asmClass).log(message);
- }
- }
-
- public void setMax(int max) {
- this.max = max;
- }
-}
--- /dev/null
+package org.sonar.java.squid;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.sonar.java.squid.check.SquidCheck;
+import org.sonar.java.squid.visitor.SquidVisitor;
+import org.sonar.squid.api.CodeScanner;
+import org.sonar.squid.api.CodeVisitor;
+import org.sonar.squid.api.SourceClass;
+import org.sonar.squid.api.SourceCode;
+import org.sonar.squid.indexer.QueryByType;
+import org.sonar.squid.indexer.SquidIndex;
+
+public class SquidScanner extends CodeScanner<CodeVisitor> {
+
+ private SquidIndex indexer;
+
+ public SquidScanner(SquidIndex indexer) {
+ this.indexer = indexer;
+ }
+
+ public void scan() {
+ Collection<SourceCode> classes = indexer.search(new QueryByType(SourceClass.class));
+ notifySquidVisitors(classes);
+ }
+
+ private void notifySquidVisitors(Collection<SourceCode> classes) {
+ SquidVisitor[] visitorArray = getVisitors().toArray(new SquidVisitor[getVisitors().size()]);
+ for (SourceCode sourceClass : classes) {
+ SquidVisitorNotifier visitorNotifier = new SquidVisitorNotifier((SourceClass) sourceClass, visitorArray);
+ visitorNotifier.notifyVisitors(indexer);
+ }
+ }
+
+ @Override
+ public Collection<Class<? extends CodeVisitor>> getVisitorClasses() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void accept(CodeVisitor visitor) {
+ if (visitor instanceof SquidCheck) {
+ super.accept(visitor);
+ }
+ }
+
+}
--- /dev/null
+package org.sonar.java.squid;
+
+import org.sonar.java.squid.visitor.SquidVisitor;
+import org.sonar.squid.api.SourceClass;
+import org.sonar.squid.api.SourceCode;
+import org.sonar.squid.api.SourceMethod;
+import org.sonar.squid.indexer.SquidIndex;
+
+public class SquidVisitorNotifier {
+
+ private final SourceClass sourceClass;
+ private final SquidVisitor[] squidVisitors;
+
+ public SquidVisitorNotifier(SourceClass sourceClass, SquidVisitor[] squidVisitors) {
+ this.sourceClass = sourceClass;
+ this.squidVisitors = new SquidVisitor[squidVisitors.length];
+ System.arraycopy(squidVisitors, 0, this.squidVisitors, 0, squidVisitors.length);
+ }
+
+ public void notifyVisitors(SquidIndex indexer) {
+ for (SquidVisitor visitor : squidVisitors) {
+ visitor.setSquidIndex(indexer);
+ }
+ callVisitClass();
+ callVisitMethod();
+ }
+
+ private void callVisitClass() {
+ for (SquidVisitor visitor : squidVisitors) {
+ visitor.visitClass(sourceClass);
+ }
+ }
+
+ private void callVisitMethod() {
+ if (sourceClass.getChildren() == null) { // TODO Most probably SourceCode#hasChildren() shouldn't be protected
+ return;
+ }
+ for (SourceCode sourceCode : sourceClass.getChildren()) {
+ if (sourceCode instanceof SourceMethod) {
+ SourceMethod sourceMethod = (SourceMethod) sourceCode;
+ for (SquidVisitor visitor : squidVisitors) {
+ visitor.visitMethod(sourceMethod);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+package org.sonar.java.squid.check;
+
+import org.sonar.check.IsoCategory;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+import org.sonar.squid.api.CheckMessage;
+import org.sonar.squid.api.SourceClass;
+import org.sonar.squid.measures.Metric;
+
+@Rule(key = "ClassComplexityCheck", name = "ClassComplexityCheck", isoCategory = IsoCategory.Maintainability)
+public class ClassComplexityCheck extends SquidCheck {
+
+ @RuleProperty(description = "Threshold.")
+ private Integer threshold;
+
+ @Override
+ public void visitClass(SourceClass sourceClass) {
+ int complexity = sourceClass.getInt(Metric.COMPLEXITY);
+ if (complexity > threshold) {
+ CheckMessage message = new CheckMessage(this, "Class complexity exceeds " + threshold + ".");
+ message.setLine(sourceClass.getStartAtLine());
+ message.setCost(complexity - threshold);
+ getSourceFile(sourceClass).log(message);
+ }
+ }
+
+ public void setThreshold(int threshold) {
+ this.threshold = threshold;
+ }
+
+}
--- /dev/null
+package org.sonar.java.squid.check;
+
+import org.sonar.check.IsoCategory;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+import org.sonar.squid.api.CheckMessage;
+import org.sonar.squid.api.SourceClass;
+import org.sonar.squid.measures.Metric;
+
+@Rule(key = "MaximumInheritanceDepth", name = "Avoid too deep inheritance tree", isoCategory = IsoCategory.Maintainability,
+ priority = Priority.MAJOR, description = "<p>Inheritance is certainly one of the most valuable concept of object-oriented "
+ + "programming. It's a way to compartmentalize and reuse code by creating collections of attributes and behaviors called "
+ + "classes which can be based on previously created classes. But abusing of this concept by creating a deep inheritance tree "
+ + "can lead to very complex and unmaintainable source code.</p>"
+ + "<p>Most of the time a too deep inheritance tree is due to bad object oriented design which has led to systematically use "
+ + "'inheritance' when 'composition' would suit better.</p>")
+public class DITCheck extends SquidCheck {
+
+ @RuleProperty(description = "Maximum depth of the inheritance tree.", defaultValue = "5")
+ private Integer max;
+
+ @Override
+ public void visitClass(SourceClass sourceClass) {
+ int dit = sourceClass.getInt(Metric.DIT);
+ if (dit > max) {
+ CheckMessage message = new CheckMessage(this, "This class has " + dit
+ + " parents which makes it complex to understand and to maintain.");
+ message.setLine(sourceClass.getStartAtLine());
+ message.setCost(dit - max);
+ getSourceFile(sourceClass).log(message);
+ }
+ }
+
+ public void setMax(int max) {
+ this.max = max;
+ }
+}
--- /dev/null
+package org.sonar.java.squid.check;
+
+import org.sonar.check.IsoCategory;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+import org.sonar.squid.api.CheckMessage;
+import org.sonar.squid.api.SourceMethod;
+import org.sonar.squid.measures.Metric;
+
+@Rule(key = "MethodComplexityCheck", name = "MethodComplexityCheck", isoCategory = IsoCategory.Maintainability)
+public class MethodComplexityCheck extends SquidCheck {
+
+ @RuleProperty(description = "Threshold.")
+ private Integer threshold;
+
+ @Override
+ public void visitMethod(SourceMethod sourceMethod) {
+ int complexity = sourceMethod.getInt(Metric.COMPLEXITY);
+ if (complexity > threshold) {
+ CheckMessage message = new CheckMessage(this, "Method complexity exceeds " + threshold + ".");
+ message.setLine(sourceMethod.getStartAtLine());
+ message.setCost(complexity - threshold);
+ getSourceFile(sourceMethod).log(message);
+ }
+ }
+
+ public void setThreshold(int threshold) {
+ this.threshold = threshold;
+ }
+
+}
--- /dev/null
+package org.sonar.java.squid.check;
+
+import org.sonar.java.squid.visitor.SquidVisitor;
+import org.sonar.squid.api.CodeCheck;
+
+public class SquidCheck extends SquidVisitor implements CodeCheck {
+
+ public String getKey() {
+ return getClass().getSimpleName();
+ }
+
+}
--- /dev/null
+package org.sonar.java.squid.visitor;
+
+import org.sonar.squid.api.CodeVisitor;
+import org.sonar.squid.api.SourceClass;
+import org.sonar.squid.api.SourceCode;
+import org.sonar.squid.api.SourceFile;
+import org.sonar.squid.api.SourceMethod;
+import org.sonar.squid.indexer.SquidIndex;
+
+public class SquidVisitor implements CodeVisitor {
+
+ SquidIndex index;
+
+ public void visitClass(SourceClass sourceClass) {
+ }
+
+ public void visitMethod(SourceMethod sourceMethod) {
+ }
+
+ protected final SourceFile getSourceFile(SourceCode sourceCode) {
+ return sourceCode.getParent(SourceFile.class);
+ }
+
+ public void setSquidIndex(SquidIndex index) {
+ this.index = index;
+ }
+
+}
*/
package org.sonar.plugins.squid;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.Collection;
+import java.util.List;
+
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.checks.CheckFactory;
import org.sonar.java.ast.JavaAstScanner;
import org.sonar.java.bytecode.BytecodeScanner;
import org.sonar.java.squid.JavaSquidConfiguration;
+import org.sonar.java.squid.SquidScanner;
import org.sonar.plugins.squid.bridges.Bridge;
import org.sonar.plugins.squid.bridges.BridgeFactory;
import org.sonar.plugins.squid.bridges.ResourceIndex;
import org.sonar.squid.indexer.QueryByType;
import org.sonar.squid.measures.Metric;
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.Collection;
-import java.util.List;
-
public final class SquidExecutor {
private Squid squid;
private boolean bytecodeScanned = false;
private CheckFactory checkFactory;
- public SquidExecutor(boolean analyzePropertyAccessors, String fieldNamesToExcludeFromLcom4Computation, CheckFactory checkFactory, Charset sourcesCharset) {
+ public SquidExecutor(boolean analyzePropertyAccessors, String fieldNamesToExcludeFromLcom4Computation, CheckFactory checkFactory,
+ Charset sourcesCharset) {
JavaSquidConfiguration conf = createJavaSquidConfiguration(analyzePropertyAccessors, fieldNamesToExcludeFromLcom4Computation,
sourcesCharset);
squid = new Squid(conf);
scanBytecode(bytecodeFilesOrDirectories);
}
squid.decorateSourceCodeTreeWith(Metric.values());
+ scanSquidIndex();
}
public void save(Project project, SensorContext context, NoSonarFilter noSonarFilter) {
}
}
+ void scanSquidIndex() {
+ TimeProfiler profiler = new TimeProfiler(getClass()).start("Java Squid scan");
+ SquidScanner squidScanner = squid.register(SquidScanner.class);
+ squidScanner.scan();
+ profiler.stop();
+ }
+
boolean isSourceScanned() {
return sourceScanned;
}
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleRepository;
import org.sonar.java.ast.check.BreakCheck;
-import org.sonar.java.ast.check.ClassComplexityCheck;
import org.sonar.java.ast.check.ContinueCheck;
-import org.sonar.java.ast.check.MethodComplexityCheck;
import org.sonar.java.ast.check.UndocumentedApiCheck;
import org.sonar.java.bytecode.check.ArchitectureCheck;
import org.sonar.java.bytecode.check.CallToDeprecatedMethodCheck;
-import org.sonar.java.bytecode.check.DITCheck;
import org.sonar.java.bytecode.check.UnusedPrivateMethodCheck;
import org.sonar.java.bytecode.check.UnusedProtectedMethodCheck;
+import org.sonar.java.squid.check.ClassComplexityCheck;
+import org.sonar.java.squid.check.DITCheck;
+import org.sonar.java.squid.check.MethodComplexityCheck;
public final class SquidRuleRepository extends RuleRepository {
private AnnotationRuleParser ruleParser;
return Arrays.asList(
// Bytecode checks
(Class) CallToDeprecatedMethodCheck.class, UnusedPrivateMethodCheck.class, UnusedProtectedMethodCheck.class,
- ArchitectureCheck.class, DITCheck.class,
+ ArchitectureCheck.class,
// AST checks
- UndocumentedApiCheck.class, ContinueCheck.class, BreakCheck.class, ClassComplexityCheck.class, MethodComplexityCheck.class);
+ UndocumentedApiCheck.class, ContinueCheck.class, BreakCheck.class, ClassComplexityCheck.class, MethodComplexityCheck.class,
+ // Squid checks
+ DITCheck.class);
}
}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2009 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-
-package org.sonar.java.ast.check;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.sonar.java.ast.SquidTestUtils.getFile;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.java.ast.JavaAstScanner;
-import org.sonar.java.squid.JavaSquidConfiguration;
-import org.sonar.squid.Squid;
-import org.sonar.squid.api.CheckMessage;
-import org.sonar.squid.api.SourceFile;
-
-public class ClassComplexityCheckTest {
-
- private Squid squid;
-
- @Before
- public void setUp() {
- squid = new Squid(new JavaSquidConfiguration());
- ClassComplexityCheck check = new ClassComplexityCheck();
- check.setThreshold(5);
- squid.registerVisitor(check);
- JavaAstScanner scanner = squid.register(JavaAstScanner.class);
- scanner.scanFile(getFile("/metrics/branches/NoBranches.java"));
- scanner.scanFile(getFile("/metrics/branches/ComplexBranches.java"));
- }
-
- @Test
- public void testComplexityExceedsThreshold() {
- SourceFile file = (SourceFile) squid.search("ComplexBranches.java");
- assertThat(file.getCheckMessages().size(), is(1));
- CheckMessage message = file.getCheckMessages().iterator().next();
- assertThat(message.getLine(), is(3));
- }
-
- @Test
- public void testComplexityNotExceedsThreshold() {
- SourceFile file = (SourceFile) squid.search("NoBranches.java");
- assertThat(file.getCheckMessages().size(), is(0));
- }
-
-}
+++ /dev/null
-package org.sonar.java.ast.check;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.sonar.java.ast.SquidTestUtils.getFile;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.java.ast.JavaAstScanner;
-import org.sonar.java.squid.JavaSquidConfiguration;
-import org.sonar.squid.Squid;
-import org.sonar.squid.api.CheckMessage;
-import org.sonar.squid.api.SourceFile;
-
-public class MethodComplexityCheckTest {
- private Squid squid;
-
- @Before
- public void setUp() {
- squid = new Squid(new JavaSquidConfiguration());
- MethodComplexityCheck check = new MethodComplexityCheck();
- check.setThreshold(5);
- squid.registerVisitor(check);
- JavaAstScanner scanner = squid.register(JavaAstScanner.class);
- scanner.scanFile(getFile("/metrics/branches/ComplexBranches.java"));
- }
-
- @Test
- public void testMethodComplexityExceedsThreshold() {
- SourceFile file = (SourceFile) squid.search("ComplexBranches.java");
- assertThat(file.getCheckMessages().size(), is(1));
- CheckMessage message = file.getCheckMessages().iterator().next();
- assertThat(message.getLine(), is(10));
- }
-}
+++ /dev/null
-package org.sonar.java.bytecode.check;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.sonar.java.ast.SquidTestUtils.getFile;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.sonar.java.ast.JavaAstScanner;
-import org.sonar.java.bytecode.BytecodeScanner;
-import org.sonar.java.squid.JavaSquidConfiguration;
-import org.sonar.squid.Squid;
-import org.sonar.squid.api.CheckMessage;
-import org.sonar.squid.api.SourceFile;
-
-public class DITCheckTest {
-
- private static Squid squid;
-
- @BeforeClass
- public static void setup() {
- squid = new Squid(new JavaSquidConfiguration());
- squid.register(JavaAstScanner.class).scanDirectory(getFile("/bytecode/unusedProtectedMethod/src"));
- DITCheck check = new DITCheck();
- check.setMax(1);
- squid.registerVisitor(check);
- squid.register(BytecodeScanner.class).scanDirectory(getFile("/bytecode/unusedProtectedMethod/bin"));
- }
-
- @Test
- public void testDepthOfInheritanceGreaterThanMaximum() {
- SourceFile file = (SourceFile) squid.search("UnusedProtectedMethod.java");
- assertThat(file.getCheckMessages().size(), is(1));
- CheckMessage message = file.getCheckMessages().iterator().next();
- assertThat(message.getLine(), is(7));
- }
-
- @Test
- public void testDepthOfInheritanceLowerThanMaximum() {
- SourceFile file = (SourceFile) squid.search("Job.java");
- assertThat(file.getCheckMessages().size(), is(0));
- }
-
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+package org.sonar.java.squid.check;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.sonar.java.ast.SquidTestUtils.getFile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.java.ast.JavaAstScanner;
+import org.sonar.java.squid.JavaSquidConfiguration;
+import org.sonar.java.squid.SquidScanner;
+import org.sonar.squid.Squid;
+import org.sonar.squid.api.CheckMessage;
+import org.sonar.squid.api.SourceFile;
+import org.sonar.squid.measures.Metric;
+
+public class ClassComplexityCheckTest {
+
+ private Squid squid;
+
+ @Before
+ public void setUp() {
+ squid = new Squid(new JavaSquidConfiguration());
+ ClassComplexityCheck check = new ClassComplexityCheck();
+ check.setThreshold(5);
+ squid.registerVisitor(check);
+ JavaAstScanner scanner = squid.register(JavaAstScanner.class);
+ scanner.scanFile(getFile("/metrics/branches/NoBranches.java"));
+ scanner.scanFile(getFile("/metrics/branches/ComplexBranches.java"));
+ squid.decorateSourceCodeTreeWith(Metric.values());
+ squid.register(SquidScanner.class).scan();
+ }
+
+ @Test
+ public void testComplexityExceedsThreshold() {
+ SourceFile file = (SourceFile) squid.search("ComplexBranches.java");
+ assertThat(file.getCheckMessages().size(), is(1));
+ CheckMessage message = file.getCheckMessages().iterator().next();
+ assertThat(message.getLine(), is(3));
+ }
+
+ @Test
+ public void testComplexityNotExceedsThreshold() {
+ SourceFile file = (SourceFile) squid.search("NoBranches.java");
+ assertThat(file.getCheckMessages().size(), is(0));
+ }
+
+}
--- /dev/null
+package org.sonar.java.squid.check;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.sonar.java.ast.SquidTestUtils.getFile;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.sonar.java.ast.JavaAstScanner;
+import org.sonar.java.bytecode.BytecodeScanner;
+import org.sonar.java.squid.JavaSquidConfiguration;
+import org.sonar.java.squid.SquidScanner;
+import org.sonar.squid.Squid;
+import org.sonar.squid.api.CheckMessage;
+import org.sonar.squid.api.SourceFile;
+
+public class DITCheckTest {
+
+ private static Squid squid;
+
+ @BeforeClass
+ public static void setup() {
+ squid = new Squid(new JavaSquidConfiguration());
+ DITCheck check = new DITCheck();
+ check.setMax(1);
+ squid.registerVisitor(check);
+ squid.register(JavaAstScanner.class).scanDirectory(getFile("/bytecode/unusedProtectedMethod/src"));
+ squid.register(BytecodeScanner.class).scanDirectory(getFile("/bytecode/unusedProtectedMethod/bin"));
+ squid.register(SquidScanner.class).scan();
+ }
+
+ @Test
+ public void testDepthOfInheritanceGreaterThanMaximum() {
+ SourceFile file = (SourceFile) squid.search("UnusedProtectedMethod.java");
+ assertThat(file.getCheckMessages().size(), is(1));
+ CheckMessage message = file.getCheckMessages().iterator().next();
+ assertThat(message.getLine(), is(7));
+ }
+
+ @Test
+ public void testDepthOfInheritanceLowerThanMaximum() {
+ SourceFile file = (SourceFile) squid.search("Job.java");
+ assertThat(file.getCheckMessages().size(), is(0));
+ }
+
+}
--- /dev/null
+package org.sonar.java.squid.check;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.sonar.java.ast.SquidTestUtils.getFile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.java.ast.JavaAstScanner;
+import org.sonar.java.squid.JavaSquidConfiguration;
+import org.sonar.java.squid.SquidScanner;
+import org.sonar.squid.Squid;
+import org.sonar.squid.api.CheckMessage;
+import org.sonar.squid.api.SourceFile;
+import org.sonar.squid.measures.Metric;
+
+public class MethodComplexityCheckTest {
+ private Squid squid;
+
+ @Before
+ public void setUp() {
+ squid = new Squid(new JavaSquidConfiguration());
+ MethodComplexityCheck check = new MethodComplexityCheck();
+ check.setThreshold(5);
+ squid.registerVisitor(check);
+ JavaAstScanner scanner = squid.register(JavaAstScanner.class);
+ scanner.scanFile(getFile("/metrics/branches/ComplexBranches.java"));
+ squid.decorateSourceCodeTreeWith(Metric.values());
+ squid.register(SquidScanner.class).scan();
+ }
+
+ @Test
+ public void testMethodComplexityExceedsThreshold() {
+ SourceFile file = (SourceFile) squid.search("ComplexBranches.java");
+ assertThat(file.getCheckMessages().size(), is(1));
+ CheckMessage message = file.getCheckMessages().iterator().next();
+ assertThat(message.getLine(), is(10));
+ }
+}