Permalink
Browse files

Make the END token optional in the multiline spec test format.

Convert all of builtins2 to use the new format.
  • Loading branch information...
Andy Chu
Andy Chu committed Dec 28, 2017
1 parent b43c738 commit a086779f89e2e6e51da67d7c3eea328d22c3a7f2
Showing with 106 additions and 34 deletions.
  1. +88 −24 spec/builtins2.test.sh
  2. +0 −1 spec/xtrace.test.sh
  3. +7 −6 test/sh_spec.py
  4. +11 −3 test/sh_spec_test.py
View
@@ -6,63 +6,127 @@ command -v echo
echo $?
command -v myfunc
echo $?
command -v nonexistent # doesn't print anything?
command -v nonexistent # doesn't print anything
echo $?
command -v for
echo $?
# stdout-json: "echo\n0\nmyfunc\n0\n1\nfor\n0\n"
# OK dash stdout-json: "echo\n0\nmyfunc\n0\n127\nfor\n0\n"
## STDOUT:
echo
0
myfunc
0
1
for
0
## OK dash STDOUT:
echo
0
myfunc
0
127
for
0
## END
### command -v with multiple names
# ALL FOUR SHELLS behave differently here!
#
# bash chooses to swallow the error! We agree with zsh if ANY word lookup
# fails, then the whole thing fails.
# All four shells behave differently here!
myfunc() { echo x; }
command -v echo myfunc ZZZ for
echo status=$?
# stdout-json: "echo\nmyfunc\nfor\nstatus=1\n"
# BUG bash stdout-json: "echo\nmyfunc\nfor\nstatus=0\n"
# BUG dash stdout-json: "echo\nstatus=0\n"
# OK mksh stdout-json: "echo\nmyfunc\nstatus=1\n"
## STDOUT:
echo
myfunc
for
status=1
## BUG bash STDOUT:
echo
myfunc
for
status=0
## BUG dash STDOUT:
echo
status=0
## OK mksh STDOUT:
echo
myfunc
status=1
## END
### dirs builtin
cd /
dirs
# stdout-json: "/\n"
# status: 0
# N-I dash/mksh status: 127
# N-I dash/mksh stdout-json: ""
## STDOUT:
/
## END
## N-I dash/mksh status: 127
## N-I dash/mksh stdout-json: ""
### dirs -c to clear the stack
set -o errexit
cd /
pushd /tmp >/dev/null # zsh pushd doesn't print anything, but bash does
echo --
dirs
dirs -c
echo --
dirs
# stdout-json: "/tmp /\n/tmp\n"
# status: 0
# N-I dash/mksh status: 127
# N-I dash/mksh stdout-json: ""
## status: 0
## STDOUT:
--
/tmp /
--
/tmp
## N-I dash/mksh status: 127
## N-I dash/mksh stdout-json: ""
### dirs -v to print numbered stack, one entry per line
set -o errexit
cd /
pushd /tmp >/dev/null
echo --
dirs -v
pushd /lib >/dev/null
echo --
dirs -v
# stdout-json: " 0 /tmp\n 1 /\n 0 /lib\n 1 /tmp\n 2 /\n"
# status: 0
# zsh uses tabs
# OK zsh stdout-json: "0\t/tmp\n1\t/\n0\t/lib\n1\t/tmp\n2\t/\n"
# N-I dash/mksh status: 127
# N-I dash/mksh stdout-json: ""
## status: 0
## STDOUT:
--
0 /tmp
1 /
--
0 /lib
1 /tmp
2 /
## END
#
# zsh uses tabs
## OK zsh stdout-json: "--\n0\t/tmp\n1\t/\n--\n0\t/lib\n1\t/tmp\n2\t/\n"
#
## N-I dash/mksh status: 127
## N-I dash/mksh stdout-json: ""
### dirs -p to print one entry per line
set -o errexit
cd /
pushd /tmp >/dev/null
echo --
dirs -p
pushd /lib >/dev/null
echo --
dirs -p
# stdout-json: "/tmp\n/\n/lib\n/tmp\n/\n"
# N-I dash/mksh status: 127
# N-I dash/mksh stdout-json: ""
## STDOUT:
--
/tmp
/
--
/lib
/tmp
/
## N-I dash/mksh status: 127
## N-I dash/mksh stdout-json: ""
View
@@ -9,7 +9,6 @@ echo 2
## STDOUT:
1
2
## END
## STDERR:
+ echo 2
## END
View
@@ -203,7 +203,6 @@ def ParseKeyValue(tokens, case):
if kind == KEY_VALUE_MULTILINE:
qualifier, shells, name, empty_value = item
print('item', item)
if empty_value:
raise ParseError(
'Line %d: got value %r for %r, but the value should be on the '
@@ -217,9 +216,6 @@ def ParseKeyValue(tokens, case):
break
value_lines.append(item2)
if kind2 != END_MULTILINE:
raise ParseError('Expected END token, got %r %r' % (kind2, item2))
value = '\n'.join(value_lines) + '\n'
name = name.lower() # STDOUT -> stdout
@@ -228,6 +224,10 @@ def ParseKeyValue(tokens, case):
else:
case[name] = value
# END token is optional.
if kind2 == END_MULTILINE:
tokens.next()
elif kind == KEY_VALUE:
qualifier, shells, name, value = item
@@ -236,10 +236,11 @@ def ParseKeyValue(tokens, case):
else:
case[name] = value
tokens.next()
else: # Unknown token type
break
tokens.next()
def ParseCodeLines(tokens, case):
@@ -266,7 +267,7 @@ def ParseTestCase(tokens):
if kind == EOF:
return None
assert kind == TEST_CASE_BEGIN, kind # Invariant
assert kind == TEST_CASE_BEGIN, (line_num, kind, item) # Invariant
tokens.next()
case = {'desc': item, 'line_num': line_num}
View
@@ -33,11 +33,14 @@
# STDOUT:
one
two
# END
# OK dash STDOUT:
dash1
dash2
# END
# OK mksh STDOUT:
mksh1
mksh2
# END
""")
TOKENS2 = list(LineIter(TEST2))
CASE2 = ParseTestCase(Tokenizer(iter(TOKENS2)))
@@ -59,6 +62,7 @@ def testLineIter(self):
self.assertEqual(
[ TEST_CASE_BEGIN, PLAIN_LINE, PLAIN_LINE,
KEY_VALUE, KEY_VALUE,
KEY_VALUE_MULTILINE, PLAIN_LINE, PLAIN_LINE,
KEY_VALUE_MULTILINE, PLAIN_LINE, PLAIN_LINE, END_MULTILINE,
KEY_VALUE_MULTILINE, PLAIN_LINE, PLAIN_LINE, END_MULTILINE,
EOF], types2)
@@ -73,14 +77,18 @@ def testParsed(self):
self.assertEqual(expected, CASE1['dash'])
self.assertEqual(expected, CASE1['mksh'])
self.assertEqual('2', CASE1['status'])
self.assertEqual('Env binding in readonly/declare disallowed', CASE1['desc'])
self.assertEqual(
'Env binding in readonly/declare disallowed', CASE1['desc'])
print('CASE2')
pprint.pprint(CASE2)
print()
print(CreateAssertions(CASE2, 'bash'))
self.assertEqual('one\ntwo\n', CASE2['stdout'])
self.assertEqual({'qualifier': 'OK', 'stdout': 'dash1\ndash2\n'}, CASE2['dash'])
self.assertEqual(
{'qualifier': 'OK', 'stdout': 'dash1\ndash2\n'}, CASE2['dash'])
self.assertEqual(
{'qualifier': 'OK', 'stdout': 'mksh1\nmksh2\n'}, CASE2['mksh'])
def testCreateAssertions(self):
print(CreateAssertions(CASE1, 'bash'))

0 comments on commit a086779

Please sign in to comment.