JS: add localStorage history load/save. Slurp using sync XHR.
[jackhill/mal.git] / runtest.py
CommitLineData
31690700
JM
1#!/usr/bin/env python
2
3import os, sys, re
4import argparse
5
6# http://pexpect.sourceforge.net/pexpect.html
7from pexpect import spawn, EOF, TIMEOUT
8
9# TODO: do we need to support '\n' too
10sep = "\r\n"
11rundir = None
12
13parser = argparse.ArgumentParser(
14 description="Run a test file against a Mal implementation")
15parser.add_argument('--rundir',
16 help="change to the directory before running tests")
17parser.add_argument('--start-timeout', default=10, type=int,
18 help="default timeout for initial prompt")
19parser.add_argument('--test-timeout', default=20, type=int,
20 help="default timeout for each individual test action")
53beaa0a
JM
21parser.add_argument('--redirect', action='store_true',
22 help="Run implementation in bash and redirect output to /dev/null")
31690700
JM
23
24parser.add_argument('test_file', type=argparse.FileType('r'),
25 help="a test file formatted as with mal test data")
26parser.add_argument('mal_cmd', nargs="*",
27 help="Mal implementation command line. Use '--' to "
28 "specify a Mal command line with dashed options.")
29
30args = parser.parse_args(sys.argv[1:])
31test_data = args.test_file.read().split('\n')
32
33if args.rundir: os.chdir(args.rundir)
34
53beaa0a
JM
35if args.redirect:
36 # Redirect to try and force raw mode (no ASCII codes)
37 p = spawn('/bin/bash -c "' + " ".join(args.mal_cmd) + ' |tee /dev/null"')
38else:
39 p = spawn(args.mal_cmd[0], args.mal_cmd[1:])
40
31690700
JM
41
42test_idx = 0
43def read_test(data):
44 global test_idx
45 form, output, ret = None, "", None
46 while data:
47 test_idx += 1
48 line = data.pop(0)
49 if re.match(r"^\s*$", line): # blank line
50 continue
51 elif line[0:3] == ";;;": # ignore comment
52 continue
53 elif line[0:2] == ";;": # output comment
54 print line[3:]
55 continue
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
60
61 # Now find the output and return value
62 while data:
63 line = data[0]
64 if line[0:3] == ";=>":
65 ret = line[3:].replace('\\r', '\r').replace('\\n', '\n')
66 test_idx += 1
67 data.pop(0)
68 break
69 elif line[0:2] == "; ":
70 output = output + line[2:] + sep
71 test_idx += 1
72 data.pop(0)
73 else:
74 ret = "*"
75 break
76 if ret: break
77
78 return form, output, ret, test_idx
79
80
81# Wait for the initial prompt
82idx = p.expect(['user> ', 'mal-user> ', EOF, TIMEOUT],
83 timeout=args.start_timeout)
84if idx not in [0,1]:
85 print "Never got 'user> ' prompt"
86 print " Got : %s" % repr(p.before)
87 sys.exit(1)
88
89fail_cnt = 0
90
91while test_data:
92 form, out, ret, line_num = read_test(test_data)
93 if form == None:
94 break
95 sys.stdout.write("TEST: %s -> [%s,%s]" % (form, repr(out), repr(ret)))
96 sys.stdout.flush()
97 expected = "%s%s%s%s" % (form, sep, out, ret)
98
99 p.sendline(form)
100 try:
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:
106 print " -> SUCCESS"
107 else:
108 print " -> FAIL (line %d):" % line_num
109 print " Expected : %s" % repr(expected)
110 print " Got : %s" % repr(p.before)
111 fail_cnt += 1
112 except EOF:
113 print "Got EOF"
114 sys.exit(1)
115 except TIMEOUT:
116 print "Got TIMEOUT, received: %s" % repr(p.before)
117 sys.exit(1)
118
119if fail_cnt > 0:
120 print "FAILURES: %d" % fail_cnt
121 sys.exit(2)
122sys.exit(0)