diff --git a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java index fd813d8..9b5afd9 100644 --- a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java +++ b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java @@ -1,10 +1,205 @@ -import static org.junit.Assert.*; +package net.kemitix.checkstyle.ruleset.builder; + +import lombok.val; +import me.andrz.builder.map.MapBuilder; +import org.junit.Before; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.MockitoAnnotations; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.AbstractMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; /** - * . + * Tests for {@link CheckstyleWriter}. * * @author Paul Campbell (pcampbell@kemitix.net) */ public class CheckstyleWriterTest { + private static final String TEMPLATE = "C:%s\nTW:%s"; + + private CheckstyleWriter checkstyleWriter; + + private OutputProperties outputProperties; + + private TemplateProperties templateProperties; + + private RulesProperties rulesProperties; + + private String ruleName; + + private Map outputFiles; + + private Path outputDirectory; + + private Path checkstyleTemplate; + + @org.junit.Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + ruleName = UUID.randomUUID() + .toString(); + outputProperties = new OutputProperties(); + outputFiles = new MapBuilder().put(getOutputFile(RuleLevel.LAYOUT)) + .put(getOutputFile(RuleLevel.NAMING)) + .put(getOutputFile(RuleLevel.JAVADOC)) + .put(getOutputFile(RuleLevel.TWEAKS)) + .put(getOutputFile(RuleLevel.COMPLEXITY)) + .build(); + outputProperties.setRulesetFiles(outputFiles); + outputDirectory = Files.createTempDirectory("test"); + outputProperties.setDirectory(outputDirectory); + templateProperties = new TemplateProperties(); + checkstyleTemplate = Files.createTempFile("checkstyle-template", ".xml"); + Files.write( + checkstyleTemplate, TEMPLATE.getBytes(StandardCharsets.UTF_8), StandardOpenOption.TRUNCATE_EXISTING); + templateProperties.setCheckstyleXml(checkstyleTemplate); + rulesProperties = new RulesProperties(); + checkstyleWriter = new CheckstyleWriter(outputProperties, templateProperties, rulesProperties); + } + + // write rule that matches current level + @Test + public void writeRuleThatMatchesCurrentLevel() throws Exception { + //given + val rule = enabledRule(RuleLevel.LAYOUT, RuleParent.TREEWALKER); + rulesProperties.getRules() + .add(rule); + //when + checkstyleWriter.run(); + //then + final List lines = loadOutputFile(RuleLevel.LAYOUT); + assertThat(lines).containsExactly("C:", String.format("TW:", ruleName)); + } + + // write rule that is below current level + @Test + public void writeRuleThatIsBelowCurrentLevel() throws Exception { + //given + val rule = enabledRule(RuleLevel.LAYOUT, RuleParent.TREEWALKER); + rulesProperties.getRules() + .add(rule); + //when + checkstyleWriter.run(); + //then + final List lines = loadOutputFile(RuleLevel.NAMING); + assertThat(lines).containsExactly("C:", String.format("TW:", ruleName)); + } + + // write rule with checker parent + @Test + public void writeRuleWithCheckerParent() throws Exception { + //given + val rule = enabledRule(RuleLevel.LAYOUT, RuleParent.CHECKER); + rulesProperties.getRules() + .add(rule); + //when + checkstyleWriter.run(); + //then + final List lines = loadOutputFile(RuleLevel.LAYOUT); + assertThat(lines).containsExactly(String.format("C:", ruleName), "TW:"); + } + + // write rule with properties + @Test + public void writeRuleWithProperties() throws Exception { + //given + val rule = enabledRule(RuleLevel.LAYOUT, RuleParent.TREEWALKER); + rule.getProperties() + .put("key", "value"); + rulesProperties.getRules() + .add(rule); + //when + checkstyleWriter.run(); + //then + final List lines = loadOutputFile(RuleLevel.LAYOUT); + assertThat(lines).containsExactly("C:", String.format("TW:", ruleName), + " ", "" + ); + } + + // ignore rule that is above current level + @Test + public void ignoreRuleThatIsAboveCurrentLevel() throws Exception { + //given + val rule = enabledRule(RuleLevel.NAMING, RuleParent.TREEWALKER); + rulesProperties.getRules() + .add(rule); + //when + checkstyleWriter.run(); + //then + final List lines = loadOutputFile(RuleLevel.LAYOUT); + assertThat(lines).containsExactly("C:", "TW:"); + } + + // ignore rule that has unspecified level + @Test + public void ignoreRuleThatHasUnspecifiedLevel() throws Exception { + //given + val rule = enabledRule(RuleLevel.UNSPECIFIED, RuleParent.TREEWALKER); + rulesProperties.getRules() + .add(rule); + //when + checkstyleWriter.run(); + //then + final List lines = loadOutputFile(RuleLevel.LAYOUT); + assertThat(lines).containsExactly("C:", "TW:"); + } + + // throw RTE if template not found + @Test + public void throwRteIfTemplateNotFound() throws Exception { + //given + templateProperties.setCheckstyleXml(Paths.get("garbage")); + exception.expect(RuntimeException.class); + exception.expectMessage("Missing template: garbage"); + //when + checkstyleWriter.run(); + } + + // throw RTE if error writing file + @Test + public void throwRteIfErrorWritingFile() throws Exception { + //given + outputProperties.setDirectory(Paths.get("/../imaginary")); + exception.expect(RuntimeException.class); + exception.expectMessage("java.nio.file.NoSuchFileException: /../imaginary/checkstyle-LAYOUT.xml"); + //when + checkstyleWriter.run(); + } + + private Map.Entry getOutputFile(final RuleLevel level) throws IOException { + final String xmlFile = String.format("checkstyle-%s.xml", level.toString()); + return new AbstractMap.SimpleImmutableEntry<>(level, xmlFile); + } + + private List loadOutputFile(final RuleLevel level) throws IOException { + final Path file = outputDirectory.resolve(outputFiles.get(level)); + assertThat(file).as("Output file exists") + .exists(); + return Files.readAllLines(file, StandardCharsets.UTF_8); + } + + private Rule enabledRule(final RuleLevel level, final RuleParent parent) { + val rule = new Rule(); + rule.setName(ruleName); + rule.setEnabled(true); + rule.setLevel(level); + rule.setParent(parent); + return rule; + } }