1 package net.avcompris.guixer.core;
2
3 import static com.google.common.base.Preconditions.checkNotNull;
4 import static net.avcompris.guixer.core.Validations.assertValidTestClassSimpleName;
5 import static net.avcompris.guixer.core.Validations.assertValidTestMethodName;
6 import static org.apache.commons.lang3.StringUtils.join;
7 import static org.junit.jupiter.api.Assertions.fail;
8
9 import java.io.File;
10 import java.io.IOException;
11 import java.lang.reflect.Method;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import javax.annotation.Nullable;
16
17 import org.apache.commons.io.FileUtils;
18 import org.junit.jupiter.api.Test;
19
20 final class Context {
21
22 private String seleniumServerURL;
23 private String seleniumDesiredCapabilities;
24 private String baseURL;
25 private final File baseDir;
26 private String contextName = "undefined";
27 private Logger dumperLogger = null;
28 private Logger consoleLogger = null;
29 private int stepCount;
30 private final List<Assertion> assertions = new ArrayList<>();
31
32 Context(final File baseDir) {
33
34 this.baseDir = checkNotNull(baseDir, "baseDir");
35 }
36
37 public String getSeleniumServerURL() {
38
39 final String seleniumServerURLCopy = seleniumServerURL;
40
41 if (seleniumServerURLCopy == null) {
42
43 throw new IllegalStateException("seleniumServerURL should not be null");
44 }
45
46 return seleniumServerURLCopy;
47 }
48
49 public String getSeleniumDesiredCapabilities() {
50
51 final String seleniumDesiredCapabilitiesCopy = seleniumDesiredCapabilities;
52
53 if (seleniumDesiredCapabilitiesCopy == null) {
54
55 throw new IllegalStateException("seleniumDesiredCapabilities should not be null");
56 }
57
58 return seleniumDesiredCapabilitiesCopy;
59 }
60
61 public String getBaseURL() {
62
63 final String baseURLCopy = baseURL;
64
65 if (baseURLCopy == null) {
66
67 throw new IllegalStateException("baseURL should not be null");
68 }
69
70 return baseURLCopy;
71 }
72
73 public Logger getDumperLogger() throws IOException {
74
75 final Logger oldLogger = dumperLogger;
76
77 final Logger newLogger = DumperLogger.getLogger(this);
78
79 if (oldLogger == null) {
80
81 final TestContext testContext = extractTestContext();
82
83 newLogger.setTestContext(testContext.testClass, testContext.testMethod);
84
85 } else if (oldLogger.equals(newLogger)) {
86
87
88
89 } else {
90
91 throw new IllegalStateException("oldLogger: " + oldLogger + ", newLogger: " + newLogger);
92 }
93
94 this.dumperLogger = newLogger;
95
96 return dumperLogger;
97 }
98
99 public Logger getConsoleLogger() throws IOException {
100
101 final Logger oldLogger = consoleLogger;
102
103 final Logger newLogger = ConsoleLogger.getLogger(this);
104
105 if (oldLogger == null) {
106
107 final TestContext testContext = extractTestContext();
108
109 newLogger.setTestContext(testContext.testClass, testContext.testMethod);
110
111 } else if (oldLogger.equals(newLogger)) {
112
113
114
115 } else {
116
117 throw new IllegalStateException("oldLogger: " + oldLogger + ", newLogger: " + newLogger);
118 }
119
120 this.consoleLogger = newLogger;
121
122 return consoleLogger;
123 }
124
125 public void setSeleniumServerURL(final String seleniumServerURL) {
126
127 this.seleniumServerURL = checkNotNull(seleniumServerURL, "seleniumServerURL");
128 }
129
130 public void setSeleniumDesiredCapabilities(final String seleniumDesiredCapabilities) {
131
132 this.seleniumDesiredCapabilities = checkNotNull(seleniumDesiredCapabilities, "seleniumDesiredCapabilities");
133 }
134
135 public void setBaseURL(final String baseURL) {
136
137 this.baseURL = checkNotNull(baseURL, "baseURL");
138 }
139
140 Context reset(final String contextName) {
141
142 this.contextName = checkNotNull(contextName, "contextName");
143
144 stepCount = 0;
145
146 return this;
147 }
148
149 int incStepCount() {
150
151 ++stepCount;
152
153 return stepCount;
154 }
155
156 int getStepCount() {
157
158 return stepCount;
159 }
160
161 String formatStepCount() {
162
163 return String.format("%04d", stepCount);
164 }
165
166 File getSubDir() throws IOException {
167
168 final TestContext testContext = extractTestContext();
169
170 final Class<?> testClass = testContext.testClass;
171 final Method testMethod = testContext.testMethod;
172
173 final String testClassSimpleName = testClass.getSimpleName();
174 final String testMethodName = testMethod.getName();
175
176 assertValidTestClassSimpleName(testClassSimpleName);
177 assertValidTestMethodName(testMethodName);
178
179 final File subDir = new File(baseDir,
180
181 testClassSimpleName + "/" + testMethodName + "/" + contextName);
182
183 FileUtils.forceMkdir(subDir);
184
185 return subDir;
186 }
187
188 private static final class TestContext {
189
190 public final Class<?> testClass;
191 public final Method testMethod;
192
193 public TestContext(final Class<?> testClass, final Method testMethod) {
194
195 this.testClass = checkNotNull(testClass, "testClass");
196 this.testMethod = checkNotNull(testMethod, "testMethod");
197 }
198
199 @Override
200 public int hashCode() {
201
202 return testClass.hashCode()
203 + testMethod.hashCode();
204 }
205
206 @Override
207 public boolean equals(@Nullable final Object arg) {
208
209 if (arg == null || !(arg instanceof TestContext)) {
210 return false;
211 }
212
213 final TestContext testContext = (TestContext) arg;
214
215 return testClass.equals(testContext.testClass)
216 && testMethod.equals(testContext.testMethod);
217 }
218 }
219
220 private static TestContext extractTestContext() {
221
222 TestContext testContext = null;
223
224 for (final StackTraceElement ste : Thread.currentThread().getStackTrace()) {
225
226 final String className = ste.getClassName();
227 final String methodName = ste.getMethodName();
228
229 final Class<?> clazz;
230
231 try {
232
233 clazz = Class.forName(className);
234
235 } catch (final ClassNotFoundException e) {
236
237 continue;
238 }
239
240 final Method method;
241
242 try {
243
244 method = clazz.getMethod(methodName);
245
246 } catch (final NoSuchMethodException e) {
247
248 continue;
249 }
250
251 if (!method.isAnnotationPresent(Test.class)) {
252
253 continue;
254 }
255
256 testContext = new TestContext(clazz, method);
257 }
258
259 if (testContext != null) {
260
261 return testContext;
262 }
263
264 throw new IllegalStateException();
265 }
266
267
268
269
270
271
272 public void addAssertion(final Assertion assertion) {
273
274 checkNotNull(assertion, "assertion");
275
276 assertions.add(assertion);
277 }
278
279 public void close() throws IOException {
280
281 if (dumperLogger != null) {
282
283 dumperLogger.close();
284
285 dumperLogger = null;
286 }
287
288 consoleLogger = null;
289
290 final List<Assertion> failedAssertions = new ArrayList<>();
291
292 for (final Assertion assertion : assertions) {
293
294 if (!assertion.isSuccess()) {
295
296 if (failedAssertions.isEmpty()) {
297
298 System.err.println("There are some failed assertions:");
299 }
300
301 failedAssertions.add(assertion);
302
303 System.err.println(" - " + assertion);
304 }
305 }
306
307 if (!failedAssertions.isEmpty()) {
308
309 fail("There are some failed assertions: " + join(assertions, ", "));
310 }
311 }
312 }