.setHtmlDescription("Generate an issue on each line of a file. It requires the metric \"lines\".");
oneIssuePerLine
.setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("1min"))
- .setEffortToFixDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code");
+ .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code");
repo.done();
}
.setHtmlDescription("Generate an issue on each line of a file. It requires the metric \"lines\".");
oneIssuePerLine
.setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("1min"))
- .setEffortToFixDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code");
+ .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code");
repo.createRule(OneIssueOnDirPerFileSensor.RULE_KEY).setName("One Issue On Dir Per File")
.setHtmlDescription("Generate issues on directories");
.setHtmlDescription("Generate an issue on each module");
oneIssuePerModule
.setDebtRemediationFunction(hasTag.debtRemediationFunctions().linearWithOffset("25min", "1h"))
- .setEffortToFixDescription("A certified architect will need roughly half an hour to start working on removal of modules, " +
+ .setGapDescription("A certified architect will need roughly half an hour to start working on removal of modules, " +
"then it's about one hour per module.");
repo.createRule(OneBlockerIssuePerFileSensor.RULE_KEY).setName("One Blocker Issue Per File")
RulesDefinition.Rule rule = repo.rule(OneIssuePerLineSensor.RULE_KEY);
assertThat(rule.name()).isNotEmpty();
assertThat(rule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.LINEAR);
- assertThat(rule.debtRemediationFunction().coefficient()).isEqualTo("1min");
- assertThat(rule.debtRemediationFunction().offset()).isNull();
- assertThat(rule.effortToFixDescription()).isNotEmpty();
+ assertThat(rule.debtRemediationFunction().gapMultiplier()).isEqualTo("1min");
+ assertThat(rule.debtRemediationFunction().baseEffort()).isNull();
+ assertThat(rule.gapDescription()).isNotEmpty();
}
@Test
verifyEffortToFix(issue, fn);
Duration debt = Duration.create(0);
- if (fn.type().usesCoefficient() && !Strings.isNullOrEmpty(fn.coefficient())) {
+ String gapMultiplier =fn.gapMultiplier();
+ if (fn.type().usesGapMultiplier() && !Strings.isNullOrEmpty(gapMultiplier)) {
int effortToFixValue = Objects.firstNonNull(issue.effortToFix(), 1).intValue();
// TODO convert to Duration directly in Rule#remediationFunction -> better performance + error handling
- debt = durations.decode(fn.coefficient()).multiply(effortToFixValue);
+ debt = durations.decode(gapMultiplier).multiply(effortToFixValue);
}
- if (fn.type().usesOffset() && !Strings.isNullOrEmpty(fn.offset())) {
+ 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(fn.offset()));
+ debt = debt.add(durations.decode(baseEffort));
}
return debt;
}
boolean hasDebtDefinition = remediationFunction != null;
rule.setDefaultRemediationFunction(hasDebtDefinition ? remediationFunction.type().name() : null);
- rule.setDefaultRemediationGapMultiplier(hasDebtDefinition ? remediationFunction.coefficient() : null);
- rule.setDefaultRemediationBaseEffort(hasDebtDefinition ? remediationFunction.offset() : null);
+ rule.setDefaultRemediationGapMultiplier(hasDebtDefinition ? remediationFunction.gapMultiplier() : null);
+ rule.setDefaultRemediationBaseEffort(hasDebtDefinition ? remediationFunction.baseEffort() : null);
}
// Reset overridden debt definitions
.setHtmlDescription("An issue is created on a file as soon as the branch coverage on this file is less than the required threshold."
+ "It gives the number of branches to be covered in order to reach the required threshold.")
.setDebtRemediationFunction(rule.debtRemediationFunctions().linear("5min"))
- .setEffortToFixDescription("number of uncovered conditions")
+ .setGapDescription("number of uncovered conditions")
.setSeverity(Severity.MAJOR);
rule.createParam(CommonRuleKeys.INSUFFICIENT_BRANCH_COVERAGE_PROPERTY)
.setName("The minimum required branch coverage ratio")
.setHtmlDescription("An issue is created on a file as soon as the line coverage on this file is less than the required threshold. " +
"It gives the number of lines to be covered in order to reach the required threshold.")
.setDebtRemediationFunction(rule.debtRemediationFunctions().linear("2min"))
- .setEffortToFixDescription("number of lines under the coverage threshold")
+ .setGapDescription("number of lines under the coverage threshold")
.setSeverity(Severity.MAJOR);
rule.createParam(CommonRuleKeys.INSUFFICIENT_LINE_COVERAGE_PROPERTY)
.setName("The minimum required line coverage ratio")
.setHtmlDescription("An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. " +
"The number of comment lines to be written in order to reach the required threshold is provided by each issue message.")
.setDebtRemediationFunction(rule.debtRemediationFunctions().linear("2min"))
- .setEffortToFixDescription("number of lines required to meet minimum density")
+ .setGapDescription("number of lines required to meet minimum density")
.setSeverity(Severity.MAJOR);
rule.createParam(CommonRuleKeys.INSUFFICIENT_COMMENT_DENSITY_PROPERTY)
.setName("The minimum required comment density")
.addTags("pitfall")
.setHtmlDescription("An issue is created on a file as soon as there is at least one block of duplicated code on this file")
.setDebtRemediationFunction(rule.debtRemediationFunctions().linearWithOffset("10min", "10min"))
- .setEffortToFixDescription("number of duplicate blocks")
+ .setGapDescription("number of duplicate blocks")
.setSeverity(Severity.MAJOR);
}
.setHtmlDescription(
"Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.")
.setDebtRemediationFunction(rule.debtRemediationFunctions().linear("10min"))
- .setEffortToFixDescription("number of failed tests")
+ .setGapDescription("number of failed tests")
.setSeverity(Severity.MAJOR);
}
.addTags("pitfall")
.setHtmlDescription("Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.")
.setDebtRemediationFunction(rule.debtRemediationFunctions().linear("10min"))
- .setEffortToFixDescription("number of skipped tests")
+ .setGapDescription("number of skipped tests")
.setSeverity(Severity.MAJOR);
}
}
.setName(ruleDef.name())
.setSeverity(ruleDef.severity())
.setStatus(ruleDef.status())
- .setGapDescription(ruleDef.effortToFixDescription())
+ .setGapDescription(ruleDef.gapDescription())
.setSystemTags(ruleDef.tags())
.setType(RuleType.valueOf(ruleDef.type().name()))
.setCreatedAt(system2.now())
if (hasDebt) {
return mergeDebtDefinitions(dto,
debtRemediationFunction.type().name(),
- debtRemediationFunction.coefficient(),
- debtRemediationFunction.offset(),
- def.effortToFixDescription());
+ debtRemediationFunction.gapMultiplier(),
+ debtRemediationFunction.baseEffort(),
+ def.gapDescription());
}
return mergeDebtDefinitions(dto, null, null, null, null);
}
} else if (!isRuleDebtSameAsOverriddenValues(ruleDto, newFunction, newCoefficient, newOffset)) {
DefaultDebtRemediationFunction debtRemediationFunction = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.valueOf(newFunction), newCoefficient, newOffset);
ruleDto.setRemediationFunction(debtRemediationFunction.type().name());
- ruleDto.setRemediationGapMultiplier(debtRemediationFunction.coefficient());
- ruleDto.setRemediationBaseEffort(debtRemediationFunction.offset());
+ ruleDto.setRemediationGapMultiplier(debtRemediationFunction.gapMultiplier());
+ ruleDto.setRemediationBaseEffort(debtRemediationFunction.baseEffort());
needUpdate = true;
}
private static boolean isRuleDebtSameAsOverriddenValues(RuleDto ruleDto, @Nullable String newFunction,
@Nullable String newCoefficient, @Nullable String newOffset) {
- return isSameRemediationFunction(newFunction, newCoefficient, newOffset, ruleDto.getRemediationFunction(), ruleDto.getRemediationGapMultiplier(), ruleDto.getRemediationBaseEffort());
+ return isSameRemediationFunction(newFunction, newCoefficient, newOffset, ruleDto.getRemediationFunction(), ruleDto.getRemediationGapMultiplier(),
+ ruleDto.getRemediationBaseEffort());
}
private static boolean isSameRemediationFunction(@Nullable String newFunction, @Nullable String newCoefficient, @Nullable String newOffset,
context.rule.setRemediationBaseEffort(null);
} else {
context.rule.setRemediationFunction(function.type().name());
- context.rule.setRemediationGapMultiplier(function.coefficient());
- context.rule.setRemediationBaseEffort(function.offset());
+ context.rule.setRemediationGapMultiplier(function.gapMultiplier());
+ context.rule.setRemediationBaseEffort(function.baseEffort());
}
}
}
private static boolean isSameAsDefaultFunction(DebtRemediationFunction fn, RuleDto rule) {
return new EqualsBuilder()
.append(fn.type().name(), rule.getDefaultRemediationFunction())
- .append(fn.coefficient(), rule.getDefaultRemediationGapMultiplier())
- .append(fn.offset(), rule.getDefaultRemediationBaseEffort())
+ .append(fn.gapMultiplier(), rule.getDefaultRemediationGapMultiplier())
+ .append(fn.baseEffort(), rule.getDefaultRemediationBaseEffort())
.isEquals();
}
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.markdown.Markdown;
if (shouldReturnField(fieldsToReturn, FIELD_DEFAULT_DEBT_REM_FUNCTION)) {
DebtRemediationFunction defaultDebtRemediationFunction = defaultDebtRemediationFunction(ruleDto);
if (defaultDebtRemediationFunction != null) {
- String gapMultiplier = defaultDebtRemediationFunction.coefficient();
+ String gapMultiplier = defaultDebtRemediationFunction.gapMultiplier();
if (gapMultiplier != null) {
ruleResponse.setDefaultRemFnGapMultiplier(gapMultiplier);
// Set deprecated field
ruleResponse.setDefaultDebtRemFnCoeff(gapMultiplier);
}
- String baseEffort = defaultDebtRemediationFunction.offset();
+ String baseEffort = defaultDebtRemediationFunction.baseEffort();
if (baseEffort != null) {
ruleResponse.setDefaultRemFnBaseEffort(baseEffort);
// Set deprecated field
// Set deprecated field
ruleResponse.setDebtRemFnType(debtRemediationFunction.type().name());
}
- String gapMultiplier = debtRemediationFunction.coefficient();
+ String gapMultiplier = debtRemediationFunction.gapMultiplier();
if (gapMultiplier != null) {
ruleResponse.setRemFnGapMultiplier(gapMultiplier);
// Set deprecated field
ruleResponse.setDebtRemFnCoeff(gapMultiplier);
}
- String baseEffort = debtRemediationFunction.offset();
+ String baseEffort = debtRemediationFunction.baseEffort();
if (baseEffort != null) {
ruleResponse.setRemFnBaseEffort(baseEffort);
// Set deprecated field
return rule.getRemediationFunction() != null;
}
+ @CheckForNull
private static DebtRemediationFunction defaultDebtRemediationFunction(final RuleDto ruleDto) {
final String function = ruleDto.getDefaultRemediationFunction();
if (function == null || function.isEmpty()) {
return null;
} else {
- return new DebtRemediationFunction() {
- @Override
- public Type type() {
- return Type.valueOf(function.toUpperCase());
- }
-
- @Override
- public String coefficient() {
- return ruleDto.getDefaultRemediationGapMultiplier();
- }
-
- @Override
- public String offset() {
- return ruleDto.getDefaultRemediationBaseEffort();
- }
- };
+ return new DefaultDebtRemediationFunction(
+ DebtRemediationFunction.Type.valueOf(function.toUpperCase(Locale.ENGLISH)),
+ ruleDto.getDefaultRemediationGapMultiplier(),
+ ruleDto.getDefaultRemediationBaseEffort());
}
}
+ @CheckForNull
private static DebtRemediationFunction debtRemediationFunction(final RuleDto ruleDto) {
final String function = ruleDto.getRemediationFunction();
if (function == null || function.isEmpty()) {
return defaultDebtRemediationFunction(ruleDto);
} else {
- return new DebtRemediationFunction() {
- @Override
- public Type type() {
- return Type.valueOf(function.toUpperCase());
- }
-
- @Override
- public String coefficient() {
- return ruleDto.getRemediationGapMultiplier();
- }
-
- @Override
- public String offset() {
- return ruleDto.getRemediationBaseEffort();
- }
- };
+ return new DefaultDebtRemediationFunction(
+ DebtRemediationFunction.Type.valueOf(function.toUpperCase(Locale.ENGLISH)),
+ ruleDto.getRemediationGapMultiplier(),
+ ruleDto.getRemediationBaseEffort());
}
}
*/
package org.sonar.server.rule;
+import java.io.Reader;
+import java.util.Arrays;
+import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.sonar.server.debt.DebtModelXMLExporter;
import org.sonar.server.debt.DebtRulesXMLImporter;
-import java.io.Reader;
-import java.util.Arrays;
-import java.util.List;
-
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
assertThat(rule).isNotNull();
assertThat(rule.key()).isEqualTo("ConstantName");
assertThat(rule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET);
- assertThat(rule.debtRemediationFunction().coefficient()).isEqualTo("1d");
- assertThat(rule.debtRemediationFunction().offset()).isEqualTo("10min");
+ assertThat(rule.debtRemediationFunction().gapMultiplier()).isEqualTo("1d");
+ assertThat(rule.debtRemediationFunction().baseEffort()).isEqualTo("10min");
}
@Test
.setInternalKey("new_internal");
rule
.setDebtRemediationFunction(rule.debtRemediationFunctions().linearWithOffset("1h", "30min"))
- .setEffortToFixDescription("Effort");
+ .setGapDescription("Effort");
}
});
.setTags("tag1", "tag2", "tag3")
.setType(RuleType.CODE_SMELL)
.setStatus(RuleStatus.BETA)
- .setEffortToFixDescription("squid.S115.effortToFix");
+ .setGapDescription("squid.S115.effortToFix");
rule1.setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("5d", "10h"));
rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default1");
.setTags("tag1", "tag4")
.setType(RuleType.BUG)
.setStatus(RuleStatus.READY)
- .setEffortToFixDescription("squid.S115.effortToFix.v2");
+ .setGapDescription("squid.S115.effortToFix.v2");
rule1.setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("6d", "2h"));
rule1.createParam("param1").setDescription("parameter one v2").setDefaultValue("default1 v2");
rule1.createParam("param2").setDescription("parameter two v2").setDefaultValue("default2 v2");
authorizedUserSession
);
} catch (Exception e) {
- assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Invalid coefficient: foo (Duration 'foo' is invalid, it should use the following sample format : 2d 10h 15min)");
+ assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Invalid gap multiplier: foo (Duration 'foo' is invalid, it should use the following sample format : 2d 10h 15min)");
}
verify(ruleDao, never()).update(eq(session), any(RuleDto.class));
/**
* Function used to calculate the remediation cost of an issue. See {@link Type} for details.
- * <p>The coefficient and offset involved in the functions are durations. They are defined in hours, minutes and/or
+ * <p>The gap multiplier and base effort involved in the functions are durations. They are defined in hours, minutes and/or
* seconds. Examples: "5min", "1h 10min". Supported units are "d" (days), "h" (hour), and "min" (minutes).</p>
*
* @since 4.3
/**
* The cost to fix an issue of this type depends on the magnitude of the issue.
* For instance, an issue related to file size might be linear, with the total cost-to-fix incrementing
- * (by the coefficient amount) for each line of code above the allowed threshold.
- * The rule must provide the "effort to fix" value when raising an issue.
+ * (by the gap multiplier amount) for each line of code above the allowed threshold.
+ * The rule must provide the "gap" value when raising an issue.
*/
LINEAR(true, false),
/**
- * It takes a certain amount of time to deal with an issue of this type (this is the offset).
+ * It takes a certain amount of time to deal with an issue of this type (this is the gap multiplier).
* Then, the magnitude of the issue comes in to play. For instance, an issue related to complexity might be linear with offset.
- * So the total cost to fix is the time to make the basic analysis (the offset) plus the time required to deal
+ * So the total cost to fix is the time to make the basic analysis (the base effort) plus the time required to deal
* with each complexity point above the allowed value.
* <p>
- * <code>Total remediation cost = offset + (number of noncompliance x coefficient)</code>
+ * <code>Total remediation cost = base effort + (number of noncompliance x gap multiplier)</code>
* </p>
- * <p>The rule must provide the "effort to fix" value when raising an issue. Let’s take as a example the “Paragraphs should not be too complex” rule.
+ * <p>The rule must provide the "gap" value when raising an issue. Let’s take as a example the “Paragraphs should not be too complex” rule.
* If you set the rule threshold to 20, and you have a paragraph with a complexity of 27, you have 7 points of complexity
- * to remove. Internally, this is called the Effort to Fix. In that case, if you use the LINEAR_OFFSET configuration
- * with an offset of 4h and a remediation cost of 1mn, the technical debt for this issue related to a
+ * to remove. Internally, this is called the Gap. In that case, if you use the LINEAR_OFFSET configuration
+ * with an base effort of 4h and a remediation cost of 1mn, the effort for this issue related to a
* too-complex block of code will be: (7 complexity points x 1min) + 4h = 4h and 7mn
* </p>
*/
*/
CONSTANT_ISSUE(false, true);
- private final boolean usesCoefficient;
- private final boolean usesOffset;
+ private final boolean usesGapMultiplier;
+ private final boolean usesBaseEffort;
- Type(boolean usesCoefficient, boolean usesOffset) {
- this.usesCoefficient = usesCoefficient;
- this.usesOffset = usesOffset;
+ Type(boolean usesGapMultiplier, boolean usesBaseEffort) {
+ this.usesGapMultiplier = usesGapMultiplier;
+ this.usesBaseEffort = usesBaseEffort;
}
+ /**
+ * @deprecated since 5.5, replaced by {@link #usesGapMultiplier()}
+ */
+ @Deprecated
public boolean usesCoefficient() {
- return usesCoefficient;
+ return usesGapMultiplier();
}
+ /**
+ * @since 5.5
+ */
+ public boolean usesGapMultiplier() {
+ return usesGapMultiplier;
+ }
+
+ /**
+ * @deprecated since 5.5, replaced by {@link #usesBaseEffort()}
+ */
+ @Deprecated
public boolean usesOffset() {
- return usesOffset;
+ return usesBaseEffort();
}
+
+ /**
+ * @since 5.5
+ */
+ public boolean usesBaseEffort() {
+ return usesBaseEffort;
+ }
+
}
+ /**
+ * @since 5.5
+ */
Type type();
/**
- * Non-null value on {@link Type#LINEAR} and {@link Type#LINEAR_OFFSET} functions, else {@code null}.
+ * @deprecated since 5.5, replaced by {@link #gapMultiplier()}
*/
+ @Deprecated
@CheckForNull
String coefficient();
/**
- * Non-null value on {@link Type#LINEAR_OFFSET} and {@link Type#CONSTANT_ISSUE} functions, else {@code null}.
+ * Non-null value on {@link Type#LINEAR} and {@link Type#LINEAR_OFFSET} functions, else {@code null}.
+ *
+ * @since 5.5
*/
@CheckForNull
+ String gapMultiplier();
+
+ /**
+ * @deprecated since 5.5, replaced by {@link #baseEffort()}
+ */
+ @Deprecated
+ @CheckForNull
String offset();
+ /**
+ * Non-null value on {@link Type#LINEAR_OFFSET} and {@link Type#CONSTANT_ISSUE} functions, else {@code null}.
+ *
+ * @since 5.5
+ */
+ @CheckForNull
+ String baseEffort();
+
}
private static final int HOURS_IN_DAY = 24;
private final Type type;
- private final String coefficient;
- private final String offset;
+ private final String gapMultiplier;
+ private final String baseEffort;
- public DefaultDebtRemediationFunction(@Nullable Type type, @Nullable String coefficient, @Nullable String offset) {
+ public DefaultDebtRemediationFunction(@Nullable Type type, @Nullable String gapMultiplier, @Nullable String baseEffort) {
this.type = type;
- this.coefficient = sanitizeValue("coefficient", coefficient);
- this.offset = sanitizeValue("offset", offset);
+ this.gapMultiplier = sanitizeValue("gap multiplier", gapMultiplier);
+ this.baseEffort = sanitizeValue("base effort", baseEffort);
validate();
}
return type;
}
+ /**
+ * @deprecated since 5.5, replaced by {@link #gapMultiplier}
+ */
@Override
@CheckForNull
+ @Deprecated
public String coefficient() {
- return coefficient;
+ return gapMultiplier();
}
+
+ @Override
+ @CheckForNull
+ public String gapMultiplier() {
+ return gapMultiplier;
+ }
+
+ /**
+ * @deprecated since 5.5, replaced by {@link #baseEffort}
+ */
@Override
@CheckForNull
+ @Deprecated
public String offset() {
- return offset;
+ return baseEffort();
}
+ @Override
+ public String baseEffort() {
+ return baseEffort;
+ }
+
+
private void validate() {
checkArgument(type != null, "Remediation function type cannot be null");
switch (type) {
case LINEAR:
- checkArgument(this.coefficient != null && this.offset == null, "Linear functions must only have a non empty coefficient");
+ checkArgument(this.gapMultiplier != null && this.baseEffort == null, "Linear functions must only have a non empty gap multiplier");
break;
case LINEAR_OFFSET:
- checkArgument(this.coefficient != null && this.offset != null, "Linear with offset functions must have both non null coefficient and offset");
+ checkArgument(this.gapMultiplier != null && this.baseEffort != null, "Linear with offset functions must have both non null gap multiplier and base effort");
break;
case CONSTANT_ISSUE:
- checkArgument(this.coefficient == null && this.offset != null, "Constant/issue functions must only have a non empty offset");
+ checkArgument(this.gapMultiplier == null && this.baseEffort != null, "Constant/issue functions must only have a non empty base effort");
break;
default:
throw new IllegalArgumentException(String.format("Unknown type on %s", this));
}
DefaultDebtRemediationFunction other = (DefaultDebtRemediationFunction) o;
return new EqualsBuilder()
- .append(coefficient, other.coefficient())
- .append(offset, other.offset())
+ .append(gapMultiplier, other.gapMultiplier())
+ .append(baseEffort, other.baseEffort())
.append(type, other.type())
.isEquals();
}
@Override
public int hashCode() {
int result = type.hashCode();
- result = 31 * result + (coefficient != null ? coefficient.hashCode() : 0);
- result = 31 * result + (offset != null ? offset.hashCode() : 0);
+ result = 31 * result + (gapMultiplier != null ? gapMultiplier.hashCode() : 0);
+ result = 31 * result + (baseEffort != null ? baseEffort.hashCode() : 0);
return result;
}
public String toString() {
return Objects.toStringHelper(DebtRemediationFunction.class)
.add("type", type)
- .add("coefficient", coefficient)
- .add("offset", offset)
+ .add("gap multiplier", gapMultiplier)
+ .add("base effort", baseEffort)
.toString();
}
}
*/
package org.sonar.api.server.rule;
+import javax.annotation.Nullable;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
import org.sonar.api.utils.MessageException;
-import javax.annotation.Nullable;
-
/**
* Factory of {@link org.sonar.api.server.debt.DebtRemediationFunction} that keeps
* a context of rule for better error messages. Used only when declaring rules.
}
@Override
- public DebtRemediationFunction linear(String coefficient) {
- return create(DefaultDebtRemediationFunction.Type.LINEAR, coefficient, null);
+ public DebtRemediationFunction linear(String gapMultiplier) {
+ return create(DefaultDebtRemediationFunction.Type.LINEAR, gapMultiplier, null);
}
@Override
- public DebtRemediationFunction linearWithOffset(String coefficient, String offset) {
- return create(DefaultDebtRemediationFunction.Type.LINEAR_OFFSET, coefficient, offset);
+ public DebtRemediationFunction linearWithOffset(String gapMultiplier, String baseEffort) {
+ return create(DefaultDebtRemediationFunction.Type.LINEAR_OFFSET, gapMultiplier, baseEffort);
}
@Override
- public DebtRemediationFunction constantPerIssue(String offset) {
- return create(DefaultDebtRemediationFunction.Type.CONSTANT_ISSUE, null, offset);
+ public DebtRemediationFunction constantPerIssue(String baseEffort) {
+ return create(DefaultDebtRemediationFunction.Type.CONSTANT_ISSUE, null, baseEffort);
}
@Override
- public DebtRemediationFunction create(DebtRemediationFunction.Type type, @Nullable String coefficient, @Nullable String offset) {
+ public DebtRemediationFunction create(DebtRemediationFunction.Type type, @Nullable String gapMultiplier, @Nullable String baseEffort) {
try {
- return new DefaultDebtRemediationFunction(type, coefficient, offset);
+ return new DefaultDebtRemediationFunction(type, gapMultiplier, baseEffort);
} catch (Exception e) {
throw MessageException.of(String.format("The rule '%s:%s' is invalid : %s ", this.repoKey, this.key, e.getMessage()));
}
interface DebtRemediationFunctions {
/**
- * Shortcut for {@code create(Type.LINEAR, coefficient, null)}.
- * @param coefficient the duration to fix one issue. See {@link DebtRemediationFunction} for details about format.
+ * Shortcut for {@code create(Type.LINEAR, gap multiplier, null)}.
+ * @param gapMultiplier the duration to fix one issue. See {@link DebtRemediationFunction} for details about format.
* @see org.sonar.api.server.debt.DebtRemediationFunction.Type#LINEAR
*/
- DebtRemediationFunction linear(String coefficient);
+ DebtRemediationFunction linear(String gapMultiplier);
/**
- * Shortcut for {@code create(Type.LINEAR_OFFSET, coefficient, offset)}.
- * @param coefficient duration to fix one point of complexity. See {@link DebtRemediationFunction} for details and format.
- * @param offset duration to make basic analysis. See {@link DebtRemediationFunction} for details and format.
+ * Shortcut for {@code create(Type.LINEAR_OFFSET, gap multiplier, base effort)}.
+ * @param gapMultiplier duration to fix one point of complexity. See {@link DebtRemediationFunction} for details and format.
+ * @param baseEffort duration to make basic analysis. See {@link DebtRemediationFunction} for details and format.
* @see org.sonar.api.server.debt.DebtRemediationFunction.Type#LINEAR_OFFSET
*/
- DebtRemediationFunction linearWithOffset(String coefficient, String offset);
+ DebtRemediationFunction linearWithOffset(String gapMultiplier, String baseEffort);
/**
- * Shortcut for {@code create(Type.CONSTANT_ISSUE, null, constant)}.
- * @param constant cost per issue. See {@link DebtRemediationFunction} for details and format.
+ * Shortcut for {@code create(Type.CONSTANT_ISSUE, null, base effort)}.
+ * @param baseEffort cost per issue. See {@link DebtRemediationFunction} for details and format.
* @see org.sonar.api.server.debt.DebtRemediationFunction.Type#CONSTANT_ISSUE
*/
- DebtRemediationFunction constantPerIssue(String constant);
+ DebtRemediationFunction constantPerIssue(String baseEffort);
/**
* Flexible way to create a {@link DebtRemediationFunction}. An unchecked exception is thrown if
* coefficient and/or offset are not valid according to the given @{code type}.
* @since 5.3
*/
- DebtRemediationFunction create(DebtRemediationFunction.Type type, @Nullable String coefficient, @Nullable String offset);
+ DebtRemediationFunction create(DebtRemediationFunction.Type type, @Nullable String gapMultiplier, @Nullable String baseEffort);
}
class NewRule {
private boolean template;
private RuleStatus status = RuleStatus.defaultStatus();
private DebtRemediationFunction debtRemediationFunction;
- private String effortToFixDescription;
+ private String gapDescription;
private final Set<String> tags = Sets.newTreeSet();
private final Map<String, NewParam> paramsByKey = Maps.newHashMap();
private final DebtRemediationFunctions functions;
return this;
}
+ /**
+ * @deprecated since 5.5, replaced by {@link #setGapDescription(String)}
+ */
+ @Deprecated
+ public NewRule setEffortToFixDescription(@Nullable String s) {
+ return setGapDescription(s);
+ }
+
/**
* For rules that use LINEAR or LINEAR_OFFSET remediation functions, the meaning
- * of the function parameter (= "effort to fix") must be set. This description
- * explains what 1 point of "effort to fix" represents for the rule.
+ * of the function parameter (= "gap") must be set. This description
+ * explains what 1 point of "gap" represents for the rule.
* <p/>
* Example: for the "Insufficient condition coverage", this description for the
- * remediation function coefficient/offset would be something like
+ * remediation function gap multiplier/base effort would be something like
* "Effort to test one uncovered condition".
*/
- public NewRule setEffortToFixDescription(@Nullable String s) {
- this.effortToFixDescription = s;
+ public NewRule setGapDescription(@Nullable String s) {
+ this.gapDescription = s;
return this;
}
private final String severity;
private final boolean template;
private final DebtRemediationFunction debtRemediationFunction;
- private final String effortToFixDescription;
+ private final String gapDescription;
private final Set<String> tags;
private final Map<String, Param> params;
private final RuleStatus status;
this.template = newRule.template;
this.status = newRule.status;
this.debtRemediationFunction = newRule.debtRemediationFunction;
- this.effortToFixDescription = newRule.effortToFixDescription;
+ this.gapDescription = newRule.gapDescription;
this.type = newRule.type == null ? RuleTagsToTypeConverter.convert(newRule.tags) : newRule.type;
this.tags = ImmutableSortedSet.copyOf(Sets.difference(newRule.tags, RuleTagsToTypeConverter.RESERVED_TAGS));
ImmutableMap.Builder<String, Param> paramsBuilder = ImmutableMap.builder();
return debtRemediationFunction;
}
+ /**
+ * @deprecated since 5.5, replaced by {@link #gapDescription()}
+ */
+ @Deprecated
@CheckForNull
public String effortToFixDescription() {
- return effortToFixDescription;
+ return gapDescription();
+ }
+
+ @CheckForNull
+ public String gapDescription() {
+ return gapDescription;
}
@CheckForNull
* <param>
* <key>another-param</key>
* </param>
- **
- * <!-- SQALE debt - type of debt remediation function -->
+ *
+ * <!-- Quality Model - type of debt remediation function -->
* <!-- See enum {@link org.sonar.api.server.debt.DebtRemediationFunction.Type} for supported values -->
- * <!-- Since 5.3 -->
- * <debtRemediationFunction>LINEAR_OFFSET</debtRemediationFunction>
+ * <!-- It was previously named 'debtRemediationFunction' which is still supported but deprecated since 5.5 -->
+ * <!-- Since 5.5 -->
+ * <remediationFunction>LINEAR_OFFSET</remediationFunction>
*
- * <!-- SQALE debt - raw description of the "effort to fix", used for some types of remediation functions. -->
- * <!-- See {@link org.sonar.api.server.rule.RulesDefinition.NewRule#setEffortToFixDescription(String)} -->
- * <!-- Since 5.3 -->
- * <effortToFixDescription>Effort to test one uncovered condition</effortToFixDescription>
+ * <!-- Quality Model - raw description of the "gap", used for some types of remediation functions. -->
+ * <!-- See {@link org.sonar.api.server.rule.RulesDefinition.NewRule#setGapDescription(String)} -->
+ * <!-- It was previously named 'effortToFixDescription' which is still supported but deprecated since 5.5 -->
+ * <!-- Since 5.5 -->
+ * <gapDescription>Effort to test one uncovered condition</gapFixDescription>
*
- * <!-- SQALE debt - coefficient of debt remediation function. Must be defined only for some function types. -->
+ * <!-- Quality Model - gap multiplier of debt remediation function. Must be defined only for some function types. -->
* <!-- See {@link org.sonar.api.server.rule.RulesDefinition.DebtRemediationFunctions} -->
- * <!-- Since 5.3 -->
- * <debtRemediationFunctionCoefficient>10min</debtRemediationFunctionCoefficient>
+ * <!-- It was previously named 'debtRemediationFunctionCoefficient' which is still supported but deprecated since 5.5 -->
+ * <!-- Since 5.5 -->
+ * <remediationFunctionGapMultiplier>10min</remediationFunctionGapMultiplier>
*
- * <!-- SQALE debt - offset of debt remediation function. Must be defined only for some function types. -->
+ * <!-- Quality Model - base effort of debt remediation function. Must be defined only for some function types. -->
* <!-- See {@link org.sonar.api.server.rule.RulesDefinition.DebtRemediationFunctions} -->
- * <!-- Since 5.3 -->
- * <debtRemediationFunctionOffset>2min</debtRemediationFunctionOffset>
+ * <!-- It was previously named 'debtRemediationFunctionOffset' which is still supported but deprecated since 5.5 -->
+ * <!-- Since 5.5 -->
+ * <remediationFunctionBaseEffort>2min</remediationFunctionBaseEffort>
*
* <!-- Deprecated field, replaced by "internalKey" -->
* <configKey>Checker/TreeWalker/LocalVariableName</configKey>
*
* <!-- Deprecated field, replaced by "severity" -->
* <priority>BLOCKER</priority>
+ *
* </rule>
* </rules>
* </pre>
* <tag>security</tag>
* <tag>user-experience</tag>
* <debtRemediationFunction>CONSTANT_ISSUE</debtRemediationFunction>
- * <debtRemediationFunctionOffset>10min</debtRemediationFunctionOffset>
+ * <debtRemediationFunctionBaseOffset>10min</debtRemediationFunctionBaseOffset>
* </rule>
*
* <!-- another rules... -->
String type = null;
RuleStatus status = RuleStatus.defaultStatus();
boolean template = false;
- String effortToFixDescription = null;
+ String gapDescription = null;
String debtRemediationFunction = null;
- String debtRemediationFunctionOffset = null;
- String debtRemediationFunctionCoeff = null;
+ String debtRemediationFunctionGapMultiplier = null;
+ String debtRemediationFunctionBaseEffort = null;
List<ParamStruct> params = new ArrayList<>();
List<String> tags = new ArrayList<>();
} else if (equalsIgnoreCase("cardinality", nodeName)) {
template = Cardinality.MULTIPLE == Cardinality.valueOf(nodeValue(cursor));
- } else if (equalsIgnoreCase("effortToFixDescription", nodeName)) {
- effortToFixDescription = nodeValue(cursor);
+ } else if (equalsIgnoreCase("gapDescription", nodeName) || equalsIgnoreCase("effortToFixDescription", nodeName)) {
+ gapDescription = nodeValue(cursor);
- } else if (equalsIgnoreCase("debtRemediationFunction", nodeName)) {
+ } else if (equalsIgnoreCase("remediationFunction", nodeName) || equalsIgnoreCase("debtRemediationFunction", nodeName)) {
debtRemediationFunction = nodeValue(cursor);
- } else if (equalsIgnoreCase("debtRemediationFunctionOffset", nodeName)) {
- debtRemediationFunctionOffset = nodeValue(cursor);
+ } else if (equalsIgnoreCase("remediationFunctionBaseEffort", nodeName) || equalsIgnoreCase("debtRemediationFunctionOffset", nodeName)) {
+ debtRemediationFunctionGapMultiplier = nodeValue(cursor);
- } else if (equalsIgnoreCase("debtRemediationFunctionCoefficient", nodeName)) {
- debtRemediationFunctionCoeff = nodeValue(cursor);
+ } else if (equalsIgnoreCase("remediationFunctionGapMultiplier", nodeName) || equalsIgnoreCase("debtRemediationFunctionCoefficient", nodeName)) {
+ debtRemediationFunctionBaseEffort = nodeValue(cursor);
} else if (equalsIgnoreCase("status", nodeName)) {
String s = nodeValue(cursor);
.setTags(tags.toArray(new String[tags.size()]))
.setTemplate(template)
.setStatus(status)
- .setEffortToFixDescription(effortToFixDescription);
+ .setGapDescription(gapDescription);
if (type != null) {
rule.setType(RuleType.valueOf(type));
}
fillDescription(rule, descriptionFormat, description);
- fillRemediationFunction(rule, debtRemediationFunction, debtRemediationFunctionOffset, debtRemediationFunctionCoeff);
+ fillRemediationFunction(rule, debtRemediationFunction, debtRemediationFunctionGapMultiplier, debtRemediationFunctionBaseEffort);
fillParams(rule, params);
} catch (Exception e) {
throw new IllegalArgumentException(format("Fail to load the rule with key [%s:%s]", repo.key(), key), e);
public void create_linear() {
DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "10h", null);
assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.LINEAR);
- assertThat(function.coefficient()).isEqualTo("10h");
- assertThat(function.offset()).isNull();
+ assertThat(function.gapMultiplier()).isEqualTo("10h");
+ assertThat(function.baseEffort()).isNull();
}
@Test
public void create_linear_with_offset() {
DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min");
assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.LINEAR_OFFSET);
- assertThat(function.coefficient()).isEqualTo("10h");
- assertThat(function.offset()).isEqualTo("5min");
+ assertThat(function.gapMultiplier()).isEqualTo("10h");
+ assertThat(function.baseEffort()).isEqualTo("5min");
}
@Test
public void create_constant_per_issue() {
DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "10h");
assertThat(function.type()).isEqualTo(DefaultDebtRemediationFunction.Type.CONSTANT_ISSUE);
- assertThat(function.coefficient()).isNull();
- assertThat(function.offset()).isEqualTo("10h");
+ assertThat(function.gapMultiplier()).isNull();
+ assertThat(function.baseEffort()).isEqualTo("10h");
}
@Test
public void sanitize_remediation_coefficient_and_offset() {
DebtRemediationFunction function = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, " 1 h ", " 10 min");
- assertThat(function.coefficient()).isEqualTo("1h");
- assertThat(function.offset()).isEqualTo("10min");
+ assertThat(function.gapMultiplier()).isEqualTo("1h");
+ assertThat(function.baseEffort()).isEqualTo("10min");
}
@Test
new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, null, "10h");
fail();
} catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Linear functions must only have a non empty coefficient");
+ assertThat(e).hasMessage("Linear functions must only have a non empty gap multiplier");
}
}
new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "5min", "10h");
fail();
} catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Linear functions must only have a non empty coefficient");
+ assertThat(e).hasMessage("Linear functions must only have a non empty gap multiplier");
}
}
new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, "10h", null);
fail();
} catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Constant/issue functions must only have a non empty offset");
+ assertThat(e).hasMessage("Constant/issue functions must only have a non empty base effort");
}
}
new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, "5min", "10h");
fail();
} catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Constant/issue functions must only have a non empty offset");
+ assertThat(e).hasMessage("Constant/issue functions must only have a non empty base effort");
}
}
new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "", "10h");
fail();
} catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Linear with offset functions must have both non null coefficient and offset");
+ assertThat(e).hasMessage("Linear with offset functions must have both non null gap multiplier and base effort");
}
}
new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "5min", "");
fail();
} catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Linear with offset functions must have both non null coefficient and offset");
+ assertThat(e).hasMessage("Linear with offset functions must have both non null gap multiplier and base effort");
}
}
@Test
public void test_to_string() {
assertThat(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "10h", "5min").toString())
- .isEqualTo("DebtRemediationFunction{type=LINEAR_OFFSET, coefficient=10h, offset=5min}");
+ .isEqualTo("DebtRemediationFunction{type=LINEAR_OFFSET, gap multiplier=10h, base effort=5min}");
}
@Test
new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR, "foo", null);
fail();
} catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Invalid coefficient: foo (Duration 'foo' is invalid, it should use the following sample format : 2d 10h 15min)");
+ assertThat(e).hasMessage("Invalid gap multiplier: foo (Duration 'foo' is invalid, it should use the following sample format : 2d 10h 15min)");
}
}
.setName("Insufficient condition coverage")
.setHtmlDescription("Insufficient condition coverage by unit tests")
.setSeverity(Severity.MAJOR)
- .setEffortToFixDescription("Effort to test one uncovered branch");
+ .setGapDescription("Effort to test one uncovered branch");
newRule.setDebtRemediationFunction(newRule.debtRemediationFunctions().linearWithOffset("1h", "10min"));
newRepo.done();
RulesDefinition.Rule rule = repo.rule("InsufficientBranchCoverage");
assertThat(rule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET);
- assertThat(rule.debtRemediationFunction().coefficient()).isEqualTo("1h");
- assertThat(rule.debtRemediationFunction().offset()).isEqualTo("10min");
- assertThat(rule.effortToFixDescription()).isEqualTo("Effort to test one uncovered branch");
+ assertThat(rule.debtRemediationFunction().gapMultiplier()).isEqualTo("1h");
+ assertThat(rule.debtRemediationFunction().baseEffort()).isEqualTo("10min");
+ assertThat(rule.gapDescription()).isEqualTo("Effort to test one uncovered branch");
}
@Test
" <name>One</name>" +
" <description>Desc</description>" +
- " <effortToFixDescription>lines</effortToFixDescription>" +
- " <debtRemediationFunction>LINEAR</debtRemediationFunction>" +
- " <debtRemediationFunctionCoefficient>2d 3h</debtRemediationFunctionCoefficient>" +
+ " <gapDescription>lines</gapDescription>" +
+ " <remediationFunction>LINEAR</remediationFunction>" +
+ " <remediationFunctionGapMultiplier>2d 3h</remediationFunctionGapMultiplier>" +
" </rule>" +
"</rules>";
RulesDefinition.Rule rule = load(xml).rule("1");
- assertThat(rule.effortToFixDescription()).isEqualTo("lines");
+ assertThat(rule.gapDescription()).isEqualTo("lines");
DebtRemediationFunction function = rule.debtRemediationFunction();
assertThat(function).isNotNull();
assertThat(function.type()).isEqualTo(DebtRemediationFunction.Type.LINEAR);
- assertThat(function.coefficient()).isEqualTo("2d3h");
- assertThat(function.offset()).isNull();
+ assertThat(function.gapMultiplier()).isEqualTo("2d3h");
+ assertThat(function.baseEffort()).isNull();
}
@Test
" <description>Desc</description>" +
" <effortToFixDescription>lines</effortToFixDescription>" +
- " <debtRemediationFunction>LINEAR_OFFSET</debtRemediationFunction>" +
- " <debtRemediationFunctionCoefficient>2d 3h</debtRemediationFunctionCoefficient>" +
- " <debtRemediationFunctionOffset>5min</debtRemediationFunctionOffset>" +
+ " <remediationFunction>LINEAR_OFFSET</remediationFunction>" +
+ " <remediationFunctionGapMultiplier>2d 3h</remediationFunctionGapMultiplier>" +
+ " <remediationFunctionBaseEffort>5min</remediationFunctionBaseEffort>" +
" </rule>" +
"</rules>";
RulesDefinition.Rule rule = load(xml).rule("1");
- assertThat(rule.effortToFixDescription()).isEqualTo("lines");
+ assertThat(rule.gapDescription()).isEqualTo("lines");
DebtRemediationFunction function = rule.debtRemediationFunction();
assertThat(function).isNotNull();
assertThat(function.type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET);
- assertThat(function.coefficient()).isEqualTo("2d3h");
- assertThat(function.offset()).isEqualTo("5min");
+ assertThat(function.gapMultiplier()).isEqualTo("2d3h");
+ assertThat(function.baseEffort()).isEqualTo("5min");
}
@Test
" <key>1</key>" +
" <name>One</name>" +
" <description>Desc</description>" +
- " <debtRemediationFunction>CONSTANT_ISSUE</debtRemediationFunction>" +
- " <debtRemediationFunctionOffset>5min</debtRemediationFunctionOffset>" +
+ " <remediationFunction>CONSTANT_ISSUE</remediationFunction>" +
+ " <remediationFunctionBaseEffort>5min</remediationFunctionBaseEffort>" +
" </rule>" +
"</rules>";
RulesDefinition.Rule rule = load(xml).rule("1");
DebtRemediationFunction function = rule.debtRemediationFunction();
assertThat(function).isNotNull();
assertThat(function.type()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE);
- assertThat(function.coefficient()).isNull();
- assertThat(function.offset()).isEqualTo("5min");
+ assertThat(function.gapMultiplier()).isNull();
+ assertThat(function.baseEffort()).isEqualTo("5min");
}
@Test
" <key>1</key>" +
" <name>One</name>" +
" <description>Desc</description>" +
- " <debtRemediationFunction>UNKNOWN</debtRemediationFunction>" +
+ " <remediationFunction>UNKNOWN</remediationFunction>" +
" </rule>" +
"</rules>");
fail();
" <description>Desc</description>" +
" <effortToFixDescription>lines</effortToFixDescription>" +
" <debtSubCharacteristic>BUG</debtSubCharacteristic>" +
- " <debtRemediationFunction>LINEAR_OFFSET</debtRemediationFunction>" +
- " <debtRemediationFunctionCoefficient>2d 3h</debtRemediationFunctionCoefficient>" +
- " <debtRemediationFunctionOffset>5min</debtRemediationFunctionOffset>" +
+ " <remediationFunction>LINEAR_OFFSET</remediationFunction>" +
+ " <remediationFunctionGapMultiplier>2d 3h</remediationFunctionGapMultiplier>" +
+ " <remediationFunctionBaseEffort>5min</remediationFunctionBaseEffort>" +
" </rule>" +
"</rules>";
RulesDefinition.Rule rule = load(xml).rule("1");
}
}
+ @Test
+ public void test_deprecated_remediation_function() {
+ String xml = "" +
+ "<rules>" +
+ " <rule>" +
+ " <key>1</key>" +
+ " <name>One</name>" +
+ " <description>Desc</description>" +
+ " <effortToFixDescription>lines</effortToFixDescription>" +
+ " <debtRemediationFunction>LINEAR_OFFSET</debtRemediationFunction>" +
+ " <debtRemediationFunctionCoefficient>2d 3h</debtRemediationFunctionCoefficient>" +
+ " <debtRemediationFunctionOffset>5min</debtRemediationFunctionOffset>" +
+ " </rule>" +
+ "</rules>";
+ RulesDefinition.Rule rule = load(xml).rule("1");
+ assertThat(rule.gapDescription()).isEqualTo("lines");
+ DebtRemediationFunction function = rule.debtRemediationFunction();
+ assertThat(function).isNotNull();
+ assertThat(function.type()).isEqualTo(DebtRemediationFunction.Type.LINEAR_OFFSET);
+ assertThat(function.gapMultiplier()).isEqualTo("2d3h");
+ assertThat(function.baseEffort()).isEqualTo("5min");
+ }
+
private RulesDefinition.Repository load(InputStream input, String encoding) {
RulesDefinition.Context context = new RulesDefinition.Context();
RulesDefinition.NewRepository newRepository = context.createRepository("squid", "java");