1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
# Test all error messages.
# coding: utf-8
import unittest
from context import sedparse
TEST_DATA = [
# pylint: disable=bad-whitespace
# fmt: off
# Note: Not all possible error messages are tested, those that were left
# out are not available in the port.
# Format: (sed script, char nr, constant, error message)
# ANCIENT_VERSION expected newer version of sed
("!!p", 2, "BAD_BANG", "multiple `!'s"),
("1,p", 3, "BAD_COMMA", "unexpected `,'"),
("s★a★b★", 2, "BAD_DELIM",
"delimiter character is not a single-byte character"),
("+1p", 2, "BAD_STEP", "invalid usage of +N or ~N as first address"),
("~1p", 2, "BAD_STEP", "invalid usage of +N or ~N as first address"),
(":", 1, "COLON_LACKS_LABEL", '":" lacks a label'),
# DISALLOWED_CMD e/r/w commands disabled in sandbox mode
("}", 1, "EXCESS_CLOSE_BRACE", "unexpected `}'"),
("b}", 2, "EXCESS_CLOSE_BRACE", "unexpected `}'"),
("bx}", 3, "EXCESS_CLOSE_BRACE", "unexpected `}'"),
("s/a/b/gg", 8, "EXCESS_G_OPT", "multiple `g' options to `s' command"),
("dp", 2, "EXCESS_JUNK", "extra characters after command"),
("xx", 2, "EXCESS_JUNK", "extra characters after command"),
("s/a/b/2p2", 9, "EXCESS_N_OPT", "multiple number options to `s' command"),
("{", 0, "EXCESS_OPEN_BRACE", "unmatched `{'"),
# ^here it should be 1. It's a GNU sed bug that sedparse emulates.
("s/a/b/pp", 8, "EXCESS_P_OPT", "multiple `p' options to `s' command"),
("a", 1, "EXPECTED_SLASH", "expected \\ after `a', `c' or `i'"),
# INCOMPLETE_CMD incomplete command
("0p", 2, "INVALID_LINE_0", "invalid usage of line address 0"),
("0,5p", 4, "INVALID_LINE_0", "invalid usage of line address 0"),
("s/a/b/w", 7, "MISSING_FILENAME", "missing filename in r/R/w/W commands"),
("r", 1, "MISSING_FILENAME", "missing filename in r/R/w/W commands"),
("{p;$}", 5, "NO_CLOSE_BRACE_ADDR", "`}' doesn't want any addresses"),
# NO_COLON_ADDR : doesn't want any addresses
("1", 1, "NO_COMMAND", "missing command"),
("1\n", 2, "NO_COMMAND", "missing command"),
# NO_SHARP_ADDR comments don't accept any addresses
# ONE_ADDR command only uses one address
# RECURSIVE_ESCAPE_C recursive escaping after \\c not allowed
("u", 1, "UNKNOWN_CMD", "unknown command: `u'"),
("s/a/b/z", 7, "UNKNOWN_S_OPT", "unknown option to `s'"),
("s/a/b/\r", 7, "UNKNOWN_S_OPT", "unknown option to `s'"),
("/a", 2, "UNTERM_ADDR_RE", "unterminated address regex"),
("s/a/b", 5, "UNTERM_S_CMD", "unterminated `s' command"),
("y/a/", 4, "UNTERM_Y_CMD", "unterminated `y' command"),
# Y_CMD_LEN strings for `y' command are different lengths
("s/a/b/0", 7, "ZERO_N_OPT", "number option to `s' command may not be zero"),
]
class TestSedparseErrors(unittest.TestCase): # pylint: disable=unused-variable
def test_errors(self):
for script, char_nr, _, message in TEST_DATA:
expected = "sedparse: -e expression #%d, char %d: %s" % (
sedparse.cur_input.string_expr_count + 1,
char_nr,
message,
)
try:
parsed = []
sedparse.compile_string(parsed, script)
sedparse.check_final_program()
self.fail(msg=script) # it should never reach here
except sedparse.ParseError as err:
self.assertEqual(expected, err.message, msg=script)
self.assertEqual(sedparse.EXIT_BAD_USAGE, err.exitcode, msg=script)
if __name__ == "__main__":
unittest.main()
|