Skip to content

Commit ef1371c

Browse files
Kimmo Linnavuod471061c
authored andcommitted
Add test for qmake plugin
1 parent 3008a6b commit ef1371c

File tree

6 files changed

+288
-17
lines changed

6 files changed

+288
-17
lines changed

tmc-langs-qmake/src/main/java/fi/helsinki/cs/tmc/langs/qmake/QTestCase.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
package fi.helsinki.cs.tmc.langs.qmake;
32

43
import fi.helsinki.cs.tmc.langs.domain.TestResult;
@@ -16,6 +15,11 @@ public final class QTestCase {
1615

1716
/**
1817
* Create a test case for QT tests.
18+
*
19+
* @param name
20+
* @param passed
21+
* @param message for failed assertion
22+
* @param points for test case
1923
*/
2024
public QTestCase(String name, boolean passed, String message, List<String> points) {
2125
this.name = name;
@@ -51,4 +55,8 @@ public String getMessage() {
5155
return message;
5256
}
5357

58+
public List<String> getPoints() {
59+
return points;
60+
}
61+
5462
}

tmc-langs-qmake/src/main/java/fi/helsinki/cs/tmc/langs/qmake/QTestResultParser.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,14 @@ private List<String> parsePoints(Element testcase) {
169169

170170
/**
171171
* Returns the test results of the tests in this file.
172+
*
173+
* @return
172174
*/
173175
public List<TestResult> getTestResults() {
174176
return this.tests;
175177
}
176178

177-
/**
178-
* Returns the combined status of the tests in this file.
179-
*/
180-
public Status getResultStatus() {
179+
private Status getResultStatus() {
181180
for (TestResult result : getTestResults()) {
182181
if (!result.isSuccessful()) {
183182
return Status.TESTS_FAILED;
@@ -189,6 +188,8 @@ public Status getResultStatus() {
189188

190189
/**
191190
* Returns the run result of this file.
191+
*
192+
* @return
192193
*/
193194
public RunResult result() {
194195
return new RunResult(

tmc-langs-qmake/src/main/java/fi/helsinki/cs/tmc/langs/qmake/QmakePlugin.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import fi.helsinki.cs.tmc.langs.domain.ExerciseBuilder;
88
import fi.helsinki.cs.tmc.langs.domain.ExerciseDesc;
99
import fi.helsinki.cs.tmc.langs.domain.RunResult;
10+
import fi.helsinki.cs.tmc.langs.domain.RunResult.Status;
11+
import fi.helsinki.cs.tmc.langs.domain.SpecialLogs;
1012
import fi.helsinki.cs.tmc.langs.domain.TestDesc;
1113
import fi.helsinki.cs.tmc.langs.domain.TestResult;
1214
import fi.helsinki.cs.tmc.langs.io.StudentFilePolicy;
@@ -20,8 +22,6 @@
2022
import com.google.common.collect.ImmutableList;
2123
import com.google.common.collect.ImmutableMap;
2224
import com.google.common.collect.Maps;
23-
import fi.helsinki.cs.tmc.langs.domain.RunResult.Status;
24-
import fi.helsinki.cs.tmc.langs.domain.SpecialLogs;
2525

2626
import org.slf4j.Logger;
2727
import org.slf4j.LoggerFactory;
@@ -80,7 +80,7 @@ public String getPluginName() {
8080
}
8181

8282
/**
83-
* Resolve the excercise .pro file from excercise directory. The file should
83+
* Resolve the exercise .pro file from exercise directory. The file should
8484
* be named after the directory.
8585
*/
8686
private Path getProFile(Path basePath) {
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package fi.helsinki.cs.tmc.langs.qmake;
2+
3+
import fi.helsinki.cs.tmc.langs.domain.RunResult;
4+
import fi.helsinki.cs.tmc.langs.domain.TestResult;
5+
import fi.helsinki.cs.tmc.langs.utils.TestUtils;
6+
import java.io.IOException;
7+
import java.io.PrintWriter;
8+
import java.nio.file.Path;
9+
import java.util.ArrayList;
10+
import java.util.Arrays;
11+
import java.util.List;
12+
import org.junit.Test;
13+
import static org.junit.Assert.*;
14+
15+
public class QTestResultParserTest {
16+
17+
private final QTestCase passing;
18+
private final QTestCase failing;
19+
private final QTestCase another;
20+
21+
public QTestResultParserTest() {
22+
passing = new QTestCase("passing", true, "Passed", Arrays.asList(new String[]{"1"}));
23+
failing = new QTestCase("failing", false, "This test should've failed", Arrays.asList(new String[]{"2"}));
24+
another = new QTestCase("another", true, "Passed", Arrays.asList(new String[]{"3"}));
25+
}
26+
27+
@Test(expected = IllegalStateException.class)
28+
public void testParsingWithNoTests() throws Exception {
29+
Path empty_test_output = TestUtils.initTempFileWithContent("empty_test_output", "xml", "");
30+
QTestResultParser qtparser = new QTestResultParser(empty_test_output);
31+
assertTrue(qtparser.getTestResults().isEmpty());
32+
}
33+
34+
@Test
35+
public void testParsingWithSuccessfulTest() {
36+
List<QTestCase> pass = new ArrayList<>();
37+
pass.add(passing);
38+
QTestResultParser qtparser = createResultParser(pass);
39+
List<TestResult> results = qtparser.getTestResults();
40+
assertEquals("There should only be one test result", 1, results.size());
41+
TestResult result = results.get(0);
42+
assertTrue("The test should be successful", result.isSuccessful());
43+
assertEquals("The name of the test should be \"passing\"",
44+
"passing",
45+
result.getName());
46+
assertEquals("The message should not contain any assertions",
47+
"",
48+
result.getMessage());
49+
}
50+
51+
@Test
52+
public void testParsingWithFailingTest() {
53+
List<QTestCase> fail = new ArrayList<>();
54+
fail.add(failing);
55+
QTestResultParser qtparser = createResultParser(fail);
56+
List<TestResult> results = qtparser.getTestResults();
57+
assertEquals("There should only be one test result", 1, results.size());
58+
TestResult result = results.get(0);
59+
assertFalse("The test should be failing", result.isSuccessful());
60+
assertEquals("The name of the test should be \"failing\"", "failing",
61+
result.getName());
62+
assertEquals("The message should contain the failed assertion",
63+
"This test should've failed",
64+
result.getMessage());
65+
}
66+
67+
@Test
68+
public void testParsingWithPassingAndFailingTest() {
69+
List<QTestCase> failAndPass = new ArrayList<>();
70+
failAndPass.add(failing);
71+
failAndPass.add(passing);
72+
QTestResultParser qtparser = createResultParser(failAndPass);
73+
List<TestResult> results = qtparser.getTestResults();
74+
assertEquals("There should only be two test results", 2, results.size());
75+
TestResult result = results.get(0);
76+
assertFalse("The test should be failing", result.isSuccessful());
77+
assertEquals("The name of the test should be \"failing\"", "failing",
78+
result.getName());
79+
assertEquals("The message should contain the failed assertion",
80+
"This test should've failed",
81+
result.getMessage());
82+
result = results.get(1);
83+
assertTrue("The test should be passing", result.isSuccessful());
84+
assertEquals("The name of the test should be \"passing\"", "passing",
85+
result.getName());
86+
assertEquals("The message should not contain any assertions",
87+
"",
88+
result.getMessage());
89+
}
90+
91+
@Test
92+
public void testTestRunWithOneFailingTestIsFailed() {
93+
List<QTestCase> failAndPass = new ArrayList<>();
94+
failAndPass.add(failing);
95+
failAndPass.add(passing);
96+
QTestResultParser qtparser = createResultParser(failAndPass);
97+
RunResult result = qtparser.result();
98+
assertEquals("Run result should be failed if one failing test",
99+
result.status,
100+
RunResult.Status.TESTS_FAILED);
101+
}
102+
103+
@Test
104+
public void testTestrunWithPassingTestsIsPassed() {
105+
List<QTestCase> allPass = new ArrayList<>();
106+
allPass.add(passing);
107+
allPass.add(passing);
108+
QTestResultParser qtparser = createResultParser(allPass);
109+
RunResult result = qtparser.result();
110+
assertEquals("Run result should be passed if all tests are passing",
111+
result.status,
112+
RunResult.Status.PASSED);
113+
}
114+
115+
@Test
116+
public void testParsedPointsMapToCorrectTests() {
117+
List<QTestCase> allPass = new ArrayList<>();
118+
allPass.add(passing);
119+
allPass.add(another);
120+
121+
QTestResultParser qtparser = createResultParser(allPass);
122+
List<TestResult> results = qtparser.result().testResults;
123+
assertEquals(2, results.size());
124+
assertEquals("Point for passing should be 1",
125+
"1",
126+
results.get(0).points.get(0));
127+
assertEquals("Point for another should be 3",
128+
"3",
129+
results.get(1).points.get(0));
130+
}
131+
132+
private QTestResultParser createResultParser(List<QTestCase> testCases) {
133+
Path testPath = null;
134+
try {
135+
testPath = constructTestOutput(testCases);
136+
} catch (Exception e) {
137+
fail("Error creating or parsing output file: " + e.getMessage());
138+
}
139+
return new QTestResultParser(testPath);
140+
}
141+
142+
private Path constructTestOutput(List<QTestCase> testCases) throws IOException {
143+
Path tmp = TestUtils.initTempFileWithContent("test_output", "xml", "");
144+
PrintWriter pw = new PrintWriter(tmp.toFile(), "UTF-8");
145+
pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
146+
pw.println("<TestCase name=\"test_runner\">");
147+
for (QTestCase t : testCases) {
148+
pw.println("<TestFunction name=\"" + t.getName() + "\">");
149+
for (String point : t.getPoints()) {
150+
pw.println("<Message type=\"qinfo\" file=\"\" line=\"0\">");
151+
pw.println("<Description><![CDATA[TMC:" + t.getName() + "." + point + "]]></Description>");
152+
pw.println("</Message>");
153+
}
154+
155+
if (t.getResult()) {
156+
pw.println("<Incident type=\"pass\" file=\"\" line=\"0\" />");
157+
} else {
158+
pw.println("<Incident type=\"fail\" file=\"test_runner.cpp\" line=\"420\">");
159+
pw.println(" <Description>" + t.getMessage() + "</Description>");
160+
pw.println("</Incident>");
161+
}
162+
163+
pw.println("</TestFunction>");
164+
}
165+
166+
pw.println("</TestCase>");
167+
168+
pw.flush();
169+
pw.close();
170+
return tmp;
171+
}
172+
173+
}
Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,115 @@
11
package fi.helsinki.cs.tmc.langs.qmake;
22

3-
import static org.junit.Assert.assertEquals;
4-
import static org.junit.Assert.assertFalse;
5-
import static org.junit.Assert.assertTrue;
3+
import com.google.common.base.Optional;
4+
import fi.helsinki.cs.tmc.langs.domain.ExerciseDesc;
5+
import fi.helsinki.cs.tmc.langs.domain.RunResult;
6+
import fi.helsinki.cs.tmc.langs.utils.TestUtils;
67

78
import org.junit.Test;
89

9-
import java.io.IOException;
10-
import java.nio.file.Files;
1110
import java.nio.file.Path;
1211
import static org.junit.Assert.assertEquals;
1312
import static org.junit.Assert.assertFalse;
1413
import static org.junit.Assert.assertTrue;
1514

1615
public class QmakePluginTest {
1716

18-
private QmakePlugin qmakePlugin;
17+
private final QmakePlugin qmakePlugin;
1918

2019
public QmakePluginTest() {
2120
qmakePlugin = new QmakePlugin();
2221
}
23-
24-
// TODO: TESTS!
2522

23+
@Test
24+
public void testGetLanguageName() {
25+
assertEquals("qmake", qmakePlugin.getLanguageName());
26+
}
27+
28+
@Test
29+
public void testQtBuildFailingWithNoLib() {
30+
assertEquals(RunResult.Status.PASSED, runTests("passing_nolib"));
31+
}
32+
33+
@Test
34+
public void testQtBuildFailingWithSingleLib() {
35+
assertEquals("Failing compile with single lib",
36+
RunResult.Status.COMPILE_FAILED,
37+
runTests("failing_compile_single_lib_compiling"));
38+
}
39+
40+
@Test
41+
public void testQtLibBuildFailing() {
42+
assertEquals(RunResult.Status.COMPILE_FAILED, runTests("failing_single_lib_not_compiling"));
43+
}
44+
45+
@Test
46+
public void testQTestsFailingNoLib() {
47+
assertEquals(RunResult.Status.TESTS_FAILED, runTests("failing_nolib"));
48+
}
49+
50+
@Test
51+
public void testQtTestsPassingSingleLib() {
52+
assertEquals(RunResult.Status.PASSED, runTests("passing_single_lib"));
53+
}
54+
55+
@Test
56+
public void testQtTestsFailingNoLibSamePoints() {
57+
assertEquals("Failing no library",
58+
RunResult.Status.TESTS_FAILED,
59+
runTests("failing_nolib_same_point"));
60+
}
61+
62+
@Test
63+
public void testScanExerciseWithFailingSamePoints() {
64+
Optional<ExerciseDesc> optional = scanExercise("failing_single_lib_same_point");
65+
assertTrue(optional.isPresent());
66+
67+
ExerciseDesc desc = optional.get();
68+
69+
assertEquals("failing_single_lib_same_point", desc.name);
70+
71+
assertEquals(3, desc.tests.size());
72+
assertEquals("test_function_two_here", desc.tests.get(0).name);
73+
74+
assertEquals(1, desc.tests.get(0).points.size());
75+
assertEquals("2", desc.tests.get(0).points.get(0));
76+
}
77+
78+
@Test
79+
public void testIsExerciseTypeCorrect() {
80+
assertTrue(isExerciseTypeCorrect("passing_nolib"));
81+
assertTrue(isExerciseTypeCorrect("passing_nolib_same_point"));
82+
assertTrue(isExerciseTypeCorrect("passing_single_lib"));
83+
assertTrue(isExerciseTypeCorrect("passing_single_lib_same_point"));
84+
85+
assertTrue(isExerciseTypeCorrect("passing_multiple_lib"));
86+
assertTrue(isExerciseTypeCorrect("passing_multiple_lib_same_point"));
87+
88+
assertTrue(isExerciseTypeCorrect("failing_single_lib_not_compiling"));
89+
assertTrue(isExerciseTypeCorrect("failing_nolib"));
90+
assertTrue(isExerciseTypeCorrect("failing_nolib_same_point"));
91+
assertTrue(isExerciseTypeCorrect("failing_single_lib"));
92+
assertTrue(isExerciseTypeCorrect("failing_single_lib_not_compiling"));
93+
assertTrue(isExerciseTypeCorrect("failing_single_lib_same_point"));
94+
assertFalse(isExerciseTypeCorrect(""));
95+
}
96+
97+
@Test
98+
public void testScanExerciseWithNonexistentProject() {
99+
Optional<ExerciseDesc> optional = scanExercise("");
100+
assertFalse(optional.isPresent());
101+
}
102+
103+
private RunResult.Status runTests(String testExercise) {
104+
return qmakePlugin.runTests(TestUtils.getPath(getClass(), testExercise)).status;
105+
}
106+
107+
private Optional<ExerciseDesc> scanExercise(String testExercise) {
108+
return qmakePlugin.scanExercise(TestUtils.getPath(getClass(), testExercise), testExercise);
109+
}
110+
111+
private boolean isExerciseTypeCorrect(String exercisePath) {
112+
Path path = TestUtils.getPath(getClass(), exercisePath);
113+
return qmakePlugin.isExerciseTypeCorrect(path);
114+
}
26115
}

tmc-langs-qmake/src/test/resources/failing_nolib/test_case_test_runner/test_case_test_runner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include <Qtest>
1+
#include <QTest>
22
#include "test_case_test_runner.h"
33
#include "test_case_app.h"
44

0 commit comments

Comments
 (0)