]> source.dussan.org Git - sonarqube.git/commitdiff
Verify that checks do not set effort to fix on constant_issue requirement
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 2 Dec 2013 13:01:04 +0000 (14:01 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 2 Dec 2013 13:44:37 +0000 (14:44 +0100)
sonar-batch/src/main/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculator.java
sonar-batch/src/test/java/org/sonar/batch/technicaldebt/TechnicalDebtCalculatorTest.java

index 16e12f74d1d0af020c4986f9d1d3badc3961de85..ded5a20aa011176c7a5a3ecfa0d7e10a220ede74 100644 (file)
@@ -25,6 +25,7 @@ import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.internal.WorkDayDuration;
 import org.sonar.api.technicaldebt.batch.Requirement;
 import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
+import org.sonar.api.technicaldebt.batch.internal.DefaultRequirement;
 import org.sonar.api.utils.WorkUnit;
 import org.sonar.core.technicaldebt.TechnicalDebtConverter;
 
@@ -44,6 +45,9 @@ public class TechnicalDebtCalculator implements BatchExtension {
   public WorkDayDuration calculTechnicalDebt(Issue issue) {
     Requirement requirement = model.requirementsByRule(issue.ruleKey());
     if (requirement != null) {
+      if (requirement.function().equals(DefaultRequirement.CONSTANT_ISSUE) && issue.effortToFix() != null) {
+        throw new IllegalArgumentException("The implementation of rule '"+ issue.ruleKey() +"' defines an effort to fix whereas its requirement is set to 'constant/issue' - which is not compatible.");
+      }
       return converter.fromMinutes(calculTechnicalDebt(requirement, issue));
     }
     return null;
index 252d127504b7bcc276aa7f203db6a68fefc3b52d..b4b5f55bfff9b3c55ebbc6ff62cb50de615cdd4c 100644 (file)
@@ -33,6 +33,7 @@ import org.sonar.api.utils.WorkUnit;
 import org.sonar.core.technicaldebt.TechnicalDebtConverter;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
 import static org.mockito.Mockito.*;
 
 @RunWith(MockitoJUnitRunner.class)
@@ -63,6 +64,7 @@ public class TechnicalDebtCalculatorTest {
     DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey);
 
     DefaultRequirement requirement = mock(DefaultRequirement.class);
+    Mockito.when(requirement.function()).thenReturn("constant_issue");
     Mockito.when(requirement.factor()).thenReturn(tenMinutes);
     Mockito.when(requirement.offset()).thenReturn(fiveMinutes);
     when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
@@ -78,6 +80,7 @@ public class TechnicalDebtCalculatorTest {
     DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey).setEffortToFix(2d);
 
     DefaultRequirement requirement = mock(DefaultRequirement.class);
+    Mockito.when(requirement.function()).thenReturn("linear_offset");
     Mockito.when(requirement.factor()).thenReturn(tenMinutes);
     Mockito.when(requirement.offset()).thenReturn(fiveMinutes);
     when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
@@ -93,6 +96,7 @@ public class TechnicalDebtCalculatorTest {
     DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey).setEffortToFix(2d);
 
     DefaultRequirement requirement = mock(DefaultRequirement.class);
+    Mockito.when(requirement.function()).thenReturn("linear");
     Mockito.when(requirement.factor()).thenReturn(tenMinutes);
     Mockito.when(requirement.offset()).thenReturn(null);
     when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
@@ -105,16 +109,17 @@ public class TechnicalDebtCalculatorTest {
   @Test
   public void calcul_technical_debt_with_no_factor() throws Exception {
     RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
-    DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey).setEffortToFix(2d);
+    DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey);
 
     DefaultRequirement requirement = mock(DefaultRequirement.class);
+    Mockito.when(requirement.function()).thenReturn("constant_issue");
     Mockito.when(requirement.factor()).thenReturn(null);
     Mockito.when(requirement.offset()).thenReturn(fiveMinutes);
     when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
 
     remediationCostCalculator.calculTechnicalDebt(issue);
 
-    verify(converter).fromMinutes(0l * 2 + 5l);
+    verify(converter).fromMinutes(0l + 5l);
   }
 
   @Test
@@ -127,5 +132,26 @@ public class TechnicalDebtCalculatorTest {
     verify(converter, never()).fromMinutes(anyLong());
   }
 
+  @Test
+  public void fail_to_calcul_technical_debt_on_constant_issue_function_with_effort_to_fix() throws Exception {
+    RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
+    DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(ruleKey).setEffortToFix(2d);
+
+    DefaultRequirement requirement = mock(DefaultRequirement.class);
+    Mockito.when(requirement.function()).thenReturn("constant_issue");
+    Mockito.when(requirement.factor()).thenReturn(null);
+    Mockito.when(requirement.offset()).thenReturn(fiveMinutes);
+    when(model.requirementsByRule(ruleKey)).thenReturn(requirement);
+
+    try {
+      remediationCostCalculator.calculTechnicalDebt(issue);
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(IllegalArgumentException.class)
+        .hasMessage("The implementation of rule 'squid:AvoidCycle' defines an effort to fix whereas its requirement is set to 'constant/issue' - which is not compatible.");
+    }
+    verifyZeroInteractions(converter);
+  }
+
 }