osc copypac from project:home:gladiac package:python-pytest-console-scripts revision:5

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:pytest/python-pytest-console-scripts?expand=0&rev=1
This commit is contained in:
Tomáš Chvátal 2019-08-22 08:30:41 +00:00 committed by Git OBS Bridge
commit 24f42ffcc2
6 changed files with 652 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.osc

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3b304a22d5baf8f627215e999af39b9b834803012e9cd7e91cbd1ec0799a7828
size 8361

View File

@ -0,0 +1,539 @@
From d60073b0c13ff33322b2762bbd065acebc88a58f Mon Sep 17 00:00:00 2001
From: Vasily Kuznetsov <kvas.it@gmail.com>
Date: Sat, 29 Sep 2018 00:14:00 +0200
Subject: [PATCH 1/2] Make tests use a separate virtualenv for installing
scripts
---
tests/test_console_scripts.py | 201 +-----------------------------
tests/test_run_scripts.py | 225 ++++++++++++++++++++++++++++++++++
tox.ini | 4 +-
3 files changed, 230 insertions(+), 200 deletions(-)
create mode 100644 tests/test_run_scripts.py
diff --git a/tests/test_console_scripts.py b/tests/test_console_scripts.py
index 8a05fbe..384ac9e 100644
--- a/tests/test_console_scripts.py
+++ b/tests/test_console_scripts.py
@@ -1,8 +1,5 @@
from __future__ import print_function, unicode_literals
-import subprocess
-
-import mock
import pytest
@@ -31,7 +28,7 @@ def launch_modes(launch_mode_conf):
@pytest.fixture
def run_test(testdir):
- def runner(script, passed=1, skipped=0, failed=0, launch_mode_conf=None):
+ def run(script, passed=1, skipped=0, failed=0, launch_mode_conf=None):
testdir.makepyfile(script)
args = []
if launch_mode_conf is not None:
@@ -41,7 +38,7 @@ def runner(script, passed=1, skipped=0, failed=0, launch_mode_conf=None):
['pytest stderr:'] + result.errlines))
result.assert_outcomes(passed=passed, skipped=skipped, failed=failed)
return result
- return runner
+ return run
CHECK_LAUNCH_MODE = """
@@ -105,197 +102,3 @@ def test_help_message(testdir):
'console-scripts:',
'*--script-launch-mode=*',
])
-
-
-def run_setup_py(cmd, script_path, uninstall=False):
- """Run setup.py to install or uninstall the script command line wrapper."""
- script_dir = script_path.join('..')
- script_name = script_path.purebasename
- setup_py = script_dir.join('setup.py')
- setup_py.write(
- """
-import setuptools
-
-setuptools.setup(
- name='{script_name}',
- version='0.1',
- py_modules=['{script_name}'],
- zip_safe=False,
- entry_points={{
- 'console_scripts': ['{cmd}={script_name}:main']
- }}
-)
- """.format(cmd=cmd, script_name=script_name))
- args = ['setup.py', 'develop']
- if uninstall:
- args.append('--uninstall')
- try:
- with script_dir.as_cwd(), mock.patch('sys.argv', args):
- exec(setup_py.read())
- except TypeError:
- # In-process call fails on some Python 2 installations
- # but it's faster, especially on PyPy.
- subprocess.check_call(['python'] + args, cwd=str(script_dir))
-
-
-@pytest.yield_fixture
-def console_script(request, testdir):
- """Console script exposed as a wrapper in python `bin` directory.
-
- Returned value is a `py.path.local` object that corresponds to a python
- file whose `main` function is exposed via console script wrapper. The
- name of the command is available via it `command_name` attribute.
- """
- script = testdir.makepyfile(console_script_module='def main(): pass')
- cmd = 'console-script-module-cmd'
- run_setup_py(cmd, script)
- script.command_name = cmd
- yield script
- run_setup_py(cmd, script, uninstall=True)
-
-
-@pytest.fixture(params=['inprocess', 'subprocess'])
-def launch_mode(request):
- """Launch mode: inprocess|subprocess."""
- return request.param
-
-
-def test_run_script(console_script, run_test, launch_mode):
- console_script.write(
- """
-from __future__ import print_function
-
-def main():
- print(u'hello world')
- print('hello world')
- """
- )
- run_test(
- r"""
-def test_hello_world(script_runner):
- ret = script_runner.run('{}')
- print(ret.stderr)
- assert ret.success
- assert ret.stdout == 'hello world\nhello world\n'
- """.format(console_script.command_name),
- launch_mode_conf=launch_mode,
- passed=1
- )
-
-
-def test_run_failing_script(console_script, run_test, launch_mode):
- console_script.write(
- """
-import sys
-
-def main():
- sys.exit('boom')
- """
- )
- run_test(
- r"""
-def test_exit_boom(script_runner):
- ret = script_runner.run('{}')
- assert not ret.success
- assert ret.stdout == ''
- assert ret.stderr == 'boom\n'
- """.format(console_script.command_name),
- launch_mode_conf=launch_mode,
- passed=1
- )
-
-
-def test_run_script_with_exception(console_script, run_test, launch_mode):
- console_script.write(
- """
-import sys
-
-def main():
- raise TypeError('boom')
- """
- )
- run_test(
- r"""
-def test_throw_exception(script_runner):
- ret = script_runner.run('{}')
- assert not ret.success
- assert ret.returncode == 1
- assert ret.stdout == ''
- assert 'TypeError: boom' in ret.stderr
- """.format(console_script.command_name),
- launch_mode_conf=launch_mode,
- passed=1
- )
-
-
-def test_run_script_with_cwd(console_script, run_test, launch_mode, tmpdir):
- console_script.write(
- """
-from __future__ import print_function
-
-import os
-
-def main():
- print(os.getcwd())
- """
- )
- run_test(
- r"""
-def test_cwd(script_runner):
- ret = script_runner.run('{script_name}', cwd='{cwd}')
- assert ret.success
- assert ret.stdout == '{cwd}\n'
- """.format(script_name=console_script.command_name, cwd=tmpdir),
- launch_mode_conf=launch_mode
- )
-
-
-def test_preserve_cwd(console_script, run_test, launch_mode):
- console_script.write(
- """
-from __future__ import print_function
-
-import os
-import sys
-
-def main():
- os.chdir(sys.argv[1])
- print(os.getcwd())
- """
- )
- run_test(
- r"""
-import os
-
-def test_preserve_cwd(script_runner, tmpdir):
- dir1 = tmpdir.mkdir('dir1')
- dir2 = tmpdir.mkdir('dir2')
- os.chdir(str(dir1))
- ret = script_runner.run('{script_name}', str(dir2))
- assert ret.stdout == str(dir2) + '\n'
- assert os.getcwd() == str(dir1)
- """.format(script_name=console_script.command_name)
- )
-
-
-def test_run_script_with_stdin(console_script, run_test, launch_mode):
- console_script.write(
- """
-import sys
-
-def main():
- for line in sys.stdin:
- sys.stdout.write('simon says ' + line)
- """
- )
- run_test(
- r"""
-import io
-
-def test_stdin(script_runner):
- ret = script_runner.run('{script_name}', stdin=io.StringIO(u'foo\nbar'))
- assert ret.success
- assert ret.stdout == 'simon says foo\nsimon says bar'
- """.format(script_name=console_script.command_name),
- launch_mode_conf=launch_mode
- )
diff --git a/tests/test_run_scripts.py b/tests/test_run_scripts.py
new file mode 100644
index 0000000..76933b6
--- /dev/null
+++ b/tests/test_run_scripts.py
@@ -0,0 +1,225 @@
+import os
+import subprocess
+import sys
+
+import mock
+import py
+import pytest
+import virtualenv
+
+
+# Template for creating setup.py for installing console scripts.
+SETUP_TEMPLATE = """
+import setuptools
+
+setuptools.setup(
+ name='{script_name}',
+ version='1.0',
+ py_modules=['{script_name}'],
+ zip_safe=False,
+ entry_points={{
+ 'console_scripts': ['{cmd}={script_name}:main']
+ }}
+)
+"""
+
+
+class VEnvWrapper:
+ """Wrapper for virtualenv that can execute code inside of it."""
+
+ def __init__(self, path):
+ self.path = path
+
+ def _update_env(self, env):
+ bin_dir = self.path.join('bin').strpath
+ env['PATH'] = bin_dir + ':' + env.get('PATH', '')
+ env['VIRTUAL_ENV'] = self.path.strpath
+ env['PYTHONPATH'] = ':'.join(sys.path)
+
+ def run(self, cmd, *args, **kw):
+ """Run a command in the virtualenv."""
+ self._update_env(kw.setdefault('env', os.environ))
+ print(kw['env']['PATH'], kw['env']['PYTHONPATH'])
+ subprocess.check_call(cmd, *args, **kw)
+
+ def install_console_script(self, cmd, script_path):
+ """Run setup.py to install console script into this virtualenv."""
+ script_dir = script_path.dirpath()
+ script_name = script_path.purebasename
+ setup_py = script_dir.join('setup.py')
+ setup_py.write(SETUP_TEMPLATE.format(cmd=cmd, script_name=script_name))
+ self.run(['python', 'setup.py', 'develop'], cwd=str(script_dir))
+
+
+@pytest.fixture(scope='session')
+def pcs_venv(tmpdir_factory):
+ """Virtualenv for testing console scripts."""
+ venv = tmpdir_factory.mktemp('venv')
+ virtualenv.create_environment(venv.strpath)
+ yield VEnvWrapper(venv)
+
+
+@pytest.fixture(scope='session')
+def console_script(pcs_venv, tmpdir_factory):
+ """Console script exposed as a wrapper in python `bin` directory.
+
+ Returned value is a `py.path.local` object that corresponds to a python
+ file whose `main` function is exposed via console script wrapper. The
+ name of the command is available via it `command_name` attribute.
+
+ The fixture is made session scoped for speed. The idea is that every test
+ will overwrite the content of the script exposed by this fixture to get
+ the behavior that it needs.
+ """
+ script = tmpdir_factory.mktemp('script').join('console_script.py')
+ script.write('def main(): pass')
+ pcs_venv.install_console_script('console-script', script)
+ return script
+
+
+@pytest.fixture(params=['inprocess', 'subprocess'])
+def launch_mode(request):
+ """Launch mode: inprocess|subprocess."""
+ return request.param
+
+
+@pytest.fixture
+def test_script_in_venv(pcs_venv, console_script, tmpdir, launch_mode):
+ """A fixture that tests provided script with provided test."""
+ pytest_path = py.path.local(sys.executable).dirpath('pytest').strpath
+
+ def run(script_src, test_src, **kw):
+ """Test provided script with a provided test."""
+ console_script.write(script_src)
+ test = tmpdir.join('test.py')
+ test.write(test_src)
+ # Execute pytest with the python of the virtualenv we created,
+ # otherwise it would be executed with the python that runs this test,
+ # which is wrong.
+ test_cmd = [
+ 'python',
+ pytest_path,
+ '--script-launch-mode=' + launch_mode,
+ test.strpath,
+ ]
+ pcs_venv.run(test_cmd, **kw)
+
+ return run
+
+
+@pytest.mark.parametrize('script,test', [
+ (
+ """
+from __future__ import print_function
+
+def main():
+ print(u'hello world')
+ print('hello world')
+ """,
+ r"""
+def test_hello_world(script_runner):
+ ret = script_runner.run('console-script')
+ print(ret.stderr)
+ assert ret.success
+ assert ret.stdout == 'hello world\nhello world\n'
+ """,
+ ),
+ # Script that exits abnormally.
+ (
+ """
+import sys
+
+def main():
+ sys.exit('boom')
+ """,
+ r"""
+def test_exit_boom(script_runner):
+ ret = script_runner.run('console-script')
+ assert not ret.success
+ assert ret.stdout == ''
+ assert ret.stderr == 'boom\n'
+ """,
+ ),
+ # Script that has an uncaught exception.
+ (
+ """
+import sys
+
+def main():
+ raise TypeError('boom')
+ """,
+ r"""
+def test_throw_exception(script_runner):
+ ret = script_runner.run('console-script')
+ assert not ret.success
+ assert ret.returncode == 1
+ assert ret.stdout == ''
+ assert 'TypeError: boom' in ret.stderr
+ """,
+ ),
+ # Script that changes to another directory. The test process should remain
+ # in the directory where it was (this is particularly relevant if we run
+ # the script inprocess).
+ (
+ """
+from __future__ import print_function
+
+import os
+import sys
+
+def main():
+ os.chdir(sys.argv[1])
+ print(os.getcwd())
+ """,
+ r"""
+import os
+
+def test_preserve_cwd(script_runner, tmpdir):
+ dir1 = tmpdir.mkdir('dir1')
+ dir2 = tmpdir.mkdir('dir2')
+ os.chdir(str(dir1))
+ ret = script_runner.run('console-script', str(dir2))
+ assert ret.stdout == str(dir2) + '\n'
+ assert os.getcwd() == str(dir1)
+ """,
+ ),
+ # Send input to tested script's stdin.
+ (
+ """
+import sys
+
+def main():
+ for line in sys.stdin:
+ sys.stdout.write('simon says ' + line)
+ """,
+ r"""
+import io
+
+def test_stdin(script_runner):
+ ret = script_runner.run('console-script', stdin=io.StringIO(u'foo\nbar'))
+ assert ret.success
+ assert ret.stdout == 'simon says foo\nsimon says bar'
+ """,
+ ),
+])
+def test_run_script(test_script_in_venv, script, test):
+ test_script_in_venv(script, test)
+
+
+def test_run_script_with_cwd(test_script_in_venv, tmpdir):
+ test_script_in_venv(
+ """
+from __future__ import print_function
+
+import os
+
+def main():
+ print(os.getcwd())
+ """,
+ r"""
+def test_cwd(script_runner):
+ ret = script_runner.run('console-script', cwd='{cwd}')
+ assert ret.success
+ assert ret.stdout == '{cwd}\n'
+ """.format(cwd=tmpdir),
+ )
diff --git a/tox.ini b/tox.ini
index 43f852b..504a20e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -3,5 +3,7 @@
envlist = py27,py34,py35,py36,py37,pypy
[testenv]
-deps = pytest
+deps =
+ pytest
+ virtualenv
commands = pytest tests
From affbb6ffd0f7b2ad3f29461e9ddb34488beac7d9 Mon Sep 17 00:00:00 2001
From: Vasily Kuznetsov <kvas.it@gmail.com>
Date: Sat, 29 Sep 2018 12:53:20 +0200
Subject: [PATCH 2/2] Work around py27 heisenbug caused by stale pyc files
---
tests/test_run_scripts.py | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/tests/test_run_scripts.py b/tests/test_run_scripts.py
index 76933b6..0d6702e 100644
--- a/tests/test_run_scripts.py
+++ b/tests/test_run_scripts.py
@@ -74,6 +74,16 @@ def console_script(pcs_venv, tmpdir_factory):
script = tmpdir_factory.mktemp('script').join('console_script.py')
script.write('def main(): pass')
pcs_venv.install_console_script('console-script', script)
+
+ def replace(new_source):
+ """Replace script source."""
+ script.write(new_source)
+ pyc = script.strpath + 'c'
+ if os.path.exists(pyc):
+ # Remove stale bytecode that causes heisenbugs on py27.
+ os.remove(pyc)
+
+ script.replace = replace
return script
@@ -86,11 +96,10 @@ def launch_mode(request):
@pytest.fixture
def test_script_in_venv(pcs_venv, console_script, tmpdir, launch_mode):
"""A fixture that tests provided script with provided test."""
- pytest_path = py.path.local(sys.executable).dirpath('pytest').strpath
def run(script_src, test_src, **kw):
"""Test provided script with a provided test."""
- console_script.write(script_src)
+ console_script.replace(script_src)
test = tmpdir.join('test.py')
test.write(test_src)
# Execute pytest with the python of the virtualenv we created,
@@ -98,7 +107,7 @@ def run(script_src, test_src, **kw):
# which is wrong.
test_cmd = [
'python',
- pytest_path,
+ '-m', 'pytest',
'--script-launch-mode=' + launch_mode,
test.strpath,
]

View File

@ -0,0 +1,10 @@
-------------------------------------------------------------------
Mon Oct 1 12:07:44 UTC 2018 - Andreas Schneider <asn@cryptomilk.org>
- Update to version 0.1.6
- Added pytest-console-scripts-0.1.6_test_virtualenv.patch
-------------------------------------------------------------------
Fri Jun 15 09:11:13 UTC 2018 - Andreas Schneider <asn@cryptomilk.org>
- Initial package

View File

@ -0,0 +1,76 @@
#
# spec file for package python-pytest-console-scripts
#
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pytest-console-scripts
Version: 0.1.6
Release: 0
License: MIT
Summary: Pytest plugin for testing console scripts
Url: https://github.com/kvas-it/pytest-console-scripts
Group: Development/Languages/Python
Source: https://files.pythonhosted.org/packages/source/p/pytest-console-scripts/pytest-console-scripts-%{version}.tar.gz
Patch0: pytest-console-scripts-0.1.6_test_virtualenv.patch
BuildRequires: python-rpm-macros
BuildRequires: %{python_module setuptools}
# SECTION test requirements
BuildRequires: %{python_module mock >= 2.0.0}
BuildRequires: %{python_module pytest >= 3.0.0}
BuildRequires: %{python_module pytest-runner}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module virtualenv}
# /SECTION
BuildRequires: fdupes
Requires: python-mock >= 2.0.0
Requires: python-pytest >= 3.0.0
Requires: python-pytest-runner
BuildArch: noarch
%python_subpackages
%description
Pytest-console-scripts is a `Pytest`_ plugin for testing python scripts
installed via ``console_scripts`` entry point of ``setup.py``. It can run the
scripts under test in a separate process or using the interpreter that's
running the test suite. The former mode ensures that the script will run in an
environment that is identical to normal execution whereas the latter one allows
much quicker test runs during development while simulating the real runs as
much as possible.
%prep
%autosetup -n pytest-console-scripts-%{version} -p1
%build
%python_build
%install
%python_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
%python_exec setup.py test
%files %{python_files}
%license LICENSE
%doc README.rst
%{python_sitelib}/*
%changelog