Skip to content

Commit a591f0f

Browse files
committed
generate TAP output with the default C++ templates
1 parent c207038 commit a591f0f

File tree

3 files changed

+64
-31
lines changed

3 files changed

+64
-31
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,7 @@ template.
182182
If you are using the default Makefile template for C++, typing ":make" without
183183
any arguments will compile your code. Typing ":make run" will run all of the
184184
test cases against your code. Typing ":make test" will also run the test
185-
cases against your code, up until the first failed test at which point it will
186-
abort.
185+
cases against your code, except it will abort at the first failed test.
187186

188187
A Makefile template is not yet provided for any other language, but you can
189188
write one yourself if you are so inclined. Read on to learn how templates
@@ -210,6 +209,13 @@ set to C++, the driver code would be in the driver.cc file. You normally
210209
don't have to do anything with this file. It just provides supporting code
211210
for running the test cases against your code.
212211

212+
The driver should output TAP (Test Anything Protocol) so that tests can be run
213+
in a test harness such as [prove](http://search.cpan.org/perldoc?prove). The
214+
default Makefile template has a `prove` target (type ":make prove") that can
215+
run the tests in a test harness; the test harness is `prove` unless otherwise
216+
configured. TAP output is also very human-readable all by itself, so having
217+
a test harness isn't really required.
218+
213219
A default driver template is currently only provided for the C++ language.
214220
You could write your own template if you wanted to.
215221

src/com/dogcows/resources/C++Driver

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
#include <sys/time.h>
1212
#include <vector>
1313

14-
using namespace std;
15-
1614

1715
const static double __EPSILON = 1e-9;
1816
static double __time = 0.0;
@@ -126,11 +124,17 @@ bool __equals(double actual, double expected)
126124
bool __equals(const std::vector<double>& actual, const std::vector<double>& expected)
127125
{
128126
if (actual.size() != expected.size())
127+
{
129128
return false;
129+
}
130130

131131
for (size_t i = 0; i < actual.size(); ++i)
132+
{
132133
if (!__equals(actual[i], expected[i]))
134+
{
133135
return false;
136+
}
137+
}
134138

135139
return true;
136140
}
@@ -144,50 +148,57 @@ int main(int argc, char* argv[])
144148

145149
if (1 < argc) __abort_on_fail = true;
146150

151+
std::cout << "TAP version 13" << std::endl;
152+
std::cout.flush();
153+
147154
std::ifstream __in("testcases.txt");
148155
for(;;)
149156
{
157+
int __testnum = __pass + __fail + 1;
158+
150159
$RETURNTYPE$ __expected;
151160
$METHODPARAMDECLARES$
152161
__in >> __expected >> $METHODPARAMSTREAMIN$;
153162
if (!__in.good()) break;
154163

155-
std::cout << "----------------------------------------" << std::endl
156-
<< "Test " << (__pass + __fail) << ": ";
164+
std::cout << "# input for test " << __testnum << ": " << $METHODPARAMSTREAMOUT$ << std::endl;
157165
std::cout.flush();
158166

159167
__timer_start();
160168

161-
$CLASSNAME$ object;
162-
$RETURNTYPE$ __actual = object.$METHODNAME$($METHODPARAMNAMES$);
169+
$CLASSNAME$ __object;
170+
$RETURNTYPE$ __actual = __object.$METHODNAME$($METHODPARAMNAMES$);
163171

164172
double __t = __timer_stop();
165173

174+
std::cout << "# test completed in " << __t << " seconds" << std::endl;
175+
std::cout.flush();
176+
166177
if (__equals(__actual, __expected))
167178
{
168-
std::cout << "[PASS] in " << __t << " seconds." << std::endl;
179+
std::cout << "ok";
169180
++__pass;
170181
}
171182
else
172183
{
173-
std::cout << "[FAIL] in " << __t << " seconds." << std::endl
174-
<< "-> Input: " << $METHODPARAMSTREAMOUT$ << std::endl
175-
<< " Actual: " << __actual << std::endl
176-
<< " Expected: " << __expected << std::endl;
184+
std::cout << "not ok";
177185
++__fail;
178-
if (__abort_on_fail) std::abort();
179186
}
187+
188+
std::cout << " " << __testnum << " - " << __actual << " must equal " << __expected << std::endl;
189+
std::cout.flush();
190+
191+
if (__abort_on_fail && 0 < __fail) std::abort();
180192
}
181193

182-
std::cout << "========================================" << std::endl
183-
<< " Total Pass: " << __pass << std::endl
184-
<< " Total Fail: " << __fail << std::endl;
194+
std::cout << "1.." << (__pass + __fail) << std::endl
195+
<< "# passed: " << __pass << std::endl
196+
<< "# failed: " << __fail << std::endl;
185197

186198
if (__fail == 0)
187199
{
188-
std::cout << std::endl << "Nice! "
189-
<< "Don't forget to compile remotely before submitting."
190-
<< std::endl;
200+
std::cout << std::endl
201+
<< "# Nice! Don't forget to compile remotely before submitting." << std::endl;
191202
}
192203

193204
return __fail;
Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,42 @@
11

2+
# Set the command for your C++ compiler, and specify any compiler flags you
3+
# want to use (e.g. -g -Werror).
24
CXX = g++
3-
CXXFLAGS = -O0 -ggdb -Wall
5+
CXXFLAGS = -ggdb -Wall
46

5-
all: driver
7+
# The driver outputs TAP (Test Anything Protocol), so it can also be used with
8+
# any TAP test harness (e.g. prove). Set the path to your test harness here,
9+
# then use the `prove' target to run the tests with that harness.
10+
PROVE = prove
11+
PROVEFLAGS = -e ""
612

7-
run: all
8-
./driver
913

10-
test: all
11-
./driver -exit_on_fail
14+
ifeq ($(OS),Windows_NT)
15+
EXEEXT = .exe
16+
endif
1217

13-
driver.o: $CLASSNAME$.o
1418

15-
driver: driver.o
16-
$(CXX) $(CXXFLAGS) $< -o $@ $(LDFLAGS) $(LDLIBS)
19+
all: driver$(EXEEXT)
1720

1821
clean:
19-
rm -f $CLASSNAME$.o driver.o driver
22+
rm -f driver$(EXEEXT)
2023

2124
distclean: clean
2225
rm -f $CLASSNAME$
2326

24-
.PHONY: all run test clean distclean
27+
run: all
28+
./driver$(EXEEXT)
29+
30+
test: all
31+
./driver$(EXEEXT) --abort-on-fail
32+
33+
prove: all
34+
$(PROVE) $(PROVEFLAGS) ./driver$(EXEEXT)
35+
36+
37+
%$(EXEEXT): %.cc
38+
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@
39+
40+
.PHONY: all clean distclean run test prove
2541

2642
# vim:ft=make:noet:ts=8

0 commit comments

Comments
 (0)