6 # http://pexpect.sourceforge.net/pexpect.html
7 from pexpect
import spawn
, EOF
, TIMEOUT
9 # TODO: do we need to support '\n' too
13 parser
= argparse
.ArgumentParser(
14 description
="Run a test file against a Mal implementation")
15 parser
.add_argument('--rundir',
16 help="change to the directory before running tests")
17 parser
.add_argument('--start-timeout', default
=10, type=int,
18 help="default timeout for initial prompt")
19 parser
.add_argument('--test-timeout', default
=20, type=int,
20 help="default timeout for each individual test action")
21 parser
.add_argument('--redirect', action
='store_true',
22 help="Run implementation in bash and redirect output to /dev/null")
24 parser
.add_argument('test_file', type=argparse
.FileType('r'),
25 help="a test file formatted as with mal test data")
26 parser
.add_argument('mal_cmd', nargs
="*",
27 help="Mal implementation command line. Use '--' to "
28 "specify a Mal command line with dashed options.")
30 args
= parser
.parse_args(sys
.argv
[1:])
31 test_data
= args
.test_file
.read().split('\n')
33 if args
.rundir
: os
.chdir(args
.rundir
)
36 # Redirect to try and force raw mode (no ASCII codes)
37 p
= spawn('/bin/bash -c "' + " ".join(args
.mal_cmd
) + ' |tee /dev/null"')
39 p
= spawn(args
.mal_cmd
[0], args
.mal_cmd
[1:])
45 form
, output
, ret
= None, "", None
49 if re
.match(r
"^\s*$", line
): # blank line
51 elif line
[0:3] == ";;;": # ignore comment
53 elif line
[0:2] == ";;": # output comment
56 elif line
[0:2] == ";": # unexpected comment
57 print "Test data error at line %d:\n%s" % (test_idx
, line
)
58 return None, None, None, test_idx
59 form
= line
# the line is a form to send
61 # Now find the output and return value
64 if line
[0:3] == ";=>":
65 ret
= line
[3:].replace('\\r', '\r').replace('\\n', '\n')
69 elif line
[0:2] == "; ":
70 output
= output
+ line
[2:] + sep
78 return form
, output
, ret
, test_idx
81 # Wait for the initial prompt
82 idx
= p
.expect(['user> ', 'mal-user> ', EOF
, TIMEOUT
],
83 timeout
=args
.start_timeout
)
85 print "Never got 'user> ' prompt"
86 print " Got : %s" % repr(p
.before
)
92 form
, out
, ret
, line_num
= read_test(test_data
)
95 sys
.stdout
.write("TEST: %s -> [%s,%s]" % (form
, repr(out
), repr(ret
)))
97 expected
= "%s%s%s%s" % (form
, sep
, out
, ret
)
101 idx
= p
.expect(['\r\nuser> ', '\nuser> ',
102 '\r\nmal-user> ', '\nmal-user> '],
103 timeout
=args
.test_timeout
)
104 #print "%s,%s,%s" % (idx, repr(p.before), repr(p.after))
105 if ret
== "*" or p
.before
== expected
:
108 print " -> FAIL (line %d):" % line_num
109 print " Expected : %s" % repr(expected
)
110 print " Got : %s" % repr(p
.before
)
116 print "Got TIMEOUT, received: %s" % repr(p
.before
)
120 print "FAILURES: %d" % fail_cnt