OILS / test / sh_spec_test.py View on Github | oilshell.org

182 lines, 114 significant
1#!/usr/bin/env python2
2"""
3sh_spec_test.py: Tests for sh_spec.py
4"""
5
6import cStringIO
7import optparse
8import pprint
9import unittest
10
11from test.sh_spec import * # module under test
12from test import sh_spec
13from test import spec_lib
14
15TEST1 = """\
16#### Env binding in readonly/declare disallowed
17FOO=foo readonly v=$(tests/printenv.py FOO)
18echo "v=$v"
19# Shells allow this misleading construct, but the correct behavior is to
20# disallow it at parse time.
21## OK bash/dash/mksh stdout: v=None
22## OK bash/dash/mksh status: 0
23## status: 2
24"""
25
26
27TEST2 = """\
28#### Multiline test case
29echo one
30echo two
31## status: 1
32## stderr-json: ""
33## STDOUT:
34one
35two
36## OK dash STDOUT:
37dash1
38dash2
39## END
40## OK mksh STDOUT:
41mksh1
42mksh2
43## END
44"""
45
46
47def Slurp(s):
48 t = Tokenizer(cStringIO.StringIO(s))
49 tokens = []
50 while True:
51 tok = t.peek()
52 print(tok)
53 tokens.append(tok)
54 if tok[1] == EOF:
55 break
56 t.next()
57 return tokens
58
59
60class ShSpecTest(unittest.TestCase):
61
62 def setUp(self):
63 self.TOKENS1 = Slurp(TEST1)
64 t = Tokenizer(cStringIO.StringIO(TEST1))
65 self.CASE1 = ParseTestCase(t)
66 assert self.CASE1 is not None
67
68 self.TOKENS2 = Slurp(TEST2)
69 t = Tokenizer(cStringIO.StringIO(TEST2))
70 self.CASE2 = ParseTestCase(t)
71 assert self.CASE2 is not None
72
73 def testTokenizer(self):
74 #pprint.pprint(TOKENS1)
75
76 types = [type_ for line_num, type_, value in self.TOKENS1]
77 self.assertEqual(
78 [ TEST_CASE_BEGIN, PLAIN_LINE, PLAIN_LINE,
79 KEY_VALUE, KEY_VALUE, KEY_VALUE,
80 EOF], types)
81
82 #pprint.pprint(TOKENS2)
83 types2 = [type_ for line_num, type_, value in self.TOKENS2]
84 self.assertEqual(
85 [ TEST_CASE_BEGIN, PLAIN_LINE, PLAIN_LINE,
86 KEY_VALUE, KEY_VALUE,
87 KEY_VALUE_MULTILINE, PLAIN_LINE, PLAIN_LINE,
88 KEY_VALUE_MULTILINE, PLAIN_LINE, PLAIN_LINE, END_MULTILINE,
89 KEY_VALUE_MULTILINE, PLAIN_LINE, PLAIN_LINE, END_MULTILINE,
90 EOF], types2)
91
92 def testParsed(self):
93 CASE1 = self.CASE1
94 CASE2 = self.CASE2
95
96 print('CASE1')
97 pprint.pprint(CASE1)
98 print()
99
100 expected = {'status': '0', 'stdout': 'v=None\n', 'qualifier': 'OK'}
101 self.assertEqual(expected, CASE1['bash'])
102 self.assertEqual(expected, CASE1['dash'])
103 self.assertEqual(expected, CASE1['mksh'])
104 self.assertEqual('2', CASE1['status'])
105 self.assertEqual(
106 'Env binding in readonly/declare disallowed', CASE1['desc'])
107
108 print('CASE2')
109 pprint.pprint(CASE2)
110 print()
111 print(CreateAssertions(CASE2, 'bash'))
112 self.assertEqual('one\ntwo\n', CASE2['stdout'])
113 self.assertEqual(
114 {'qualifier': 'OK', 'stdout': 'dash1\ndash2\n'}, CASE2['dash'])
115 self.assertEqual(
116 {'qualifier': 'OK', 'stdout': 'mksh1\nmksh2\n'}, CASE2['mksh'])
117
118 def testCreateAssertions(self):
119 print(CreateAssertions(self.CASE1, 'bash'))
120
121 def testRunCases(self):
122 this_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
123 repo_root = os.path.dirname(this_dir)
124
125 o = optparse.OptionParser()
126 spec_lib.DefineCommon(o)
127 spec_lib.DefineShSpec(o)
128 opts, _ = o.parse_args(['--tmp-env', os.path.join(repo_root, '_tmp')])
129
130 shells = [('bash', '/bin/bash'), ('osh', os.path.join(repo_root, 'bin/osh'))]
131 env = {}
132 if 0:
133 out_f = sys.stdout
134 else:
135 out_f = cStringIO.StringIO()
136 out = AnsiOutput(out_f, False)
137 RunCases([self.CASE1], lambda i, case: True, shells, env, out, opts)
138 print(repr(out.f.getvalue()))
139
140 def testMakeShellPairs(self):
141 pairs = spec_lib.MakeShellPairs(['bin/osh', '_bin/osh'])
142 print(pairs)
143 self.assertEqual(
144 [('osh', 'bin/osh'), ('osh_ALT', '_bin/osh')], pairs)
145
146 pairs = spec_lib.MakeShellPairs(['bin/osh', '_bin/cxx-dbg/osh'])
147 print(pairs)
148 self.assertEqual(
149 [('osh', 'bin/osh'), ('osh-cpp', '_bin/cxx-dbg/osh')], pairs)
150
151 pairs = spec_lib.MakeShellPairs(['bin/osh', '_bin/cxx-dbg-sh/osh'])
152 print(pairs)
153 self.assertEqual(
154 [('osh', 'bin/osh'), ('osh-cpp', '_bin/cxx-dbg-sh/osh')], pairs)
155
156
157class FunctionsTest(unittest.TestCase):
158
159 def testSuccessOrFailure(self):
160 stats = sh_spec.Stats(3, ['bash', 'dash'])
161
162 stats.Set('num_failed', 0)
163 stats.Set('oils_num_failed', 0)
164 # zero allowed
165 status = sh_spec._SuccessOrFailure('foo', 0, stats)
166 self.assertEqual(0, status)
167
168 # 1 allowed
169 status = sh_spec._SuccessOrFailure('foo', 1, stats)
170 self.assertEqual(1, status)
171
172 stats.Set('num_failed', 1)
173 stats.Set('oils_num_failed', 1)
174 status = sh_spec._SuccessOrFailure('foo', 0, stats)
175 self.assertEqual(1, status)
176
177 status = sh_spec._SuccessOrFailure('foo', 1, stats)
178 self.assertEqual(0, status)
179
180
181if __name__ == '__main__':
182 unittest.main()