summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJared Crapo <jared@kotfu.net>2017-08-21 18:30:07 -0600
committerJared Crapo <jared@kotfu.net>2017-08-21 18:30:07 -0600
commitd3766eb29f728b5e9d60645bbbac9062c683870e (patch)
tree19d8a2e93694fbef44f40bac03e946c54cf0fa2e
parent560133d0c95845e0b573d70303fc96d999c52c03 (diff)
downloadcmd2-git-d3766eb29f728b5e9d60645bbbac9062c683870e.tar.gz
Checkpoint. Many tests working, multiline seems broken
-rwxr-xr-xcmd2.py71
-rw-r--r--tests/test_transcript.py13
2 files changed, 70 insertions, 14 deletions
diff --git a/cmd2.py b/cmd2.py
index 1bfdd939..1a3a408c 100755
--- a/cmd2.py
+++ b/cmd2.py
@@ -2311,35 +2311,86 @@ class Cmd2TestCase(unittest.TestCase):
fname, line_num, command, expected, result)
self.assertTrue(re.match(expected, result, re.MULTILINE | re.DOTALL), message)
- def _transform_transcript_expected(self, expected):
- """parse the expected text from the transcript into a valid regex"""
+ def _transform_transcript_expected(self, s):
+ """parse the string with slashed regexes into a valid regex"""
slash = '/'
backslash = '\\'
regex = ''
start = 0
+
while True:
- first_slash_pos = expected.find(slash, start)
+ (regex, first_slash_pos, start) = self._escaped_find(regex, s, start, False)
if first_slash_pos == -1:
# no more slashes, add the rest of the string and bail
- regex += re.escape(expected[start:])
+ regex += re.escape(s[start:])
break
else:
- # there is a slash, go find the next one
- second_slash_pos = expected.find(slash, first_slash_pos+1)
+ # there is a slash, add everything we have found so far
+ # add stuff before the first slash as plain text
+ regex += re.escape(s[start:first_slash_pos])
+ start = first_slash_pos+1
+ # and go find the next one
+ (regex, second_slash_pos, start) = self._escaped_find(regex, s, start, True)
if second_slash_pos > 0:
- # add everything before the first slash as plain text
- regex += re.escape(expected[start:first_slash_pos])
# add everything between the slashes (but not the slashes)
# as a regular expression
- regex += expected[first_slash_pos+1:second_slash_pos]
+ regex += s[start:second_slash_pos]
# and change where we start looking for slashed on the
# turn through the loop
start = second_slash_pos + 1
else:
# no closing slash, treat it all as plain text
- regex += re.escape(expected[start:])
+ regex += re.escape(s[start:])
return regex
+
+ def _escaped_find(self, regex, s, start, in_regex):
+ """
+ Find the next slash in {s} after {start} that is not preceded by a backslash.
+
+ If we find an escaped slash, add everything up to and including it to regex,
+ updating {start}. {start} therefore serves two purposes, tells us where to start
+ looking for the next thing, and also tells us where in {s} we have already
+ added things to {regex}
+ {in_regex} specifies whether we are currently searching in a regex, we behave
+ differently if we are or if we aren't.
+ """
+
+ while True:
+ pos = s.find('/', start)
+ if pos == -1:
+ # no match, return to caller
+ break
+ elif pos == 0:
+ # slash at the beginning of the string, so it can't be
+ # escaped. We found it.
+ break
+ else:
+ # check if the slash is preceeded by a backslash
+ if s[pos-1:pos] == '\\':
+ # it is.
+ if in_regex:
+ # add everything up to the backslash as a
+ # regular expression
+ regex += s[start:pos-1]
+ # skip the backslash, and add the slash
+ regex += s[pos]
+ else:
+ # add everything up to the backslash as escaped
+ # plain text
+ regex += re.escape(s[start:pos-1])
+ # and then add the slash as escaped
+ # plain text
+ regex += re.escape(s[pos])
+ # update start to show we have handled everything
+ # before it
+ start = pos+1
+ # and continue to look
+ else:
+ # slash is not escaped, this is what we are looking for
+ break
+ return (regex, pos, start)
+
def tearDown(self):
if self.cmdapp:
# Restore stdout
diff --git a/tests/test_transcript.py b/tests/test_transcript.py
index fef28c7b..caa5174d 100644
--- a/tests/test_transcript.py
+++ b/tests/test_transcript.py
@@ -256,7 +256,8 @@ def test_invalid_syntax(_cmdline_app, capsys):
('spaces.txt', False),
])
def test_transcript(request, capsys, filename, feedback_to_output):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
+ # Create a cmd2.Cmd() instance and make sure basic settings are
+ # like we want for test
app = CmdLineApp()
app.feedback_to_output = feedback_to_output
@@ -264,7 +265,8 @@ def test_transcript(request, capsys, filename, feedback_to_output):
test_dir = os.path.dirname(request.module.__file__)
transcript_file = os.path.join(test_dir, 'transcripts', filename)
- # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
+ # Need to patch sys.argv so cmd2 doesn't think it was called with
+ # arguments equal to the py.test args
testargs = ['prog', '-t', transcript_file]
with mock.patch.object(sys, 'argv', testargs):
# Run the command loop
@@ -288,6 +290,11 @@ def test_transcript(request, capsys, filename, feedback_to_output):
( '/.*/', '.*'),
( 'specials ^ and + /[0-9]+/', 'specials\ \^\ and\ \+\ [0-9]+'),
( '/a{6}/ but not a{6} with /.*?/ more', 'a{6}\ but\ not\ a\{6\}\ with\ .*?\ more'),
+ ( 'not this slash\/ or this one\/', 'not\ this\ slash\\/\ or\ this\ one\\/'),
+ ( 'not \/, use /\|?/, not \/', 'not\ \\/\,\ use\ \|?\,\ not\ \\/'),
+ # inception: we have a slashes in our regex: backslashed on input, bare on output
+ ( 'not \/, use /\/?/, not \/', 'not\ \\/\,\ use\ /?\,\ not\ \\/'),
+ ( 'the /\/?/ more /.*/ stuff', 'the\ /?\ more\ .*\ stuff')
])
def test_parse_transcript_expected(expected, transformed):
app = CmdLineApp()
@@ -296,6 +303,4 @@ def test_parse_transcript_expected(expected, transformed):
cmdapp = app
testcase = TestMyAppCase()
-
assert testcase._transform_transcript_expected(expected) == transformed
-