package com.pablissimo.sonar; import com.pablissimo.sonar.model.TsLintRule; import org.junit.Before; import org.junit.Test; import org.sonar.api.config.Settings; import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RulesDefinition.Context; import org.sonar.api.server.rule.RulesDefinition.Rule; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.*; public class TsRulesDefinitionTest { Settings settings; TsRulesDefinition definition; Context context; @Before public void setUp() throws Exception { this.settings = mock(Settings.class); when(this.settings.getKeysStartingWith(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS)) .thenReturn(new ArrayList<String>() {{ add(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg1.name"); add(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg1.config"); add(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg2.name"); add(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg2.config"); add(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg3.name"); add(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg3.config"); }}); // config with one disabled rule when(this.settings.getString(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg1.config")) .thenReturn( "custom-rule-1=false\n" + "custom-rule-1.name=test rule #1\n" + "custom-rule-1.severity=MAJOR\n" + "custom-rule-1.description=#1 description\n" + "\n" ); // config with a basic rule (no debt settings) when(this.settings.getString(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg2.config")) .thenReturn( "custom-rule-2=true\n" + "custom-rule-2.name=test rule #2\n" + "custom-rule-2.severity=MINOR\n" + "custom-rule-2.description=#2 description\n" + "\n" ); // config with a advanced rules (including debt settings) when(this.settings.getString(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS + ".cfg3.config")) .thenReturn( "custom-rule-3=true\n" + "custom-rule-3.name=test rule #3\n" + "custom-rule-3.severity=INFO\n" + "custom-rule-3.description=#3 description\n" + "custom-rule-3.debtFunc=" + DebtRemediationFunction.Type.CONSTANT_ISSUE + "\n" + "custom-rule-3.debtScalar=15min\n" + "custom-rule-3.debtOffset=1min\n" + "custom-rule-3.debtType=INVALID_TYPE_GOES_HERE\n" + "\n" + "custom-rule-4=true\n" + "custom-rule-4.name=test rule #4\n" + "custom-rule-4.severity=MINOR\n" + "custom-rule-4.description=#4 description\n" + "custom-rule-4.debtFunc=" + DebtRemediationFunction.Type.LINEAR + "\n" + "custom-rule-4.debtScalar=5min\n" + "custom-rule-4.debtOffset=2h\n" + "custom-rule-4.debtType=" + RuleType.BUG.name() + "\n" + "\n" + "custom-rule-5=true\n" + "custom-rule-5.name=test rule #5\n" + "custom-rule-5.severity=MAJOR\n" + "custom-rule-5.description=#5 description\n" + "custom-rule-5.debtFunc=" + DebtRemediationFunction.Type.LINEAR_OFFSET + "\n" + "custom-rule-5.debtScalar=30min\n" + "custom-rule-5.debtOffset=15min\n" + "custom-rule-5.debtType=" + RuleType.VULNERABILITY.name() + "\n" + "\n" ); this.definition = new TsRulesDefinition(this.settings); this.context = new Context(); this.definition.define(context); } @Test public void CreatesRepository() { Context context = mock(Context.class, RETURNS_DEEP_STUBS); this.definition.define(context); verify(context).createRepository(eq(TsRulesDefinition.REPOSITORY_NAME), eq(TypeScriptLanguage.LANGUAGE_KEY)); } @Test public void ConfiguresAdditionalRules() { // cfg1 Rule rule1 = getRule("custom-rule-1"); assertNull(rule1); // cfg2 Rule rule2 = getRule("custom-rule-2"); assertNotNull(rule2); assertEquals("test rule #2", rule2.name()); assertEquals(Severity.MINOR, rule2.severity()); assertEquals("#2 description", rule2.htmlDescription()); assertEquals(null, rule2.debtRemediationFunction()); assertEquals(RuleType.CODE_SMELL, rule2.type()); // cfg3 Rule rule3 = getRule("custom-rule-3"); assertNotNull(rule3); assertEquals("test rule #3", rule3.name()); assertEquals(Severity.INFO, rule3.severity()); assertEquals("#3 description", rule3.htmlDescription()); assertEquals( DebtRemediationFunction.Type.CONSTANT_ISSUE, rule3.debtRemediationFunction().type() ); assertEquals(null, rule3.debtRemediationFunction().gapMultiplier()); assertEquals("15min", rule3.debtRemediationFunction().baseEffort()); assertEquals(RuleType.CODE_SMELL, rule3.type()); // cfg4 Rule rule4 = getRule("custom-rule-4"); assertNotNull(rule4); assertEquals("test rule #4", rule4.name()); assertEquals(Severity.MINOR, rule4.severity()); assertEquals("#4 description", rule4.htmlDescription()); assertEquals( DebtRemediationFunction.Type.LINEAR, rule4.debtRemediationFunction().type() ); assertEquals("5min", rule4.debtRemediationFunction().gapMultiplier()); assertEquals(null, rule4.debtRemediationFunction().baseEffort()); assertEquals(RuleType.BUG, rule4.type()); // cfg5 Rule rule5 = getRule("custom-rule-5"); assertNotNull(rule5); assertEquals("test rule #5", rule5.name()); assertEquals(Severity.MAJOR, rule5.severity()); assertEquals("#5 description", rule5.htmlDescription()); assertEquals(RuleType.VULNERABILITY, rule5.type()); assertEquals("30min", rule5.debtRemediationFunction().gapMultiplier()); assertEquals("15min", rule5.debtRemediationFunction().baseEffort()); } @Test public void LoadRulesFromInvalidStream() throws IOException { List<TsLintRule> rules = new ArrayList<>(); InputStream testStream = new InputStream() { @Override public int read() throws IOException { throw new IOException("Test exception"); } }; TsRulesDefinition.loadRules(testStream, rules); } @Test public void CheckAdditionalRulesConfigProvided() { TsRulesDefinition rulesDef = new TsRulesDefinition(this.settings); List<TsLintRule> rules = rulesDef.getRules(); assertNotNull(rules); assertEquals(4, rules.size()); // 4 enabled rules, 1 disabled rule } @Test public void CheckCustomRulesConfigNotProvided() { Settings settings = mock(Settings.class); when(settings.getKeysStartingWith(TypeScriptPlugin.SETTING_TS_RULE_CONFIGS)).thenReturn(new ArrayList<String>()); TsRulesDefinition rulesDef = new TsRulesDefinition(settings); List<TsLintRule> rules = rulesDef.getRules(); assertNotNull(rules); assertEquals(0, rules.size()); } @Test public void CheckCustomRulesInhibited() { Settings settings = mock(Settings.class); when(settings.getBoolean(TypeScriptPlugin.SETTING_TS_LINT_DISALLOW_CUSTOM_RULES)).thenReturn(true); TsRulesDefinition rulesDef = new TsRulesDefinition(settings); List<TsLintRule> rules = rulesDef.getRules(); assertNotNull(rules); assertEquals(0, rules.size()); } private Rule getRule(String name) { return this.context.repository(TsRulesDefinition.REPOSITORY_NAME).rule(name); } }