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;
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;
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)
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);
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);
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);
@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
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);
+ }
+
}