summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2017-07-01 20:54:06 -0400
committerGitHub <noreply@github.com>2017-07-01 20:54:06 -0400
commit26743a702afa42ff199614def9f7c5eb04308f76 (patch)
treef249feee0eda6894482d45045a796271851ad7dd
parent79d5b675ab52a0522462e0ccfdab236787f3dac0 (diff)
parent4e8c08eb8fb22afa61b805f545c0d0460e79184e (diff)
downloadcmd2-git-26743a702afa42ff199614def9f7c5eb04308f76.tar.gz
Merge pull request #162 from python-cmd2/py_tests
Fixed a major bug in the pyscript command on Windows
-rw-r--r--CHANGES.md9
-rwxr-xr-xcmd2.py6
-rw-r--r--tests/scripts/raises_exception.py6
-rw-r--r--tests/scripts/recursive.py6
-rw-r--r--tests/test_cmd2.py48
5 files changed, 67 insertions, 8 deletions
diff --git a/CHANGES.md b/CHANGES.md
index b853f222..82b4a59e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,12 +4,13 @@ News
0.7.4
-----
-*Release date: TBD*
+*Release date: 2017-07-TBD*
* Bug fixes
* Fixed a couple bugs in interacting with pastebuffer/clipboard on macOS and Linux
* Fixed a couple bugs in edit and save commands if called when history is empty
* Ability to pipe ``cmd2`` command output to a shell command is now more reliable, particularly on Windows
+ * Fixed a bug in ``pyscript`` command on Windows related to ``\`` being interpreted as an escape
* Enhancements
* Ensure that path and shell command tab-completion results are alphabetically sorted
* Removed feature for load command to load scripts from URLS
@@ -18,8 +19,10 @@ News
* These also strongly felt out of place
* ``load`` and ``_relative_load`` now require a file path
* ``edit`` and ``save`` now use a temporary file if a file path isn't provided
- * Load command has better error checking and reporting
- * Clipboard copy and paste functionality is now handled by the ``pyperclip`` module
+ * ``load`` command has better error checking and reporting
+ * Clipboard copy and paste functionality is now handled by the **pyperclip** module
+ * NOTE: This adds an additional required 3rd-party dependency
+ * Added a lot of unit tests
0.7.3
-----
diff --git a/cmd2.py b/cmd2.py
index 89ed1b7c..b04bf215 100755
--- a/cmd2.py
+++ b/cmd2.py
@@ -1421,7 +1421,7 @@ Paths or arguments that contain spaces must be enclosed in quotes
arg = shlex.split(arg, posix=POSIX_SHLEX)
# Get the absolute path of the script
- script_path = os.path.abspath(os.path.expanduser(arg[0]))
+ script_path = os.path.expanduser(arg[0])
# Save current command line arguments
orig_args = sys.argv
@@ -1430,8 +1430,8 @@ Paths or arguments that contain spaces must be enclosed in quotes
sys.argv = [script_path]
sys.argv.extend(arg[1:])
- # Run the script
- self.do_py("run('{}')".format(script_path))
+ # Run the script - use repr formatting to escape things which need to be escaped to prevent issues on Windows
+ self.do_py("run({!r})".format(script_path))
# Restore command line arguments to original state
sys.argv = orig_args
diff --git a/tests/scripts/raises_exception.py b/tests/scripts/raises_exception.py
new file mode 100644
index 00000000..738edaf2
--- /dev/null
+++ b/tests/scripts/raises_exception.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""
+Example demonstrating what happens when a Python script raises an exception
+"""
+1 + 'blue'
diff --git a/tests/scripts/recursive.py b/tests/scripts/recursive.py
new file mode 100644
index 00000000..84f445bb
--- /dev/null
+++ b/tests/scripts/recursive.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""
+Example demonstrating that running a Python script recursively inside another Python script isn't allowed
+"""
+cmd('pyscript ../script.py')
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 7e9769e3..592e6af2 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -131,8 +131,6 @@ def test_base_run_python_script(base_app, capsys, request):
assert out == expected
-@pytest.mark.skipif(sys.platform == 'win32',
- reason="Unit test doesn't work on win32, but feature does")
def test_base_run_pyscript(base_app, capsys, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'script.py')
@@ -142,6 +140,34 @@ def test_base_run_pyscript(base_app, capsys, request):
out, err = capsys.readouterr()
assert out == expected
+def test_recursive_pyscript_not_allowed(base_app, capsys, request):
+ test_dir = os.path.dirname(request.module.__file__)
+ python_script = os.path.join(test_dir, 'scripts', 'recursive.py')
+ expected = 'ERROR: Recursively entering interactive Python consoles is not allowed.\n'
+
+ run_cmd(base_app, "pyscript {}".format(python_script))
+ out, err = capsys.readouterr()
+ assert err == expected
+
+def test_pyscript_with_nonexist_file(base_app, capsys):
+ python_script = 'does_not_exist.py'
+ run_cmd(base_app, "pyscript {}".format(python_script))
+ out, err = capsys.readouterr()
+ assert err.startswith('ERROR: [Errno 2] No such file or directory:')
+
+def test_pyscript_with_exception(base_app, capsys, request):
+ test_dir = os.path.dirname(request.module.__file__)
+ python_script = os.path.join(test_dir, 'scripts', 'raises_exception.py')
+ run_cmd(base_app, "pyscript {}".format(python_script))
+ out, err = capsys.readouterr()
+ assert err.startswith('Traceback')
+ assert err.endswith("TypeError: unsupported operand type(s) for +: 'int' and 'str'\n")
+
+def test_pyscript_requires_an_argument(base_app, capsys):
+ run_cmd(base_app, "pyscript")
+ out, err = capsys.readouterr()
+ assert err.startswith('ERROR: pyscript command requires at least 1 argument ...')
+
def test_base_error(base_app):
out = run_cmd(base_app, 'meow')
@@ -957,3 +983,21 @@ Charm us with the {}...
# And verify the expected output to stdout
assert out == expected
+
+@pytest.fixture
+def noarglist_app():
+ cmd2.set_use_arg_list(False)
+ app = cmd2.Cmd()
+ app.stdout = StdOut()
+ return app
+
+def test_pyscript_with_noarglist(noarglist_app, capsys, request):
+ test_dir = os.path.dirname(request.module.__file__)
+ python_script = os.path.join(test_dir, '..', 'examples', 'scripts', 'arg_printer.py')
+ expected = """Running Python script 'arg_printer.py' which was called with 2 arguments
+arg 1: 'foo'
+arg 2: 'bar'
+"""
+ run_cmd(noarglist_app, 'pyscript {} foo bar'.format(python_script))
+ out, err = capsys.readouterr()
+ assert out == expected