]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5389 Add medium tests
authorJulien HENRY <julien.henry@sonarsource.com>
Thu, 19 Jun 2014 15:10:01 +0000 (17:10 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Thu, 19 Jun 2014 15:12:09 +0000 (17:12 +0200)
29 files changed:
sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java
sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerIssueCache.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultAnalyzerContext.java
sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/AnalyzerMediumTester.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/XooMediumTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/base/Xoo.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/base/XooConstants.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureAnalyzer.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/rule/OneIssuePerLineAnalyzer.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/scan2/AnalyzerOptimizerTest.java
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/sonar-project.properties [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo.measures [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo.scm [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.scm [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/helloscala.xoo [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssueBuilder.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasure.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilder.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewActiveRule.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java

index 49f762ef811d129fce5b928b1d2c746df52b9068..ca90e38d01c4a1298f4cc31a3be5b0a1ce3fc6f0 100644 (file)
  */
 package org.sonar.batch.rule;
 
-import org.sonar.api.batch.rules.QProfile;
-
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ListMultimap;
 import org.picocontainer.injectors.ProviderAdapter;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.rule.internal.NewActiveRule;
+import org.sonar.api.batch.rules.QProfile;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleFinder;
 import org.sonar.api.rules.RuleParam;
@@ -62,7 +61,7 @@ public class ActiveRulesProvider extends ProviderAdapter {
       for (ActiveRuleDto activeDto : dao.selectByProfileId(qProfileWithId.id())) {
         Rule rule = ruleFinder.findById(activeDto.getRulId());
         if (rule != null) {
-          NewActiveRule newActiveRule = builder.activate(rule.ruleKey());
+          NewActiveRule newActiveRule = builder.create(rule.ruleKey());
           newActiveRule.setSeverity(activeDto.getSeverityString());
           newActiveRule.setLanguage(rule.getLanguage());
           Rule template = rule.getTemplate();
@@ -83,6 +82,7 @@ public class ActiveRulesProvider extends ProviderAdapter {
               newActiveRule.setParam(param.getKey(), param.getDefaultValue());
             }
           }
+          newActiveRule.activate();
         }
       }
     }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerIssueCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerIssueCache.java
new file mode 100644 (file)
index 0000000..613507d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.scan2;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.analyzer.issue.internal.DefaultAnalyzerIssue;
+import org.sonar.batch.index.Cache;
+import org.sonar.batch.index.Caches;
+
+/**
+ * Shared issues among all project modules
+ */
+public class AnalyzerIssueCache implements BatchComponent {
+
+  // component key -> issue key -> issue
+  private final Cache<DefaultAnalyzerIssue> cache;
+
+  public AnalyzerIssueCache(Caches caches) {
+    cache = caches.createCache("issues");
+  }
+
+  public Iterable<DefaultAnalyzerIssue> byComponent(String resourceKey) {
+    return cache.values(resourceKey);
+  }
+
+  public Iterable<DefaultAnalyzerIssue> all() {
+    return cache.values();
+  }
+
+  public AnalyzerIssueCache put(String resourceKey, DefaultAnalyzerIssue issue) {
+    cache.put(resourceKey, issue.key(), issue);
+    return this;
+  }
+
+}
index 1ec141ada84e4a41f636fcbab4f7b9f60f12f809..d9f03c17e50604a7605bb2d06a0eb0a93497f1bb 100644 (file)
  */
 package org.sonar.batch.scan2;
 
-import org.sonar.api.batch.measure.Metric;
-
 import org.sonar.api.batch.analyzer.AnalyzerContext;
 import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
 import org.sonar.api.batch.analyzer.issue.AnalyzerIssueBuilder;
+import org.sonar.api.batch.analyzer.issue.internal.DefaultAnalyzerIssue;
 import org.sonar.api.batch.analyzer.issue.internal.DefaultAnalyzerIssueBuilder;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasureBuilder;
@@ -32,30 +31,27 @@ import org.sonar.api.batch.analyzer.measure.internal.DefaultAnalyzerMeasureBuild
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.measure.Metric;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.batch.issue.ModuleIssues;
 import org.sonar.core.component.ComponentKeys;
-import org.sonar.core.issue.DefaultIssueBuilder;
 
 import java.io.Serializable;
 
 public class DefaultAnalyzerContext implements AnalyzerContext {
 
   private final AnalyzerMeasureCache measureCache;
+  private final AnalyzerIssueCache issueCache;
   private ProjectDefinition def;
-  private ModuleIssues moduleIssues;
   private Settings settings;
   private FileSystem fs;
   private ActiveRules activeRules;
 
-  public DefaultAnalyzerContext(ProjectDefinition def, AnalyzerMeasureCache measureCache,
-    ModuleIssues moduleIssues, Settings settings, FileSystem fs, ActiveRules activeRules) {
+  public DefaultAnalyzerContext(ProjectDefinition def, AnalyzerMeasureCache measureCache, AnalyzerIssueCache issueCache,
+    Settings settings, FileSystem fs, ActiveRules activeRules) {
     this.def = def;
     this.measureCache = measureCache;
-    this.moduleIssues = moduleIssues;
+    this.issueCache = issueCache;
     this.settings = settings;
     this.fs = fs;
     this.activeRules = activeRules;
@@ -117,20 +113,14 @@ public class DefaultAnalyzerContext implements AnalyzerContext {
 
   @Override
   public void addIssue(AnalyzerIssue issue) {
-    DefaultIssueBuilder builder = new DefaultIssueBuilder()
-      .projectKey(def.getKey());
+    String resourceKey;
     if (issue.inputFile() != null) {
-      builder.componentKey(ComponentKeys.createEffectiveKey(def.getKey(), issue.inputFile()));
+      resourceKey = ComponentKeys.createEffectiveKey(def.getKey(), issue.inputFile());
     } else {
-      builder.componentKey(def.getKey());
+      resourceKey = def.getKey();
     }
 
-    moduleIssues.initAndAddIssue((DefaultIssue) builder
-      .ruleKey(RuleKey.of(issue.ruleKey().repository(), issue.ruleKey().rule()))
-      .message(issue.message())
-      .line(issue.line())
-      .effortToFix(issue.effortToFix())
-      .build());
+    issueCache.put(resourceKey, (DefaultAnalyzerIssue) issue);
   }
 
 }
index f5dd041678eb9b8cf2d0d110fc8190db4614978d..8dad42fd7e6c7546eefe044ea90cba524c7cf35e 100644 (file)
@@ -29,38 +29,15 @@ import org.sonar.api.batch.bootstrap.ProjectReactor;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.utils.SonarException;
 import org.sonar.batch.bootstrap.ExtensionInstaller;
 import org.sonar.batch.bootstrap.ExtensionMatcher;
 import org.sonar.batch.bootstrap.ExtensionUtils;
-import org.sonar.batch.debt.IssueChangelogDebtCalculator;
 import org.sonar.batch.index.Caches;
-import org.sonar.batch.index.ComponentDataCache;
-import org.sonar.batch.index.ComponentDataPersister;
-import org.sonar.batch.index.ResourceCache;
-import org.sonar.batch.index.SnapshotCache;
-import org.sonar.batch.issue.DefaultProjectIssues;
-import org.sonar.batch.issue.DeprecatedViolations;
-import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.issue.IssuePersister;
-import org.sonar.batch.issue.ScanIssueStorage;
-import org.sonar.batch.phases.GraphPersister;
 import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
 import org.sonar.batch.scan.ProjectReactorBuilder;
 import org.sonar.batch.scan.filesystem.InputFileCache;
 import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
 import org.sonar.batch.scan.maven.MavenPluginExecutor;
-import org.sonar.batch.source.HighlightableBuilder;
-import org.sonar.batch.source.SymbolizableBuilder;
-import org.sonar.core.component.ScanGraph;
-import org.sonar.core.issue.IssueNotifications;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.workflow.FunctionExecutor;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-import org.sonar.core.test.TestPlanBuilder;
-import org.sonar.core.test.TestPlanPerspectiveLoader;
-import org.sonar.core.test.TestableBuilder;
-import org.sonar.core.test.TestablePerspectiveLoader;
 
 public class ProjectScanContainer extends ComponentContainer {
   public ProjectScanContainer(ComponentContainer taskContainer) {
@@ -93,7 +70,7 @@ public class ProjectScanContainer extends ComponentContainer {
       reactor = bootstrapper.bootstrap();
     }
     if (reactor == null) {
-      throw new SonarException(bootstrapper + " has returned null as ProjectReactor");
+      throw new IllegalStateException(bootstrapper + " has returned null as ProjectReactor");
     }
     add(reactor);
   }
@@ -101,10 +78,8 @@ public class ProjectScanContainer extends ComponentContainer {
   private void addBatchComponents() {
     add(
       Caches.class,
-      SnapshotCache.class,
-      ResourceCache.class,
-      ComponentDataCache.class,
-      ComponentDataPersister.class,
+
+      // Measures
       AnalyzerMeasureCache.class,
 
       // file system
@@ -112,28 +87,7 @@ public class ProjectScanContainer extends ComponentContainer {
       PathResolver.class,
 
       // issues
-      IssueUpdater.class,
-      FunctionExecutor.class,
-      IssueWorkflow.class,
-      DeprecatedViolations.class,
-      IssueCache.class,
-      ScanIssueStorage.class,
-      IssuePersister.class,
-      IssueNotifications.class,
-      DefaultProjectIssues.class,
-      IssueChangelogDebtCalculator.class,
-
-      // tests
-      TestPlanPerspectiveLoader.class,
-      TestablePerspectiveLoader.class,
-      TestPlanBuilder.class,
-      TestableBuilder.class,
-      ScanGraph.create(),
-      GraphPersister.class,
-
-      // lang
-      HighlightableBuilder.class,
-      SymbolizableBuilder.class,
+      AnalyzerIssueCache.class,
 
       ScanTaskObservers.class);
   }
index bacfe55be16fb3f0945700cf93f467cd403df25a..ef507f38001a98a0b0b1f8c9848b0f57d60a4c45 100644 (file)
@@ -47,7 +47,9 @@ import static org.fest.assertions.Assertions.assertThat;
 import static org.fest.assertions.Fail.fail;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ModuleIssuesTest {
@@ -122,7 +124,7 @@ public class ModuleIssuesTest {
   @Test
   public void ignore_null_rule_of_active_rule() throws Exception {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
-    activeRulesBuilder.activate(SQUID_RULE_KEY);
+    activeRulesBuilder.create(SQUID_RULE_KEY).activate();
     initModuleIssues();
 
     DefaultIssue issue = new DefaultIssue().setRuleKey(SQUID_RULE_KEY);
@@ -135,7 +137,7 @@ public class ModuleIssuesTest {
   @Test
   public void add_issue_to_cache() throws Exception {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     Date analysisDate = new Date();
@@ -159,7 +161,7 @@ public class ModuleIssuesTest {
   @Test
   public void use_severity_from_active_rule_if_no_severity_on_issue() throws Exception {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     Date analysisDate = new Date();
@@ -178,7 +180,7 @@ public class ModuleIssuesTest {
   @Test
   public void use_rule_name_if_no_message() throws Exception {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     Date analysisDate = new Date();
@@ -202,7 +204,7 @@ public class ModuleIssuesTest {
   @Test
   public void add_deprecated_violation() throws Exception {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     org.sonar.api.rules.Rule rule = org.sonar.api.rules.Rule.create("squid", "AvoidCycle", "Avoid Cycle");
@@ -232,7 +234,7 @@ public class ModuleIssuesTest {
   @Test
   public void filter_issue() throws Exception {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     DefaultIssue issue = new DefaultIssue()
@@ -254,7 +256,7 @@ public class ModuleIssuesTest {
       .setName(SQUID_RULE_NAME)
       .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
       .setDebtRemediationFunction(DebtRemediationFunction.createLinear(Duration.create(10L)));
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     Date analysisDate = new Date();
@@ -280,7 +282,7 @@ public class ModuleIssuesTest {
       .setName(SQUID_RULE_NAME)
       .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
       .setDebtRemediationFunction(DebtRemediationFunction.createLinearWithOffset(Duration.create(10L), Duration.create(25L)));
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     Date analysisDate = new Date();
@@ -306,7 +308,7 @@ public class ModuleIssuesTest {
       .setName(SQUID_RULE_NAME)
       .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
       .setDebtRemediationFunction(DebtRemediationFunction.createConstantPerIssue(Duration.create(10L)));
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     Date analysisDate = new Date();
@@ -332,7 +334,7 @@ public class ModuleIssuesTest {
       .setName(SQUID_RULE_NAME)
       .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
       .setDebtRemediationFunction(DebtRemediationFunction.createConstantPerIssue(Duration.create(25L)));
-    activeRulesBuilder.activate(SQUID_RULE_KEY).setSeverity(Severity.INFO);
+    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
     initModuleIssues();
 
     DefaultIssue issue = new DefaultIssue()
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/AnalyzerMediumTester.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/AnalyzerMediumTester.java
new file mode 100644 (file)
index 0000000..c8dc898
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.io.IOUtils;
+import org.junit.rules.ExternalResource;
+import org.sonar.api.SonarPlugin;
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
+import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
+import org.sonar.api.batch.debt.internal.DefaultDebtModel;
+import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
+import org.sonar.api.batch.rule.internal.RulesBuilder;
+import org.sonar.api.batch.rules.QProfile;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.platform.PluginMetadata;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.rules.RuleQuery;
+import org.sonar.batch.bootstrap.PluginsReferential;
+import org.sonar.batch.bootstrapper.Batch;
+import org.sonar.batch.bootstrapper.EnvironmentInformation;
+import org.sonar.batch.languages.Language;
+import org.sonar.batch.languages.LanguagesReferential;
+import org.sonar.batch.rules.QProfilesReferential;
+import org.sonar.batch.scan2.AnalyzerIssueCache;
+import org.sonar.batch.scan2.AnalyzerMeasureCache;
+import org.sonar.batch.scan2.ProjectScanContainer;
+import org.sonar.batch.scan2.ScanTaskObserver;
+import org.sonar.batch.settings.SettingsReferential;
+import org.sonar.core.plugins.DefaultPluginMetadata;
+import org.sonar.core.plugins.RemotePlugin;
+
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+public class AnalyzerMediumTester extends ExternalResource {
+
+  private Batch batch;
+
+  public static AnalyzerMediumTesterBuilder builder() {
+    return new AnalyzerMediumTesterBuilder().registerCoreMetrics();
+  }
+
+  public static class AnalyzerMediumTesterBuilder {
+    private final FakeSettingsReferential settingsReferential = new FakeSettingsReferential();
+    private final FackPluginsReferential pluginsReferential = new FackPluginsReferential();
+    private final FakeMetricFinder metricFinder = new FakeMetricFinder();
+    private final FakeRuleFinder ruleFinder = new FakeRuleFinder();
+    private final FakeQProfileReferential qProfileReferential = new FakeQProfileReferential();
+    private final FakeLanguageReferential languageReferential = new FakeLanguageReferential();
+    private final Map<String, String> bootstrapProperties = new HashMap<String, String>();
+    private final RulesBuilder rulesBuilder = new RulesBuilder();
+    private final ActiveRulesBuilder activeRulesBuilder = new ActiveRulesBuilder();
+    private int metricId = 1;
+
+    public AnalyzerMediumTester build() {
+      return new AnalyzerMediumTester(this);
+    }
+
+    public AnalyzerMediumTesterBuilder registerPlugin(String pluginKey, File location) {
+      pluginsReferential.addPlugin(pluginKey, location);
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder registerPlugin(String pluginKey, SonarPlugin instance) {
+      pluginsReferential.addPlugin(pluginKey, instance);
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder registerCoreMetrics() {
+      for (Metric<?> m : CoreMetrics.getMetrics()) {
+        registerMetric(m);
+      }
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder registerMetric(Metric<?> metric) {
+      metricFinder.add(metricId++, metric);
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder addQProfile(String language, String name) {
+      qProfileReferential.add(new QProfile(name, language, 1));
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder addDefaultQProfile(String language, String name) {
+      qProfileReferential.add(new QProfile(name, language, 1));
+      settingsReferential.globalSettings().put("sonar.profile." + language, name);
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder registerLanguage(org.sonar.api.resources.Language... languages) {
+      languageReferential.register(languages);
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder bootstrapProperties(Map<String, String> props) {
+      bootstrapProperties.putAll(props);
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder activateRule(RuleKey key) {
+      rulesBuilder.add(key);
+      activeRulesBuilder.create(key).activate();
+      return this;
+    }
+
+    public AnalyzerMediumTesterBuilder registerInactiveRule(RuleKey key) {
+      rulesBuilder.add(key);
+      return this;
+    }
+
+  }
+
+  @Override
+  protected void before() throws Throwable {
+    batch.start();
+  }
+
+  @Override
+  protected void after() {
+    batch.stop();
+  }
+
+  private AnalyzerMediumTester(AnalyzerMediumTesterBuilder builder) {
+    batch = Batch.builder()
+      .setEnableLoggingConfiguration(true)
+      .addComponents(
+        new EnvironmentInformation("mediumTest", "1.0"),
+        builder.settingsReferential,
+        builder.pluginsReferential,
+        builder.metricFinder,
+        builder.ruleFinder,
+        builder.qProfileReferential,
+        builder.rulesBuilder.build(),
+        builder.activeRulesBuilder.build(),
+        new DefaultDebtModel(),
+        builder.languageReferential)
+      .setBootstrapProperties(builder.bootstrapProperties)
+      .build();
+  }
+
+  public TaskBuilder newTask() {
+    return new TaskBuilder(this);
+  }
+
+  public TaskBuilder newScanTask(File sonarProps) {
+    Properties prop = new Properties();
+    FileReader reader = null;
+    try {
+      reader = new FileReader(sonarProps);
+      prop.load(reader);
+    } catch (Exception e) {
+      throw new IllegalStateException("Unable to read configuration file", e);
+    } finally {
+      if (reader != null) {
+        IOUtils.closeQuietly(reader);
+      }
+    }
+    TaskBuilder builder = new TaskBuilder(this);
+    builder.property("sonar.task", "scan");
+    builder.property("sonar.projectBaseDir", sonarProps.getParentFile().getAbsolutePath());
+    for (Map.Entry entry : prop.entrySet()) {
+      builder.property(entry.getKey().toString(), entry.getValue().toString());
+    }
+    return builder;
+  }
+
+  public static class TaskBuilder {
+    private final Map<String, String> taskProperties = new HashMap<String, String>();
+    private AnalyzerMediumTester tester;
+
+    public TaskBuilder(AnalyzerMediumTester tester) {
+      this.tester = tester;
+    }
+
+    public TaskResult start() {
+      TaskResult result = new TaskResult();
+      tester.batch.executeTask(taskProperties,
+        result
+        );
+      return result;
+    }
+
+    public TaskBuilder properties(Map<String, String> props) {
+      taskProperties.putAll(props);
+      return this;
+    }
+
+    public TaskBuilder property(String key, String value) {
+      taskProperties.put(key, value);
+      return this;
+    }
+  }
+
+  public static class TaskResult implements ScanTaskObserver {
+    private List<AnalyzerIssue> issues = new ArrayList<AnalyzerIssue>();
+    private List<AnalyzerMeasure> measures = new ArrayList<AnalyzerMeasure>();
+
+    @Override
+    public void scanTaskCompleted(ProjectScanContainer container) {
+      for (AnalyzerIssue issue : container.getComponentByType(AnalyzerIssueCache.class).all()) {
+        issues.add(issue);
+      }
+
+      for (AnalyzerMeasure<?> measure : container.getComponentByType(AnalyzerMeasureCache.class).all()) {
+        measures.add(measure);
+      }
+    }
+
+    public List<AnalyzerIssue> issues() {
+      return issues;
+    }
+
+    public List<AnalyzerMeasure> measures() {
+      return measures;
+    }
+
+  }
+
+  private static class FakeSettingsReferential implements SettingsReferential {
+
+    private Map<String, String> globalSettings = new HashMap<String, String>();
+    private Map<String, Map<String, String>> projectSettings = new HashMap<String, Map<String, String>>();
+
+    @Override
+    public Map<String, String> globalSettings() {
+      return globalSettings;
+    }
+
+    @Override
+    public Map<String, String> projectSettings(String projectKey) {
+      return projectSettings.containsKey(projectKey) ? projectSettings.get(projectKey) : Collections.<String, String>emptyMap();
+    }
+
+  }
+
+  private static class FackPluginsReferential implements PluginsReferential {
+
+    private List<RemotePlugin> pluginList = new ArrayList<RemotePlugin>();
+    private Map<RemotePlugin, File> pluginFiles = new HashMap<RemotePlugin, File>();
+    Map<PluginMetadata, SonarPlugin> localPlugins = new HashMap<PluginMetadata, SonarPlugin>();
+
+    @Override
+    public List<RemotePlugin> pluginList() {
+      return pluginList;
+    }
+
+    @Override
+    public File pluginFile(RemotePlugin remote) {
+      return pluginFiles.get(remote);
+    }
+
+    public FackPluginsReferential addPlugin(String pluginKey, File location) {
+      RemotePlugin plugin = new RemotePlugin(pluginKey, false);
+      pluginList.add(plugin);
+      pluginFiles.put(plugin, location);
+      return this;
+    }
+
+    public FackPluginsReferential addPlugin(String pluginKey, SonarPlugin pluginInstance) {
+      localPlugins.put(DefaultPluginMetadata.create(null).setKey(pluginKey), pluginInstance);
+      return this;
+    }
+
+    @Override
+    public Map<PluginMetadata, SonarPlugin> localPlugins() {
+      return localPlugins;
+    }
+
+  }
+
+  private static class FakeMetricFinder implements MetricFinder {
+
+    private Map<String, Metric> metricsByKey = Maps.newLinkedHashMap();
+    private Map<Integer, Metric> metricsById = Maps.newLinkedHashMap();
+
+    public FakeMetricFinder add(int id, Metric metric) {
+      metricsByKey.put(metric.getKey(), metric);
+      metricsById.put(id, metric);
+      return this;
+    }
+
+    @Override
+    public Metric findById(int metricId) {
+      return metricsById.get(metricId);
+    }
+
+    @Override
+    public Metric findByKey(String key) {
+      return metricsByKey.get(key);
+    }
+
+    @Override
+    public Collection<Metric> findAll(List<String> metricKeys) {
+      List<Metric> result = Lists.newLinkedList();
+      for (String metricKey : metricKeys) {
+        Metric metric = findByKey(metricKey);
+        if (metric != null) {
+          result.add(metric);
+        }
+      }
+      return result;
+    }
+
+    @Override
+    public Collection<Metric> findAll() {
+      return metricsByKey.values();
+    }
+
+  }
+
+  private static class FakeRuleFinder implements RuleFinder {
+    private BiMap<Integer, Rule> rulesById = HashBiMap.create();
+    private Map<String, Map<String, Rule>> rulesByRepoKeyAndRuleKey = Maps.newHashMap();
+
+    @Override
+    public Rule findById(int ruleId) {
+      return rulesById.get(ruleId);
+    }
+
+    @Override
+    public Rule findByKey(String repositoryKey, String ruleKey) {
+      Map<String, Rule> repository = rulesByRepoKeyAndRuleKey.get(repositoryKey);
+      return repository != null ? repository.get(ruleKey) : null;
+    }
+
+    @Override
+    public Rule findByKey(RuleKey key) {
+      return findByKey(key.repository(), key.rule());
+    }
+
+    @Override
+    public Rule find(RuleQuery query) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Collection<Rule> findAll(RuleQuery query) {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  private static class FakeQProfileReferential implements QProfilesReferential {
+
+    private Map<String, Map<String, QProfile>> profiles = new HashMap<String, Map<String, QProfile>>();
+
+    @Override
+    public QProfile get(String language, String name) {
+      return profiles.get(language).get(name);
+    }
+
+    public void add(QProfile qprofile) {
+      if (!profiles.containsKey(qprofile.language())) {
+        profiles.put(qprofile.language(), new HashMap<String, QProfile>());
+      }
+      profiles.get(qprofile.language()).put(qprofile.name(), qprofile);
+    }
+
+  }
+
+  private static class FakeLanguageReferential implements LanguagesReferential {
+
+    private Map<String, Language> languages = new HashMap<String, Language>();
+
+    public FakeLanguageReferential register(org.sonar.api.resources.Language... languages) {
+      for (org.sonar.api.resources.Language language : languages) {
+        this.languages.put(language.getKey(), new Language(language.getKey(), language.getName(), language.getFileSuffixes()));
+      }
+      return this;
+    }
+
+    @Override
+    public Language get(String languageKey) {
+      return languages.get(languageKey);
+    }
+
+    @Override
+    public Collection<Language> all() {
+      return languages.values();
+    }
+
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/XooMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/XooMediumTest.java
new file mode 100644 (file)
index 0000000..73c2b56
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.xoo;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FileUtils;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
+import org.sonar.api.batch.analyzer.measure.internal.DefaultAnalyzerMeasureBuilder;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.batch.mediumtest.AnalyzerMediumTester;
+import org.sonar.batch.mediumtest.AnalyzerMediumTester.TaskResult;
+import org.sonar.batch.mediumtest.xoo.plugin.XooPlugin;
+import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class XooMediumTest {
+
+  @org.junit.Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @org.junit.Rule
+  public AnalyzerMediumTester tester = AnalyzerMediumTester.builder()
+    // .registerPlugin("xoo", new File("target/sonar-xoo-plugin-2.0-SNAPSHOT.jar"))
+    .registerPlugin("xoo", new XooPlugin())
+    .registerLanguage(new Xoo())
+    .addDefaultQProfile("xoo", "Sonar Way")
+    .activateRule(RuleKey.of("xoo", "OneIssuePerLine"))
+    .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor"))
+    .build();
+
+  @Test
+  public void mediumTestOfSample() throws Exception {
+    File projectDir = new File(XooMediumTest.class.getResource("/org/sonar/batch/mediumtest/xoo/sample").toURI());
+
+    TaskResult result = tester
+      .newScanTask(new File(projectDir, "sonar-project.properties"))
+      .start();
+
+    assertThat(result.measures()).hasSize(13);
+    assertThat(result.issues()).hasSize(24);
+  }
+
+  @Test
+  public void mediumTest() throws IOException {
+
+    File baseDir = temp.newFolder();
+    File srcDir = new File(baseDir, "src");
+    srcDir.mkdir();
+
+    File xooFile = new File(srcDir, "sample.xoo");
+    File xooMeasureFile = new File(srcDir, "sample.xoo.measures");
+    FileUtils.write(xooFile, "Sample xoo\ncontent");
+    FileUtils.write(xooMeasureFile, "lines:20");
+
+    TaskResult result = tester.newTask()
+      .properties(ImmutableMap.<String, String>builder()
+        .put("sonar.task", "scan")
+        .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+        .put("sonar.projectKey", "com.foo.project")
+        .put("sonar.projectName", "Foo Project")
+        .put("sonar.projectVersion", "1.0-SNAPSHOT")
+        .put("sonar.projectDescription", "Description of Foo Project")
+        .put("sonar.sources", "src")
+        .build())
+      .start();
+
+    assertThat(result.measures()).hasSize(1);
+    assertThat(result.issues()).hasSize(20);
+
+    assertThat(result.measures()).contains(new DefaultAnalyzerMeasureBuilder<Integer>()
+      .forMetric(CoreMetrics.LINES)
+      .onFile(new DefaultInputFile("src/sample.xoo"))
+      .withValue(20)
+      .build());
+
+    boolean foundIssueAtLine1 = false;
+    for (AnalyzerIssue issue : result.issues()) {
+      if (issue.line() == 1) {
+        foundIssueAtLine1 = true;
+        assertThat(issue.inputFile()).isEqualTo(new DefaultInputFile("src/sample.xoo"));
+        assertThat(issue.message()).isEqualTo("This issue is generated on each line");
+        assertThat(issue.effortToFix()).isNull();
+      }
+    }
+    assertThat(foundIssueAtLine1).isTrue();
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java
new file mode 100644 (file)
index 0000000..a93cdbf
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.xoo.plugin;
+
+import org.sonar.api.SonarPlugin;
+import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo;
+import org.sonar.batch.mediumtest.xoo.plugin.lang.MeasureAnalyzer;
+import org.sonar.batch.mediumtest.xoo.plugin.rule.OneIssuePerLineAnalyzer;
+
+import java.util.Arrays;
+import java.util.List;
+
+public final class XooPlugin extends SonarPlugin {
+
+  @Override
+  public List getExtensions() {
+    return Arrays.asList(
+      // language
+      MeasureAnalyzer.class,
+      Xoo.class,
+
+      // rules
+      OneIssuePerLineAnalyzer.class
+      );
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/base/Xoo.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/base/Xoo.java
new file mode 100644 (file)
index 0000000..1922fd7
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.xoo.plugin.base;
+
+import org.sonar.api.resources.AbstractLanguage;
+
+public class Xoo extends AbstractLanguage {
+
+  public static final String KEY = "xoo";
+  public static final String NAME = "Xoo";
+
+  public Xoo() {
+    super(KEY, NAME);
+  }
+
+  /**
+   * ${@inheritDoc}
+   */
+  public String[] getFileSuffixes() {
+    return XooConstants.FILE_SUFFIXES;
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/base/XooConstants.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/base/XooConstants.java
new file mode 100644 (file)
index 0000000..c59091f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.xoo.plugin.base;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public interface XooConstants {
+
+  String PLUGIN_KEY = "xoo";
+  String PLUGIN_NAME = "Xoo";
+
+  String REPOSITORY_KEY = PLUGIN_KEY;
+  String REPOSITORY_NAME = PLUGIN_NAME;
+
+  String[] FILE_SUFFIXES = {"xoo"};
+
+  Logger LOG = LoggerFactory.getLogger("xoo");
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureAnalyzer.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureAnalyzer.java
new file mode 100644 (file)
index 0000000..8da7690
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.xoo.plugin.lang;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.analyzer.Analyzer;
+import org.sonar.api.batch.analyzer.AnalyzerContext;
+import org.sonar.api.batch.analyzer.AnalyzerDescriptor;
+import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
+import org.sonar.api.batch.analyzer.measure.AnalyzerMeasureBuilder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo;
+import org.sonar.batch.mediumtest.xoo.plugin.base.XooConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.measures
+ */
+public class MeasureAnalyzer implements Analyzer {
+
+  private static final String MEASURES_EXTENSION = ".measures";
+
+  private MetricFinder metricFinder;
+
+  public MeasureAnalyzer(MetricFinder metricFinder) {
+    this.metricFinder = metricFinder;
+  }
+
+  private void processFileMeasures(InputFile inputFile, AnalyzerContext context) {
+    File ioFile = inputFile.file();
+    File measureFile = new File(ioFile.getParentFile(), ioFile.getName() + MEASURES_EXTENSION);
+    if (measureFile.exists()) {
+      XooConstants.LOG.debug("Processing " + measureFile.getAbsolutePath());
+      try {
+        List<String> lines = FileUtils.readLines(measureFile, context.fileSystem().encoding().name());
+        int lineNumber = 0;
+        for (String line : lines) {
+          lineNumber++;
+          if (StringUtils.isBlank(line)) {
+            continue;
+          }
+          if (line.startsWith("#")) {
+            continue;
+          }
+          try {
+            String metricKey = StringUtils.substringBefore(line, ":");
+            String value = line.substring(metricKey.length() + 1);
+            context.addMeasure(createMeasure(context, inputFile, metricKey, value));
+          } catch (Exception e) {
+            throw new IllegalStateException("Error processing line " + lineNumber + " of file " + measureFile.getAbsolutePath(), e);
+          }
+        }
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  private AnalyzerMeasure<?> createMeasure(AnalyzerContext context, InputFile xooFile, String metricKey, String value) {
+    Metric metric = metricFinder.findByKey(metricKey);
+    AnalyzerMeasureBuilder<Serializable> builder = context.measureBuilder()
+      .forMetric(metric)
+      .onFile(xooFile);
+    switch (metric.getType()) {
+      case BOOL:
+        builder.withValue(Boolean.parseBoolean(value));
+        break;
+      case INT:
+      case MILLISEC:
+        builder.withValue(Integer.valueOf(value));
+        break;
+      case FLOAT:
+      case PERCENT:
+      case RATING:
+        builder.withValue(Double.valueOf(value));
+        break;
+      case STRING:
+      case LEVEL:
+      case DATA:
+      case DISTRIB:
+        builder.withValue(value);
+        break;
+      case WORK_DUR:
+        builder.withValue(Long.valueOf(value));
+        break;
+      default:
+        if (metric.isNumericType()) {
+          builder.withValue(Double.valueOf(value));
+        } else if (metric.isDataType()) {
+          builder.withValue(value);
+        } else {
+          throw new UnsupportedOperationException("Unsupported type :" + metric.getType());
+        }
+    }
+    return builder.build();
+  }
+
+  @Override
+  public void describe(AnalyzerDescriptor descriptor) {
+    descriptor
+      .name("Xoo Measure Analyzer")
+      .provides(CoreMetrics.LINES)
+      .workOnLanguages(Xoo.KEY)
+      .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+  }
+
+  @Override
+  public void analyse(AnalyzerContext context) {
+    for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+      processFileMeasures(file, context);
+    }
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/rule/OneIssuePerLineAnalyzer.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/rule/OneIssuePerLineAnalyzer.java
new file mode 100644 (file)
index 0000000..522ad3b
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.mediumtest.xoo.plugin.rule;
+
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.analyzer.Analyzer;
+import org.sonar.api.batch.analyzer.AnalyzerContext;
+import org.sonar.api.batch.analyzer.AnalyzerDescriptor;
+import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo;
+import org.sonar.batch.mediumtest.xoo.plugin.base.XooConstants;
+
+public class OneIssuePerLineAnalyzer implements Analyzer {
+
+  public static final String RULE_KEY = "OneIssuePerLine";
+  private static final String EFFORT_TO_FIX_PROPERTY = "sonar.oneIssuePerLine.effortToFix";
+
+  @Override
+  public void describe(AnalyzerDescriptor descriptor) {
+    descriptor
+      .name("One Issue Per Line")
+      .dependsOn(CoreMetrics.LINES)
+      .workOnLanguages(Xoo.KEY)
+      .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+  }
+
+  @Override
+  public void analyse(AnalyzerContext context) {
+    for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+      createIssues(file, context);
+    }
+  }
+
+  private void createIssues(InputFile file, AnalyzerContext context) {
+    RuleKey ruleKey = RuleKey.of(XooConstants.REPOSITORY_KEY, RULE_KEY);
+    AnalyzerMeasure<Integer> linesMeasure = context.getMeasure(file, CoreMetrics.LINES);
+    if (linesMeasure == null) {
+      LoggerFactory.getLogger(getClass()).warn("Missing measure " + CoreMetrics.LINES_KEY + " on " + file);
+    } else {
+      for (int line = 1; line <= (Integer) linesMeasure.value(); line++) {
+        context.addIssue(context.issueBuilder()
+          .ruleKey(ruleKey)
+          .onFile(file)
+          .atLine(line)
+          .effortToFix(context.settings().getDouble(EFFORT_TO_FIX_PROPERTY))
+          .message("This issue is generated on each line")
+          .build());
+      }
+    }
+  }
+}
index 1384950b99d8540e5f607ffdbdd69f83a33b96cf..8940c3dd2fc34474efd389c7a0a8e0efc683db7c 100644 (file)
@@ -98,18 +98,18 @@ public class AnalyzerOptimizerTest {
     assertThat(optimizer.shouldExecute(descriptor)).isFalse();
 
     ActiveRules activeRules = new ActiveRulesBuilder()
-      .activate(RuleKey.of("repo1", "foo"))
-      .end()
+      .create(RuleKey.of("repo1", "foo"))
+      .activate()
       .build();
     optimizer = new AnalyzerOptimizer(fs, activeRules);
 
     assertThat(optimizer.shouldExecute(descriptor)).isFalse();
 
     activeRules = new ActiveRulesBuilder()
-      .activate(RuleKey.of("repo1", "foo"))
-      .end()
-      .activate(RuleKey.of("squid", "rule"))
-      .end()
+      .create(RuleKey.of("repo1", "foo"))
+      .activate()
+      .create(RuleKey.of("squid", "rule"))
+      .activate()
       .build();
     optimizer = new AnalyzerOptimizer(fs, activeRules);
     assertThat(optimizer.shouldExecute(descriptor)).isTrue();
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/sonar-project.properties b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/sonar-project.properties
new file mode 100644 (file)
index 0000000..8810e37
--- /dev/null
@@ -0,0 +1,6 @@
+sonar.projectKey=sample
+sonar.projectName=Sample
+sonar.projectVersion=0.1-SNAPSHOT
+sonar.sources=xources
+sonar.tests=testx
+sonar.language=xoo
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo
new file mode 100644 (file)
index 0000000..8c0967e
--- /dev/null
@@ -0,0 +1,11 @@
+package org.sonar.tests;
+
+import org.junit.Test;
+
+public class ClassOneTest  {
+
+  @Test
+  public void nothing() {
+
+  }
+}
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo.measures b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo.measures
new file mode 100644 (file)
index 0000000..23b08dc
--- /dev/null
@@ -0,0 +1,7 @@
+lines:11
+ncloc:7
+tests:1
+test_execution_time:1
+skipped_tests:0
+test_errors:0
+test_failures:0
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo.scm b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/testx/ClassOneTest.xoo.scm
new file mode 100644 (file)
index 0000000..2cec35b
--- /dev/null
@@ -0,0 +1,11 @@
+1,user1,2013-01-04
+1,user1,2013-01-04
+1,user1,2013-01-04
+1,user1,2013-01-04
+2,user2,2013-01-05
+2,user2,2013-01-05
+3,user3,2013-01-06
+4,user4,2013-01-07
+4,user4,2013-01-07
+4,user4,2013-01-07
+4,user4,2013-01-07
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo
new file mode 100644 (file)
index 0000000..1d9c60d
--- /dev/null
@@ -0,0 +1,8 @@
+package hello;
+
+public class HelloJava {
+
+  public static void main(String[] args) {
+    System.out.println("Hello");
+  }
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures
new file mode 100644 (file)
index 0000000..388d08b
--- /dev/null
@@ -0,0 +1,3 @@
+lines:8
+ncloc:3
+complexity:1
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.scm b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.scm
new file mode 100644 (file)
index 0000000..03a9de2
--- /dev/null
@@ -0,0 +1,8 @@
+1,user1,2013-01-04
+1,user1,2013-01-04
+1,user1,2013-01-04
+1,user1,2013-01-04
+2,user2,2013-01-05
+2,user2,2013-01-05
+3,user3,2013-01-06
+4,user4,2013-01-07
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/helloscala.xoo b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/helloscala.xoo
new file mode 100644 (file)
index 0000000..53cb085
--- /dev/null
@@ -0,0 +1,6 @@
+  object HelloWorld {
+    def main(args: Array[String]) {
+      println("Hello, world of xoo!")
+    }
+  }
+  
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures b/sonar-batch/src/test/resources/org/sonar/batch/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures
new file mode 100644 (file)
index 0000000..c47948f
--- /dev/null
@@ -0,0 +1,3 @@
+lines:5
+ncloc:5
+complexity:2
index 92a51acd100a8ec0cfd4ea559ce78268d07743e7..ba75d12fca7151d8d5ec15608537acf639c6113a 100644 (file)
@@ -20,6 +20,9 @@
 package org.sonar.api.batch.analyzer.issue.internal;
 
 import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
 import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.rule.RuleKey;
@@ -27,9 +30,11 @@ import org.sonar.api.rule.RuleKey;
 import javax.annotation.Nullable;
 
 import java.io.Serializable;
+import java.util.UUID;
 
 public class DefaultAnalyzerIssue implements AnalyzerIssue, Serializable {
 
+  private final String key;
   private final InputFile inputFile;
   private final RuleKey ruleKey;
   private final String message;
@@ -43,6 +48,12 @@ public class DefaultAnalyzerIssue implements AnalyzerIssue, Serializable {
     this.message = builder.message;
     this.line = builder.line;
     this.effortToFix = builder.effortToFix;
+    this.key = builder.key == null ? UUID.randomUUID().toString() : builder.key;
+    Preconditions.checkState(!Strings.isNullOrEmpty(key), "Fail to generate issue key");
+  }
+
+  public String key() {
+    return key;
   }
 
   @Override
@@ -72,4 +83,26 @@ public class DefaultAnalyzerIssue implements AnalyzerIssue, Serializable {
     return effortToFix;
   }
 
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    DefaultAnalyzerIssue that = (DefaultAnalyzerIssue) o;
+    return !key.equals(that.key);
+  }
+
+  @Override
+  public int hashCode() {
+    return key.hashCode();
+  }
+
+  @Override
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+  }
+
 }
index d56ecaf1bcafac2f5dad7a06c8a8bd69a05c68b3..42a6b9703804531243c9a6bcfed9c59719b053eb 100644 (file)
@@ -29,6 +29,7 @@ import javax.annotation.Nullable;
 
 public class DefaultAnalyzerIssueBuilder implements AnalyzerIssueBuilder {
 
+  String key;
   Boolean onProject = null;
   InputFile file;
   RuleKey ruleKey;
@@ -80,6 +81,14 @@ public class DefaultAnalyzerIssueBuilder implements AnalyzerIssueBuilder {
     return this;
   }
 
+  /**
+   * For testing only.
+   */
+  public DefaultAnalyzerIssueBuilder withKey(String key) {
+    this.key = key;
+    return this;
+  }
+
   @Override
   public AnalyzerIssue build() {
     return new DefaultAnalyzerIssue(this);
index e9e9be05f61a18141b0943525b9edde1200c0417..1e0f696416894dd2e47a99f8910681989e3c9482 100644 (file)
  */
 package org.sonar.api.batch.analyzer.measure.internal;
 
-import org.sonar.api.batch.measure.Metric;
-
 import com.google.common.base.Preconditions;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.measure.Metric;
 
 import javax.annotation.Nullable;
 
@@ -62,26 +65,35 @@ public class DefaultAnalyzerMeasure<G extends Serializable> implements AnalyzerM
 
   @Override
   public boolean equals(Object obj) {
-    if (!(obj instanceof DefaultAnalyzerMeasure)) {
+    if (obj == null) {
+      return false;
+    }
+    if (obj == this) {
+      return true;
+    }
+    if (obj.getClass() != getClass()) {
       return false;
     }
-    DefaultAnalyzerMeasure<?> other = (DefaultAnalyzerMeasure<?>) obj;
-    return metric.equals(other.metric)
-      && value.equals(other.value)
-      && (inputFile == null ? other.inputFile == null : inputFile.equals(other.inputFile));
+    DefaultAnalyzerMeasure rhs = (DefaultAnalyzerMeasure) obj;
+    return new EqualsBuilder()
+      .append(inputFile, rhs.inputFile)
+      .append(metric, rhs.metric)
+      .append(value, rhs.value)
+      .isEquals();
   }
 
   @Override
   public int hashCode() {
-    return metric.hashCode()
-      + value.hashCode()
-      + (inputFile != null ? inputFile.hashCode() : 0);
+    return new HashCodeBuilder(27, 45).
+      append(inputFile).
+      append(metric).
+      append(value).
+      toHashCode();
   }
 
   @Override
   public String toString() {
-    return "AnalyzerMeasure[" + (inputFile != null ? "inputFile=" + inputFile.toString() : "onProject")
-      + ",metric=" + metric + ",value=" + value + "]";
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
   }
 
 }
index 208335e2ff3b448bee8ce7e322491452fd39fc67..fa9e0cdab24a2b5951af6ac36ae498687a2d340e 100644 (file)
@@ -35,13 +35,15 @@ public class ActiveRulesBuilder {
 
   private final Map<RuleKey, NewActiveRule> map = Maps.newHashMap();
 
-  public NewActiveRule activate(RuleKey ruleKey) {
-    if (map.containsKey(ruleKey)) {
-      throw new IllegalStateException(String.format("Rule '%s' is already activated", ruleKey));
+  public NewActiveRule create(RuleKey ruleKey) {
+    return new NewActiveRule(this, ruleKey);
+  }
+
+  void activate(NewActiveRule newActiveRule) {
+    if (map.containsKey(newActiveRule.ruleKey)) {
+      throw new IllegalStateException(String.format("Rule '%s' is already activated", newActiveRule.ruleKey));
     }
-    NewActiveRule newActiveRule = new NewActiveRule(this, ruleKey);
-    map.put(ruleKey, newActiveRule);
-    return newActiveRule;
+    map.put(newActiveRule.ruleKey, newActiveRule);
   }
 
   public ActiveRules build() {
index d2dbcf3f420bacd60e60bad840c1eb774c623560..dd4b53d5953a3077c9fa52e1550dbff381334533 100644 (file)
@@ -72,7 +72,8 @@ public class NewActiveRule {
     return params;
   }
 
-  public ActiveRulesBuilder end() {
+  public ActiveRulesBuilder activate() {
+    builder.activate(this);
     return builder;
   }
 }
index 64ce0c8c93770ed2be02323d917861d14771800e..42f8d7f66541062ace3368a9254eb5d326ec2319 100644 (file)
@@ -46,7 +46,7 @@ public class CheckFactoryTest {
   @Test
   public void class_name_as_check_key() {
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithoutProperties");
-    builder.activate(ruleKey);
+    builder.create(ruleKey).activate();
     CheckFactory checkFactory = new CheckFactory(builder.build());
 
     Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithoutProperties.class);
@@ -60,7 +60,7 @@ public class CheckFactoryTest {
   @Test
   public void param_as_string_field() {
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty");
-    builder.activate(ruleKey).setParam("pattern", "foo");
+    builder.create(ruleKey).setParam("pattern", "foo").activate();
 
     CheckFactory checkFactory = new CheckFactory(builder.build());
     Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithStringProperty.class);
@@ -77,7 +77,7 @@ public class CheckFactoryTest {
     thrown.expectMessage("The field 'unknown' does not exist or is not annotated with @RuleProperty in the class org.sonar.api.batch.rule.CheckWithStringProperty");
 
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty");
-    builder.activate(ruleKey).setParam("unknown", "foo");
+    builder.create(ruleKey).setParam("unknown", "foo").activate();
 
     CheckFactory checkFactory = new CheckFactory(builder.build());
     checkFactory.create("squid").addAnnotatedChecks(CheckWithStringProperty.class);
@@ -86,7 +86,7 @@ public class CheckFactoryTest {
   @Test
   public void param_as_primitive_fields() {
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithPrimitiveProperties");
-    builder.activate(ruleKey).setParam("max", "300").setParam("ignore", "true");
+    builder.create(ruleKey).setParam("max", "300").setParam("ignore", "true").activate();
 
     CheckFactory checkFactory = new CheckFactory(builder.build());
     Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithPrimitiveProperties.class);
@@ -103,7 +103,7 @@ public class CheckFactoryTest {
   @Test
   public void param_as_inherited_field() {
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithPrimitiveProperties");
-    builder.activate(ruleKey).setParam("max", "300");
+    builder.create(ruleKey).setParam("max", "300").activate();
 
     CheckFactory checkFactory = new CheckFactory(builder.build());
     Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithPrimitiveProperties.class);
@@ -116,7 +116,7 @@ public class CheckFactoryTest {
   @Test
   public void use_engine_key() {
     RuleKey ruleKey = RuleKey.of("squid", "One");
-    builder.activate(ruleKey).setInternalKey("S0001");
+    builder.create(ruleKey).setInternalKey("S0001").activate();
 
     CheckFactory checkFactory = new CheckFactory(builder.build());
     Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithKey.class);
@@ -133,7 +133,7 @@ public class CheckFactoryTest {
     thrown.expect(SonarException.class);
 
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithUnsupportedPropertyType");
-    builder.activate(ruleKey).setParam("max", "300");
+    builder.create(ruleKey).setParam("max", "300").activate();
 
     CheckFactory checkFactory = new CheckFactory(builder.build());
     checkFactory.create("squid").addAnnotatedChecks(CheckWithUnsupportedPropertyType.class);
@@ -142,7 +142,7 @@ public class CheckFactoryTest {
   @Test
   public void override_field_key() {
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithOverriddenPropertyKey");
-    builder.activate(ruleKey).setParam("maximum", "300");
+    builder.create(ruleKey).setParam("maximum", "300").activate();
 
     CheckFactory checkFactory = new CheckFactory(builder.build());
     Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithOverriddenPropertyKey.class);
@@ -158,7 +158,7 @@ public class CheckFactoryTest {
   @Test
   public void checks_as_objects() {
     RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty");
-    builder.activate(ruleKey).setParam("pattern", "foo");
+    builder.create(ruleKey).setParam("pattern", "foo").activate();
     CheckFactory checkFactory = new CheckFactory(builder.build());
 
     CheckWithStringProperty check = new CheckWithStringProperty();
index d83456058fdac4442ce1ed368d1940780ed2395a..c308024616f31268f7660d2a6d3a69764d64605f 100644 (file)
@@ -39,14 +39,14 @@ public class ActiveRulesBuilderTest {
   @Test
   public void build_rules() throws Exception {
     ActiveRules activeRules = new ActiveRulesBuilder()
-      .activate(RuleKey.of("squid", "S0001"))
+      .create(RuleKey.of("squid", "S0001"))
       .setSeverity(Severity.CRITICAL)
       .setInternalKey("__S0001__")
       .setParam("min", "20")
-      .end()
+      .activate()
       // most simple rule
-      .activate(RuleKey.of("squid", "S0002")).end()
-      .activate(RuleKey.of("findbugs", "NPE")).setInternalKey(null).setSeverity(null).setParam("foo", null).end()
+      .create(RuleKey.of("squid", "S0002")).activate()
+      .create(RuleKey.of("findbugs", "NPE")).setInternalKey(null).setSeverity(null).setParam("foo", null).activate()
       .build();
 
     assertThat(activeRules.findAll()).hasSize(3);
@@ -77,9 +77,9 @@ public class ActiveRulesBuilderTest {
   @Test
   public void fail_to_add_twice_the_same_rule() throws Exception {
     ActiveRulesBuilder builder = new ActiveRulesBuilder();
-    builder.activate(RuleKey.of("squid", "S0001"));
+    builder.create(RuleKey.of("squid", "S0001")).activate();
     try {
-      builder.activate(RuleKey.of("squid", "S0001"));
+      builder.create(RuleKey.of("squid", "S0001")).activate();
       fail();
     } catch (IllegalStateException e) {
       assertThat(e).hasMessage("Rule 'squid:S0001' is already activated");