Skip to content

Commit 1b43121

Browse files
committed
Refactored boilerplate in tests into a TaskTest class
1 parent 245a5f4 commit 1b43121

13 files changed

+513
-518
lines changed

wpiformat/test/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import pytest
2+
3+
pytest.register_assert_rewrite("test.tasktest")

wpiformat/test/tasktest.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""This class is for writing unit tests for tasks."""
2+
3+
from enum import Enum
4+
import io
5+
import os
6+
import sys
7+
8+
from wpiformat.config import Config
9+
10+
11+
class OutputType(Enum):
12+
FILE = 1
13+
STDOUT = 2
14+
15+
16+
class TaskTest:
17+
18+
def __init__(self, task):
19+
"""Constructor for Test object.
20+
21+
Keyword arguments:
22+
task -- task on which to run tests
23+
"""
24+
self.task = task
25+
self.inputs = []
26+
self.outputs = []
27+
28+
def reset(self):
29+
"""Clears input and output lists."""
30+
self.inputs = []
31+
self.outputs = []
32+
33+
def add_input(self, file_name, contents):
34+
"""Adds the given file and its contents to the input list.
35+
36+
Keyword arguments:
37+
file_name -- file name string
38+
contents -- file contents string
39+
"""
40+
self.inputs.append((file_name, contents))
41+
42+
def add_output(self, contents, contents_modified, succeeded):
43+
"""Adds the given file contents, whether they were modified from the
44+
corresponding input, and whether processing of the input list was
45+
successful.
46+
47+
Keyword arguments:
48+
contents -- file contents string
49+
contents_modified -- whether file contents were modified from the
50+
corresponding input
51+
succeeded -- whether processing of the input list was successful
52+
"""
53+
self.outputs.append((contents, contents_modified, succeeded))
54+
55+
def add_latest_input_as_output(self, succeeded):
56+
"""Adds the latest input to the output list.
57+
58+
Since the output matches its corresponding input, the contents_modified
59+
flag is automatically set to False.
60+
61+
Keyword arguments:
62+
succeeded -- whether processing of the input list was successful
63+
"""
64+
self.add_output(self.inputs[len(self.inputs) - 1][1], False, succeeded)
65+
66+
def run(self, output_type):
67+
"""Runs the task on each input list element, then compares the resulting
68+
output against the corresponding output list element.
69+
70+
output_type == FILE: output list contains file contents
71+
output_type == STDOUT: output list contains stdout contents
72+
73+
Keyword Arguments:
74+
output_type -- the type of output stored in the output list
75+
"""
76+
assert len(self.inputs) == len(self.outputs)
77+
78+
config_file = Config(os.path.abspath(os.getcwd()), ".styleguide")
79+
80+
for i in range(len(self.inputs)):
81+
if self.task.should_process_file(config_file, self.inputs[i][0]):
82+
if output_type == OutputType.FILE:
83+
output, file_changed, success = self.task.run_pipeline(
84+
config_file, self.inputs[i][0], self.inputs[i][1])
85+
elif output_type == OutputType.STDOUT:
86+
saved_stdout = sys.stdout
87+
sys.stdout = io.StringIO()
88+
_output, file_changed, success = self.task.run_pipeline(
89+
config_file, self.inputs[i][0], self.inputs[i][1])
90+
sys.stdout.seek(0)
91+
output = sys.stdout.read()
92+
sys.stdout = saved_stdout
93+
94+
print("Running test {}...".format(i))
95+
assert output == self.outputs[i][0]
96+
assert file_changed == self.outputs[i][1]
97+
assert success == self.outputs[i][2]

wpiformat/test/test_bracecomment.py

Lines changed: 46 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,56 @@
11
import os
22

3-
from wpiformat.config import Config
3+
from test.tasktest import *
44
from wpiformat.bracecomment import BraceComment
55

66

77
def test_bracecomment():
8-
task = BraceComment()
9-
10-
inputs = []
11-
outputs = []
8+
test = TaskTest(BraceComment())
129

1310
# Empty anonymous namespace
14-
inputs.append(("./Test.h",
11+
test.add_input("./Test.h",
1512
"namespace {" + os.linesep + \
16-
"}// comment" + os.linesep))
17-
outputs.append((
13+
"}// comment" + os.linesep)
14+
test.add_output(
1815
"namespace {" + os.linesep + \
19-
"} // namespace" + os.linesep, True, True))
16+
"} // namespace" + os.linesep, True, True)
2017

2118
# Anonymous namespace containing comment
22-
inputs.append(("./Test.h",
19+
test.add_input("./Test.h",
2320
"namespace {" + os.linesep + \
2421
" // comment" + os.linesep + \
25-
"}// comment" + os.linesep))
26-
outputs.append((
22+
"}// comment" + os.linesep)
23+
test.add_output(
2724
"namespace {" + os.linesep + \
2825
" // comment" + os.linesep + \
29-
"} // namespace" + os.linesep, True, True))
26+
"} // namespace" + os.linesep, True, True)
3027

3128
# namespace
32-
inputs.append(("./Test.h",
29+
test.add_input("./Test.h",
3330
"namespace hal {" + os.linesep + \
3431
" // comment" + os.linesep + \
35-
"}// comment" + os.linesep))
36-
outputs.append((
32+
"}// comment" + os.linesep)
33+
test.add_output(
3734
"namespace hal {" + os.linesep + \
3835
" // comment" + os.linesep + \
39-
"} // namespace hal" + os.linesep, True, True))
36+
"} // namespace hal" + os.linesep, True, True)
4037

4138
# namespace with leftover input
42-
inputs.append(("./Test.h",
39+
test.add_input("./Test.h",
4340
"// comment before namespace" + os.linesep + \
4441
"namespace hal {" + os.linesep + \
4542
" // comment" + os.linesep + \
4643
"}// comment" + os.linesep + \
47-
"// comment after namespace" + os.linesep))
48-
outputs.append((
44+
"// comment after namespace" + os.linesep)
45+
test.add_output(
4946
"// comment before namespace" + os.linesep + \
5047
"namespace hal {" + os.linesep + \
5148
" // comment" + os.linesep + \
5249
"} // namespace hal" + os.linesep + \
53-
"// comment after namespace" + os.linesep, True, True))
50+
"// comment after namespace" + os.linesep, True, True)
5451

5552
# Braces within namespace
56-
inputs.append(("./Test.h",
53+
test.add_input("./Test.h",
5754
"namespace {" + os.linesep + \
5855
os.linesep + \
5956
"struct AnalogGyro {" + os.linesep + \
@@ -63,8 +60,8 @@ def test_bracecomment():
6360
" int32_t center;" + os.linesep + \
6461
"}" + os.linesep + \
6562
os.linesep + \
66-
"}" + os.linesep))
67-
outputs.append((
63+
"}" + os.linesep)
64+
test.add_output(
6865
"namespace {" + os.linesep + \
6966
os.linesep + \
7067
"struct AnalogGyro {" + os.linesep + \
@@ -74,76 +71,68 @@ def test_bracecomment():
7471
" int32_t center;" + os.linesep + \
7572
"}" + os.linesep + \
7673
os.linesep + \
77-
"} // namespace" + os.linesep, True, True))
74+
"} // namespace" + os.linesep, True, True)
7875

7976
# extern "C"
80-
inputs.append(("./Test.h",
77+
test.add_input("./Test.h",
8178
"extern \"C\" {" + os.linesep + \
8279
" // nothing" + os.linesep + \
83-
"}// comment" + os.linesep))
84-
outputs.append((
80+
"}// comment" + os.linesep)
81+
test.add_output(
8582
"extern \"C\" {" + os.linesep + \
8683
" // nothing" + os.linesep + \
87-
"} // extern \"C\"" + os.linesep, True, True))
84+
"} // extern \"C\"" + os.linesep, True, True)
8885

8986
# Nested brackets should be handled properly
90-
inputs.append(("./Test.cpp",
87+
test.add_input("./Test.cpp",
9188
"extern \"C\" {" + os.linesep + \
9289
"void func() {" + os.linesep + \
9390
" if (1) {" + os.linesep + \
9491
" } else if (1) {" + os.linesep + \
9592
" } else {" + os.linesep + \
9693
" }" + os.linesep + \
9794
"}" + os.linesep + \
98-
"} // extern \"C\"" + os.linesep))
99-
outputs.append((inputs[len(inputs) - 1][1], False, True))
95+
"} // extern \"C\"" + os.linesep)
96+
test.add_latest_input_as_output(True)
10097

10198
# Nested brackets on same line
102-
inputs.append(("./Test.cpp",
99+
test.add_input("./Test.cpp",
103100
"namespace wpi {" + os.linesep + \
104101
"{{}}" + os.linesep + \
105-
"} // namespace java" + os.linesep))
106-
outputs.append((
102+
"} // namespace java" + os.linesep)
103+
test.add_output(
107104
"namespace wpi {" + os.linesep + \
108105
"{{}}" + os.linesep + \
109-
"} // namespace wpi" + os.linesep, True, True))
106+
"} // namespace wpi" + os.linesep, True, True)
110107

111108
# Handle single-line statements correctly
112-
inputs.append(("./Test.cpp",
113-
"namespace hal { Type typeName; }" + os.linesep))
114-
outputs.append(
115-
("namespace hal { Type typeName; } // namespace hal" + os.linesep,
116-
True, True))
109+
test.add_input("./Test.cpp",
110+
"namespace hal { Type typeName; }" + os.linesep)
111+
test.add_output(
112+
"namespace hal { Type typeName; } // namespace hal" + os.linesep, True,
113+
True)
117114

118115
# Two incorrect comments
119-
inputs.append(("./Test.h",
116+
test.add_input("./Test.h",
120117
"namespace {" + os.linesep + \
121118
" // nothing" + os.linesep + \
122119
"}// comment" + os.linesep + \
123120
"namespace Name {" + os.linesep + \
124121
" // nothing" + os.linesep + \
125-
"}" + os.linesep))
126-
outputs.append((
122+
"}" + os.linesep)
123+
test.add_output(
127124
"namespace {" + os.linesep + \
128125
" // nothing" + os.linesep + \
129126
"} // namespace" + os.linesep + \
130127
"namespace Name {" + os.linesep + \
131128
" // nothing" + os.linesep + \
132-
"} // namespace Name" + os.linesep, True, True))
129+
"} // namespace Name" + os.linesep, True, True)
133130

134131
# Don't touch correct comment
135-
inputs.append(("./Test.h",
132+
test.add_input("./Test.h",
136133
"namespace {" + os.linesep + \
137134
" // nothing" + os.linesep + \
138-
"} // namespace" + os.linesep))
139-
outputs.append((inputs[len(inputs) - 1][1], False, True))
140-
141-
assert len(inputs) == len(outputs)
135+
"} // namespace" + os.linesep)
136+
test.add_latest_input_as_output(True)
142137

143-
config_file = Config(os.path.abspath(os.getcwd()), ".styleguide")
144-
for i in range(len(inputs)):
145-
output, file_changed, success = task.run_pipeline(
146-
config_file, inputs[i][0], inputs[i][1])
147-
assert output == outputs[i][0]
148-
assert file_changed == outputs[i][1]
149-
assert success == outputs[i][2]
138+
test.run(OutputType.FILE)

0 commit comments

Comments
 (0)