public boolean setPastGap(DefaultIssue issue, @Nullable Double previousGap, IssueChangeContext context) { Double currentGap = issue.gap(); issue.setGap(previousGap); return setGap(issue, currentGap, context); }
private static void verifyEffortToFix(DefaultIssue issue, DebtRemediationFunction fn) { if (Type.CONSTANT_ISSUE.equals(fn.type()) && issue.gap() != null) { throw new IllegalArgumentException("Rule '" + issue.getRuleKey() + "' can not use 'Constant/issue' remediation function " + "because this rule does not have a fixed remediation cost."); } } }
public boolean setGap(DefaultIssue issue, @Nullable Double d, IssueChangeContext context) { if (!Objects.equals(d, issue.gap())) { issue.setGap(d); issue.setUpdateDate(context.date()); issue.setChanged(true); // Do not send notifications to prevent spam when installing the SQALE plugin, // and do not complete the changelog (for the moment) return true; } return false; }
@Test public void set_gap_to_fix() { boolean updated = underTest.setGap(issue, 3.14, context); assertThat(updated).isTrue(); assertThat(issue.isChanged()).isTrue(); assertThat(issue.gap()).isEqualTo(3.14); assertThat(issue.mustSendNotifications()).isFalse(); }
@Test public void not_set_gap_to_fix_if_unchanged() { issue.setGap(3.14); boolean updated = underTest.setGap(issue, 3.14, context); assertThat(updated).isFalse(); assertThat(issue.isChanged()).isFalse(); assertThat(issue.gap()).isEqualTo(3.14); assertThat(issue.mustSendNotifications()).isFalse(); }
@Test public void issue_if_not_enough_comments__test_ceil() { prepareForIssue("25", FILE, 0.0, 0, 1); DefaultIssue issue = underTest.processFile(FILE, PLUGIN_KEY); assertThat(issue.ruleKey()).isEqualTo(RULE_KEY); assertThat(issue.severity()).isEqualTo(Severity.CRITICAL); // 1 ncloc requires 1 comment line to reach 25% of comment density assertThat(issue.gap()).isEqualTo(1.0); assertThat(issue.message()).isEqualTo("1 more comment lines need to be written to reach the minimum threshold of 25.0% comment density."); }
@Test public void issue_if_not_enough_comments() { prepareForIssue("25", FILE, 10.0, 40, 360); DefaultIssue issue = underTest.processFile(FILE, PLUGIN_KEY); assertThat(issue.ruleKey()).isEqualTo(RULE_KEY); assertThat(issue.severity()).isEqualTo(Severity.CRITICAL); // min_comments = (min_percent * ncloc) / (1 - min_percent) // -> threshold of 25% for 360 ncloc is 120 comment lines. 40 are already written. assertThat(issue.gap()).isEqualTo(120.0 - 40.0); assertThat(issue.message()).isEqualTo("80 more comment lines need to be written to reach the minimum threshold of 25.0% comment density."); }
@Test public void set_past_gap() { issue.setGap(3.14); boolean updated = underTest.setPastGap(issue, 1.0, context); assertThat(updated).isTrue(); assertThat(issue.gap()).isEqualTo(3.14); // do not save change assertThat(issue.currentChange()).isNull(); assertThat(issue.mustSendNotifications()).isFalse(); }
@CheckForNull public Duration calculate(DefaultIssue issue) { if (issue.isFromExternalRuleEngine()) { return issue.effort(); } Rule rule = ruleRepository.getByKey(issue.ruleKey()); DebtRemediationFunction fn = rule.getRemediationFunction(); if (fn != null) { verifyEffortToFix(issue, fn); Duration debt = Duration.create(0); String gapMultiplier = fn.gapMultiplier(); if (fn.type().usesGapMultiplier() && !Strings.isNullOrEmpty(gapMultiplier)) { int effortToFixValue = MoreObjects.firstNonNull(issue.gap(), 1).intValue(); // TODO convert to Duration directly in Rule#remediationFunction -> better performance + error handling debt = durations.decode(gapMultiplier).multiply(effortToFixValue); } String baseEffort = fn.baseEffort(); if (fn.type().usesBaseEffort() && !Strings.isNullOrEmpty(baseEffort)) { // TODO convert to Duration directly in Rule#remediationFunction -> better performance + error handling debt = debt.add(durations.decode(baseEffort)); } return debt; } return null; }
@Test public void test_nullable_fields() { issue.setGap(null).setSeverity(null).setLine(null); assertThat(issue.gap()).isNull(); assertThat(issue.severity()).isNull(); assertThat(issue.line()).isNull(); }
assertThat(issue.message()).isEqualTo("a message"); assertThat(issue.line()).isEqualTo(7); assertThat(issue.gap()).isEqualTo(1.2d); assertThat(issue.effort()).isEqualTo(Duration.create(28800L)); assertThat(issue.status()).isEqualTo(Issue.STATUS_CLOSED);
assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); assertThat(issue.line()).isEqualTo(2); assertThat(issue.gap()).isEqualTo(3.14); assertThat(issue.message()).isEqualTo("the message");
assertThat(issue.status()).isEqualTo(Issue.STATUS_CLOSED); assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FALSE_POSITIVE); assertThat(issue.gap()).isEqualTo(15.0); assertThat(issue.effort()).isEqualTo(Duration.create(10L)); assertThat(issue.line()).isEqualTo(6);
updater.setPastLocations(raw, base.getLocations()); updater.setPastMessage(raw, base.getMessage(), changeContext); updater.setPastGap(raw, base.gap(), changeContext); updater.setPastEffort(raw, base.effort(), changeContext);
.setLocations((DbIssues.Locations) issue.getLocations()) .setMessage(issue.message()) .setGap(issue.gap()) .setEffort(issue.effortInMinutes()) .setResolution(issue.resolution())
.setLocations((DbIssues.Locations) issue.getLocations()) .setMessage(issue.message()) .setGap(issue.gap()) .setEffort(issue.effortInMinutes()) .setResolution(issue.resolution())
public boolean setPastGap(DefaultIssue issue, @Nullable Double previousGap, IssueChangeContext context) { Double currentGap = issue.gap(); issue.setGap(previousGap); return setGap(issue, currentGap, context); }
private static void verifyEffortToFix(DefaultIssue issue, DebtRemediationFunction fn) { if (Type.CONSTANT_ISSUE.equals(fn.type()) && issue.gap() != null) { throw new IllegalArgumentException("Rule '" + issue.getRuleKey() + "' can not use 'Constant/issue' remediation function " + "because this rule does not have a fixed remediation cost."); } } }
public boolean setGap(DefaultIssue issue, @Nullable Double d, IssueChangeContext context) { if (!Objects.equals(d, issue.gap())) { issue.setGap(d); issue.setUpdateDate(context.date()); issue.setChanged(true); // Do not send notifications to prevent spam when installing the SQALE plugin, // and do not complete the changelog (for the moment) return true; } return false; }
public void mergeExistingOpenIssue(DefaultIssue raw, DefaultIssue base) { raw.setKey(base.key()); raw.setNew(false); copyFields(raw, base); if (base.manualSeverity()) { raw.setManualSeverity(true); raw.setSeverity(base.severity()); } else { updater.setPastSeverity(raw, base.severity(), changeContext); } // set component/module related fields from base in case current component has been moved // (in which case base issue belongs to original file and raw issue to component) raw.setComponentUuid(base.componentUuid()); raw.setComponentKey(base.componentKey()); raw.setModuleUuid(base.moduleUuid()); raw.setModuleUuidPath(base.moduleUuidPath()); // fields coming from raw updater.setPastLine(raw, base.getLine()); updater.setPastLocations(raw, base.getLocations()); updater.setPastMessage(raw, base.getMessage(), changeContext); updater.setPastGap(raw, base.gap(), changeContext); updater.setPastEffort(raw, base.effort(), changeContext); }