Skip to content

Commit 98889ce

Browse files
authored
Merge pull request #5 from CodinGame/fix_runWith_testcase
Fix: testcase with @RunWith annotation fail
2 parents d8bb2d2 + 54680b5 commit 98889ce

File tree

12 files changed

+642
-157
lines changed

12 files changed

+642
-157
lines changed

pom.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,29 @@
2626
<artifactId>commons-io</artifactId>
2727
<version>1.3.2</version>
2828
</dependency>
29+
<dependency>
30+
<groupId>org.assertj</groupId>
31+
<artifactId>assertj-core</artifactId>
32+
<version>3.6.1</version>
33+
<scope>test</scope>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.mockito</groupId>
37+
<artifactId>mockito-core</artifactId>
38+
<version>2.6.8</version>
39+
</dependency>
40+
<dependency>
41+
<groupId>io.vertx</groupId>
42+
<artifactId>vertx-core</artifactId>
43+
<version>3.0.0</version>
44+
<scope>test</scope>
45+
</dependency>
46+
<dependency>
47+
<groupId>io.vertx</groupId>
48+
<artifactId>vertx-unit</artifactId>
49+
<version>3.0.0</version>
50+
<scope>test</scope>
51+
</dependency>
2952
</dependencies>
3053

3154
<build>
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package com.codingame.codemachine.runner.junit;
2+
3+
import com.codingame.codemachine.runner.junit.core.TestResultDto;
4+
import com.google.gson.Gson;
5+
import org.apache.commons.io.FileUtils;
6+
import org.junit.internal.runners.ErrorReportingRunner;
7+
import org.junit.runner.JUnitCore;
8+
import org.junit.runner.Request;
9+
import org.junit.runner.Runner;
10+
11+
import java.io.File;
12+
import java.io.IOException;
13+
import java.io.PrintStream;
14+
import java.util.ArrayList;
15+
import java.util.List;
16+
import java.util.regex.Matcher;
17+
import java.util.regex.Pattern;
18+
19+
public class JUnitTest {
20+
private static final String DEFAULT_OUTPUT = "-";
21+
private static final Pattern COMMAND_PATTERN = Pattern.compile("(?<class>[^#]+)(?:#(?<method>[^#]+))?");
22+
23+
private final PrintStream realOut;
24+
private final PrintStream realErr;
25+
private final JUnitCore jUnitCore;
26+
private List<TestResultDto> results;
27+
private boolean oneFailure;
28+
29+
JUnitTest() {
30+
realOut = System.out;
31+
realErr = System.err;
32+
jUnitCore = new JUnitCore();
33+
oneFailure = false;
34+
}
35+
36+
boolean isOneFailure() {
37+
return this.oneFailure;
38+
}
39+
40+
int run(String... args) {
41+
List<TestCase> testCases = findRequests(args);
42+
runTestCases(testCases);
43+
44+
int statusCode = isOneFailure() ? 1 : 0;
45+
statusCode = generateResult() ? statusCode : 3;
46+
47+
return statusCode;
48+
}
49+
50+
List<TestCase> findRequests(String... args) {
51+
List<TestCase> requests = new ArrayList<>();
52+
for (String arg : args) {
53+
Matcher matcher = COMMAND_PATTERN.matcher(arg);
54+
if (matcher.matches()) {
55+
try {
56+
Class<?> clazz = Class.forName(matcher.group("class"));
57+
String method = matcher.group("method");
58+
if (method != null) {
59+
requests.add(TestCase.createTestCase(Request.method(clazz, method), arg));
60+
}
61+
else {
62+
requests.add(TestCase.createTestCase(Request.aClass(clazz), arg));
63+
}
64+
}
65+
catch (ClassNotFoundException ignored) {
66+
requests.add(TestCase.createTestCase());
67+
}
68+
}
69+
}
70+
return requests;
71+
}
72+
73+
void runTestCases(List<TestCase> testCases) {
74+
results = new ArrayList<>();
75+
jUnitCore.addListener(new TestResultProvider(results));
76+
77+
testCases.forEach(this::runTestCase);
78+
}
79+
80+
private void runTestCase(TestCase testCase) {
81+
if (testCase.exists()) {
82+
if (!testCase.run(jUnitCore)) {
83+
oneFailure = true;
84+
}
85+
}
86+
else {
87+
results.add(createTestNotFoundResult(testCase.description()));
88+
oneFailure = true;
89+
}
90+
}
91+
92+
private TestResultDto createTestNotFoundResult(String testReference) {
93+
TestResultDto result = new TestResultDto();
94+
result.setSuccess(false);
95+
result.setNotFound(true);
96+
result.setTestReference(testReference);
97+
return result;
98+
}
99+
100+
private boolean generateResult() {
101+
String resultOutput = System.getProperty("codingame.junit-runner.output", DEFAULT_OUTPUT);
102+
String resultStr = new Gson().toJson(results);
103+
if (DEFAULT_OUTPUT.equals(resultOutput)) {
104+
realOut.println(resultStr);
105+
}
106+
else {
107+
try {
108+
FileUtils.writeStringToFile(new File(resultOutput), resultStr);
109+
}
110+
catch (IOException e) {
111+
realErr.println(e.getMessage());
112+
return false;
113+
}
114+
}
115+
return true;
116+
}
117+
118+
static class TestCase {
119+
120+
static TestCase createTestCase() {
121+
return new TestCase(null, null);
122+
}
123+
124+
static TestCase createTestCase(Request request, String description) {
125+
TestCase testCase = new TestCase(null, null);
126+
if (request != null) {
127+
Runner runner = request.getRunner();
128+
if (!(runner instanceof ErrorReportingRunner)) {
129+
testCase = new TestCase(request, description);
130+
}
131+
}
132+
return testCase;
133+
}
134+
135+
private final Request request;
136+
private final String description;
137+
138+
private TestCase(Request request, String description) {
139+
this.request = request;
140+
this.description = description;
141+
}
142+
143+
Request request() {
144+
return this.request;
145+
}
146+
147+
String description() {
148+
return this.description;
149+
}
150+
151+
boolean exists() {
152+
return request() != null;
153+
}
154+
155+
boolean run(final JUnitCore jUnitCore) {
156+
return jUnitCore.run(request).wasSuccessful();
157+
}
158+
}
159+
160+
}
Lines changed: 2 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,9 @@
11
package com.codingame.codemachine.runner.junit;
22

