commit 24f42ffcc212b6a8ec8033559ba3ef8fbb4525a631f3744861f5dacb57b5fdeb Author: Tomáš Chvátal Date: Thu Aug 22 08:30:41 2019 +0000 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 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/pytest-console-scripts-0.1.6.tar.gz b/pytest-console-scripts-0.1.6.tar.gz new file mode 100644 index 0000000..4f2e374 --- /dev/null +++ b/pytest-console-scripts-0.1.6.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b304a22d5baf8f627215e999af39b9b834803012e9cd7e91cbd1ec0799a7828 +size 8361 diff --git a/pytest-console-scripts-0.1.6_test_virtualenv.patch b/pytest-console-scripts-0.1.6_test_virtualenv.patch new file mode 100644 index 0000000..73d53fb --- /dev/null +++ b/pytest-console-scripts-0.1.6_test_virtualenv.patch @@ -0,0 +1,539 @@ +From d60073b0c13ff33322b2762bbd065acebc88a58f Mon Sep 17 00:00:00 2001 +From: Vasily Kuznetsov +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 +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, + ] diff --git a/python-pytest-console-scripts.changes b/python-pytest-console-scripts.changes new file mode 100644 index 0000000..c3963ba --- /dev/null +++ b/python-pytest-console-scripts.changes @@ -0,0 +1,10 @@ +------------------------------------------------------------------- +Mon Oct 1 12:07:44 UTC 2018 - Andreas Schneider + +- 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 + +- Initial package diff --git a/python-pytest-console-scripts.spec b/python-pytest-console-scripts.spec new file mode 100644 index 0000000..f9a3f9d --- /dev/null +++ b/python-pytest-console-scripts.spec @@ -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