]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6730 Fix test implementation
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 1 Sep 2015 11:54:09 +0000 (13:54 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 2 Sep 2015 12:28:19 +0000 (14:28 +0200)
21 files changed:
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/ComponentImpl.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/IssueImpl.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerImpl.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerImplementationContext.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerProviderContext.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerTester.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureImpl.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/SettingsImpl.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinitionContext.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestSettings.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestComponentTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestIssueTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureComputerContextTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinitionTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestSettingsTest.java [new file with mode: 0644]

diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/ComponentImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/ComponentImpl.java
deleted file mode 100644 (file)
index 866b30f..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-import org.sonar.api.ce.measure.Component;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-@Immutable
-public class ComponentImpl implements Component {
-
-  private final String key;
-
-  private final Type type;
-
-  @CheckForNull
-  private final FileAttributes fileAttributes;
-
-  public ComponentImpl(String key, Type type, @Nullable FileAttributes fileAttributes) {
-    this.key = requireNonNull(key, "Key cannot be null");
-    this.type = requireNonNull(type, "Type cannot be null");
-    this.fileAttributes = checkFileAttributes(fileAttributes);
-  }
-
-  @CheckForNull
-  private FileAttributes checkFileAttributes(@Nullable FileAttributes fileAttributes) {
-    if (fileAttributes == null && type == Type.FILE) {
-      throw new IllegalArgumentException("Component of type FILE must have a FileAttributes object");
-    } else if (fileAttributes != null && type != Type.FILE) {
-      throw new IllegalArgumentException("Only component of type FILE have a FileAttributes object");
-    }
-    return fileAttributes;
-  }
-
-  @Override
-  public Type getType() {
-    return type;
-  }
-
-  @Override
-  public String getKey() {
-    return key;
-  }
-
-  @Override
-  public FileAttributes getFileAttributes() {
-    checkState(this.type == Component.Type.FILE, "Only component of type FILE have a FileAttributes object");
-    return fileAttributes;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-
-    ComponentImpl component = (ComponentImpl) o;
-
-    return key.equals(component.key);
-  }
-
-  @Override
-  public int hashCode() {
-    return key.hashCode();
-  }
-
-  @Override
-  public String toString() {
-    return "ComponentImpl{" +
-      "key=" + key +
-      ", type='" + type + '\'' +
-      ", fileAttributes=" + fileAttributes +
-      '}';
-  }
-
-  @Immutable
-  public static class FileAttributesImpl implements FileAttributes {
-
-    private final boolean unitTest;
-    private final String languageKey;
-
-    public FileAttributesImpl(@Nullable String languageKey, boolean unitTest) {
-      this.languageKey = languageKey;
-      this.unitTest = unitTest;
-    }
-
-    @Override
-    public boolean isUnitTest() {
-      return unitTest;
-    }
-
-    @Override
-    @CheckForNull
-    public String getLanguageKey() {
-      return languageKey;
-    }
-
-    @Override
-    public String toString() {
-      return "FileAttributesImpl{" +
-        "languageKey='" + languageKey + '\'' +
-        ", unitTest=" + unitTest +
-        '}';
-    }
-  }
-}
-
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/IssueImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/IssueImpl.java
deleted file mode 100644 (file)
index a2dfacc..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.sonar.api.ce.measure.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.utils.Duration;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class IssueImpl implements Issue {
-
-  private String key;
-  private String status;
-  private String resolution;
-  private String severity;
-  private RuleKey ruleKey;
-  private Duration debt;
-
-  private IssueImpl(Builder builder) {
-    this.key = builder.key;
-    this.status = builder.status;
-    this.resolution = builder.resolution;
-    this.severity = builder.severity;
-    this.ruleKey = builder.ruleKey;
-    this.debt = builder.debt;
-  }
-
-  @Override
-  public String key() {
-    return key;
-  }
-
-  @Override
-  public RuleKey ruleKey() {
-    return ruleKey;
-  }
-
-  @Override
-  public String status() {
-    return status;
-  }
-
-  @Override
-  @CheckForNull
-  public String resolution() {
-    return resolution;
-  }
-
-  @Override
-  public String severity() {
-    return severity;
-  }
-
-  @Override
-  @CheckForNull
-  public Duration debt() {
-    return debt;
-  }
-
-  public static class Builder {
-    private String key;
-    private String status;
-    private String resolution;
-    private String severity;
-    private RuleKey ruleKey;
-    private Duration debt;
-
-    public Builder setKey(String key) {
-      this.key = validateKey(key);
-      return this;
-    }
-
-    public Builder setResolution(@Nullable String resolution) {
-      this.resolution = validateResolution(resolution);
-      return this;
-    }
-
-    public Builder setSeverity(String severity) {
-      this.severity = validateSeverity(severity);
-      return this;
-    }
-
-    public Builder setStatus(String status) {
-      this.status = validateStatus(status);
-      return this;
-    }
-
-    public Builder setRuleKey(RuleKey ruleKey) {
-      this.ruleKey = validateRuleKey(ruleKey);
-      return this;
-    }
-
-    public Builder setDebt(@Nullable Duration debt) {
-      this.debt = debt;
-      return this;
-    }
-
-    private static String validateKey(String key){
-      checkNotNull(key, "key cannot be null");
-      return key;
-    }
-
-    private static RuleKey validateRuleKey(RuleKey ruleKey){
-      checkNotNull(ruleKey, "ruleKey cannot be null");
-      return ruleKey;
-    }
-
-    private static String validateResolution(@Nullable String resolution){
-      checkArgument(resolution == null || org.sonar.api.issue.Issue.RESOLUTIONS.contains(resolution), String.format("resolution '%s' is invalid", resolution));
-      return resolution;
-    }
-
-    private static String validateSeverity(String severity){
-      checkNotNull(severity, "severity cannot be null");
-      checkArgument(Severity.ALL.contains(severity), String.format("severity '%s' is invalid", severity));
-      return severity;
-    }
-
-    private static String validateStatus(String status){
-      checkNotNull(status, "status cannot be null");
-      checkArgument(org.sonar.api.issue.Issue.STATUSES.contains(status), String.format("status '%s' is invalid", status));
-      return status;
-    }
-
-    public Issue build(){
-      validateKey(key);
-      validateResolution(resolution);
-      validateSeverity(severity);
-      validateStatus(status);
-      validateRuleKey(ruleKey);
-      return new IssueImpl(this);
-    }
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerImpl.java
deleted file mode 100644 (file)
index 09d5a7a..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
-import javax.annotation.Nullable;
-import org.sonar.api.ce.measure.MeasureComputer;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-public class MeasureComputerImpl implements MeasureComputer {
-
-  private final Set<String> inputMetricKeys;
-  private final Set<String> outputMetrics;
-  private final Implementation measureComputerImplementation;
-
-  public MeasureComputerImpl(MeasureComputerBuilderImpl builder) {
-    this.inputMetricKeys = ImmutableSet.copyOf(builder.inputMetricKeys);
-    this.outputMetrics = ImmutableSet.copyOf(builder.outputMetrics);
-    this.measureComputerImplementation = builder.measureComputerImplementation;
-  }
-
-  @Override
-  public Set<String> getInputMetrics() {
-    return inputMetricKeys;
-  }
-
-  @Override
-  public Set<String> getOutputMetrics() {
-    return outputMetrics;
-  }
-
-  @Override
-  public Implementation getImplementation() {
-    return measureComputerImplementation;
-  }
-
-  @Override
-  public String toString() {
-    return "MeasureComputerImpl{" +
-      "inputMetricKeys=" + inputMetricKeys +
-      ", outputMetrics=" + outputMetrics +
-      ", implementation=" + measureComputerImplementation.toString() +
-      '}';
-  }
-
-  public static class MeasureComputerBuilderImpl implements MeasureComputerBuilder {
-
-    private String[] inputMetricKeys = new String[] {};
-    private String[] outputMetrics;
-    private Implementation measureComputerImplementation;
-
-    @Override
-    public MeasureComputerBuilder setInputMetrics(String... inputMetrics) {
-      this.inputMetricKeys = validateInputMetricKeys(inputMetrics);
-      return this;
-    }
-
-    @Override
-    public MeasureComputerBuilder setOutputMetrics(String... outputMetrics) {
-      this.outputMetrics = validateOutputMetricKeys(outputMetrics);
-      return this;
-    }
-
-    @Override
-    public MeasureComputerBuilder setImplementation(Implementation impl) {
-      this.measureComputerImplementation = validateImplementation(impl);
-      return this;
-    }
-
-    @Override
-    public MeasureComputer build() {
-      validateInputMetricKeys(this.inputMetricKeys);
-      validateOutputMetricKeys(this.outputMetrics);
-      validateImplementation(this.measureComputerImplementation);
-      return new MeasureComputerImpl(this);
-    }
-
-    private static String[] validateInputMetricKeys(@Nullable String[] inputMetrics) {
-      requireNonNull(inputMetrics, "Input metrics cannot be null");
-      checkNotNull(inputMetrics);
-      return inputMetrics;
-    }
-
-    private static String[] validateOutputMetricKeys(@Nullable String[] outputMetrics) {
-      requireNonNull(outputMetrics, "Output metrics cannot be null");
-      checkArgument(outputMetrics.length > 0, "At least one output metric must be defined");
-      checkNotNull(outputMetrics);
-      return outputMetrics;
-    }
-
-    private static Implementation validateImplementation(Implementation impl) {
-      return requireNonNull(impl, "The implementation is missing");
-    }
-  }
-
-  private static void checkNotNull(String[] metrics){
-    for (String metric : metrics) {
-      requireNonNull(metric, "Null metric is not allowed");
-    }
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerImplementationContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerImplementationContext.java
deleted file mode 100644 (file)
index d50cc66..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import org.sonar.api.ce.measure.Component;
-import org.sonar.api.ce.measure.Issue;
-import org.sonar.api.ce.measure.Measure;
-import org.sonar.api.ce.measure.MeasureComputer;
-import org.sonar.api.ce.measure.Settings;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-public class MeasureComputerImplementationContext implements MeasureComputer.Implementation.Context {
-
-  private final Component component;
-  private final MeasureComputer measureComputer;
-  private final Settings settings;
-
-  private Map<String, Measure> componentMeasureByMetricKey = new HashMap<>();
-  private Multimap<String, Measure> childrenComponentMeasureByMetricKey = ArrayListMultimap.create();
-  private List<Issue> issues = new ArrayList<>();
-
-  public MeasureComputerImplementationContext(Component component, Settings settings, MeasureComputer measureComputer) {
-    this.measureComputer = measureComputer;
-    this.settings = settings;
-    this.component = component;
-  }
-
-  @Override
-  public Component getComponent() {
-    return component;
-  }
-
-  @Override
-  public Settings getSettings() {
-    return settings;
-  }
-
-  @Override
-  @CheckForNull
-  public Measure getMeasure(String metric) {
-    validateInputMetric(metric);
-    return componentMeasureByMetricKey.get(metric);
-  }
-
-  @Override
-  public Iterable<Measure> getChildrenMeasures(String metric) {
-    validateInputMetric(metric);
-    return childrenComponentMeasureByMetricKey.get(metric);
-  }
-
-  @Override
-  public void addMeasure(String metricKey, int value) {
-    validateAddMeasure(metricKey);
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addInputMeasure(String metricKey, int value) {
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addChildrenMeasures(String metricKey, Integer... values) {
-    for (Integer value : values) {
-      childrenComponentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-    }
-  }
-
-  @Override
-  public void addMeasure(String metricKey, double value) {
-    validateAddMeasure(metricKey);
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addInputMeasure(String metricKey, double value) {
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addChildrenMeasures(String metricKey, Double... values) {
-    for (Double value : values) {
-      childrenComponentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-    }
-  }
-
-  @Override
-  public void addMeasure(String metricKey, long value) {
-    validateAddMeasure(metricKey);
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addInputMeasure(String metricKey, long value) {
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addChildrenMeasures(String metricKey, Long... values) {
-    for (Long value : values) {
-      childrenComponentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-    }
-  }
-
-  @Override
-  public void addMeasure(String metricKey, String value) {
-    validateAddMeasure(metricKey);
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addInputMeasure(String metricKey, String value) {
-    componentMeasureByMetricKey.put(metricKey, MeasureImpl.createMeasure(value));
-  }
-
-  public void addChildrenMeasures(String metricKey, String... values) {
-    for (String value : values) {
-      childrenComponentMeasureByMetricKey.put(metricKey,MeasureImpl.createMeasure(value));
-    }
-  }
-
-  @Override
-  public List<Issue> getIssues() {
-    return issues;
-  }
-
-  public void setIssues(List<Issue> issues){
-    this.issues = issues;
-  }
-
-  private void validateInputMetric(String metric) {
-    Set<String> allowedMetrics = new HashSet<>();
-    allowedMetrics.addAll(measureComputer.getInputMetrics());
-    allowedMetrics.addAll(measureComputer.getOutputMetrics());
-    checkArgument(allowedMetrics.contains(metric), "Only metrics in %s can be used to load measures", measureComputer.getInputMetrics());
-  }
-
-  private void validateAddMeasure(String metricKey) {
-    checkArgument(measureComputer.getOutputMetrics().contains(metricKey), "Only metrics in %s can be used to add measures. Metric '%s' is not allowed.",
-      measureComputer.getOutputMetrics(), metricKey);
-    if (componentMeasureByMetricKey.get(metricKey) != null) {
-      throw new UnsupportedOperationException(String.format("A measure on metric '%s' already exists", metricKey));
-    }
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerProviderContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerProviderContext.java
deleted file mode 100644 (file)
index a3cdc01..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.sonar.api.ce.measure.MeasureComputer;
-import org.sonar.api.ce.measure.MeasureComputerProvider;
-
-public class MeasureComputerProviderContext implements MeasureComputerProvider.Context {
-
-  private final List<MeasureComputer> measureComputers = new ArrayList<>();
-  private final Map<String, MeasureComputer> computerByOutputMetrics = new HashMap<>();
-
-  @Override
-  public MeasureComputerProvider.Context add(MeasureComputer measureComputer) {
-    checkOutputMetricsNotAlreadyDefinedByAnotherComputer(measureComputer);
-    this.measureComputers.add(measureComputer);
-    for (String metric : measureComputer.getOutputMetrics()) {
-      computerByOutputMetrics.put(metric, measureComputer);
-    }
-    return this;
-  }
-
-  public List<MeasureComputer> getMeasureComputers() {
-    return measureComputers;
-  }
-
-  private void checkOutputMetricsNotAlreadyDefinedByAnotherComputer(MeasureComputer measureComputer) {
-    Set<String> duplicated = ImmutableSet.copyOf(Sets.intersection(computerByOutputMetrics.keySet(), measureComputer.getOutputMetrics()));
-    if (!duplicated.isEmpty()) {
-      throw new UnsupportedOperationException(generateErrorMsg(duplicated));
-    }
-  }
-
-  private String generateErrorMsg(Set<String> duplicated){
-    StringBuilder errorMsg = new StringBuilder();
-    for (String duplicationMetric : duplicated) {
-      MeasureComputer otherComputer = computerByOutputMetrics.get(duplicationMetric);
-      errorMsg.append(String.format(
-        "The output metric '%s' is already declared by another computer. This computer has these input metrics '%s' and these output metrics '%s'. ",
-        duplicationMetric, otherComputer.getInputMetrics(), otherComputer.getOutputMetrics()));
-    }
-    return errorMsg.toString();
-  }
-
-  @Override
-  public MeasureComputer.MeasureComputerBuilder newMeasureComputerBuilder() {
-    return new MeasureComputerImpl.MeasureComputerBuilderImpl();
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureComputerTester.java
deleted file mode 100644 (file)
index 84063b3..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import java.util.List;
-import javax.annotation.CheckForNull;
-import org.sonar.api.ce.measure.MeasureComputer;
-import org.sonar.api.ce.measure.MeasureComputerProvider;
-
-public class MeasureComputerTester {
-
-  private final MeasureComputerProviderContext context = new MeasureComputerProviderContext();
-
-  public MeasureComputerTester(MeasureComputerProvider... providers) {
-    for (MeasureComputerProvider provider : providers) {
-      provider.register(context);
-    }
-  }
-
-  public MeasureComputerProvider.Context context() {
-    return context;
-  }
-
-  public List<MeasureComputer> getMeasureComputers() {
-    return context.getMeasureComputers();
-  }
-
-  /**
-   * Return the measure computer that provide the output metric
-   */
-  @CheckForNull
-  public MeasureComputer measureComputer(String outputMetric){
-    Optional<MeasureComputer> measureComputer = FluentIterable.from(getMeasureComputers()).firstMatch(new MatchingOuputMetricKey(outputMetric));
-    return measureComputer.isPresent() ? measureComputer.get() : null;
-  }
-
-  private static class MatchingOuputMetricKey implements Predicate<MeasureComputer> {
-
-    private final String metricKey;
-
-    public MatchingOuputMetricKey(String metricKey) {
-      this.metricKey = metricKey;
-    }
-
-    @Override
-    public boolean apply(MeasureComputer input) {
-      return input.getOutputMetrics().contains(metricKey);
-    }
-  }
-
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/MeasureImpl.java
deleted file mode 100644 (file)
index a7bd1c8..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import javax.annotation.concurrent.Immutable;
-import org.sonar.api.ce.measure.Measure;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-@Immutable
-public class MeasureImpl implements Measure {
-
-  private Integer intValue;
-  private Long longValue;
-  private Double doubleValue;
-  private String stringValue;
-
-  public static MeasureImpl createMeasure(double doubleValue){
-    MeasureImpl measure = new MeasureImpl();
-    measure.doubleValue = doubleValue;
-    return measure;
-  }
-
-  public static MeasureImpl createMeasure(int intValue) {
-    MeasureImpl measure = new MeasureImpl();
-    measure.intValue = intValue;
-    return measure;
-  }
-
-  public static MeasureImpl createMeasure(long longValue) {
-    MeasureImpl measure = new MeasureImpl();
-    measure.longValue = longValue;
-    return measure;
-  }
-
-  public static MeasureImpl createMeasure(String stringValue) {
-    MeasureImpl measure = new MeasureImpl();
-    measure.stringValue = requireNonNull(stringValue, "Value cannot be null");
-    return measure;
-  }
-
-  @Override
-  public int getIntValue() {
-    checkState(intValue != null, "Not an int measure");
-    return intValue;
-  }
-
-  @Override
-  public long getLongValue() {
-    checkState(longValue != null, "Not a long measure");
-    return longValue;
-  }
-
-  @Override
-  public double getDoubleValue() {
-    checkState(doubleValue != null, "Not a double measure");
-    return doubleValue;
-  }
-
-  @Override
-  public String getStringValue() {
-    checkState(stringValue != null, "Not a string measure");
-    return stringValue;
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/SettingsImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/SettingsImpl.java
deleted file mode 100644 (file)
index 80b2d45..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.api.ce.measure.test;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.ce.measure.Settings;
-
-public class SettingsImpl implements Settings {
-
-  private Map<String, String> valuesByKey = new HashMap<>();
-
-  public Settings setValue(String key, String value){
-    valuesByKey.put(key, value);
-    return this;
-  }
-
-  @Override
-  @CheckForNull
-  public String getString(String key) {
-    return valuesByKey.get(key);
-  }
-
-  @Override
-  public String[] getStringArray(String key) {
-    String value = getString(key);
-    if (value != null) {
-      String[] strings = StringUtils.splitByWholeSeparator(value, ",");
-      String[] result = new String[strings.length];
-      for (int index = 0; index < strings.length; index++) {
-        result[index] = StringUtils.trim(strings[index]);
-      }
-      return result;
-    }
-    return ArrayUtils.EMPTY_STRING_ARRAY;
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java
new file mode 100644 (file)
index 0000000..3e4246f
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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.api.ce.measure.test;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.api.ce.measure.Component;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+@Immutable
+public class TestComponent implements Component {
+
+  private final String key;
+
+  private final Type type;
+
+  @CheckForNull
+  private final FileAttributes fileAttributes;
+
+  public TestComponent(String key, Type type, @Nullable FileAttributes fileAttributes) {
+    this.key = requireNonNull(key, "Key cannot be null");
+    this.type = requireNonNull(type, "Type cannot be null");
+    this.fileAttributes = checkFileAttributes(fileAttributes);
+  }
+
+  @CheckForNull
+  private FileAttributes checkFileAttributes(@Nullable FileAttributes fileAttributes) {
+    if (fileAttributes == null && type == Type.FILE) {
+      throw new IllegalArgumentException("Component of type FILE must have a FileAttributes object");
+    } else if (fileAttributes != null && type != Type.FILE) {
+      throw new IllegalArgumentException("Only component of type FILE have a FileAttributes object");
+    }
+    return fileAttributes;
+  }
+
+  @Override
+  public Type getType() {
+    return type;
+  }
+
+  @Override
+  public String getKey() {
+    return key;
+  }
+
+  @Override
+  public FileAttributes getFileAttributes() {
+    checkState(this.type == Component.Type.FILE, "Only component of type FILE have a FileAttributes object");
+    return fileAttributes;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    TestComponent component = (TestComponent) o;
+
+    return key.equals(component.key);
+  }
+
+  @Override
+  public int hashCode() {
+    return key.hashCode();
+  }
+
+  @Override
+  public String toString() {
+    return "ComponentImpl{" +
+      "key=" + key +
+      ", type='" + type + '\'' +
+      ", fileAttributes=" + fileAttributes +
+      '}';
+  }
+
+  @Immutable
+  public static class FileAttributesImpl implements FileAttributes {
+
+    private final boolean unitTest;
+    private final String languageKey;
+
+    public FileAttributesImpl(@Nullable String languageKey, boolean unitTest) {
+      this.languageKey = languageKey;
+      this.unitTest = unitTest;
+    }
+
+    @Override
+    public boolean isUnitTest() {
+      return unitTest;
+    }
+
+    @Override
+    @CheckForNull
+    public String getLanguageKey() {
+      return languageKey;
+    }
+
+    @Override
+    public String toString() {
+      return "FileAttributesImpl{" +
+        "languageKey='" + languageKey + '\'' +
+        ", unitTest=" + unitTest +
+        '}';
+    }
+  }
+}
+
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java
new file mode 100644 (file)
index 0000000..8f8696b
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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.api.ce.measure.test;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.api.ce.measure.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.Duration;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@Immutable
+public class TestIssue implements Issue {
+
+  private String key;
+  private String status;
+  private String resolution;
+  private String severity;
+  private RuleKey ruleKey;
+  private Duration debt;
+
+  private TestIssue(Builder builder) {
+    this.key = builder.key;
+    this.status = builder.status;
+    this.resolution = builder.resolution;
+    this.severity = builder.severity;
+    this.ruleKey = builder.ruleKey;
+    this.debt = builder.debt;
+  }
+
+  @Override
+  public String key() {
+    return key;
+  }
+
+  @Override
+  public RuleKey ruleKey() {
+    return ruleKey;
+  }
+
+  @Override
+  public String status() {
+    return status;
+  }
+
+  @Override
+  @CheckForNull
+  public String resolution() {
+    return resolution;
+  }
+
+  @Override
+  public String severity() {
+    return severity;
+  }
+
+  @Override
+  @CheckForNull
+  public Duration debt() {
+    return debt;
+  }
+
+  public static class Builder {
+    private String key;
+    private String status;
+    private String resolution;
+    private String severity;
+    private RuleKey ruleKey;
+    private Duration debt;
+
+    public Builder setKey(String key) {
+      this.key = validateKey(key);
+      return this;
+    }
+
+    public Builder setResolution(@Nullable String resolution) {
+      this.resolution = validateResolution(resolution);
+      return this;
+    }
+
+    public Builder setSeverity(String severity) {
+      this.severity = validateSeverity(severity);
+      return this;
+    }
+
+    public Builder setStatus(String status) {
+      this.status = validateStatus(status);
+      return this;
+    }
+
+    public Builder setRuleKey(RuleKey ruleKey) {
+      this.ruleKey = validateRuleKey(ruleKey);
+      return this;
+    }
+
+    public Builder setDebt(@Nullable Duration debt) {
+      this.debt = debt;
+      return this;
+    }
+
+    private static String validateKey(String key){
+      checkNotNull(key, "key cannot be null");
+      return key;
+    }
+
+    private static RuleKey validateRuleKey(RuleKey ruleKey){
+      checkNotNull(ruleKey, "ruleKey cannot be null");
+      return ruleKey;
+    }
+
+    private static String validateResolution(@Nullable String resolution){
+      checkArgument(resolution == null || org.sonar.api.issue.Issue.RESOLUTIONS.contains(resolution), String.format("resolution '%s' is invalid", resolution));
+      return resolution;
+    }
+
+    private static String validateSeverity(String severity){
+      checkNotNull(severity, "severity cannot be null");
+      checkArgument(Severity.ALL.contains(severity), String.format("severity '%s' is invalid", severity));
+      return severity;
+    }
+
+    private static String validateStatus(String status){
+      checkNotNull(status, "status cannot be null");
+      checkArgument(org.sonar.api.issue.Issue.STATUSES.contains(status), String.format("status '%s' is invalid", status));
+      return status;
+    }
+
+    public Issue build(){
+      validateKey(key);
+      validateResolution(resolution);
+      validateSeverity(severity);
+      validateStatus(status);
+      validateRuleKey(ruleKey);
+      return new TestIssue(this);
+    }
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java
new file mode 100644 (file)
index 0000000..fbe8bc9
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.api.ce.measure.test;
+
+import javax.annotation.concurrent.Immutable;
+import org.sonar.api.ce.measure.Measure;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+@Immutable
+public class TestMeasure implements Measure {
+
+  private Integer intValue;
+  private Long longValue;
+  private Double doubleValue;
+  private String stringValue;
+
+  public static TestMeasure createMeasure(double doubleValue){
+    TestMeasure measure = new TestMeasure();
+    measure.doubleValue = doubleValue;
+    return measure;
+  }
+
+  public static TestMeasure createMeasure(int intValue) {
+    TestMeasure measure = new TestMeasure();
+    measure.intValue = intValue;
+    return measure;
+  }
+
+  public static TestMeasure createMeasure(long longValue) {
+    TestMeasure measure = new TestMeasure();
+    measure.longValue = longValue;
+    return measure;
+  }
+
+  public static TestMeasure createMeasure(String stringValue) {
+    TestMeasure measure = new TestMeasure();
+    measure.stringValue = requireNonNull(stringValue, "Value cannot be null");
+    return measure;
+  }
+
+  @Override
+  public int getIntValue() {
+    checkState(intValue != null, "Not an integer measure");
+    return intValue;
+  }
+
+  @Override
+  public long getLongValue() {
+    checkState(longValue != null, "Not a long measure");
+    return longValue;
+  }
+
+  @Override
+  public double getDoubleValue() {
+    checkState(doubleValue != null, "Not a double measure");
+    return doubleValue;
+  }
+
+  @Override
+  public String getStringValue() {
+    checkState(stringValue != null, "Not a string measure");
+    return stringValue;
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java
new file mode 100644 (file)
index 0000000..55ed021
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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.api.ce.measure.test;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import org.sonar.api.ce.measure.Component;
+import org.sonar.api.ce.measure.Issue;
+import org.sonar.api.ce.measure.Measure;
+import org.sonar.api.ce.measure.Settings;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.api.ce.measure.MeasureComputer.MeasureComputerContext;
+import static org.sonar.api.ce.measure.MeasureComputer.MeasureComputerDefinition;
+
+public class TestMeasureComputerContext implements MeasureComputerContext {
+
+  private final Component component;
+  private final MeasureComputerDefinition definition;
+  private final Settings settings;
+
+  private Map<String, Measure> componentMeasureByMetricKey = new HashMap<>();
+  private Multimap<String, Measure> childrenComponentMeasureByMetricKey = ArrayListMultimap.create();
+  private List<Issue> issues = new ArrayList<>();
+
+  public TestMeasureComputerContext(Component component, Settings settings, MeasureComputerDefinition definition) {
+    this.settings = settings;
+    this.component = component;
+    this.definition = definition;
+  }
+
+  @Override
+  public Component getComponent() {
+    return component;
+  }
+
+  @Override
+  public Settings getSettings() {
+    return settings;
+  }
+
+  @Override
+  @CheckForNull
+  public Measure getMeasure(String metric) {
+    validateInputMetric(metric);
+    return componentMeasureByMetricKey.get(metric);
+  }
+
+  @Override
+  public Iterable<Measure> getChildrenMeasures(String metric) {
+    validateInputMetric(metric);
+    return childrenComponentMeasureByMetricKey.get(metric);
+  }
+
+  @Override
+  public void addMeasure(String metricKey, int value) {
+    validateAddMeasure(metricKey);
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addInputMeasure(String metricKey, int value) {
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addChildrenMeasures(String metricKey, Integer... values) {
+    for (Integer value : values) {
+      childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+    }
+  }
+
+  @Override
+  public void addMeasure(String metricKey, double value) {
+    validateAddMeasure(metricKey);
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addInputMeasure(String metricKey, double value) {
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addChildrenMeasures(String metricKey, Double... values) {
+    for (Double value : values) {
+      childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+    }
+  }
+
+  @Override
+  public void addMeasure(String metricKey, long value) {
+    validateAddMeasure(metricKey);
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addInputMeasure(String metricKey, long value) {
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addChildrenMeasures(String metricKey, Long... values) {
+    for (Long value : values) {
+      childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+    }
+  }
+
+  @Override
+  public void addMeasure(String metricKey, String value) {
+    validateAddMeasure(metricKey);
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addInputMeasure(String metricKey, String value) {
+    componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+  }
+
+  public void addChildrenMeasures(String metricKey, String... values) {
+    for (String value : values) {
+      childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+    }
+  }
+
+  @Override
+  public List<Issue> getIssues() {
+    return issues;
+  }
+
+  public void setIssues(List<Issue> issues) {
+    this.issues = issues;
+  }
+
+  private void validateInputMetric(String metric) {
+    Set<String> allowedMetrics = new HashSet<>();
+    allowedMetrics.addAll(definition.getInputMetrics());
+    allowedMetrics.addAll(definition.getOutputMetrics());
+    checkArgument(allowedMetrics.contains(metric), "Only metrics in %s can be used to load measures", definition.getInputMetrics());
+  }
+
+  private void validateAddMeasure(String metricKey) {
+    checkArgument(definition.getOutputMetrics().contains(metricKey), "Only metrics in %s can be used to add measures. Metric '%s' is not allowed.",
+      definition.getOutputMetrics(), metricKey);
+    if (componentMeasureByMetricKey.get(metricKey) != null) {
+      throw new UnsupportedOperationException(String.format("A measure on metric '%s' already exists", metricKey));
+    }
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java
new file mode 100644 (file)
index 0000000..877a41a
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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.api.ce.measure.test;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import javax.annotation.Nullable;
+import org.sonar.api.ce.measure.MeasureComputer;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+public class TestMeasureComputerDefinition implements MeasureComputer.MeasureComputerDefinition {
+
+  private final Set<String> inputMetricKeys;
+  private final Set<String> outputMetrics;
+
+  private TestMeasureComputerDefinition(MeasureComputerDefinitionBuilderImpl builder) {
+    this.inputMetricKeys = ImmutableSet.copyOf(builder.inputMetricKeys);
+    this.outputMetrics = ImmutableSet.copyOf(builder.outputMetrics);
+  }
+
+  @Override
+  public Set<String> getInputMetrics() {
+    return inputMetricKeys;
+  }
+
+  @Override
+  public Set<String> getOutputMetrics() {
+    return outputMetrics;
+  }
+
+  public static class MeasureComputerDefinitionBuilderImpl implements Builder {
+
+    private String[] inputMetricKeys = new String[] {};
+    private String[] outputMetrics;
+
+    @Override
+    public Builder setInputMetrics(String... inputMetrics) {
+      this.inputMetricKeys = validateInputMetricKeys(inputMetrics);
+      return this;
+    }
+
+    @Override
+    public Builder setOutputMetrics(String... outputMetrics) {
+      this.outputMetrics = validateOutputMetricKeys(outputMetrics);
+      return this;
+    }
+
+    @Override
+    public MeasureComputer.MeasureComputerDefinition build() {
+      validateInputMetricKeys(this.inputMetricKeys);
+      validateOutputMetricKeys(this.outputMetrics);
+      return new TestMeasureComputerDefinition(this);
+    }
+
+    private static String[] validateInputMetricKeys(@Nullable String[] inputMetrics) {
+      requireNonNull(inputMetrics, "Input metrics cannot be null");
+      checkNotNull(inputMetrics);
+      return inputMetrics;
+    }
+
+    private static String[] validateOutputMetricKeys(@Nullable String[] outputMetrics) {
+      requireNonNull(outputMetrics, "Output metrics cannot be null");
+      checkArgument(outputMetrics.length > 0, "At least one output metric must be defined");
+      checkNotNull(outputMetrics);
+      return outputMetrics;
+    }
+  }
+
+  private static void checkNotNull(String[] metrics) {
+    for (String metric : metrics) {
+      requireNonNull(metric, "Null metric is not allowed");
+    }
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinitionContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinitionContext.java
new file mode 100644 (file)
index 0000000..64e4768
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.api.ce.measure.test;
+
+import org.sonar.api.ce.measure.MeasureComputer;
+
+public class TestMeasureComputerDefinitionContext implements MeasureComputer.MeasureComputerDefinitionContext {
+  @Override
+  public MeasureComputer.MeasureComputerDefinition.Builder newDefinitionBuilder() {
+    return new TestMeasureComputerDefinition.MeasureComputerDefinitionBuilderImpl();
+  }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestSettings.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestSettings.java
new file mode 100644 (file)
index 0000000..c169658
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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.api.ce.measure.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.ce.measure.Settings;
+
+public class TestSettings implements Settings {
+
+  private Map<String, String> valuesByKey = new HashMap<>();
+
+  public Settings setValue(String key, String value){
+    valuesByKey.put(key, value);
+    return this;
+  }
+
+  @Override
+  @CheckForNull
+  public String getString(String key) {
+    return valuesByKey.get(key);
+  }
+
+  @Override
+  public String[] getStringArray(String key) {
+    String value = getString(key);
+    if (value != null) {
+      String[] strings = StringUtils.splitByWholeSeparator(value, ",");
+      String[] result = new String[strings.length];
+      for (int index = 0; index < strings.length; index++) {
+        result[index] = StringUtils.trim(strings[index]);
+      }
+      return result;
+    }
+    return ArrayUtils.EMPTY_STRING_ARRAY;
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestComponentTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestComponentTest.java
new file mode 100644 (file)
index 0000000..139962b
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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.api.ce.measure.test;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.ce.measure.Component;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestComponentTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void create_project() throws Exception {
+    TestComponent component = new TestComponent("Project", Component.Type.PROJECT, null);
+
+    assertThat(component.getKey()).isEqualTo("Project");
+    assertThat(component.getType()).isEqualTo(Component.Type.PROJECT);
+  }
+
+  @Test
+  public void create_source_file() throws Exception {
+    TestComponent component = new TestComponent("File", Component.Type.FILE, new TestComponent.FileAttributesImpl("xoo", false));
+
+    assertThat(component.getType()).isEqualTo(Component.Type.FILE);
+    assertThat(component.getFileAttributes().getLanguageKey()).isEqualTo("xoo");
+    assertThat(component.getFileAttributes().isUnitTest()).isFalse();
+  }
+
+  @Test
+  public void create_test_file() throws Exception {
+    TestComponent component = new TestComponent("File", Component.Type.FILE, new TestComponent.FileAttributesImpl(null, true));
+
+    assertThat(component.getType()).isEqualTo(Component.Type.FILE);
+    assertThat(component.getFileAttributes().isUnitTest()).isTrue();
+    assertThat(component.getFileAttributes().getLanguageKey()).isNull();
+  }
+
+  @Test
+  public void fail_with_ISE_when_calling_get_file_attributes_on_not_file() throws Exception {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Only component of type FILE have a FileAttributes object");
+
+    TestComponent component = new TestComponent("Project", Component.Type.PROJECT, null);
+    component.getFileAttributes();
+  }
+
+  @Test
+  public void fail_with_IAE_when_trying_to_create_a_file_without_file_attributes() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("omponent of type FILE must have a FileAttributes object");
+
+    new TestComponent("File", Component.Type.FILE, null);
+  }
+
+  @Test
+  public void fail_with_IAE_when_trying_to_create_not_a_file_with_file_attributes() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Only component of type FILE have a FileAttributes object");
+
+    new TestComponent("Project", Component.Type.PROJECT, new TestComponent.FileAttributesImpl(null, true));
+  }
+
+  @Test
+  public void fail_with_NPE_when_creating_component_without_key() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("Key cannot be null");
+
+    new TestComponent(null, Component.Type.PROJECT, null);
+  }
+
+  @Test
+  public void fail_with_NPE_when_creating_component_without_type() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("Type cannot be null");
+
+    new TestComponent("Project", null, null);
+  }
+
+  @Test
+  public void test_equals_and_hashcode() throws Exception {
+    TestComponent component = new TestComponent("Project1", Component.Type.PROJECT, null);
+    TestComponent sameComponent = new TestComponent("Project1", Component.Type.PROJECT, null);
+    TestComponent anotherComponent = new TestComponent("Project2", Component.Type.PROJECT, null);
+
+    assertThat(component).isEqualTo(component);
+    assertThat(component).isEqualTo(sameComponent);
+    assertThat(component).isNotEqualTo(anotherComponent);
+    assertThat(component).isNotEqualTo(null);
+
+    assertThat(component.hashCode()).isEqualTo(component.hashCode());
+    assertThat(component.hashCode()).isEqualTo(sameComponent.hashCode());
+    assertThat(component.hashCode()).isNotEqualTo(anotherComponent.hashCode());
+  }
+
+  @Test
+  public void test_to_string() throws Exception {
+    assertThat(new TestComponent("File", Component.Type.FILE, new TestComponent.FileAttributesImpl("xoo", true)).toString())
+      .isEqualTo("ComponentImpl{key=File, type='FILE', fileAttributes=FileAttributesImpl{languageKey='xoo', unitTest=true}}");
+  }
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestIssueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestIssueTest.java
new file mode 100644 (file)
index 0000000..4696666
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * 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.api.ce.measure.test;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.ce.measure.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.Duration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestIssueTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void create_issue() throws Exception {
+    Issue issue = new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .setDebt(Duration.create(10L))
+      .build();
+
+    assertThat(issue.key()).isEqualTo("ABCD");
+    assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("xoo", "S01"));
+    assertThat(issue.severity()).isEqualTo(Severity.BLOCKER);
+    assertThat(issue.status()).isEqualTo(org.sonar.api.issue.Issue.STATUS_RESOLVED);
+    assertThat(issue.resolution()).isEqualTo(org.sonar.api.issue.Issue.RESOLUTION_FIXED);
+    assertThat(issue.debt()).isEqualTo(Duration.create(10L));
+  }
+
+  @Test
+  public void create_issue_with_minimal_fields() throws Exception {
+    Issue issue = new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .build();
+
+    assertThat(issue.resolution()).isNull();
+    assertThat(issue.debt()).isNull();
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_issue_without_key() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("key cannot be null");
+
+    new TestIssue.Builder()
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_creating_issue_with_null_key() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("key cannot be null");
+
+    new TestIssue.Builder().setKey(null);
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_issue_without_rule_key() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("ruleKey cannot be null");
+
+    new TestIssue.Builder()
+      .setKey("ABCD")
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_creating_issue_with_null_rule_key() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("ruleKey cannot be null");
+
+    new TestIssue.Builder().setRuleKey(null);
+  }
+
+  @Test
+  public void fail_with_IAE_when_building_issue_with_invalid_resolution() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("resolution 'unknown' is invalid");
+
+    new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .setResolution("unknown")
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_issue_without_severity() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("severity cannot be null");
+
+    new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_creating_issue_with_null_severity() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("severity cannot be null");
+
+    new TestIssue.Builder().setSeverity(null);
+  }
+
+  @Test
+  public void fail_with_IAE_when_building_issue_with_invalid_severity() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("severity 'unknown' is invalid");
+
+    new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity("unknown")
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_issue_without_status() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("status cannot be null");
+
+    new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity(Severity.BLOCKER)
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_creating_issue_with_null_status() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("status cannot be null");
+
+    new TestIssue.Builder().setStatus(null);
+  }
+
+  @Test
+  public void fail_with_IAE_when_building_issue_with_invalid_status() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("status 'unknown' is invalid");
+
+    new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity(Severity.BLOCKER)
+      .setStatus("unknown")
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .build();
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureComputerContextTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureComputerContextTest.java
new file mode 100644 (file)
index 0000000..8ad7b67
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * 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.api.ce.measure.test;
+
+import java.util.Arrays;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.ce.measure.Component;
+import org.sonar.api.ce.measure.Issue;
+import org.sonar.api.ce.measure.Settings;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.Duration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.ce.measure.MeasureComputer.MeasureComputerDefinition;
+
+public class TestMeasureComputerContextTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  static final String INPUT_METRIC = "INPUT_METRIC";
+  static final String OUTPUT_METRIC = "OUTPUT_METRIC";
+
+  final static Component PROJECT = new TestComponent("Project", Component.Type.PROJECT, null);
+
+  final static MeasureComputerDefinition DEFINITION = new TestMeasureComputerDefinition.MeasureComputerDefinitionBuilderImpl()
+    .setInputMetrics(INPUT_METRIC)
+    .setOutputMetrics(OUTPUT_METRIC)
+    .build();
+
+  Settings settings = new TestSettings();
+
+  TestMeasureComputerContext underTest = new TestMeasureComputerContext(PROJECT, settings, DEFINITION);
+
+  @Test
+  public void get_component() throws Exception {
+    assertThat(underTest.getComponent()).isEqualTo(PROJECT);
+  }
+
+  @Test
+  public void get_settings() throws Exception {
+    assertThat(underTest.getSettings()).isEqualTo(settings);
+  }
+
+  @Test
+  public void get_int_measure() throws Exception {
+    underTest.addInputMeasure(INPUT_METRIC, 10);
+
+    assertThat(underTest.getMeasure(INPUT_METRIC).getIntValue()).isEqualTo(10);
+  }
+
+  @Test
+  public void get_double_measure() throws Exception {
+    underTest.addInputMeasure(INPUT_METRIC, 10d);
+
+    assertThat(underTest.getMeasure(INPUT_METRIC).getDoubleValue()).isEqualTo(10d);
+  }
+
+  @Test
+  public void get_long_measure() throws Exception {
+    underTest.addInputMeasure(INPUT_METRIC, 10L);
+
+    assertThat(underTest.getMeasure(INPUT_METRIC).getLongValue()).isEqualTo(10L);
+  }
+
+  @Test
+  public void get_string_measure() throws Exception {
+    underTest.addInputMeasure(INPUT_METRIC, "text");
+
+    assertThat(underTest.getMeasure(INPUT_METRIC).getStringValue()).isEqualTo("text");
+  }
+
+  @Test
+  public void fail_with_IAE_when_trying_to_get_measure_on_unknown_metric() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Only metrics in [INPUT_METRIC] can be used to load measures");
+
+    underTest.getMeasure("unknown");
+  }
+
+  @Test
+  public void get_int_children_measures() throws Exception {
+    underTest.addChildrenMeasures(INPUT_METRIC, 10, 20);
+
+    assertThat(underTest.getChildrenMeasures(INPUT_METRIC)).hasSize(2);
+  }
+
+  @Test
+  public void get_doublet_children_measures() throws Exception {
+    underTest.addChildrenMeasures(INPUT_METRIC, 10d, 20d);
+
+    assertThat(underTest.getChildrenMeasures(INPUT_METRIC)).hasSize(2);
+  }
+
+  @Test
+  public void get_long_children_measures() throws Exception {
+    underTest.addChildrenMeasures(INPUT_METRIC, 10L, 20L);
+
+    assertThat(underTest.getChildrenMeasures(INPUT_METRIC)).hasSize(2);
+  }
+
+  @Test
+  public void get_string_children_measures() throws Exception {
+    underTest.addChildrenMeasures(INPUT_METRIC, "value1", "value2");
+
+    assertThat(underTest.getChildrenMeasures(INPUT_METRIC)).hasSize(2);
+  }
+
+  @Test
+  public void fail_with_IAE_when_trying_to_get_children_measures_on_unknown_metric() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Only metrics in [INPUT_METRIC] can be used to load measures");
+
+    underTest.getChildrenMeasures("unknown");
+  }
+
+  @Test
+  public void add_int_measure() throws Exception {
+    underTest.addMeasure(OUTPUT_METRIC, 10);
+
+    assertThat(underTest.getMeasure(OUTPUT_METRIC).getIntValue()).isEqualTo(10);
+  }
+
+  @Test
+  public void add_double_measure() throws Exception {
+    underTest.addMeasure(OUTPUT_METRIC, 10d);
+
+    assertThat(underTest.getMeasure(OUTPUT_METRIC).getDoubleValue()).isEqualTo(10d);
+  }
+
+  @Test
+  public void add_long_measure() throws Exception {
+    underTest.addMeasure(OUTPUT_METRIC, 10L);
+
+    assertThat(underTest.getMeasure(OUTPUT_METRIC).getLongValue()).isEqualTo(10L);
+  }
+
+  @Test
+  public void add_string_measure() throws Exception {
+    underTest.addMeasure(OUTPUT_METRIC, "text");
+
+    assertThat(underTest.getMeasure(OUTPUT_METRIC).getStringValue()).isEqualTo("text");
+  }
+
+  @Test
+  public void fail_with_IAE_when_trying_to_add_measure_on_unknown_metric() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Only metrics in [OUTPUT_METRIC] can be used to add measures. Metric 'unknown' is not allowed");
+
+    underTest.addMeasure("unknown", 10);
+  }
+
+  @Test
+  public void fail_with_IAE_when_trying_to_add_measure_on_input_metric() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Only metrics in [OUTPUT_METRIC] can be used to add measures. Metric 'INPUT_METRIC' is not allowed");
+
+    underTest.addMeasure(INPUT_METRIC, 10);
+  }
+
+  @Test
+  public void fail_with_UOE_when_trying_to_add_same_measures_twice() throws Exception {
+    thrown.expect(UnsupportedOperationException.class);
+    thrown.expectMessage("A measure on metric 'OUTPUT_METRIC' already exists");
+
+    underTest.addMeasure(OUTPUT_METRIC, 10);
+    underTest.addMeasure(OUTPUT_METRIC, 20);
+  }
+
+  @Test
+  public void get_issues() throws Exception {
+    Issue issue = new TestIssue.Builder()
+      .setKey("ABCD")
+      .setRuleKey(RuleKey.of("xoo", "S01"))
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(org.sonar.api.issue.Issue.STATUS_RESOLVED)
+      .setResolution(org.sonar.api.issue.Issue.RESOLUTION_FIXED)
+      .setDebt(Duration.create(10L))
+      .build();
+    underTest.setIssues(Arrays.asList(issue));
+
+    assertThat(underTest.getIssues()).hasSize(1);
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinitionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinitionTest.java
new file mode 100644 (file)
index 0000000..6a34b47
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * 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.api.ce.measure.test;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.ce.measure.MeasureComputer.MeasureComputerDefinition;
+import org.sonar.api.ce.measure.test.TestMeasureComputerDefinition.MeasureComputerDefinitionBuilderImpl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestMeasureComputerDefinitionTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void build_definition() throws Exception {
+    MeasureComputerDefinition definition = new MeasureComputerDefinitionBuilderImpl()
+      .setInputMetrics("INPUT_1", "INPUT_2")
+      .setOutputMetrics("OUTPUT_1", "OUTPUT_2")
+      .build();
+
+    assertThat(definition.getInputMetrics()).containsOnly("INPUT_1", "INPUT_2");
+    assertThat(definition.getOutputMetrics()).containsOnly("OUTPUT_1", "OUTPUT_2");
+  }
+
+  @Test
+  public void build_definition_without_input_metric() throws Exception {
+    MeasureComputerDefinition definition = new MeasureComputerDefinitionBuilderImpl()
+      .setOutputMetrics("OUTPUT_1", "OUTPUT_2")
+      .build();
+
+    assertThat(definition.getInputMetrics()).isEmpty();
+    assertThat(definition.getOutputMetrics()).containsOnly("OUTPUT_1", "OUTPUT_2");
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_definition_with_null_input_metrics() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("Input metrics cannot be null");
+
+    new MeasureComputerDefinitionBuilderImpl()
+      .setInputMetrics(null)
+      .setOutputMetrics("OUTPUT_1", "OUTPUT_2")
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_definition_with_on_null_input_metric() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("Null metric is not allowed");
+
+    new MeasureComputerDefinitionBuilderImpl()
+      .setInputMetrics("INPUT_1", null)
+      .setOutputMetrics("OUTPUT_1", "OUTPUT_2")
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_definition_with_null_output_metrics() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("Output metrics cannot be null");
+
+    new MeasureComputerDefinitionBuilderImpl()
+      .setInputMetrics("INPUT_1", "INPUT_2")
+      .setOutputMetrics(null)
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_definition_without_output_metrics() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("Output metrics cannot be null");
+
+    new MeasureComputerDefinitionBuilderImpl()
+      .setInputMetrics("INPUT_1", "INPUT_2")
+      .build();
+  }
+
+  @Test
+  public void fail_with_NPE_when_building_definition_with_on_null_ouput_metric() throws Exception {
+    thrown.expect(NullPointerException.class);
+    thrown.expectMessage("Null metric is not allowed");
+
+    new MeasureComputerDefinitionBuilderImpl()
+      .setInputMetrics("INPUT_1", "INPUT_2")
+      .setOutputMetrics("OUTPUT_1", null)
+      .build();
+  }
+
+  @Test
+  public void fail_with_IAE_when_building_definition_with_empty_output_metrics() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("At least one output metric must be defined");
+
+    new MeasureComputerDefinitionBuilderImpl()
+      .setInputMetrics("INPUT_1", "INPUT_2")
+      .setOutputMetrics()
+      .build();
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestMeasureTest.java
new file mode 100644 (file)
index 0000000..fb54b4b
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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.api.ce.measure.test;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestMeasureTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void create_double_measure() throws Exception {
+    assertThat(TestMeasure.createMeasure(10d).getDoubleValue()).isEqualTo(10d);
+  }
+
+  @Test
+  public void create_int_measure() throws Exception {
+    assertThat(TestMeasure.createMeasure(10).getIntValue()).isEqualTo(10);
+  }
+
+  @Test
+  public void create_long_measure() throws Exception {
+    assertThat(TestMeasure.createMeasure(10L).getLongValue()).isEqualTo(10L);
+  }
+
+  @Test
+  public void create_string_measure() throws Exception {
+    assertThat(TestMeasure.createMeasure("value").getStringValue()).isEqualTo("value");
+  }
+
+  @Test
+  public void getDoubleValue_fails_with_ISE_when_not_a_double() throws Exception {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Not a double measure");
+
+    TestMeasure.createMeasure(10).getDoubleValue();
+  }
+
+  @Test
+  public void getIntValue_fails_with_ISE_when_not_an_int() throws Exception {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Not an integer measure");
+
+    TestMeasure.createMeasure(10L).getIntValue();
+  }
+
+  @Test
+  public void getLongValue_fails_with_ISE_when_not_a_long() throws Exception {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Not a long measure");
+
+    TestMeasure.createMeasure(10).getLongValue();
+  }
+
+  @Test
+  public void getStringValue_fails_with_ISE_when_not_a_string() throws Exception {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Not a string measure");
+
+    TestMeasure.createMeasure(10).getStringValue();
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestSettingsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/test/TestSettingsTest.java
new file mode 100644 (file)
index 0000000..911be29
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.api.ce.measure.test;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestSettingsTest {
+
+  TestSettings underTest = new TestSettings();
+
+  @Test
+  public void get_string_value() throws Exception {
+    underTest.setValue("key", "value");
+
+    assertThat(underTest.getString("key")).isEqualTo("value");
+    assertThat(underTest.getString("unknown")).isNull();
+  }
+
+  @Test
+  public void get_string_array_value() throws Exception {
+    underTest.setValue("key", "value1,value2");
+
+    assertThat(underTest.getStringArray("key")).containsOnly("value1", "value2");
+    assertThat(underTest.getStringArray("unknown")).isEmpty();
+  }
+}