3-
import com.codingame.codemachine.runner.junit.core.RunLogDto;
4-
import com.codingame.codemachine.runner.junit.core.RunLogStackTraceDto;
5-
import com.codingame.codemachine.runner.junit.core.TestResultDto;
6-
import com.google.gson.Gson;
7-
import org.apache.commons.io.FileUtils;
8-
import org.junit.runner.Description;
9-
import org.junit.runner.JUnitCore;
10-
import org.junit.runner.Request;
11-
import org.junit.runner.Result;
12-
import org.junit.runner.notification.Failure;
13-
import org.junit.runner.notification.RunListener;
14-
15-
import java.io.ByteArrayOutputStream;
16-
import java.io.File;
17-
import java.io.IOException;
18-
import java.io.PrintStream;
19-
import java.util.ArrayList;
20-
import java.util.List;
21-
import java.util.regex.Matcher;
22-
import java.util.regex.Pattern;
23-
24-
import static java.util.Collections.singletonList;
25-
263
public class JUnitTestListRunner {
27-
private static final String DEFAULT_OUTPUT = "-";
28-
29-
private static RunLogDto parseThrowable(Throwable t) {
30-
RunLogDto runLog = new RunLogDto();
31-
runLog.setMessage(t.getMessage());
32-
List<RunLogStackTraceDto> stack = new ArrayList<>();
33-
for (StackTraceElement item : t.getStackTrace()) {
34-
RunLogStackTraceDto stackItem = new RunLogStackTraceDto();
35-
stackItem.setLine(item.getLineNumber());
36-
stackItem.setContainer(item.getClassName());
37-
stackItem.setFunction(item.getMethodName());
38-
stack.add(stackItem);
39-
}
40-
runLog.setStacktrace(stack);
41-
42-
if (t.getCause() != null) {
43-
runLog.setCause(parseThrowable(t.getCause()));
44-
}
45-
return runLog;
46-
}
47-
48-
private static TestResultDto parseTestResult(boolean success, Description description, Throwable t) {
49-
TestResultDto result = new TestResultDto();
50-
result.setSuccess(success);
51-
result.setNotFound(false);
52-
result.setTestReference(description.getClassName() + "#" + description.getMethodName());
53-
if (t != null) {
54-
result.setLogs(singletonList(parseThrowable(t)));
55-
}
56-
return result;
57-
}
58-
59-
private static TestResultDto createTestNotFoundResult(String testReference) {
60-
TestResultDto result = new TestResultDto();
61-
result.setSuccess(false);
62-
result.setNotFound(true);
63-
result.setTestReference(testReference);
64-
return result;
65-
}
66-
67-
private static final Pattern COMMAND_PATTERN = Pattern.compile("(?<class>[^#]+)(?:#(?<method>[^#]+))?");
68-
69-
private static ByteArrayOutputStream out, err;
70-
714
public static void main(String... args) {
72-
PrintStream realOut = System.out;
73-
PrintStream realErr = System.err;
74-
75-
List<TestResultDto> results = new ArrayList<>();
76-
77-
JUnitCore jUnitCore = new JUnitCore();
78-
jUnitCore.addListener(new RunListener() {
79-
private TestResultDto currentResult;
80-
81-
public void testStarted(Description description) {
82-
out = new ByteArrayOutputStream();
83-
err = new ByteArrayOutputStream();
84-
System.setOut(new PrintStream(out, true));
85-
System.setErr(new PrintStream(err, true));
86-
currentResult = null;
87-
}
88-
89-
public void testFailure(Failure failure) throws Exception {
90-
currentResult = parseTestResult(false, failure.getDescription(), failure.getException());
91-
}
92-
93-
public void testFinished(Description description) throws Exception {
94-
if (currentResult == null) {
95-
currentResult = parseTestResult(true, description, null);
96-
}
97-
currentResult.setProgramStderr(new String(err.toByteArray()));
98-
currentResult.setProgramStdout(new String(out.toByteArray()));
99-
err.close();
100-
out.close();
101-
results.add(currentResult);
102-
}
103-
});
104-
105-
boolean successful = true;
106-
for (String arg : args) {
107-
Matcher matcher = COMMAND_PATTERN.matcher(arg);
108-
if (matcher.matches()) {
109-
try {
110-
Class<?> clazz = Class.forName(matcher.group("class"));
111-
String method = matcher.group("method");
112-
Request request = null;
113-
if (method != null) {
114-
try {
115-
clazz.getMethod(method);
116-
request = Request.method(clazz, method);
117-
}
118-
catch (NoSuchMethodException | SecurityException ignored) {
119-
}
120-
}
121-
else {
122-
request = Request.aClass(clazz);
123-
}
124-
125-
if (request != null) {
126-
Result result = jUnitCore.run(request);
127-
if (!result.wasSuccessful()) {
128-
successful = false;
129-
}
130-
}
131-
else {
132-
results.add(createTestNotFoundResult(arg));
133-
successful = false;
134-
}
135-
}
136-
catch (ClassNotFoundException e) {
137-
results.add(createTestNotFoundResult(arg));
138-
successful = false;
139-
}
140-
}
141-
else {
142-
results.add(createTestNotFoundResult(arg));
143-
successful = false;
144-
}
145-
}
146-
int statusCode = successful ? 0 : 1;
147-
148-
String resultOutput = System.getProperty("codingame.junit-runner.output", DEFAULT_OUTPUT);
149-
String resultStr = new Gson().toJson(results);
150-
if (DEFAULT_OUTPUT.equals(resultOutput)) {
151-
realOut.println(resultStr);
152-
}
153-
else {
154-
try {
155-
FileUtils.writeStringToFile(new File(resultOutput), resultStr);
156-
} catch (IOException e) {
157-
realErr.println(e.getMessage());
158-
statusCode = 3;
159-
}
160-
}
161-
5+
JUnitTest jUnitTest = new JUnitTest();
6+
int statusCode = jUnitTest.run(args);
1627
System.exit(statusCode);
1638
}
1649
}

0 commit comments

Comments
 (0)