summaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2013-11-28 18:46:26 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2013-11-28 18:47:39 +0100
commit32a20516bb3bcd67e08aa8136df68bfe2565aab6 (patch)
treeb93d15b1d3664907a8095d28e9d2d1e09b6916d2 /sonar-batch
parent9b0e7a93043f93e65181c9d152f06feceadc702f (diff)
downloadsonarqube-32a20516bb3bcd67e08aa8136df68bfe2565aab6.tar.gz
sonarqube-32a20516bb3bcd67e08aa8136df68bfe2565aab6.zip
SONAR-4831 Refactored technical debt
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java14
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculator.java12
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoader.java103
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProvider.java7
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculatorTest.java26
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoaderTest.java115
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProviderTest.java27
8 files changed, 262 insertions, 46 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java
index f7b821493ad..88ce12563d1 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java
@@ -31,10 +31,10 @@ import org.sonar.api.measures.Metric;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
-import org.sonar.api.technicaldebt.Characteristic;
-import org.sonar.api.technicaldebt.Requirement;
+import org.sonar.api.technicaldebt.batch.Characteristic;
+import org.sonar.api.technicaldebt.batch.Requirement;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
import org.sonar.batch.index.DefaultIndex;
-import org.sonar.core.technicaldebt.TechnicalDebtModel;
import javax.annotation.Nullable;
import javax.persistence.Query;
@@ -100,10 +100,10 @@ public class DefaultTimeMachine implements TimeMachine {
sb.append("SELECT s.createdAt, m.metricId, m.value ");
}
sb.append(" FROM ")
- .append(MeasureModel.class.getSimpleName())
- .append(" m, ")
- .append(Snapshot.class.getSimpleName())
- .append(" s WHERE m.snapshotId=s.id AND s.resourceId=:resourceId AND s.status=:status AND s.qualifier<>:lib");
+ .append(MeasureModel.class.getSimpleName())
+ .append(" m, ")
+ .append(Snapshot.class.getSimpleName())
+ .append(" s WHERE m.snapshotId=s.id AND s.resourceId=:resourceId AND s.status=:status AND s.qualifier<>:lib");
params.put("resourceId", resource.getId());
params.put("status", Snapshot.STATUS_PROCESSED);
params.put("lib", Qualifiers.LIBRARY);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
index 3e27654af56..2c18795727d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
@@ -45,6 +45,7 @@ import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
import org.sonar.batch.source.HighlightableBuilder;
import org.sonar.batch.source.SymbolizableBuilder;
+import org.sonar.batch.technicaldebt.TechnicalDebtModelLoader;
import org.sonar.batch.technicaldebt.TechnicalDebtModelProvider;
import org.sonar.core.component.ScanGraph;
import org.sonar.core.issue.IssueNotifications;
@@ -53,7 +54,6 @@ import org.sonar.core.issue.workflow.FunctionExecutor;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.technicaldebt.TechnicalDebtConverter;
-import org.sonar.core.technicaldebt.TechnicalDebtFinder;
import org.sonar.core.test.TestPlanBuilder;
import org.sonar.core.test.TestPlanPerspectiveLoader;
import org.sonar.core.test.TestableBuilder;
@@ -148,7 +148,7 @@ public class ProjectScanContainer extends ComponentContainer {
SymbolizableBuilder.class,
// technical debt
- TechnicalDebtFinder.class,
+ TechnicalDebtModelLoader.class,
TechnicalDebtConverter.class,
new TechnicalDebtModelProvider(),
diff --git a/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculator.java b/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculator.java
index cbb83221a26..2e71d86e640 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculator.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculator.java
@@ -23,10 +23,10 @@ import com.google.common.base.Objects;
import org.sonar.api.BatchExtension;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.WorkDayDuration;
-import org.sonar.api.technicaldebt.Requirement;
import org.sonar.api.technicaldebt.WorkUnit;
+import org.sonar.api.technicaldebt.batch.Requirement;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
import org.sonar.core.technicaldebt.TechnicalDebtConverter;
-import org.sonar.core.technicaldebt.TechnicalDebtModel;
/**
* Computes the remediation cost based on the quality and analysis models.
@@ -34,15 +34,15 @@ import org.sonar.core.technicaldebt.TechnicalDebtModel;
public class TechnicalDebtCalculator implements BatchExtension {
private final TechnicalDebtConverter converter;
- private TechnicalDebtModel technicalDebtModel;
+ private TechnicalDebtModel model;
- public TechnicalDebtCalculator(TechnicalDebtModel technicalDebtModel, TechnicalDebtConverter converter) {
- this.technicalDebtModel = technicalDebtModel;
+ public TechnicalDebtCalculator(TechnicalDebtModel model, TechnicalDebtConverter converter) {
+ this.model = model;
this.converter = converter;
}
public WorkDayDuration calculTechnicalDebt(Issue issue) {
- Requirement requirement = technicalDebtModel.requirementsByRule(issue.ruleKey());
+ Requirement requirement = model.requirementsByRule(issue.ruleKey());
if (requirement != null) {
return converter.fromMinutes(calculTechnicalDebt(requirement, issue));
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoader.java b/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoader.java
new file mode 100644
index 00000000000..1c8fac76f42
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoader.java
@@ -0,0 +1,103 @@
+/*
+ * 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.batch.technicaldebt;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.rules.RuleQuery;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
+import org.sonar.api.technicaldebt.internal.DefaultCharacteristic;
+import org.sonar.core.technicaldebt.DefaultTechnicalDebtModel;
+import org.sonar.core.technicaldebt.db.CharacteristicDao;
+import org.sonar.core.technicaldebt.db.CharacteristicDto;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+public class TechnicalDebtModelLoader implements BatchComponent {
+
+ private final CharacteristicDao dao;
+ private final RuleFinder ruleFinder;
+
+ public TechnicalDebtModelLoader(CharacteristicDao dao, RuleFinder ruleFinder) {
+ this.dao = dao;
+ this.ruleFinder = ruleFinder;
+ }
+
+ public TechnicalDebtModel load() {
+ DefaultTechnicalDebtModel model = new DefaultTechnicalDebtModel();
+ List<CharacteristicDto> dtos = dao.selectEnabledCharacteristics();
+ Map<Integer, DefaultCharacteristic> characteristicsById = newHashMap();
+
+ addRootCharacteristics(model, dtos, characteristicsById);
+ addCharacteristics(model, dtos, characteristicsById);
+ addRequirements(model, dtos, characteristicsById);
+ return model;
+ }
+
+ private void addRootCharacteristics(DefaultTechnicalDebtModel model, List<CharacteristicDto> dtos, Map<Integer, DefaultCharacteristic> characteristicsById) {
+ for (CharacteristicDto dto : dtos) {
+ if (dto.getParentId() == null) {
+ DefaultCharacteristic rootCharacteristic = dto.toCharacteristic(null);
+ model.addRootCharacteristic(rootCharacteristic);
+ characteristicsById.put(dto.getId(), rootCharacteristic);
+ }
+ }
+ }
+
+ private void addCharacteristics(DefaultTechnicalDebtModel model, List<CharacteristicDto> dtos, Map<Integer, DefaultCharacteristic> characteristicsById) {
+ for (CharacteristicDto dto : dtos) {
+ if (dto.getParentId() != null && dto.getRuleId() == null) {
+ DefaultCharacteristic parent = characteristicsById.get(dto.getParentId());
+ DefaultCharacteristic characteristic = dto.toCharacteristic(parent);
+ characteristicsById.put(dto.getId(), characteristic);
+ }
+ }
+ }
+
+ private void addRequirements(DefaultTechnicalDebtModel model, List<CharacteristicDto> dtos, Map<Integer, DefaultCharacteristic> characteristicsById) {
+ Map<Integer, Rule> rulesById = rulesById(ruleFinder.findAll(RuleQuery.create()));
+ for (CharacteristicDto dto : dtos) {
+ Integer ruleId = dto.getRuleId();
+ if (ruleId != null) {
+ DefaultCharacteristic characteristic = characteristicsById.get(dto.getParentId());
+ DefaultCharacteristic rootCharacteristic = characteristicsById.get(dto.getRootId());
+ Rule rule = rulesById.get(ruleId);
+ RuleKey ruleKey = RuleKey.of(rule.getRepositoryKey(), rule.getKey());
+ dto.toRequirement(ruleKey, characteristic, rootCharacteristic);
+ }
+ }
+ }
+
+ private Map<Integer, Rule> rulesById(Collection<Rule> rules) {
+ Map<Integer, Rule> rulesById = newHashMap();
+ for (Rule rule : rules) {
+ rulesById.put(rule.getId(), rule);
+ }
+ return rulesById;
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProvider.java b/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProvider.java
index 1bb8e0642e2..24ea9b6543f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProvider.java
@@ -23,9 +23,8 @@ package org.sonar.batch.technicaldebt;
import org.picocontainer.injectors.ProviderAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
import org.sonar.api.utils.TimeProfiler;
-import org.sonar.core.technicaldebt.TechnicalDebtFinder;
-import org.sonar.core.technicaldebt.TechnicalDebtModel;
public class TechnicalDebtModelProvider extends ProviderAdapter {
@@ -33,10 +32,10 @@ public class TechnicalDebtModelProvider extends ProviderAdapter {
private TechnicalDebtModel model;
- public TechnicalDebtModel provide(TechnicalDebtFinder modelFinder) {
+ public TechnicalDebtModel provide(TechnicalDebtModelLoader loader) {
if (model == null) {
TimeProfiler profiler = new TimeProfiler(LOG).start("Loading technical debt model");
- model = modelFinder.findAll();
+ model = loader.load();
profiler.stop();
}
return model;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculatorTest.java b/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculatorTest.java
index ae829e70e55..acf0d993d0c 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculatorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculatorTest.java
@@ -27,10 +27,10 @@ import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.technicaldebt.Requirement;
import org.sonar.api.technicaldebt.WorkUnit;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
+import org.sonar.api.technicaldebt.internal.DefaultRequirement;
import org.sonar.core.technicaldebt.TechnicalDebtConverter;
-import org.sonar.core.technicaldebt.TechnicalDebtModel;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.*;
@@ -39,7 +39,7 @@ import static org.mockito.Mockito.*;
public class TechnicalDebtCalculatorTest {
@Mock
- TechnicalDebtModel technicalDebtModel;
+ TechnicalDebtModel model;
@Mock
TechnicalDebtConverter converter;
@@ -54,7 +54,7 @@ public class TechnicalDebtCalculatorTest {
when(converter.toMinutes(tenMinutes)).thenReturn(10l);
when(converter.toMinutes(fiveMinutes)).thenReturn(5l);
- remediationCostCalculator = new TechnicalDebtCalculator(technicalDebtModel, converter);
+ remediationCostCalculator = new TechnicalDebtCalculator(model, converter);
}
@Test
@@ -62,10 +62,10 @@ public class TechnicalDebtCalculatorTest {
RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey);
- Requirement requirement = mock(Requirement.class);
+ DefaultRequirement requirement = mock(DefaultRequirement.class);
Mockito.when(requirement.factor()).thenReturn(tenMinutes);
Mockito.when(requirement.offset()).thenReturn(fiveMinutes);
- when(technicalDebtModel.requirementsByRule(ruleKey)).thenReturn(requirement);
+ when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
remediationCostCalculator.calculTechnicalDebt(issue);
@@ -77,10 +77,10 @@ public class TechnicalDebtCalculatorTest {
RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey).setEffortToFix(2d);
- Requirement requirement = mock(Requirement.class);
+ DefaultRequirement requirement = mock(DefaultRequirement.class);
Mockito.when(requirement.factor()).thenReturn(tenMinutes);
Mockito.when(requirement.offset()).thenReturn(fiveMinutes);
- when(technicalDebtModel.requirementsByRule(ruleKey)).thenReturn(requirement);
+ when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
remediationCostCalculator.calculTechnicalDebt(issue);
@@ -92,10 +92,10 @@ public class TechnicalDebtCalculatorTest {
RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey).setEffortToFix(2d);
- Requirement requirement = mock(Requirement.class);
+ DefaultRequirement requirement = mock(DefaultRequirement.class);
Mockito.when(requirement.factor()).thenReturn(tenMinutes);
Mockito.when(requirement.offset()).thenReturn(null);
- when(technicalDebtModel.requirementsByRule(ruleKey)).thenReturn(requirement);
+ when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
remediationCostCalculator.calculTechnicalDebt(issue);
@@ -107,10 +107,10 @@ public class TechnicalDebtCalculatorTest {
RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey).setEffortToFix(2d);
- Requirement requirement = mock(Requirement.class);
+ DefaultRequirement requirement = mock(DefaultRequirement.class);
Mockito.when(requirement.factor()).thenReturn(null);
Mockito.when(requirement.offset()).thenReturn(fiveMinutes);
- when(technicalDebtModel.requirementsByRule(ruleKey)).thenReturn(requirement);
+ when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
remediationCostCalculator.calculTechnicalDebt(issue);
@@ -121,7 +121,7 @@ public class TechnicalDebtCalculatorTest {
public void no_technical_debt_if_requirement_not_found() throws Exception {
RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey);
- when(technicalDebtModel.requirementsByRule(ruleKey)).thenReturn(null);
+ when(model.requirementsByRule(ruleKey)).thenReturn(null);
assertThat(remediationCostCalculator.calculTechnicalDebt(issue)).isNull();
verify(converter, never()).fromMinutes(anyLong());
diff --git a/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoaderTest.java
new file mode 100644
index 00000000000..6d6cea6d4db
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelLoaderTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.batch.technicaldebt;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.rules.RuleQuery;
+import org.sonar.api.technicaldebt.WorkUnit;
+import org.sonar.api.technicaldebt.internal.DefaultCharacteristic;
+import org.sonar.api.technicaldebt.internal.DefaultRequirement;
+import org.sonar.core.technicaldebt.DefaultTechnicalDebtModel;
+import org.sonar.core.technicaldebt.db.CharacteristicDao;
+import org.sonar.core.technicaldebt.db.CharacteristicDto;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TechnicalDebtModelLoaderTest {
+
+ @Mock
+ CharacteristicDao dao;
+
+ @Mock
+ RuleFinder ruleFinder;
+
+ TechnicalDebtModelLoader loader;
+
+ @Before
+ public void before() {
+ loader = new TechnicalDebtModelLoader(dao, ruleFinder);
+ }
+
+ @Test
+ public void find_all() throws Exception {
+ CharacteristicDto rootCharacteristicDto = new CharacteristicDto()
+ .setId(1)
+ .setKey("MEMORY_EFFICIENCY")
+ .setName("Memory use");
+
+ CharacteristicDto characteristicDto = new CharacteristicDto()
+ .setId(2)
+ .setKey("EFFICIENCY")
+ .setName("Efficiency")
+ .setParentId(1);
+
+ CharacteristicDto requirementDto = new CharacteristicDto()
+ .setId(3)
+ .setParentId(2)
+ .setRuleId(100)
+ .setFunction("linear")
+ .setFactorValue(2d)
+ .setFactorUnit(WorkUnit.DAYS)
+ .setOffsetValue(0d)
+ .setOffsetUnit(WorkUnit.DEFAULT_UNIT);
+
+ RuleKey ruleKey = RuleKey.of("checkstyle", "Regexp");
+ Rule rule = Rule.create(ruleKey.repository(), ruleKey.rule());
+ rule.setId(100);
+ when(ruleFinder.findAll(any(RuleQuery.class))).thenReturn(newArrayList(rule));
+ when(dao.selectEnabledCharacteristics()).thenReturn(newArrayList(rootCharacteristicDto, characteristicDto, requirementDto));
+
+ DefaultTechnicalDebtModel result = (DefaultTechnicalDebtModel) loader.load();
+ assertThat(result.rootCharacteristics()).hasSize(1);
+
+ DefaultCharacteristic rootCharacteristic = result.characteristicByKey("MEMORY_EFFICIENCY");
+ assertThat(rootCharacteristic.key()).isEqualTo("MEMORY_EFFICIENCY");
+ assertThat(rootCharacteristic.name()).isEqualTo("Memory use");
+ assertThat(rootCharacteristic.parent()).isNull();
+ assertThat(rootCharacteristic.requirements()).isEmpty();
+ assertThat(rootCharacteristic.children()).hasSize(1);
+ assertThat(rootCharacteristic.children().get(0).key()).isEqualTo("EFFICIENCY");
+
+ DefaultCharacteristic characteristic = result.characteristicByKey("EFFICIENCY");
+ assertThat(characteristic.key()).isEqualTo("EFFICIENCY");
+ assertThat(characteristic.name()).isEqualTo("Efficiency");
+ assertThat(characteristic.parent().key()).isEqualTo("MEMORY_EFFICIENCY");
+ assertThat(characteristic.children()).isEmpty();
+ assertThat(characteristic.requirements()).hasSize(1);
+ assertThat(characteristic.requirements().get(0).ruleKey()).isEqualTo(ruleKey);
+
+ DefaultRequirement requirement = result.requirementsByRule(ruleKey);
+ assertThat(requirement.ruleKey()).isEqualTo(ruleKey);
+ assertThat(requirement.function()).isEqualTo("linear");
+ assertThat(requirement.factor()).isEqualTo(WorkUnit.create(2d, WorkUnit.DAYS));
+ assertThat(requirement.offset()).isEqualTo(WorkUnit.create(0d, WorkUnit.DEFAULT_UNIT));
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProviderTest.java
index b632b32fb4d..e4bee8d0ea2 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProviderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtModelProviderTest.java
@@ -24,8 +24,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.core.technicaldebt.TechnicalDebtFinder;
-import org.sonar.core.technicaldebt.TechnicalDebtModel;
+import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.*;
@@ -34,28 +33,28 @@ import static org.mockito.Mockito.*;
public class TechnicalDebtModelProviderTest {
@Mock
- TechnicalDebtFinder modelFinder;
+ TechnicalDebtModelLoader loader;
@Test
- public void load_model(){
- TechnicalDebtModel model = new TechnicalDebtModel();
- when(modelFinder.findAll()).thenReturn(model);
+ public void load_model() {
+ TechnicalDebtModel model = mock(TechnicalDebtModel.class);
+ when(loader.load()).thenReturn(model);
TechnicalDebtModelProvider provider = new TechnicalDebtModelProvider();
- TechnicalDebtModel result = provider.provide(modelFinder);
+ TechnicalDebtModel result = provider.provide(loader);
assertThat(result).isNotNull();
}
@Test
- public void load_model_only_once(){
- TechnicalDebtModel model = new TechnicalDebtModel();
- when(modelFinder.findAll()).thenReturn(model);
+ public void load_model_only_once() {
+ TechnicalDebtModel model = mock(TechnicalDebtModel.class);
+ when(loader.load()).thenReturn(model);
TechnicalDebtModelProvider provider = new TechnicalDebtModelProvider();
- provider.provide(modelFinder);
- verify(modelFinder).findAll();
+ provider.provide(loader);
+ verify(loader).load();
- provider.provide(modelFinder);
- verifyZeroInteractions(modelFinder);
+ provider.provide(loader);
+ verifyZeroInteractions(loader);
}
}