1
2
3
4
5 package com.qulice.checkstyle;
6
7 import com.google.common.base.Joiner;
8 import com.qulice.spi.Environment;
9 import com.qulice.spi.Violation;
10 import java.io.File;
11 import java.io.IOException;
12 import java.util.Collection;
13 import org.cactoos.io.ResourceOf;
14 import org.cactoos.text.FormattedText;
15 import org.cactoos.text.IoCheckedText;
16 import org.cactoos.text.TextOf;
17 import org.hamcrest.MatcherAssert;
18 import org.hamcrest.Matchers;
19 import org.junit.jupiter.api.Assertions;
20 import org.junit.jupiter.api.Assumptions;
21 import org.junit.jupiter.api.Test;
22
23
24
25
26
27
28
29
30
31
32
33
34 final class CheckstyleValidatorTest {
35
36 @Test
37 void acceptsInstanceMethodReferences() throws Exception {
38 Assertions.assertDoesNotThrow(
39 () -> this.runValidation("InstanceMethodRef.java", true)
40 );
41 }
42
43 @Test
44 void acceptsIdAsMethodName() throws Exception {
45 Assertions.assertDoesNotThrow(
46 () -> this.runValidation("IdMethodName.java", true)
47 );
48 }
49
50 @Test
51 void acceptsDefaultMethodsWithFinalModifiers() throws Exception {
52 Assertions.assertDoesNotThrow(
53 () -> this.runValidation("DefaultMethods.java", true)
54 );
55 }
56
57 @Test
58 void supportsRecordTypes() throws Exception {
59 Assertions.assertDoesNotThrow(
60 () -> this.runValidation("ValidRecord.java", true)
61 );
62 }
63
64 @Test
65 void acceptsLambdaAndGenericsAtEndOfLine() throws Exception {
66 Assertions.assertDoesNotThrow(
67 () -> this.runValidation("ValidLambdaAndGenericsAtEndOfLine.java", true)
68 );
69 }
70
71 @Test
72 void acceptsChainedLambdaAsArgument() throws Exception {
73 Assertions.assertDoesNotThrow(
74 () -> this.runValidation("ValidLambdaIndentation.java", true)
75 );
76 }
77
78 @Test
79 void allowsStringLiteralsOnBothSideInComparisons() throws Exception {
80 Assertions.assertDoesNotThrow(
81 () -> this.runValidation("ValidLiteralComparisonCheck.java", true)
82 );
83 }
84
85 @Test
86 void countsRulesItApplies() throws Exception {
87 MatcherAssert.assertThat(
88 "Checkstyle cannot stay silent about how many rules it applies",
89 new CheckstyleValidator(new Environment.Mock()).rules(),
90 Matchers.greaterThan(100)
91 );
92 }
93
94 @Test
95 void failsClearlyWhenCacheParentIsNotWritable() throws Exception {
96 final Environment.Mock mock = new Environment.Mock();
97 final File parent = new File(mock.tempdir(), "checkstyle");
98 Assumptions.assumeTrue(
99 parent.mkdirs() || parent.isDirectory(),
100 "Parent directory must exist for the regression scenario"
101 );
102 try {
103 Assumptions.assumeTrue(
104 parent.setReadOnly(),
105 "Filesystem does not support marking a directory read-only"
106 );
107 Assumptions.assumeFalse(
108 parent.canWrite(),
109 "Skipped: current user can write despite read-only attribute"
110 );
111 final Environment env = mock.withFile(
112 "src/main/java/foo/Foo.java",
113 "package foo; class Foo {}"
114 );
115 MatcherAssert.assertThat(
116 "Validation must fail fast with a clear writability error",
117 Assertions.assertThrows(
118 IllegalStateException.class,
119 () -> new CheckstyleValidator(env).validate(env.files("Foo.java"))
120 ).getMessage(),
121 Matchers.allOf(
122 Matchers.containsString("write"),
123 Matchers.containsString(parent.getAbsolutePath())
124 )
125 );
126 } finally {
127 parent.setWritable(true, false);
128 }
129 }
130
131 @Test
132 void doesNotThrowExceptionIfImportsOnly() throws Exception {
133 final Environment.Mock mock = new Environment.Mock();
134 final String crlf = String.valueOf('\r').concat(String.valueOf('\n'));
135 final String name = "Foo.java";
136 final Environment env = mock.withParam(
137 "license",
138 String.format(
139 "file:%s",
140 new License().savePackageInfo(
141 new File(mock.basedir(), "src/main/java/foo")
142 ).withLines("License-1.", "", "License-2.")
143 .withEol(String.valueOf('\n'))
144 .file()
145 )
146 ).withFile(
147 String.format("src/main/java/foo/%s", name),
148 Joiner.on(crlf).join(
149 "package com.google;",
150 crlf,
151 "import java.util.*;"
152 )
153 );
154 MatcherAssert.assertThat(
155 "Validation error should exist",
156 new CheckstyleValidator(env).validate(env.files(name)),
157 Matchers.not(Matchers.<Violation>empty())
158 );
159 }
160
161 private Collection<Violation> runValidation(final String file,
162 final boolean passes) throws IOException {
163 final Environment.Mock mock = new Environment.Mock();
164 final Environment env = mock.withParam(
165 "license",
166 String.format(
167 "file:%s",
168 new License().savePackageInfo(
169 new File(mock.basedir(), "src/main/java/foo")
170 ).withLines("Hello.")
171 .withEol(String.valueOf('\n')).file()
172 )
173 ).withFile(
174 String.format("src/main/java/foo/%s", file),
175 new IoCheckedText(
176 new TextOf(
177 new ResourceOf(
178 new FormattedText("com/qulice/checkstyle/%s", file)
179 )
180 )
181 ).asString()
182 );
183 final Collection<Violation> results =
184 new CheckstyleValidator(env).validate(env.files(file));
185 MatcherAssert.assertThat(
186 "validation result should match expected state",
187 results.isEmpty(),
188 Matchers.is(passes)
189 );
190 return results;
191 }
192 }