+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 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.plugins.core.technicaldebt;
-
-import com.google.common.collect.Lists;
-
-import javax.annotation.Nullable;
-
-import java.util.List;
-
-public final class Characteristic implements Characteristicable {
-
- private String key;
- private org.sonar.api.qualitymodel.Characteristic characteristic;
- private Characteristic parent = null;
- private List<Characteristic> subCharacteristics = Lists.newArrayList();
- private List<Requirement> requirements = Lists.newArrayList();
-
- public Characteristic(org.sonar.api.qualitymodel.Characteristic c) {
- this(c, null);
- }
-
- public Characteristic(org.sonar.api.qualitymodel.Characteristic c, @Nullable Characteristic parent) {
- this.characteristic = c;
- this.key = c.getKey();
- this.parent = parent;
- for (org.sonar.api.qualitymodel.Characteristic subc : c.getChildren()) {
- if (subc.getEnabled()) {
- if (subc.getRule() != null) {
- requirements.add(new Requirement(subc, this));
- } else {
- subCharacteristics.add(new Characteristic(subc, this));
- }
- }
- }
- }
-
- public String getKey() {
- return key;
- }
-
- public List<Characteristic> getSubCharacteristics() {
- return subCharacteristics;
- }
-
- public Characteristic getParent() {
- return parent;
- }
-
- public List<Requirement> getRequirements() {
- return requirements;
- }
-
- public org.sonar.api.qualitymodel.Characteristic toCharacteristic() {
- return characteristic;
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 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.plugins.core.technicaldebt;
-
-import org.sonar.api.rules.Rule;
-import org.sonar.plugins.core.technicaldebt.functions.LinearFunction;
-import org.sonar.plugins.core.technicaldebt.functions.LinearWithOffsetFunction;
-import org.sonar.plugins.core.technicaldebt.functions.LinearWithThresholdFunction;
-
-public class Requirement implements Characteristicable {
-
- public static final String PROPERTY_REMEDIATION_FUNCTION = "remediationFunction";
- public static final String PROPERTY_REMEDIATION_FACTOR = "remediationFactor";
- public static final String PROPERTY_OFFSET = "offset";
-
- private Rule rule;
- private Characteristic parent;
- private org.sonar.api.qualitymodel.Characteristic characteristic;
- private String function;
- private WorkUnit factor;
- private WorkUnit offset;
-
- public Requirement(org.sonar.api.qualitymodel.Characteristic requirement, Characteristic parent) {
- this.characteristic = requirement;
- this.rule = requirement.getRule();
- this.parent = parent;
-
- initFunction();
- initFactor();
- initOffset();
- }
-
- private void initFunction() {
- function = characteristic.getPropertyTextValue(PROPERTY_REMEDIATION_FUNCTION, LinearFunction.FUNCTION_LINEAR);
- }
-
- private void initFactor() {
- factor = WorkUnit.create(characteristic.getPropertyValue(PROPERTY_REMEDIATION_FACTOR, null),
- characteristic.getPropertyTextValue(PROPERTY_REMEDIATION_FACTOR, null));
- }
-
- private void initOffset() {
- if (LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET.equals(function) || LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD.equals(function)) {
- offset = WorkUnit.create(characteristic.getPropertyValue(PROPERTY_OFFSET, null),
- characteristic.getPropertyTextValue(PROPERTY_OFFSET, null));
- }
- }
-
- public Rule getRule() {
- return rule;
- }
-
- public Characteristic getParent() {
- return parent;
- }
-
- public String getRemediationFunction() {
- return function;
- }
-
- public WorkUnit getRemediationFactor() {
- return factor;
- }
-
- public WorkUnit getOffset() {
- return offset;
- }
-
- public org.sonar.api.qualitymodel.Characteristic toCharacteristic() {
- return characteristic;
- }
-}
public class TechnicalDebtCalculator implements BatchExtension {
private double total = 0.0;
- private Map<Characteristic, Double> characteristicCosts = Maps.newHashMap();
- private Map<Requirement, Double> requirementCosts = Maps.newHashMap();
+ private Map<TechnicalDebtCharacteristic, Double> characteristicCosts = Maps.newHashMap();
+ private Map<TechnicalDebtRequirement, Double> requirementCosts = Maps.newHashMap();
private Functions functions;
private TechnicalDebtModel technicalDebtModel;
reset();
// group violations by requirement
- ListMultimap<Requirement, Violation> violationsByRequirement = groupViolations(context);
+ ListMultimap<TechnicalDebtRequirement, Violation> violationsByRequirement = groupViolations(context);
// the total cost is: cost(violations)
- for (Requirement requirement : technicalDebtModel.getAllRequirements()) {
+ for (TechnicalDebtRequirement requirement : technicalDebtModel.getAllRequirements()) {
List<Violation> violations = violationsByRequirement.get(requirement);
double allViolationsCost = computeRemediationCost(CoreMetrics.TECHNICAL_DEBT, context, requirement, violations);
updateRequirementCosts(requirement, allViolationsCost);
return total;
}
- public Map<Characteristic, Double> getCharacteristicCosts() {
+ public Map<TechnicalDebtCharacteristic, Double> getCharacteristicCosts() {
return characteristicCosts;
}
- public Map<Requirement, Double> getRequirementCosts() {
+ public Map<TechnicalDebtRequirement, Double> getRequirementCosts() {
return requirementCosts;
}
@VisibleForTesting
- protected ListMultimap<Requirement, Violation> groupViolations(DecoratorContext context) {
- ListMultimap<Requirement, Violation> violationsByRequirement = ArrayListMultimap.create();
+ protected ListMultimap<TechnicalDebtRequirement, Violation> groupViolations(DecoratorContext context) {
+ ListMultimap<TechnicalDebtRequirement, Violation> violationsByRequirement = ArrayListMultimap.create();
for (Violation violation : context.getViolations()) {
String repositoryKey = violation.getRule().getRepositoryKey();
String key = violation.getRule().getKey();
- Requirement requirement = technicalDebtModel.getRequirementByRule(repositoryKey, key);
+ TechnicalDebtRequirement requirement = technicalDebtModel.getRequirementByRule(repositoryKey, key);
if (requirement == null) {
LoggerFactory.getLogger(getClass()).debug("No technical debt requirement for: " + repositoryKey + "/" + key);
} else {
}
@VisibleForTesting
- protected void updateRequirementCosts(Requirement requirement, double cost) {
+ protected void updateRequirementCosts(TechnicalDebtRequirement requirement, double cost) {
requirementCosts.put(requirement, cost);
total += cost;
propagateCostInParents(characteristicCosts, requirement.getParent(), cost);
}
- private double computeRemediationCost(Metric metric, DecoratorContext context, Requirement requirement, Collection<Violation> violations) {
+ private double computeRemediationCost(Metric metric, DecoratorContext context, TechnicalDebtRequirement requirement, Collection<Violation> violations) {
double cost = 0.0;
if (violations != null) {
cost = functions.calculateCost(requirement, violations);
requirementCosts.clear();
}
- private void propagateCostInParents(Map<Characteristic, Double> hierarchyMap, Characteristic characteristic, double cost) {
+ private void propagateCostInParents(Map<TechnicalDebtCharacteristic, Double> hierarchyMap, TechnicalDebtCharacteristic characteristic, double cost) {
if (characteristic != null) {
Double parentCost = hierarchyMap.get(characteristic);
if (parentCost == null) {
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.plugins.core.technicaldebt;
+
+import com.google.common.collect.Lists;
+
+import javax.annotation.Nullable;
+
+import java.util.List;
+
+public final class TechnicalDebtCharacteristic implements Characteristicable {
+
+ private String key;
+ private org.sonar.api.qualitymodel.Characteristic characteristic;
+ private TechnicalDebtCharacteristic parent = null;
+ private List<TechnicalDebtCharacteristic> subCharacteristics = Lists.newArrayList();
+ private List<TechnicalDebtRequirement> requirements = Lists.newArrayList();
+
+ public TechnicalDebtCharacteristic(org.sonar.api.qualitymodel.Characteristic c) {
+ this(c, null);
+ }
+
+ public TechnicalDebtCharacteristic(org.sonar.api.qualitymodel.Characteristic c, @Nullable TechnicalDebtCharacteristic parent) {
+ this.characteristic = c;
+ this.key = c.getKey();
+ this.parent = parent;
+ for (org.sonar.api.qualitymodel.Characteristic subc : c.getChildren()) {
+ if (subc.getEnabled()) {
+ if (subc.getRule() != null) {
+ requirements.add(new TechnicalDebtRequirement(subc, this));
+ } else {
+ subCharacteristics.add(new TechnicalDebtCharacteristic(subc, this));
+ }
+ }
+ }
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public List<TechnicalDebtCharacteristic> getSubCharacteristics() {
+ return subCharacteristics;
+ }
+
+ public TechnicalDebtCharacteristic getParent() {
+ return parent;
+ }
+
+ public List<TechnicalDebtRequirement> getRequirements() {
+ return requirements;
+ }
+
+ public org.sonar.api.qualitymodel.Characteristic toCharacteristic() {
+ return characteristic;
+ }
+}
return Arrays.asList(CoreMetrics.TECHNICAL_DEBT);
}
- @SuppressWarnings("rawtypes")
public void decorate(Resource resource, DecoratorContext context) {
if (!ResourceUtils.isUnitTestClass(resource)) {
costCalculator.compute(context);
}
private void saveCharacteristicCosts(DecoratorContext context) {
- for (Map.Entry<Characteristic, Double> entry : costCalculator.getCharacteristicCosts().entrySet()) {
+ for (Map.Entry<TechnicalDebtCharacteristic, Double> entry : costCalculator.getCharacteristicCosts().entrySet()) {
saveCost(context, entry.getKey().toCharacteristic(), entry.getValue(), false);
}
}
private void saveRequirementCosts(DecoratorContext context) {
- for (Map.Entry<Requirement, Double> entry : costCalculator.getRequirementCosts().entrySet()) {
+ for (Map.Entry<TechnicalDebtRequirement, Double> entry : costCalculator.getRequirementCosts().entrySet()) {
saveCost(context, entry.getKey().toCharacteristic(), entry.getValue(), ResourceUtils.isEntity(context.getResource()));
}
}
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonar.api.BatchExtension;
import org.sonar.api.qualitymodel.Model;
import org.sonar.api.qualitymodel.ModelFinder;
import org.sonar.api.rules.Rule;
import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.TimeProfiler;
import java.util.Collection;
import java.util.List;
public class TechnicalDebtModel implements BatchExtension {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TechnicalDebtModel.class);
+
// FIXME Use the same as in RegisterTechnicalDebtModel
public static final String MODEL_NAME = "TECHNICAL_DEBT";
- private List<Characteristic> characteristics = Lists.newArrayList();
- private Map<Rule, Requirement> requirementsByRule = Maps.newHashMap();
+ private List<TechnicalDebtCharacteristic> characteristics = Lists.newArrayList();
+ private Map<Rule, TechnicalDebtRequirement> requirementsByRule = Maps.newHashMap();
public TechnicalDebtModel(ModelFinder modelFinder) {
+ TimeProfiler profiler = new TimeProfiler(LOGGER).start("TechnicalDebtModel");
Model model = modelFinder.findByName(MODEL_NAME);
if (model == null) {
throw new SonarException("Can not find the model in database: " + MODEL_NAME);
}
init(model);
+ profiler.stop();
}
/**
private void init(Model model) {
for (org.sonar.api.qualitymodel.Characteristic characteristic : model.getRootCharacteristics()) {
if (characteristic.getEnabled()) {
- Characteristic sc = new Characteristic(characteristic);
+ TechnicalDebtCharacteristic sc = new TechnicalDebtCharacteristic(characteristic);
characteristics.add(sc);
registerRequirements(sc);
}
}
}
- private void registerRequirements(Characteristic c) {
- for (Requirement requirement : c.getRequirements()) {
+ private void registerRequirements(TechnicalDebtCharacteristic c) {
+ for (TechnicalDebtRequirement requirement : c.getRequirements()) {
if (requirement.getRule() != null) {
requirementsByRule.put(requirement.getRule(), requirement);
}
}
- for (Characteristic subCharacteristic : c.getSubCharacteristics()) {
+ for (TechnicalDebtCharacteristic subCharacteristic : c.getSubCharacteristics()) {
registerRequirements(subCharacteristic);
}
}
- public List<Characteristic> getCharacteristics() {
+ public List<TechnicalDebtCharacteristic> getCharacteristics() {
return characteristics;
}
- public Collection<Requirement> getAllRequirements() {
+ public Collection<TechnicalDebtRequirement> getAllRequirements() {
return requirementsByRule.values();
}
- public Requirement getRequirementByRule(String repositoryKey, String key) {
+ public TechnicalDebtRequirement getRequirementByRule(String repositoryKey, String key) {
return requirementsByRule.get(Rule.create().setUniqueKey(repositoryKey, key));
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.plugins.core.technicaldebt;
+
+import org.sonar.api.rules.Rule;
+import org.sonar.plugins.core.technicaldebt.functions.LinearFunction;
+import org.sonar.plugins.core.technicaldebt.functions.LinearWithOffsetFunction;
+import org.sonar.plugins.core.technicaldebt.functions.LinearWithThresholdFunction;
+
+public class TechnicalDebtRequirement implements Characteristicable {
+
+ public static final String PROPERTY_REMEDIATION_FUNCTION = "remediationFunction";
+ public static final String PROPERTY_REMEDIATION_FACTOR = "remediationFactor";
+ public static final String PROPERTY_OFFSET = "offset";
+
+ private Rule rule;
+ private TechnicalDebtCharacteristic parent;
+ private org.sonar.api.qualitymodel.Characteristic characteristic;
+ private String function;
+ private WorkUnit factor;
+ private WorkUnit offset;
+
+ public TechnicalDebtRequirement(org.sonar.api.qualitymodel.Characteristic requirement, TechnicalDebtCharacteristic parent) {
+ this.characteristic = requirement;
+ this.rule = requirement.getRule();
+ this.parent = parent;
+
+ initFunction();
+ initFactor();
+ initOffset();
+ }
+
+ private void initFunction() {
+ function = characteristic.getPropertyTextValue(PROPERTY_REMEDIATION_FUNCTION, LinearFunction.FUNCTION_LINEAR);
+ }
+
+ private void initFactor() {
+ factor = WorkUnit.create(characteristic.getPropertyValue(PROPERTY_REMEDIATION_FACTOR, null),
+ characteristic.getPropertyTextValue(PROPERTY_REMEDIATION_FACTOR, null));
+ }
+
+ private void initOffset() {
+ if (LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET.equals(function) || LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD.equals(function)) {
+ offset = WorkUnit.create(characteristic.getPropertyValue(PROPERTY_OFFSET, null),
+ characteristic.getPropertyTextValue(PROPERTY_OFFSET, null));
+ }
+ }
+
+ public Rule getRule() {
+ return rule;
+ }
+
+ public TechnicalDebtCharacteristic getParent() {
+ return parent;
+ }
+
+ public String getRemediationFunction() {
+ return function;
+ }
+
+ public WorkUnit getRemediationFactor() {
+ return factor;
+ }
+
+ public WorkUnit getOffset() {
+ return offset;
+ }
+
+ public org.sonar.api.qualitymodel.Characteristic toCharacteristic() {
+ return characteristic;
+ }
+}
package org.sonar.plugins.core.technicaldebt.functions;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
import java.util.Collection;
public abstract String getKey();
- public abstract double calculateCost(Requirement requirement, Collection<Violation> violations);
+ public abstract double calculateCost(TechnicalDebtRequirement requirement, Collection<Violation> violations);
}
package org.sonar.plugins.core.technicaldebt.functions;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
import java.util.Collection;
return FUNCTION_CONSTANT_RESOURCE;
}
- public double calculateCost(Requirement requirement, Collection<Violation> violations) {
+ public double calculateCost(TechnicalDebtRequirement requirement, Collection<Violation> violations) {
double cost = 0.0;
if (!violations.isEmpty()) {
cost = getConverter().toDays(requirement.getRemediationFactor());
import org.sonar.api.BatchExtension;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import java.util.Collection;
String getKey();
- double calculateCost(Requirement requirement, Collection<Violation> violations);
+ double calculateCost(TechnicalDebtRequirement requirement, Collection<Violation> violations);
}
import com.google.common.collect.Maps;
import org.sonar.api.BatchExtension;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import java.util.Collection;
import java.util.Map;
return functionsByKey.get(key);
}
- public Function getFunction(Requirement requirement) {
+ public Function getFunction(TechnicalDebtRequirement requirement) {
return getFunction(requirement.getRemediationFunction());
}
- public double calculateCost(Requirement requirement, Collection<Violation> violations) {
+ public double calculateCost(TechnicalDebtRequirement requirement, Collection<Violation> violations) {
return getFunction(requirement).calculateCost(requirement, violations);
}
package org.sonar.plugins.core.technicaldebt.functions;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
import java.util.Collection;
return FUNCTION_LINEAR;
}
- public double calculateCost(Requirement requirement, Collection<Violation> violations) {
+ public double calculateCost(TechnicalDebtRequirement requirement, Collection<Violation> violations) {
double points = 0.0;
for (Violation violation : violations) {
points += (violation.getCost() != null ? violation.getCost() : DEFAULT_VIOLATION_COST);
package org.sonar.plugins.core.technicaldebt.functions;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
import java.util.Collection;
return FUNCTION_LINEAR_WITH_OFFSET;
}
- public double calculateCost(Requirement requirement, Collection<Violation> violations) {
+ public double calculateCost(TechnicalDebtRequirement requirement, Collection<Violation> violations) {
if (violations.isEmpty()) {
return 0.0;
}
package org.sonar.plugins.core.technicaldebt.functions;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
import java.util.Collection;
return FUNCTION_LINEAR_WITH_THRESHOLD;
}
- public double calculateCost(Requirement requirement, Collection<Violation> violations) {
+ public double calculateCost(TechnicalDebtRequirement requirement, Collection<Violation> violations) {
if (violations.isEmpty()) {
return 0.0;
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 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.plugins.core.technicaldebt;
-
-import org.junit.Test;
-import org.sonar.api.qualitymodel.Characteristic;
-import org.sonar.plugins.core.technicaldebt.functions.ConstantFunction;
-import org.sonar.plugins.core.technicaldebt.functions.LinearFunction;
-import org.sonar.plugins.core.technicaldebt.functions.LinearWithOffsetFunction;
-import org.sonar.plugins.core.technicaldebt.functions.LinearWithThresholdFunction;
-
-import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-public class RequirementTest {
-
- @Test
- public void defaultFactor() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFactor().getValue(), is(WorkUnit.DEFAULT_VALUE));
- assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DEFAULT_UNIT));
- }
-
- @Test
- public void testOverriddenFactor() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- persistedRequirement.setProperty(Requirement.PROPERTY_REMEDIATION_FACTOR, 3.14);
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFactor().getValue(), is(3.14));
- assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DAYS));
- }
-
- @Test
- public void defaultFunctionIsLinear() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFunction(), is(LinearFunction.FUNCTION_LINEAR));
- assertThat(requirement.getOffset(), is(nullValue()));
- }
-
- @Test
- public void testOverriddenFunction() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- persistedRequirement.setProperty(Requirement.PROPERTY_REMEDIATION_FUNCTION, ConstantFunction.FUNCTION_CONSTANT_RESOURCE);
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFunction(), is(ConstantFunction.FUNCTION_CONSTANT_RESOURCE));
- }
-
- @Test
- public void testDefaultLinearWithOffset() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- persistedRequirement.setProperty(Requirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET);
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFunction(), is(LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET));
- assertThat(requirement.getRemediationFactor().getValue(), is(WorkUnit.DEFAULT_VALUE));
- assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DEFAULT_UNIT));
- assertThat(requirement.getOffset().getValue(), is(WorkUnit.DEFAULT_VALUE));
- assertThat(requirement.getOffset().getUnit(), is(WorkUnit.DEFAULT_UNIT));
- }
-
- @Test
- public void testCustomizedLinearWithOffset() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- persistedRequirement.setProperty(Requirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET);
- persistedRequirement.setProperty(Requirement.PROPERTY_OFFSET, 5.0);
- persistedRequirement.addProperty(persistedRequirement.getProperty(Requirement.PROPERTY_OFFSET).setTextValue("h"));
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFunction(), is(LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET));
- assertThat(requirement.getOffset().getValue(), is(5.0));
- assertThat(requirement.getOffset().getUnit(), is(WorkUnit.HOURS));
- }
-
- @Test
- public void testDefaultLinearWithThreshold() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- persistedRequirement.setProperty(Requirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD);
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFunction(), is(LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD));
- assertThat(requirement.getRemediationFactor().getValue(), is(WorkUnit.DEFAULT_VALUE));
- assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DEFAULT_UNIT));
- assertThat(requirement.getOffset().getValue(), is(WorkUnit.DEFAULT_VALUE));
- assertThat(requirement.getOffset().getUnit(), is(WorkUnit.DEFAULT_UNIT));
- }
-
- @Test
- public void testCustomizedLinearWithThreshold() {
- Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
- persistedRequirement.setProperty(Requirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD);
- persistedRequirement.setProperty(Requirement.PROPERTY_OFFSET, 5.0);
- persistedRequirement.addProperty(persistedRequirement.getProperty(Requirement.PROPERTY_OFFSET).setTextValue("h"));
- Requirement requirement = new Requirement(persistedRequirement, null);
- assertThat(requirement.getRemediationFunction(), is(LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD));
- assertThat(requirement.getOffset().getValue(), is(5.0));
- assertThat(requirement.getOffset().getUnit(), is(WorkUnit.HOURS));
- }
-}
@Test
public void group_violations_by_requirement() throws Exception {
- Requirement requirement1 = mock(Requirement.class);
- Requirement requirement2 = mock(Requirement.class);
+ TechnicalDebtRequirement requirement1 = mock(TechnicalDebtRequirement.class);
+ TechnicalDebtRequirement requirement2 = mock(TechnicalDebtRequirement.class);
Violation violation1 = buildViolation("rule1", "repo1", NOW);
Violation violation2 = buildViolation("rule1", "repo1", NOW);
DecoratorContext context = mock(DecoratorContext.class);
when(context.getViolations()).thenReturn(violations);
- ListMultimap<Requirement, Violation> groupedViolations = remediationCostCalculator.groupViolations(context);
+ ListMultimap<TechnicalDebtRequirement, Violation> groupedViolations = remediationCostCalculator.groupViolations(context);
assertThat(groupedViolations.keySet().size()).isEqualTo(2);
assertThat(groupedViolations.get(requirement1)).containsExactly(violation1, violation2);
double requirementCost = 1.0;
- Requirement requirement = mock(Requirement.class);
+ TechnicalDebtRequirement requirement = mock(TechnicalDebtRequirement.class);
when(requirement.getParent()).thenReturn(null);
remediationCostCalculator.updateRequirementCosts(requirement, requirementCost);
double requirementCost = 1.0;
- Characteristic parentCharacteristic = new Characteristic(org.sonar.api.qualitymodel.Characteristic.create());
+ TechnicalDebtCharacteristic parentCharacteristic = new TechnicalDebtCharacteristic(org.sonar.api.qualitymodel.Characteristic.create());
- Characteristic characteristic = new Characteristic(org.sonar.api.qualitymodel.Characteristic.create(), parentCharacteristic);
+ TechnicalDebtCharacteristic characteristic = new TechnicalDebtCharacteristic(org.sonar.api.qualitymodel.Characteristic.create(), parentCharacteristic);
- Requirement requirement = mock(Requirement.class);
+ TechnicalDebtRequirement requirement = mock(TechnicalDebtRequirement.class);
when(requirement.getParent()).thenReturn(characteristic);
remediationCostCalculator.updateRequirementCosts(requirement, requirementCost);
@Test
public void compute_totals_costs() throws Exception {
- Requirement requirement1 = mock(Requirement.class);
- Requirement requirement2 = mock(Requirement.class);
+ TechnicalDebtRequirement requirement1 = mock(TechnicalDebtRequirement.class);
+ TechnicalDebtRequirement requirement2 = mock(TechnicalDebtRequirement.class);
Violation violation1 = buildViolation("rule1", "repo1", NOW);
Violation violation2 = buildViolation("rule1", "repo1", NOW);
stub(technicalDebtModel.getRequirementByRule("repo2", "rule2")).toReturn(requirement2);
stub(technicalDebtModel.getAllRequirements()).toReturn(Lists.newArrayList(requirement1, requirement2));
- stub(functions.calculateCost(any(Requirement.class), any(Collection.class))).toReturn(1.0);
+ stub(functions.calculateCost(any(TechnicalDebtRequirement.class), any(Collection.class))).toReturn(1.0);
DecoratorContext context = mock(DecoratorContext.class);
stub(context.getViolations()).toReturn(violations);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.plugins.core.technicaldebt;
+
+import org.junit.Test;
+import org.sonar.api.qualitymodel.Characteristic;
+import org.sonar.plugins.core.technicaldebt.functions.ConstantFunction;
+import org.sonar.plugins.core.technicaldebt.functions.LinearFunction;
+import org.sonar.plugins.core.technicaldebt.functions.LinearWithOffsetFunction;
+import org.sonar.plugins.core.technicaldebt.functions.LinearWithThresholdFunction;
+
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class TechnicalDebtRequirementTest {
+
+ @Test
+ public void defaultFactor() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFactor().getValue(), is(WorkUnit.DEFAULT_VALUE));
+ assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DEFAULT_UNIT));
+ }
+
+ @Test
+ public void testOverriddenFactor() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_REMEDIATION_FACTOR, 3.14);
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFactor().getValue(), is(3.14));
+ assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DAYS));
+ }
+
+ @Test
+ public void defaultFunctionIsLinear() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFunction(), is(LinearFunction.FUNCTION_LINEAR));
+ assertThat(requirement.getOffset(), is(nullValue()));
+ }
+
+ @Test
+ public void testOverriddenFunction() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_REMEDIATION_FUNCTION, ConstantFunction.FUNCTION_CONSTANT_RESOURCE);
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFunction(), is(ConstantFunction.FUNCTION_CONSTANT_RESOURCE));
+ }
+
+ @Test
+ public void testDefaultLinearWithOffset() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET);
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFunction(), is(LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET));
+ assertThat(requirement.getRemediationFactor().getValue(), is(WorkUnit.DEFAULT_VALUE));
+ assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DEFAULT_UNIT));
+ assertThat(requirement.getOffset().getValue(), is(WorkUnit.DEFAULT_VALUE));
+ assertThat(requirement.getOffset().getUnit(), is(WorkUnit.DEFAULT_UNIT));
+ }
+
+ @Test
+ public void testCustomizedLinearWithOffset() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET);
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_OFFSET, 5.0);
+ persistedRequirement.addProperty(persistedRequirement.getProperty(TechnicalDebtRequirement.PROPERTY_OFFSET).setTextValue("h"));
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFunction(), is(LinearWithOffsetFunction.FUNCTION_LINEAR_WITH_OFFSET));
+ assertThat(requirement.getOffset().getValue(), is(5.0));
+ assertThat(requirement.getOffset().getUnit(), is(WorkUnit.HOURS));
+ }
+
+ @Test
+ public void testDefaultLinearWithThreshold() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD);
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFunction(), is(LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD));
+ assertThat(requirement.getRemediationFactor().getValue(), is(WorkUnit.DEFAULT_VALUE));
+ assertThat(requirement.getRemediationFactor().getUnit(), is(WorkUnit.DEFAULT_UNIT));
+ assertThat(requirement.getOffset().getValue(), is(WorkUnit.DEFAULT_VALUE));
+ assertThat(requirement.getOffset().getUnit(), is(WorkUnit.DEFAULT_UNIT));
+ }
+
+ @Test
+ public void testCustomizedLinearWithThreshold() {
+ Characteristic persistedRequirement = Characteristic.createByName("Efficiency");
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_REMEDIATION_FUNCTION, LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD);
+ persistedRequirement.setProperty(TechnicalDebtRequirement.PROPERTY_OFFSET, 5.0);
+ persistedRequirement.addProperty(persistedRequirement.getProperty(TechnicalDebtRequirement.PROPERTY_OFFSET).setTextValue("h"));
+ TechnicalDebtRequirement requirement = new TechnicalDebtRequirement(persistedRequirement, null);
+ assertThat(requirement.getRemediationFunction(), is(LinearWithThresholdFunction.FUNCTION_LINEAR_WITH_THRESHOLD));
+ assertThat(requirement.getOffset().getValue(), is(5.0));
+ assertThat(requirement.getOffset().getUnit(), is(WorkUnit.HOURS));
+ }
+}
import org.junit.Test;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnit;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
public class ConstantFunctionTest {
- private Requirement requirement;
+ private TechnicalDebtRequirement requirement;
private Function function;
@Before
public void before() {
function = new ConstantFunction(new WorkUnitConverter(new PropertiesConfiguration()));
- requirement = mock(Requirement.class);
+ requirement = mock(TechnicalDebtRequirement.class);
when(requirement.getRemediationFactor()).thenReturn(WorkUnit.createInDays(3.14));
}
import org.junit.Test;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnit;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
public class LinearFunctionTest {
- private Requirement requirement;
+ private TechnicalDebtRequirement requirement;
private Function function = new LinearFunction(new WorkUnitConverter(new PropertiesConfiguration()));
@Before
public void before() {
- requirement = mock(Requirement.class);
+ requirement = mock(TechnicalDebtRequirement.class);
when(requirement.getRemediationFactor()).thenReturn(WorkUnit.createInDays(3.14));
}
import org.junit.Test;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnit;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
public class LinearWithOffsetFunctionTest {
- private Requirement requirement;
+ private TechnicalDebtRequirement requirement;
private Function function = new LinearWithOffsetFunction(new WorkUnitConverter(new PropertiesConfiguration()));
@Before
public void before() {
- requirement = mock(Requirement.class);
+ requirement = mock(TechnicalDebtRequirement.class);
when(requirement.getRemediationFactor()).thenReturn(WorkUnit.createInDays(3.14));
when(requirement.getOffset()).thenReturn(WorkUnit.createInDays(2.12));
}
import org.junit.Test;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.Violation;
-import org.sonar.plugins.core.technicaldebt.Requirement;
+import org.sonar.plugins.core.technicaldebt.TechnicalDebtRequirement;
import org.sonar.plugins.core.technicaldebt.WorkUnit;
import org.sonar.plugins.core.technicaldebt.WorkUnitConverter;
public class LinearWithThresholdFunctionTest {
- private Requirement requirement;
+ private TechnicalDebtRequirement requirement;
private Function function = new LinearWithThresholdFunction(new WorkUnitConverter(new PropertiesConfiguration()));
@Before
public void before() {
- requirement = mock(Requirement.class);
+ requirement = mock(TechnicalDebtRequirement.class);
when(requirement.getRemediationFactor()).thenReturn(WorkUnit.createInDays(2.0));
when(requirement.getOffset()).thenReturn(WorkUnit.createInDays(5.0));
}