From f5521caa09810aac91e1dbb86dee52e435f4bbd5 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Mon, 13 Jan 2014 17:22:14 +0100 Subject: [PATCH] SONAR-4908 add template rules and param types --- .../org/sonar/api/rule/RuleDefinitions.java | 43 ++++-- .../org/sonar/api/rule/RuleParamType.java | 61 ++++++++ .../sonar/api/rule/RuleDefinitionsTest.java | 32 +++-- .../org/sonar/api/rule/RuleParamTypeTest.java | 45 ++++++ .../org/sonar/server/platform/Platform.java | 2 + .../rule/DeprecatedRuleDefinitions.java | 103 ++++++++++++++ .../rule/DeprecatedRuleDefinitionsTest.java | 133 ++++++++++++++++++ 7 files changed, 398 insertions(+), 21 deletions(-) create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleParamType.java create mode 100644 sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleParamTypeTest.java create mode 100644 sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java create mode 100644 sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleDefinitions.java b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleDefinitions.java index b8333948133..939377f2d40 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleDefinitions.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleDefinitions.java @@ -168,6 +168,7 @@ public interface RuleDefinitions extends ServerExtension { this.name = newRepository.name; ImmutableMap.Builder ruleBuilder = ImmutableMap.builder(); for (NewRule newRule : newRepository.newRules.values()) { + newRule.validate(); ruleBuilder.put(newRule.key, new Rule(newRule)); } this.rulesByKey = ruleBuilder.build(); @@ -221,22 +222,25 @@ public interface RuleDefinitions extends ServerExtension { static class NewRule { private final String repoKey, key; private String name, htmlDescription, metadata, defaultSeverity = Severity.MAJOR; + private boolean template; private final Set tags = Sets.newHashSet(); private final Map paramsByKey = Maps.newHashMap(); private NewRule(String repoKey, String key) { this.repoKey = repoKey; - this.key = this.name = key; + this.key = key; } public NewRule setName(String s) { - if (StringUtils.isBlank(s)) { - throw new IllegalArgumentException(String.format("Name of rule %s is blank", this)); - } this.name = s; return this; } + public NewRule setTemplate(boolean template) { + this.template = template; + return this; + } + public NewRule setDefaultSeverity(String s) { if (!Severity.ALL.contains(s)) { throw new IllegalArgumentException(String.format("Default severity of rule %s is not correct: %s", this, s)); @@ -246,9 +250,6 @@ public interface RuleDefinitions extends ServerExtension { } public NewRule setHtmlDescription(String s) { - if (StringUtils.isBlank(s)) { - throw new IllegalArgumentException(String.format("HTML description of rule %s is blank", this)); - } this.htmlDescription = s; return this; } @@ -292,6 +293,15 @@ public interface RuleDefinitions extends ServerExtension { return this; } + private void validate() { + if (StringUtils.isBlank(name)) { + throw new IllegalStateException(String.format("Name of rule %s is empty", this)); + } + if (StringUtils.isBlank(htmlDescription)) { + throw new IllegalStateException(String.format("HTML description of rule %s is empty", this)); + } + } + @Override public String toString() { return String.format("[repository=%s, key=%s]", repoKey, key); @@ -300,6 +310,7 @@ public interface RuleDefinitions extends ServerExtension { static class Rule { private final String repoKey, key, name, htmlDescription, metadata, defaultSeverity; + private final boolean template; private final Set tags; private final Map params; @@ -310,6 +321,7 @@ public interface RuleDefinitions extends ServerExtension { this.htmlDescription = newRule.htmlDescription; this.metadata = newRule.metadata; this.defaultSeverity = newRule.defaultSeverity; + this.template = newRule.template; this.tags = ImmutableSet.copyOf(newRule.tags); ImmutableMap.Builder paramsBuilder = ImmutableMap.builder(); for (NewParam newParam : newRule.paramsByKey.values()) { @@ -335,6 +347,10 @@ public interface RuleDefinitions extends ServerExtension { return htmlDescription; } + public boolean template() { + return template; + } + @CheckForNull public Param param(String key) { return params.get(key); @@ -385,7 +401,7 @@ public interface RuleDefinitions extends ServerExtension { static class NewParam { private final String key; private String name, description, defaultValue; - // TODO type + private RuleParamType type = RuleParamType.STRING; private NewParam(String key) { this.key = this.name = key; @@ -397,6 +413,11 @@ public interface RuleDefinitions extends ServerExtension { return this; } + public NewParam setType(RuleParamType t) { + this.type = t; + return this; + } + /** * Plain-text description. Can be null. */ @@ -413,12 +434,14 @@ public interface RuleDefinitions extends ServerExtension { static class Param { private final String key, name, description, defaultValue; + private final RuleParamType type; private Param(NewParam newParam) { this.key = newParam.key; this.name = newParam.name; this.description = newParam.description; this.defaultValue = newParam.defaultValue; + this.type = newParam.type; } public String key() { @@ -439,6 +462,10 @@ public interface RuleDefinitions extends ServerExtension { return defaultValue; } + public RuleParamType type() { + return type; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleParamType.java b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleParamType.java new file mode 100644 index 00000000000..5b9599db989 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleParamType.java @@ -0,0 +1,61 @@ +/* + * 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.api.rule; + +/** + * @since 4.2 + */ +public final class RuleParamType { + + public static final RuleParamType STRING = new RuleParamType("STRING"); + public static final RuleParamType TEXT = new RuleParamType("TEXT"); + public static final RuleParamType BOOLEAN = new RuleParamType("BOOLEAN"); + public static final RuleParamType INTEGER = new RuleParamType("INTEGER"); + public static final RuleParamType REGULAR_EXPRESSION = new RuleParamType("REGULAR_EXPRESSION"); + + private final String key; + + private RuleParamType(String key) { + this.key = key; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + RuleParamType that = (RuleParamType) o; + return key.equals(that.key); + } + + @Override + public int hashCode() { + return key.hashCode(); + } + + @Override + public String toString() { + return key; + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleDefinitionsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleDefinitionsTest.java index 4f391609c51..87b891d04ac 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleDefinitionsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleDefinitionsTest.java @@ -62,12 +62,13 @@ public class RuleDefinitionsTest { RuleDefinitions.NewRepository newFindbugs = context.newRepository("findbugs", "java"); newFindbugs.newRule("NPE") .setName("Detect NPE") + .setHtmlDescription("Detect NPE") .setHtmlDescription("Detect java.lang.NullPointerException") .setDefaultSeverity(Severity.BLOCKER) .setMetadata("/something") .setTags("one", "two") .addTags("two", "three", "four"); - newFindbugs.newRule("ABC"); + newFindbugs.newRule("ABC").setName("ABC").setHtmlDescription("ABC"); newFindbugs.done(); RuleDefinitions.Repository findbugs = context.repository("findbugs"); @@ -81,6 +82,7 @@ public class RuleDefinitionsTest { assertThat(npeRule.tags()).containsOnly("one", "two", "three", "four"); assertThat(npeRule.params()).isEmpty(); assertThat(npeRule.metadata()).isEqualTo("/something"); + assertThat(npeRule.template()).isFalse(); assertThat(npeRule.toString()).isEqualTo("[repository=findbugs, key=NPE]"); // test equals() and hashCode() @@ -92,14 +94,12 @@ public class RuleDefinitionsTest { @Test public void define_rule_with_default_fields() { RuleDefinitions.NewRepository newFindbugs = context.newRepository("findbugs", "java"); - newFindbugs.newRule("NPE"); + newFindbugs.newRule("NPE").setName("NPE").setHtmlDescription("NPE"); newFindbugs.done(); RuleDefinitions.Rule rule = context.repository("findbugs").rule("NPE"); assertThat(rule.key()).isEqualTo("NPE"); - assertThat(rule.name()).isEqualTo("NPE"); assertThat(rule.defaultSeverity()).isEqualTo(Severity.MAJOR); - assertThat(rule.htmlDescription()).isNull(); assertThat(rule.params()).isEmpty(); assertThat(rule.metadata()).isNull(); assertThat(rule.tags()).isEmpty(); @@ -108,8 +108,8 @@ public class RuleDefinitionsTest { @Test public void define_rule_parameters() { RuleDefinitions.NewRepository newFindbugs = context.newRepository("findbugs", "java"); - RuleDefinitions.NewRule newNpe = newFindbugs.newRule("NPE"); - newNpe.newParam("level").setDefaultValue("LOW").setName("Level").setDescription("The level"); + RuleDefinitions.NewRule newNpe = newFindbugs.newRule("NPE").setName("NPE").setHtmlDescription("NPE"); + newNpe.newParam("level").setDefaultValue("LOW").setName("Level").setDescription("The level").setType(RuleParamType.INTEGER); newNpe.newParam("effort"); newFindbugs.done(); @@ -121,11 +121,13 @@ public class RuleDefinitionsTest { assertThat(level.name()).isEqualTo("Level"); assertThat(level.description()).isEqualTo("The level"); assertThat(level.defaultValue()).isEqualTo("LOW"); + assertThat(level.type()).isEqualTo(RuleParamType.INTEGER); RuleDefinitions.Param effort = rule.param("effort"); assertThat(effort.key()).isEqualTo("effort").isEqualTo(effort.name()); assertThat(effort.description()).isNull(); assertThat(effort.defaultValue()).isNull(); + assertThat(effort.type()).isEqualTo(RuleParamType.STRING); // test equals() and hashCode() assertThat(level).isEqualTo(level).isNotEqualTo(effort).isNotEqualTo("level").isNotEqualTo(null); @@ -138,7 +140,7 @@ public class RuleDefinitionsTest { // for example fb-contrib RuleDefinitions.NewExtendedRepository newFindbugs = context.extendRepository("findbugs"); - newFindbugs.newRule("NPE"); + newFindbugs.newRule("NPE").setName("NPE").setHtmlDescription("NPE"); newFindbugs.done(); assertThat(context.repositories()).isEmpty(); @@ -187,11 +189,13 @@ public class RuleDefinitionsTest { @Test public void fail_if_blank_rule_name() { + RuleDefinitions.NewRepository newRepository = context.newRepository("findbugs", "java"); + newRepository.newRule("NPE").setName(null).setHtmlDescription("NPE"); try { - context.newRepository("findbugs", "java").newRule("NPE").setName(null); + newRepository.done(); fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Name of rule [repository=findbugs, key=NPE] is blank"); + } catch (IllegalStateException e) { + assertThat(e).hasMessage("Name of rule [repository=findbugs, key=NPE] is empty"); } } @@ -208,11 +212,13 @@ public class RuleDefinitionsTest { @Test public void fail_if_blank_rule_html_description() { + RuleDefinitions.NewRepository newRepository = context.newRepository("findbugs", "java"); + newRepository.newRule("NPE").setName("NPE").setHtmlDescription(null); try { - context.newRepository("findbugs", "java").newRule("NPE").setHtmlDescription(null); + newRepository.done(); fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("HTML description of rule [repository=findbugs, key=NPE] is blank"); + } catch (IllegalStateException e) { + assertThat(e).hasMessage("HTML description of rule [repository=findbugs, key=NPE] is empty"); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleParamTypeTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleParamTypeTest.java new file mode 100644 index 00000000000..722c672696f --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleParamTypeTest.java @@ -0,0 +1,45 @@ +/* + * 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.api.rule; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class RuleParamTypeTest { + @Test + public void testEquals() throws Exception { + assertThat(RuleParamType.INTEGER) + .isEqualTo(RuleParamType.INTEGER) + .isNotEqualTo(RuleParamType.STRING) + .isNotEqualTo("INTEGER") + .isNotEqualTo(null); + } + + @Test + public void testHashCode() throws Exception { + assertThat(RuleParamType.INTEGER.hashCode()).isEqualTo(RuleParamType.INTEGER.hashCode()); + } + + @Test + public void testToString() throws Exception { + assertThat(RuleParamType.INTEGER.toString()).isEqualTo("INTEGER"); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index fb102855555..7dcb10367ab 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -91,6 +91,7 @@ import org.sonar.server.permission.InternalPermissionTemplateService; import org.sonar.server.permission.PermissionFinder; import org.sonar.server.plugins.*; import org.sonar.server.qualityprofile.*; +import org.sonar.server.rule.DeprecatedRuleDefinitions; import org.sonar.server.rule.ProfileRules; import org.sonar.server.rule.RubyRuleService; import org.sonar.server.rule.RuleRegistry; @@ -368,6 +369,7 @@ public final class Platform { ComponentContainer startupContainer = servicesContainer.createChild(); startupContainer.addSingleton(GwtPublisher.class); startupContainer.addSingleton(RegisterMetrics.class); + startupContainer.addSingleton(DeprecatedRuleDefinitions.class); startupContainer.addSingleton(RegisterRules.class); startupContainer.addSingleton(RegisterNewProfiles.class); startupContainer.addSingleton(JdbcDriverDeployer.class); diff --git a/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java b/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java new file mode 100644 index 00000000000..cc61dfa0f8b --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.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.server.rule; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.rule.RuleDefinitions; +import org.sonar.api.rules.RuleParam; +import org.sonar.api.rules.RuleRepository; +import org.sonar.check.Cardinality; +import org.sonar.core.i18n.RuleI18nManager; + +import javax.annotation.CheckForNull; + +/** + * Inject deprecated RuleRepository into RuleDefinitions for backward-compatibility. + * @since 4.2 + */ +public class DeprecatedRuleDefinitions implements RuleDefinitions { + private final RuleI18nManager i18n; + private final RuleRepository[] repositories; + + public DeprecatedRuleDefinitions(RuleI18nManager i18n, RuleRepository[] repositories) { + this.i18n = i18n; + this.repositories = repositories; + } + + public DeprecatedRuleDefinitions(RuleI18nManager i18n) { + this(i18n, new RuleRepository[0]); + } + + @Override + public void define(Context context) { + for (RuleRepository repository : repositories) { + // RuleRepository API does not handle difference between new and extended repositories, + NewRepository newRepository; + if (context.repository(repository.getKey()) == null) { + newRepository = context.newRepository(repository.getKey(), repository.getLanguage()); + newRepository.setName(repository.getName()); + } else { + newRepository = (NewRepository) context.extendRepository(repository.getKey()); + } + for (org.sonar.api.rules.Rule rule : repository.createRules()) { + // TODO remove org.sonar.api.rules.Rule#tags + NewRule newRule = newRepository.newRule(rule.getKey()); + newRule.setName(ruleName(repository.getKey(), rule)); + newRule.setHtmlDescription(ruleDescription(repository.getKey(), rule)); + newRule.setMetadata(rule.getConfigKey()); + newRule.setTemplate(Cardinality.MULTIPLE.equals(rule.getCardinality())); + newRule.setDefaultSeverity(rule.getSeverity().toString()); + for (RuleParam param : rule.getParams()) { + NewParam newParam = newRule.newParam(param.getKey()); + newParam.setDefaultValue(param.getDefaultValue()); + newParam.setDescription(paramDescription(repository.getKey(), rule.getKey(), param)); + } + } + newRepository.done(); + } + } + + @CheckForNull + private String ruleName(String repositoryKey, org.sonar.api.rules.Rule rule) { + String name = i18n.getName(repositoryKey, rule.getKey()); + if (StringUtils.isNotBlank(name)) { + return name; + } + return StringUtils.defaultIfBlank(rule.getName(), null); + } + + @CheckForNull + private String ruleDescription(String repositoryKey, org.sonar.api.rules.Rule rule) { + String description = i18n.getDescription(repositoryKey, rule.getKey()); + if (StringUtils.isNotBlank(description)) { + return description; + } + return StringUtils.defaultIfBlank(rule.getDescription(), null); + } + + @CheckForNull + private String paramDescription(String repositoryKey, String ruleKey, RuleParam param) { + String desc = StringUtils.defaultIfEmpty( + i18n.getParamDescription(repositoryKey, ruleKey, param.getKey()), + param.getDescription() + ); + return StringUtils.defaultIfBlank(desc, null); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java b/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java new file mode 100644 index 00000000000..e199c47d742 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java @@ -0,0 +1,133 @@ +/* + * 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.server.rule; + +import org.junit.Test; +import org.sonar.api.rule.RuleDefinitions; +import org.sonar.api.rule.Severity; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RulePriority; +import org.sonar.api.rules.RuleRepository; +import org.sonar.core.i18n.RuleI18nManager; + +import java.util.Arrays; +import java.util.List; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DeprecatedRuleDefinitionsTest { + + static class CheckstyleRules extends RuleRepository { + public CheckstyleRules() { + super("checkstyle", "java"); + setName("Checkstyle"); + } + + @Override + public List createRules() { + Rule rule = Rule.create("checkstyle", "ConstantName", "Constant Name"); + rule.setDescription("Checks that constant names conform to the specified format"); + rule.setConfigKey("Checker/TreeWalker/ConstantName"); + rule.setSeverity(RulePriority.BLOCKER); + rule.createParameter("format").setDescription("Regular expression").setDefaultValue("A-Z").setType("REGULAR_EXPRESSION"); + return Arrays.asList(rule); + } + } + + @Test + public void wrap_deprecated_rule_repositories() throws Exception { + RuleDefinitions.Context context = new RuleDefinitions.Context(); + RuleI18nManager i18n = mock(RuleI18nManager.class); + + new DeprecatedRuleDefinitions(i18n, new RuleRepository[]{new CheckstyleRules()}).define(context); + + assertThat(context.repositories()).hasSize(1); + RuleDefinitions.Repository checkstyle = context.repository("checkstyle"); + assertThat(checkstyle).isNotNull(); + assertThat(checkstyle.key()).isEqualTo("checkstyle"); + assertThat(checkstyle.name()).isEqualTo("Checkstyle"); + assertThat(checkstyle.language()).isEqualTo("java"); + assertThat(checkstyle.rules()).hasSize(1); + RuleDefinitions.Rule rule = checkstyle.rule("ConstantName"); + assertThat(rule).isNotNull(); + assertThat(rule.key()).isEqualTo("ConstantName"); + assertThat(rule.name()).isEqualTo("Constant Name"); + assertThat(rule.htmlDescription()).isEqualTo("Checks that constant names conform to the specified format"); + assertThat(rule.defaultSeverity()).isEqualTo(Severity.BLOCKER); + assertThat(rule.metadata()).isEqualTo("Checker/TreeWalker/ConstantName"); + assertThat(rule.tags()).isEmpty(); + assertThat(rule.params()).hasSize(1); + RuleDefinitions.Param param = rule.param("format"); + assertThat(param).isNotNull(); + assertThat(param.key()).isEqualTo("format"); + assertThat(param.name()).isEqualTo("format"); + assertThat(param.description()).isEqualTo("Regular expression"); + assertThat(param.defaultValue()).isEqualTo("A-Z"); + } + + @Test + public void emulate_the_day_deprecated_api_can_be_dropped() throws Exception { + RuleDefinitions.Context context = new RuleDefinitions.Context(); + RuleI18nManager i18n = mock(RuleI18nManager.class); + + // no more RuleRepository ! + new DeprecatedRuleDefinitions(i18n); + + assertThat(context.repositories()).isEmpty(); + } + + + static class UseBundles extends RuleRepository { + public UseBundles() { + super("checkstyle", "java"); + setName("Checkstyle"); + } + + @Override + public List createRules() { + Rule rule = Rule.create("checkstyle", "ConstantName"); + rule.createParameter("format"); + return Arrays.asList(rule); + } + } + + @Test + public void use_l10n_bundles() throws Exception { + RuleDefinitions.Context context = new RuleDefinitions.Context(); + RuleI18nManager i18n = mock(RuleI18nManager.class); + when(i18n.getName("checkstyle", "ConstantName")).thenReturn("Constant Name"); + when(i18n.getDescription("checkstyle", "ConstantName")).thenReturn("Checks that constant names conform to the specified format"); + when(i18n.getParamDescription("checkstyle", "ConstantName", "format")).thenReturn("Regular expression"); + + new DeprecatedRuleDefinitions(i18n, new RuleRepository[]{new UseBundles()}).define(context); + + RuleDefinitions.Repository checkstyle = context.repository("checkstyle"); + RuleDefinitions.Rule rule = checkstyle.rule("ConstantName"); + assertThat(rule.key()).isEqualTo("ConstantName"); + assertThat(rule.name()).isEqualTo("Constant Name"); + assertThat(rule.htmlDescription()).isEqualTo("Checks that constant names conform to the specified format"); + RuleDefinitions.Param param = rule.param("format"); + assertThat(param.key()).isEqualTo("format"); + assertThat(param.name()).isEqualTo("format"); + assertThat(param.description()).isEqualTo("Regular expression"); + } +} -- 2.39.5