diff --git a/.travis.yml b/.travis.yml index 1847cc3e..bd4bfa2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,25 @@ +sudo: false +cache: pip language: python python: - "2.7" - - "3.4" - - "3.5" - "3.6" - # - "pypy" # too many cache issues - # - "3.7-dev" # no need, slows down builds - # - "pypy3" # TODO: pkg_config issues +env: + - TEST_SUITE='install' + - TEST_SUITE='dotvenv or check or unused' + - TEST_SUITE='cli or requirements' + - TEST_SUITE='complex' + - TEST_SUITE='run or project or utils' # command to install dependencies install: - - "pip install -e . --upgrade" + - "pip install --upgrade pip" + - "pip install -e . --upgrade --upgrade-strategy=only-if-needed" - "pipenv install --dev" # command to run the dependencies script: - - "pipenv run pytest -n 8 tests" + - "pipenv run bash ./run-tests.sh" # command to run tests # jobs: diff --git a/Pipfile b/Pipfile index 5a3aa2ab..683a8a0c 100644 --- a/Pipfile +++ b/Pipfile @@ -8,6 +8,7 @@ twine = "*" sphinx-click = "*" pytest-xdist = "*" click = "*" +"bf8d106" = {path = "./tests/pytest-pypi", editable = true} [packages] diff --git a/Pipfile.lock b/Pipfile.lock index 36c2606d..f6653c5e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "30cda285af4ec2464aed0a9c99ec997e3423ec9d69068910f77ec100db2ec653" + "sha256": "f901280e04e0d3e853369cf63eb52086c265e54b10c036e4d0d1f2e06c82aca1" }, "pipfile-spec": 6, "requires": {}, @@ -124,6 +124,10 @@ ], "version": "==2.5.3" }, + "bf8d106": { + "editable": true, + "path": "./tests/pytest-pypi" + }, "certifi": { "hashes": [ "sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296", @@ -192,6 +196,13 @@ ], "version": "==3.5.0" }, + "flask": { + "hashes": [ + "sha256:0749df235e3ff61ac108f69ac178c9770caeaccad2509cb762ce1f65570a8856", + "sha256:49f44461237b69ecd901cc7ce66feea0319b9158743dd27a2899962ab214dac1" + ], + "version": "==0.12.2" + }, "funcsigs": { "hashes": [ "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca", @@ -214,6 +225,12 @@ ], "version": "==1.0.0" }, + "itsdangerous": { + "hashes": [ + "sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519" + ], + "version": "==0.24" + }, "jinja2": { "hashes": [ "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", @@ -386,6 +403,13 @@ "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" ], "version": "==1.22" + }, + "werkzeug": { + "hashes": [ + "sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c", + "sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b" + ], + "version": "==0.14.1" } } } diff --git a/pipenv/environments.py b/pipenv/environments.py index eaf0be55..a8745a9a 100644 --- a/pipenv/environments.py +++ b/pipenv/environments.py @@ -13,6 +13,9 @@ PIPENV_SHELL_FANCY = bool(os.environ.get('PIPENV_SHELL_FANCY')) # Create the virtualenv in the project, instead of with pew. PIPENV_VENV_IN_PROJECT = bool(os.environ.get('PIPENV_VENV_IN_PROJECT')) or os.path.isdir('.venv') +# Overwrite all index funcitonality. +PIPENV_TEST_INDEX = os.environ.get('PIPENV_TEST_INDEX') + # No color mode, for unfun people. PIPENV_COLORBLIND = bool(os.environ.get('PIPENV_COLORBLIND')) diff --git a/pipenv/project.py b/pipenv/project.py index a1f0c790..5634b762 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -23,7 +23,8 @@ from .environments import ( PIPENV_PIPFILE, PIPENV_VENV_IN_PROJECT, PIPENV_VIRTUALENV, - PIPENV_NO_INHERIT + PIPENV_NO_INHERIT, + PIPENV_TEST_INDEX ) if PIPENV_PIPFILE: @@ -410,17 +411,20 @@ class Project(object): install = dict(config_parser.get_config_section('install')) indexes = install.get('extra-index-url', '').lstrip('\n').split('\n') - # Default source. - pypi_source = {u'url': u'https://pypi.python.org/simple', u'verify_ssl': True, u'name': 'pypi'} - sources = [pypi_source] + if PIPENV_TEST_INDEX: + sources = [{u'url': PIPENV_TEST_INDEX, u'verify_ssl': True, u'name': u'custom'}] + else: + # Default source. + pypi_source = {u'url': u'https://pypi.python.org/simple', u'verify_ssl': True, u'name': 'pypi'} + sources = [pypi_source] - for i, index in enumerate(indexes): - if not index: - continue - source_name = 'pip_index_{}'.format(i) - verify_ssl = index.startswith('https') + for i, index in enumerate(indexes): + if not index: + continue + source_name = 'pip_index_{}'.format(i) + verify_ssl = index.startswith('https') - sources.append({u'url': index, u'verify_ssl': verify_ssl, u'name': source_name}) + sources.append({u'url': index, u'verify_ssl': verify_ssl, u'name': source_name}) data = { u'source': sources, diff --git a/run-tests.sh b/run-tests.sh new file mode 100644 index 00000000..c4199524 --- /dev/null +++ b/run-tests.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +PYPI_VENDOR_DIR="$(pwd)/tests/pypi/" +export PYPI_VENDOR_DIR + +pytest -n 8 tests -m "$TEST_SUITE" \ No newline at end of file diff --git a/tests/pypi/alembic/alembic-0.9.8.tar.gz b/tests/pypi/alembic/alembic-0.9.8.tar.gz new file mode 100644 index 00000000..a23b9200 Binary files /dev/null and b/tests/pypi/alembic/alembic-0.9.8.tar.gz differ diff --git a/tests/pypi/certifi/certifi-2018.1.18-py2.py3-none-any.whl b/tests/pypi/certifi/certifi-2018.1.18-py2.py3-none-any.whl new file mode 100644 index 00000000..3348f725 Binary files /dev/null and b/tests/pypi/certifi/certifi-2018.1.18-py2.py3-none-any.whl differ diff --git a/tests/pypi/certifi/certifi-2018.1.18.tar.gz b/tests/pypi/certifi/certifi-2018.1.18.tar.gz new file mode 100644 index 00000000..a7f32456 Binary files /dev/null and b/tests/pypi/certifi/certifi-2018.1.18.tar.gz differ diff --git a/tests/pypi/chardet/chardet-3.0.4-py2.py3-none-any.whl b/tests/pypi/chardet/chardet-3.0.4-py2.py3-none-any.whl new file mode 100644 index 00000000..d276977d Binary files /dev/null and b/tests/pypi/chardet/chardet-3.0.4-py2.py3-none-any.whl differ diff --git a/tests/pypi/chardet/chardet-3.0.4.tar.gz b/tests/pypi/chardet/chardet-3.0.4.tar.gz new file mode 100644 index 00000000..13028bfc Binary files /dev/null and b/tests/pypi/chardet/chardet-3.0.4.tar.gz differ diff --git a/tests/pypi/click/click-6.7-py2.py3-none-any.whl b/tests/pypi/click/click-6.7-py2.py3-none-any.whl new file mode 100644 index 00000000..56c7ff34 Binary files /dev/null and b/tests/pypi/click/click-6.7-py2.py3-none-any.whl differ diff --git a/tests/pypi/click/click-6.7.tar.gz b/tests/pypi/click/click-6.7.tar.gz new file mode 100644 index 00000000..b0790fc0 Binary files /dev/null and b/tests/pypi/click/click-6.7.tar.gz differ diff --git a/tests/pypi/django-classy-tags/django-classy-tags-0.8.0.tar.gz b/tests/pypi/django-classy-tags/django-classy-tags-0.8.0.tar.gz new file mode 100644 index 00000000..b88f48ae Binary files /dev/null and b/tests/pypi/django-classy-tags/django-classy-tags-0.8.0.tar.gz differ diff --git a/tests/pypi/django-classy-tags/django_classy_tags-0.8.0-py2.py3-none-any.whl b/tests/pypi/django-classy-tags/django_classy_tags-0.8.0-py2.py3-none-any.whl new file mode 100644 index 00000000..47ac7f85 Binary files /dev/null and b/tests/pypi/django-classy-tags/django_classy_tags-0.8.0-py2.py3-none-any.whl differ diff --git a/tests/pypi/django-formtools/django-formtools-2.1.tar.gz b/tests/pypi/django-formtools/django-formtools-2.1.tar.gz new file mode 100644 index 00000000..2b8ca348 Binary files /dev/null and b/tests/pypi/django-formtools/django-formtools-2.1.tar.gz differ diff --git a/tests/pypi/django-formtools/django_formtools-2.1-py2.py3-none-any.whl b/tests/pypi/django-formtools/django_formtools-2.1-py2.py3-none-any.whl new file mode 100644 index 00000000..1086751a Binary files /dev/null and b/tests/pypi/django-formtools/django_formtools-2.1-py2.py3-none-any.whl differ diff --git a/tests/pypi/django-sekizai/django-sekizai-0.10.0.tar.gz b/tests/pypi/django-sekizai/django-sekizai-0.10.0.tar.gz new file mode 100644 index 00000000..b11067dc Binary files /dev/null and b/tests/pypi/django-sekizai/django-sekizai-0.10.0.tar.gz differ diff --git a/tests/pypi/django-sekizai/django_sekizai-0.10.0-py2.py3-none-any.whl b/tests/pypi/django-sekizai/django_sekizai-0.10.0-py2.py3-none-any.whl new file mode 100644 index 00000000..20c107cc Binary files /dev/null and b/tests/pypi/django-sekizai/django_sekizai-0.10.0-py2.py3-none-any.whl differ diff --git a/tests/pypi/django-treebeard/django-treebeard-4.2.0.tar.gz b/tests/pypi/django-treebeard/django-treebeard-4.2.0.tar.gz new file mode 100644 index 00000000..3d92cb7e Binary files /dev/null and b/tests/pypi/django-treebeard/django-treebeard-4.2.0.tar.gz differ diff --git a/tests/pypi/django/Django-1.11.10-py2.py3-none-any.whl b/tests/pypi/django/Django-1.11.10-py2.py3-none-any.whl new file mode 100644 index 00000000..8d515c4a Binary files /dev/null and b/tests/pypi/django/Django-1.11.10-py2.py3-none-any.whl differ diff --git a/tests/pypi/django/Django-1.11.10.tar.gz b/tests/pypi/django/Django-1.11.10.tar.gz new file mode 100644 index 00000000..2d69623e Binary files /dev/null and b/tests/pypi/django/Django-1.11.10.tar.gz differ diff --git a/tests/pypi/djangocms-admin-style/djangocms-admin-style-1.2.7.tar.gz b/tests/pypi/djangocms-admin-style/djangocms-admin-style-1.2.7.tar.gz new file mode 100644 index 00000000..f3afc45b Binary files /dev/null and b/tests/pypi/djangocms-admin-style/djangocms-admin-style-1.2.7.tar.gz differ diff --git a/tests/pypi/docopt/docopt-0.6.2.tar.gz b/tests/pypi/docopt/docopt-0.6.2.tar.gz new file mode 100644 index 00000000..153ce415 Binary files /dev/null and b/tests/pypi/docopt/docopt-0.6.2.tar.gz differ diff --git a/tests/pypi/et-xmlfile/et_xmlfile-1.0.1.tar.gz b/tests/pypi/et-xmlfile/et_xmlfile-1.0.1.tar.gz new file mode 100644 index 00000000..73a5894e Binary files /dev/null and b/tests/pypi/et-xmlfile/et_xmlfile-1.0.1.tar.gz differ diff --git a/tests/pypi/flask/Flask-0.12.2-py2.py3-none-any.whl b/tests/pypi/flask/Flask-0.12.2-py2.py3-none-any.whl new file mode 100644 index 00000000..98e55415 Binary files /dev/null and b/tests/pypi/flask/Flask-0.12.2-py2.py3-none-any.whl differ diff --git a/tests/pypi/flask/Flask-0.12.2.tar.gz b/tests/pypi/flask/Flask-0.12.2.tar.gz new file mode 100644 index 00000000..278c2108 Binary files /dev/null and b/tests/pypi/flask/Flask-0.12.2.tar.gz differ diff --git a/tests/pypi/gitdb2/gitdb2-2.0.3-py2.py3-none-any.whl b/tests/pypi/gitdb2/gitdb2-2.0.3-py2.py3-none-any.whl new file mode 100644 index 00000000..26ffc716 Binary files /dev/null and b/tests/pypi/gitdb2/gitdb2-2.0.3-py2.py3-none-any.whl differ diff --git a/tests/pypi/gitdb2/gitdb2-2.0.3.tar.gz b/tests/pypi/gitdb2/gitdb2-2.0.3.tar.gz new file mode 100644 index 00000000..de6ee8af Binary files /dev/null and b/tests/pypi/gitdb2/gitdb2-2.0.3.tar.gz differ diff --git a/tests/pypi/idna/idna-2.6-py2.py3-none-any.whl b/tests/pypi/idna/idna-2.6-py2.py3-none-any.whl new file mode 100644 index 00000000..11cb4140 Binary files /dev/null and b/tests/pypi/idna/idna-2.6-py2.py3-none-any.whl differ diff --git a/tests/pypi/idna/idna-2.6.tar.gz b/tests/pypi/idna/idna-2.6.tar.gz new file mode 100644 index 00000000..d38e1f29 Binary files /dev/null and b/tests/pypi/idna/idna-2.6.tar.gz differ diff --git a/tests/pypi/itsdangerous/itsdangerous-0.24.tar.gz b/tests/pypi/itsdangerous/itsdangerous-0.24.tar.gz new file mode 100644 index 00000000..d0416330 Binary files /dev/null and b/tests/pypi/itsdangerous/itsdangerous-0.24.tar.gz differ diff --git a/tests/pypi/jdcal/jdcal-1.3.tar.gz b/tests/pypi/jdcal/jdcal-1.3.tar.gz new file mode 100644 index 00000000..2f3ba8ce Binary files /dev/null and b/tests/pypi/jdcal/jdcal-1.3.tar.gz differ diff --git a/tests/pypi/jinja2/Jinja2-2.10-py2.py3-none-any.whl b/tests/pypi/jinja2/Jinja2-2.10-py2.py3-none-any.whl new file mode 100644 index 00000000..7bc4e35f Binary files /dev/null and b/tests/pypi/jinja2/Jinja2-2.10-py2.py3-none-any.whl differ diff --git a/tests/pypi/jinja2/Jinja2-2.10.tar.gz b/tests/pypi/jinja2/Jinja2-2.10.tar.gz new file mode 100644 index 00000000..c311087a Binary files /dev/null and b/tests/pypi/jinja2/Jinja2-2.10.tar.gz differ diff --git a/tests/pypi/mako/Mako-1.0.7.tar.gz b/tests/pypi/mako/Mako-1.0.7.tar.gz new file mode 100644 index 00000000..9e5825f6 Binary files /dev/null and b/tests/pypi/mako/Mako-1.0.7.tar.gz differ diff --git a/tests/pypi/markupsafe/MarkupSafe-1.0.tar.gz b/tests/pypi/markupsafe/MarkupSafe-1.0.tar.gz new file mode 100644 index 00000000..606021ae Binary files /dev/null and b/tests/pypi/markupsafe/MarkupSafe-1.0.tar.gz differ diff --git a/tests/pypi/odfpy/odfpy-1.3.6-py2.7.egg b/tests/pypi/odfpy/odfpy-1.3.6-py2.7.egg new file mode 100644 index 00000000..ccb4eeed Binary files /dev/null and b/tests/pypi/odfpy/odfpy-1.3.6-py2.7.egg differ diff --git a/tests/pypi/odfpy/odfpy-1.3.6.tar.gz b/tests/pypi/odfpy/odfpy-1.3.6.tar.gz new file mode 100644 index 00000000..c8861245 Binary files /dev/null and b/tests/pypi/odfpy/odfpy-1.3.6.tar.gz differ diff --git a/tests/pypi/openpyxl/openpyxl-2.5.0.tar.gz b/tests/pypi/openpyxl/openpyxl-2.5.0.tar.gz new file mode 100644 index 00000000..52f84550 Binary files /dev/null and b/tests/pypi/openpyxl/openpyxl-2.5.0.tar.gz differ diff --git a/tests/pypi/parse/parse-1.8.2.tar.gz b/tests/pypi/parse/parse-1.8.2.tar.gz new file mode 100644 index 00000000..d24aa0d1 Binary files /dev/null and b/tests/pypi/parse/parse-1.8.2.tar.gz differ diff --git a/tests/pypi/pysocks/PySocks-1.6.8.tar.gz b/tests/pypi/pysocks/PySocks-1.6.8.tar.gz new file mode 100644 index 00000000..e6366dcf Binary files /dev/null and b/tests/pypi/pysocks/PySocks-1.6.8.tar.gz differ diff --git a/tests/pypi/python-dateutil/python-dateutil-2.6.1.tar.gz b/tests/pypi/python-dateutil/python-dateutil-2.6.1.tar.gz new file mode 100644 index 00000000..6b86c6d3 Binary files /dev/null and b/tests/pypi/python-dateutil/python-dateutil-2.6.1.tar.gz differ diff --git a/tests/pypi/python-dateutil/python_dateutil-2.6.1-py2.py3-none-any.whl b/tests/pypi/python-dateutil/python_dateutil-2.6.1-py2.py3-none-any.whl new file mode 100644 index 00000000..97b3947a Binary files /dev/null and b/tests/pypi/python-dateutil/python_dateutil-2.6.1-py2.py3-none-any.whl differ diff --git a/tests/pypi/python-editor/python-editor-1.0.3.tar.gz b/tests/pypi/python-editor/python-editor-1.0.3.tar.gz new file mode 100644 index 00000000..8149cccc Binary files /dev/null and b/tests/pypi/python-editor/python-editor-1.0.3.tar.gz differ diff --git a/tests/pypi/pytz/pytz-2018.3-py2.py3-none-any.whl b/tests/pypi/pytz/pytz-2018.3-py2.py3-none-any.whl new file mode 100644 index 00000000..d274bd36 Binary files /dev/null and b/tests/pypi/pytz/pytz-2018.3-py2.py3-none-any.whl differ diff --git a/tests/pypi/pytz/pytz-2018.3.tar.gz b/tests/pypi/pytz/pytz-2018.3.tar.gz new file mode 100644 index 00000000..c8045799 Binary files /dev/null and b/tests/pypi/pytz/pytz-2018.3.tar.gz differ diff --git a/tests/pypi/pyyaml/PyYAML-3.12.tar.gz b/tests/pypi/pyyaml/PyYAML-3.12.tar.gz new file mode 100644 index 00000000..aabee39f Binary files /dev/null and b/tests/pypi/pyyaml/PyYAML-3.12.tar.gz differ diff --git a/tests/pypi/records/records-0.5.2-py2.py3-none-any.whl b/tests/pypi/records/records-0.5.2-py2.py3-none-any.whl new file mode 100644 index 00000000..0516a923 Binary files /dev/null and b/tests/pypi/records/records-0.5.2-py2.py3-none-any.whl differ diff --git a/tests/pypi/records/records-0.5.2.tar.gz b/tests/pypi/records/records-0.5.2.tar.gz new file mode 100644 index 00000000..f3690c19 Binary files /dev/null and b/tests/pypi/records/records-0.5.2.tar.gz differ diff --git a/tests/pypi/requests/requests-1.0.0.tar.gz b/tests/pypi/requests/requests-1.0.0.tar.gz new file mode 100644 index 00000000..d6184496 Binary files /dev/null and b/tests/pypi/requests/requests-1.0.0.tar.gz differ diff --git a/tests/pypi/requests/requests-2.18.4-py2.py3-none-any.whl b/tests/pypi/requests/requests-2.18.4-py2.py3-none-any.whl new file mode 100644 index 00000000..cf3bdc07 Binary files /dev/null and b/tests/pypi/requests/requests-2.18.4-py2.py3-none-any.whl differ diff --git a/tests/pypi/requests/requests-2.18.4.tar.gz b/tests/pypi/requests/requests-2.18.4.tar.gz new file mode 100644 index 00000000..fce54795 Binary files /dev/null and b/tests/pypi/requests/requests-2.18.4.tar.gz differ diff --git a/tests/pypi/six/six-1.11.0-py2.py3-none-any.whl b/tests/pypi/six/six-1.11.0-py2.py3-none-any.whl new file mode 100644 index 00000000..59960239 Binary files /dev/null and b/tests/pypi/six/six-1.11.0-py2.py3-none-any.whl differ diff --git a/tests/pypi/six/six-1.11.0.tar.gz b/tests/pypi/six/six-1.11.0.tar.gz new file mode 100644 index 00000000..353f31f9 Binary files /dev/null and b/tests/pypi/six/six-1.11.0.tar.gz differ diff --git a/tests/pypi/smmap2/smmap2-2.0.3-py2.py3-none-any.whl b/tests/pypi/smmap2/smmap2-2.0.3-py2.py3-none-any.whl new file mode 100644 index 00000000..72599115 Binary files /dev/null and b/tests/pypi/smmap2/smmap2-2.0.3-py2.py3-none-any.whl differ diff --git a/tests/pypi/smmap2/smmap2-2.0.3.tar.gz b/tests/pypi/smmap2/smmap2-2.0.3.tar.gz new file mode 100644 index 00000000..e959ad02 Binary files /dev/null and b/tests/pypi/smmap2/smmap2-2.0.3.tar.gz differ diff --git a/tests/pypi/sqlalchemy/SQLAlchemy-1.2.4.tar.gz b/tests/pypi/sqlalchemy/SQLAlchemy-1.2.4.tar.gz new file mode 100644 index 00000000..e965a280 Binary files /dev/null and b/tests/pypi/sqlalchemy/SQLAlchemy-1.2.4.tar.gz differ diff --git a/tests/pypi/tablib/tablib-0.12.1.tar.gz b/tests/pypi/tablib/tablib-0.12.1.tar.gz new file mode 100644 index 00000000..825ee278 Binary files /dev/null and b/tests/pypi/tablib/tablib-0.12.1.tar.gz differ diff --git a/tests/pypi/tpfd/tpfd-0.2.4-py2.py3-none-any.whl b/tests/pypi/tpfd/tpfd-0.2.4-py2.py3-none-any.whl new file mode 100644 index 00000000..a1e64899 Binary files /dev/null and b/tests/pypi/tpfd/tpfd-0.2.4-py2.py3-none-any.whl differ diff --git a/tests/pypi/tpfd/tpfd-0.2.4.tar.gz b/tests/pypi/tpfd/tpfd-0.2.4.tar.gz new file mode 100644 index 00000000..c13d45c0 Binary files /dev/null and b/tests/pypi/tpfd/tpfd-0.2.4.tar.gz differ diff --git a/tests/pypi/unicodecsv/unicodecsv-0.14.1.tar.gz b/tests/pypi/unicodecsv/unicodecsv-0.14.1.tar.gz new file mode 100644 index 00000000..a7858b00 Binary files /dev/null and b/tests/pypi/unicodecsv/unicodecsv-0.14.1.tar.gz differ diff --git a/tests/pypi/urllib3/urllib3-1.22-py2.py3-none-any.whl b/tests/pypi/urllib3/urllib3-1.22-py2.py3-none-any.whl new file mode 100644 index 00000000..d4464993 Binary files /dev/null and b/tests/pypi/urllib3/urllib3-1.22-py2.py3-none-any.whl differ diff --git a/tests/pypi/urllib3/urllib3-1.22.tar.gz b/tests/pypi/urllib3/urllib3-1.22.tar.gz new file mode 100644 index 00000000..3d9ee9f1 Binary files /dev/null and b/tests/pypi/urllib3/urllib3-1.22.tar.gz differ diff --git a/tests/pypi/werkzeug/Werkzeug-0.14.1-py2.py3-none-any.whl b/tests/pypi/werkzeug/Werkzeug-0.14.1-py2.py3-none-any.whl new file mode 100644 index 00000000..865d5248 Binary files /dev/null and b/tests/pypi/werkzeug/Werkzeug-0.14.1-py2.py3-none-any.whl differ diff --git a/tests/pypi/werkzeug/Werkzeug-0.14.1.tar.gz b/tests/pypi/werkzeug/Werkzeug-0.14.1.tar.gz new file mode 100644 index 00000000..27e7b2d7 Binary files /dev/null and b/tests/pypi/werkzeug/Werkzeug-0.14.1.tar.gz differ diff --git a/tests/pypi/xlrd/xlrd-1.1.0-py2.py3-none-any.whl b/tests/pypi/xlrd/xlrd-1.1.0-py2.py3-none-any.whl new file mode 100644 index 00000000..fd326f8a Binary files /dev/null and b/tests/pypi/xlrd/xlrd-1.1.0-py2.py3-none-any.whl differ diff --git a/tests/pypi/xlrd/xlrd-1.1.0.tar.gz b/tests/pypi/xlrd/xlrd-1.1.0.tar.gz new file mode 100644 index 00000000..6f8d5666 Binary files /dev/null and b/tests/pypi/xlrd/xlrd-1.1.0.tar.gz differ diff --git a/tests/pypi/xlwt/xlwt-1.3.0-py2.py3-none-any.whl b/tests/pypi/xlwt/xlwt-1.3.0-py2.py3-none-any.whl new file mode 100644 index 00000000..ab824454 Binary files /dev/null and b/tests/pypi/xlwt/xlwt-1.3.0-py2.py3-none-any.whl differ diff --git a/tests/pypi/xlwt/xlwt-1.3.0.tar.gz b/tests/pypi/xlwt/xlwt-1.3.0.tar.gz new file mode 100644 index 00000000..f9a65e06 Binary files /dev/null and b/tests/pypi/xlwt/xlwt-1.3.0.tar.gz differ diff --git a/tests/pytest-pypi/DESCRIPTION.rst b/tests/pytest-pypi/DESCRIPTION.rst new file mode 100644 index 00000000..4e0cba87 --- /dev/null +++ b/tests/pytest-pypi/DESCRIPTION.rst @@ -0,0 +1,30 @@ +pytest-httpbin +============== + +httpbin is an amazing web service for testing HTTP libraries. It has several +great endpoints that can test pretty much everything you need in a HTTP +library. The only problem is: maybe you don't want to wait for your tests to +travel across the Internet and back to make assertions against a remote web +service. + +Enter pytest-httpbin. Pytest-httpbin creates a pytest "fixture" that is +dependency-injected into your tests. It automatically starts up a HTTP server +in a separate thread running httpbin and provides your test with the URL in the +fixture. Check out this example: + +.. code-block:: python + + def test_that_my_library_works_kinda_ok(httpbin): + assert requests.get(httpbin.url + '/get/').status_code == 200 + +This replaces a test that might have looked like this before: + +.. code-block:: python + + def test_that_my_library_works_kinda_ok(): + assert requests.get('http://httpbin.org/get').status_code == 200 + +pytest-httpbin also supports https and includes its own CA cert you can use. +Check out `the full documentation`_ on the github page. + +.. _the full documentation: https://github.com/kevin1024/pytest-httpbin diff --git a/tests/pytest-pypi/MANIFEST.in b/tests/pytest-pypi/MANIFEST.in new file mode 100644 index 00000000..4104865b --- /dev/null +++ b/tests/pytest-pypi/MANIFEST.in @@ -0,0 +1,4 @@ +# If using Python 2.6 or less, then have to include package data, even though +# it's already declared in setup.py +include pytest_httpbin/certs/* +include DESCRIPTION.rst diff --git a/tests/pytest-pypi/Pipfile b/tests/pytest-pypi/Pipfile new file mode 100644 index 00000000..366b2617 --- /dev/null +++ b/tests/pytest-pypi/Pipfile @@ -0,0 +1,23 @@ +[[source]] + +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + + +[packages] + + + +[dev-packages] + +pytest = "*" +"e1839a8" = {path = ".", editable = true} +httpbin = "*" +requests = "*" +twine = "*" + + +[requires] + +python_version = "3.6" diff --git a/tests/pytest-pypi/Pipfile.lock b/tests/pytest-pypi/Pipfile.lock new file mode 100644 index 00000000..b60f1990 --- /dev/null +++ b/tests/pytest-pypi/Pipfile.lock @@ -0,0 +1,480 @@ +{ + "_meta": { + "hash": { + "sha256": "b871e70f9f0b7bd3852672c371c754d8db50e5015c8dbdad1d217a3e58a26c33" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.6" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": {}, + "develop": { + "argparse": { + "hashes": [ + "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4", + "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" + ], + "markers": "python_version == '2.6'", + "version": "==1.4.0" + }, + "attrs": { + "hashes": [ + "sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9", + "sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450" + ], + "version": "==17.4.0" + }, + "blinker": { + "hashes": [ + "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6" + ], + "version": "==1.4" + }, + "brotlipy": { + "hashes": [ + "sha256:07194f4768eb62a4f4ea76b6d0df6ade185e24ebd85877c351daa0a069f1111a", + "sha256:091b299bf36dd6ef7a06570dbc98c0f80a504a56c5b797f31934d2ad01ae7d17", + "sha256:09ec3e125d16749b31c74f021aba809541b3564e5359f8c265cbae442810b41a", + "sha256:0be698678a114addcf87a4b9496c552c68a2c99bf93cf8e08f5738b392e82057", + "sha256:0fa6088a9a87645d43d7e21e32b4a6bf8f7c3939015a50158c10972aa7f425b7", + "sha256:1ea4e578241504b58f2456a6c69952c88866c794648bdc74baee74839da61d44", + "sha256:2699945a0a992c04fc7dc7fa2f1d0575a2c8b4b769f2874a08e8eae46bef36ae", + "sha256:2a80319ae13ea8dd60ecdc4f5ccf6da3ae64787765923256b62c598c5bba4121", + "sha256:2e5c64522364a9ebcdf47c5744a5ddeb3f934742d31e61ebfbbc095460b47162", + "sha256:36def0b859beaf21910157b4c33eb3b06d8ce459c942102f16988cca6ea164df", + "sha256:3a3e56ced8b15fbbd363380344f70f3b438e0fd1fcf27b7526b6172ea950e867", + "sha256:3c1d5e2cf945a46975bdb11a19257fa057b67591eb232f393d260e7246d9e571", + "sha256:50ca336374131cfad20612f26cc43c637ac0bfd2be3361495e99270883b52962", + "sha256:5de6f7d010b7558f72f4b061a07395c5c3fd57f0285c5af7f126a677b976a868", + "sha256:637847560d671657f993313ecc6c6c6666a936b7a925779fd044065c7bc035b9", + "sha256:653faef61241bf8bf99d73ca7ec4baa63401ba7b2a2aa88958394869379d67c7", + "sha256:786afc8c9bd67de8d31f46e408a3386331e126829114e4db034f91eacb05396d", + "sha256:79aaf217072840f3e9a3b641cccc51f7fc23037496bd71e26211856b93f4b4cb", + "sha256:7e31f7adcc5851ca06134705fcf3478210da45d35ad75ec181e1ce9ce345bb38", + "sha256:8b39abc3256c978f575df5cd7893153277216474f303e26f0e43ba3d3969ef96", + "sha256:9448227b0df082e574c45c983fa5cd4bda7bfb11ea6b59def0940c1647be0c3c", + "sha256:96bc59ff9b5b5552843dc67999486a220e07a0522dddd3935da05dc194fa485c", + "sha256:a07647886e24e2fb2d68ca8bf3ada398eb56fd8eac46c733d4d95c64d17f743b", + "sha256:af65d2699cb9f13b26ec3ba09e75e80d31ff422c03675fcb36ee4dabe588fdc2", + "sha256:b4c98b0d2c9c7020a524ca5bbff42027db1004c6571f8bc7b747f2b843128e7a", + "sha256:c6cc0036b1304dd0073eec416cb2f6b9e37ac8296afd9e481cac3b1f07f9db25", + "sha256:d2c1c724c4ac375feb2110f1af98ecdc0e5a8ea79d068efb5891f621a5b235cb", + "sha256:dc6c5ee0df9732a44d08edab32f8a616b769cc5a4155a12d2d010d248eb3fb07", + "sha256:fd1d1c64214af5d90014d82cee5d8141b13d44c92ada7a0c0ec0679c6f15a471" + ], + "version": "==0.7.0" + }, + "certifi": { + "hashes": [ + "sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296", + "sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d" + ], + "version": "==2018.1.18" + }, + "cffi": { + "hashes": [ + "sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743", + "sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef", + "sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50", + "sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f", + "sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93", + "sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257", + "sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3", + "sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc", + "sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04", + "sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6", + "sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359", + "sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596", + "sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b", + "sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd", + "sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95", + "sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e", + "sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6", + "sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca", + "sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31", + "sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1", + "sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085", + "sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801", + "sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4", + "sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184", + "sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917", + "sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f", + "sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb" + ], + "version": "==1.11.5" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "click": { + "hashes": [ + "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d", + "sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b" + ], + "version": "==6.7" + }, + "colorama": { + "hashes": [ + "sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda", + "sha256:48eb22f4f8461b1df5734a074b57042430fb06e1d61bd1e11b078c0fe6d7a1f1" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.3.9" + }, + "contextlib2": { + "hashes": [ + "sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48", + "sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00" + ], + "markers": "python_version < '3.2'", + "version": "==0.5.5" + }, + "crayons": { + "hashes": [ + "sha256:5e17691605e564d63482067eb6327d01a584bbaf870beffd4456a3391bd8809d", + "sha256:6f51241d0c4faec1c04c1c0ac6a68f1d66a4655476ce1570b3f37e5166a599cc" + ], + "version": "==0.1.2" + }, + "dateparser": { + "hashes": [ + "sha256:940828183c937bcec530753211b70f673c0a9aab831e43273489b310538dff86", + "sha256:b452ef8b36cd78ae86a50721794bc674aa3994e19b570f7ba92810f4e0a2ae03" + ], + "version": "==0.7.0" + }, + "decorator": { + "hashes": [ + "sha256:7d46dd9f3ea1cf5f06ee0e4e1277ae618cf48dfb10ada7c8427cd46c42702a0e", + "sha256:94d1d8905f5010d74bbbd86c30471255661a14187c45f8d7f3e5aa8540fdb2e5" + ], + "version": "==4.2.1" + }, + "e1839a8": { + "editable": true, + "path": "." + }, + "flask": { + "hashes": [ + "sha256:0749df235e3ff61ac108f69ac178c9770caeaccad2509cb762ce1f65570a8856", + "sha256:49f44461237b69ecd901cc7ce66feea0319b9158743dd27a2899962ab214dac1" + ], + "version": "==0.12.2" + }, + "flask-cache": { + "hashes": [ + "sha256:33187b3ddceeee233fe3db68ffcc118b5498e8ad28edde711bcbdcbf4924ce35", + "sha256:90126ca9bc063854ef8ee276e95d38b2b4ec8e45fd77d5751d37971ee27c7ef4", + "sha256:ae9d1ac4549517dfbc1f178ccc5429f61f836be3cc109a0b2481c98b3711c329" + ], + "version": "==0.13.1" + }, + "flask-common": { + "hashes": [ + "sha256:44fbb57a12bc7478d56c223eb5de7b2fb98ce42a70314c74ffecf5dbe75ed1b8" + ], + "version": "==0.2.0" + }, + "flask-limiter": { + "hashes": [ + "sha256:473aa5bc97310406aa8c12ab3dc080697bcfa8cd21a6d0aba30916911bbc673c", + "sha256:8cce98dcf25bf2ddbb824c2b503b4fc8e1a139154240fd2c60d9306bad8a0db8" + ], + "version": "==1.0.1" + }, + "funcsigs": { + "hashes": [ + "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca", + "sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50" + ], + "markers": "python_version < '3.0'", + "version": "==1.0.2" + }, + "greenlet": { + "hashes": [ + "sha256:09ef2636ea35782364c830f07127d6c7a70542b178268714a9a9ba16318e7e8b", + "sha256:0fef83d43bf87a5196c91e73cb9772f945a4caaff91242766c5916d1dd1381e4", + "sha256:1b7df09c6598f5cfb40f843ade14ed1eb40596e75cd79b6fa2efc750ba01bb01", + "sha256:1fff21a2da5f9e03ddc5bd99131a6b8edf3d7f9d6bc29ba21784323d17806ed7", + "sha256:42118bf608e0288e35304b449a2d87e2ba77d1e373e8aa221ccdea073de026fa", + "sha256:50643fd6d54fd919f9a0a577c5f7b71f5d21f0959ab48767bd4bb73ae0839500", + "sha256:58798b5d30054bb4f6cf0f712f08e6092df23a718b69000786634a265e8911a9", + "sha256:5b49b3049697aeae17ef7bf21267e69972d9e04917658b4e788986ea5cc518e8", + "sha256:75c413551a436b462d5929255b6dc9c0c3c2b25cbeaee5271a56c7fda8ca49c0", + "sha256:769b740aeebd584cd59232be84fdcaf6270b8adc356596cdea5b2152c82caaac", + "sha256:ad2383d39f13534f3ca5c48fe1fc0975676846dc39c2cece78c0f1f9891418e0", + "sha256:b417bb7ff680d43e7bd7a13e2e08956fa6acb11fd432f74c97b7664f8bdb6ec1", + "sha256:b6ef0cabaf5a6ecb5ac122e689d25ba12433a90c7b067b12e5f28bdb7fb78254", + "sha256:c2de19c88bdb0366c976cc125dca1002ec1b346989d59524178adfd395e62421", + "sha256:c7b04a6dc74087b1598de8d713198de4718fa30ec6cbb84959b26426c198e041", + "sha256:f8f2a0ae8de0b49c7b5b2daca4f150fdd9c1173e854df2cce3b04123244f9f45", + "sha256:fcfadaf4bf68a27e5dc2f42cbb2f4b4ceea9f05d1d0b8f7787e640bed2801634" + ], + "version": "==0.4.13" + }, + "gunicorn": { + "hashes": [ + "sha256:75af03c99389535f218cc596c7de74df4763803f7b63eb09d77e92b3956b36c6", + "sha256:eee1169f0ca667be05db3351a0960765620dad53f53434262ff8901b68a1b622" + ], + "version": "==19.7.1" + }, + "httpbin": { + "hashes": [ + "sha256:0afa0486a76305cac441b5cc80d5d4ccd82b20875da7c5119ecfe616cefef45f", + "sha256:7c3a4d69f9d495e6df1d51a50ba7b1e4f33a1cb61e0db95ee7f8953e27a2243f" + ], + "version": "==0.6.2" + }, + "humanize": { + "hashes": [ + "sha256:a43f57115831ac7c70de098e6ac46ac13be00d69abbf60bdcac251344785bb19" + ], + "version": "==0.5.1" + }, + "idna": { + "hashes": [ + "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", + "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4" + ], + "version": "==2.6" + }, + "itsdangerous": { + "hashes": [ + "sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519" + ], + "version": "==0.24" + }, + "jinja2": { + "hashes": [ + "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", + "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" + ], + "version": "==2.10" + }, + "limits": { + "hashes": [ + "sha256:9df578f4161017d79f5188609f1d65f6b639f8aad2914c3960c9252e56a0ff95", + "sha256:a017b8d9e9da6761f4574642149c337f8f540d4edfe573fb91ad2c4001a2bc76" + ], + "version": "==1.3" + }, + "markupsafe": { + "hashes": [ + "sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665" + ], + "version": "==1.0" + }, + "maya": { + "hashes": [ + "sha256:ad1969bae78afb148c45a2f63591a7575ec05b4a0ab7ec04987ab7d73649f9d6", + "sha256:d8a7ed8513b2990036fe456c9f595b54d19ec49cb4461cd95a2ef6c487fb55eb" + ], + "version": "==0.3.4" + }, + "meinheld": { + "hashes": [ + "sha256:293eff4983b7fcbd9134b47706b22189883fe354993bd10163c65869d141e565", + "sha256:40d9dbce0165b2d9142f364d26fd6d59d3682f89d0dfe2117717a8ddad1f4133" + ], + "version": "==0.6.1" + }, + "pendulum": { + "hashes": [ + "sha256:0c14388546db6605a860b8b7112cb69d0b11c9ce5e072210504544e0d4575799", + "sha256:39a255776528afe11ea0d57814f9bf3729c1e0b99063af2e5c6cfd750c3e1f7f", + "sha256:3c85e8cbc91f45e1cc916cc9180b34153cd6aaaaacfb51a48b3156318314fa82", + "sha256:8199206c479b13947dcac63c025575d035331bb3819d1783dc1d568a11962906", + "sha256:8798aeca58b3dd7ffdc5a4993c9eaafedc4048165429e8f499ddd62c73bf3964", + "sha256:881efe37328de0785c0731d462e1485a45712f2cd5cb55907d6c15458460ebeb", + "sha256:bcca072f82e84b419efec1320cd3ee5c230d263f3a601b146651ed4db77d89f0", + "sha256:ff0c5fa3af4a471a218408c448b804ac6bccb105127727474f4e83c0e4072e97" + ], + "version": "==1.4.2" + }, + "pkginfo": { + "hashes": [ + "sha256:31a49103180ae1518b65d3f4ce09c784e2bc54e338197668b4fb7dc539521024", + "sha256:bb1a6aeabfc898f5df124e7e00303a5b3ec9a489535f346bfbddb081af93f89e" + ], + "version": "==1.4.1" + }, + "pluggy": { + "hashes": [ + "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff" + ], + "version": "==0.6.0" + }, + "py": { + "hashes": [ + "sha256:8cca5c229d225f8c1e3085be4fcf306090b00850fefad892f9d96c7b6e2f310f", + "sha256:ca18943e28235417756316bfada6cd96b23ce60dd532642690dcfdaba988a76d" + ], + "version": "==1.5.2" + }, + "pycparser": { + "hashes": [ + "sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226" + ], + "version": "==2.18" + }, + "pytest": { + "hashes": [ + "sha256:8970e25181e15ab14ae895599a0a0e0ade7d1f1c4c8ca1072ce16f25526a184d", + "sha256:9ddcb879c8cc859d2540204b5399011f842e5e8823674bf429f70ada281b3cc6" + ], + "version": "==3.4.1" + }, + "python-dateutil": { + "hashes": [ + "sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca", + "sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c" + ], + "version": "==2.6.1" + }, + "pytz": { + "hashes": [ + "sha256:07edfc3d4d2705a20a6e99d97f0c4b61c800b8232dc1c04d87e8554f130148dd", + "sha256:3a47ff71597f821cd84a162e71593004286e5be07a340fd462f0d33a760782b5", + "sha256:410bcd1d6409026fbaa65d9ed33bf6dd8b1e94a499e32168acfc7b332e4095c0", + "sha256:5bd55c744e6feaa4d599a6cbd8228b4f8f9ba96de2c38d56f08e534b3c9edf0d", + "sha256:61242a9abc626379574a166dc0e96a66cd7c3b27fc10868003fa210be4bff1c9", + "sha256:887ab5e5b32e4d0c86efddd3d055c1f363cbaa583beb8da5e22d2fa2f64d51ef", + "sha256:ba18e6a243b3625513d85239b3e49055a2f0318466e0b8a92b8fb8ca7ccdf55f", + "sha256:ed6509d9af298b7995d69a440e2822288f2eca1681b8cce37673dbb10091e5fe", + "sha256:f93ddcdd6342f94cea379c73cddb5724e0d6d0a1c91c9bdef364dc0368ba4fda" + ], + "version": "==2018.3" + }, + "pytzdata": { + "hashes": [ + "sha256:4e2cceb54335cd6c28caea46b15cd592e2aec5e8b05b0241cbccfb1b23c02ae7", + "sha256:7cd949123e2c2060fd12793de3a4a449e36b5dea5e169b810a3ac3f0b9877cfa" + ], + "version": "==2018.3" + }, + "raven": { + "hashes": [ + "sha256:738a52019d01955d5b44b49d67c9f2f4cedb1b4f70d4fb0b493931174d00e044", + "sha256:92bf4c4819472ed20f1b9905eeeafe1bc6fe5f273d7c14506fdb8fb3a6ab2074" + ], + "version": "==6.6.0" + }, + "regex": { + "hashes": [ + "sha256:1b428a296531ea1642a7da48562746309c5c06471a97bd0c02dd6a82e9cecee8", + "sha256:27d72bb42dffb32516c28d218bb054ce128afd3e18464f30837166346758af67", + "sha256:32cf4743debee9ea12d3626ee21eae83052763740e04086304e7a74778bf58c9", + "sha256:32f6408dbca35040bc65f9f4ae1444d5546411fde989cb71443a182dd643305e", + "sha256:333687d9a44738c486735955993f83bd22061a416c48f5a5f9e765e90cf1b0c9", + "sha256:35eeccf17af3b017a54d754e160af597036435c58eceae60f1dd1364ae1250c7", + "sha256:361a1fd703a35580a4714ec28d85e29780081a4c399a99bbfb2aee695d72aedb", + "sha256:494bed6396a20d3aa6376bdf2d3fbb1005b8f4339558d8ac7b53256755f80303", + "sha256:5b9c0ddd5b4afa08c9074170a2ea9b34ea296e32aeea522faaaaeeeb2fe0af2e", + "sha256:a50532f61b23d4ab9d216a6214f359dd05c911c1a1ad20986b6738a782926c1a", + "sha256:a9243d7b359b72c681a2c32eaa7ace8d346b7e8ce09d172a683acf6853161d9c", + "sha256:b44624a38d07d3c954c84ad302c29f7930f4bf01443beef5589e9157b14e2a29", + "sha256:be42a601aaaeb7a317f818490a39d153952a97c40c6e9beeb2a1103616405348", + "sha256:eee4d94b1a626490fc8170ffd788883f8c641b576e11ba9b4a29c9f6623371e0", + "sha256:f69d1201a4750f763971ea8364ed95ee888fc128968b39d38883a72a4d005895" + ], + "version": "==2018.2.21" + }, + "requests": { + "hashes": [ + "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b", + "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e" + ], + "version": "==2.18.4" + }, + "requests-toolbelt": { + "hashes": [ + "sha256:42c9c170abc2cacb78b8ab23ac957945c7716249206f90874651971a4acff237", + "sha256:f6a531936c6fa4c6cfce1b9c10d5c4f498d16528d2a54a22ca00011205a187b5" + ], + "version": "==0.8.0" + }, + "ruamel.yaml": { + "hashes": [ + "sha256:01e30ecb1b1c0ebf9fce814dc20dace402571517277799291202b61b22096c24", + "sha256:02babffd019911841ba01b76e23dfec7c9e9b2725503fb2698c4982fa1a6e835", + "sha256:072f6364a89972e8dc0afdce3335a709d5464dfeaa4f736d092a54574338b874", + "sha256:14d161558e3bf89e87d77c218098be22fa9a0d6d0bea40250fce525b1d0cbee2", + "sha256:5504398fc755a2b14c9983b2101161a8591a4b30812590cc1c365e7fcc117dfa", + "sha256:68c8f2986bcb91b6db1aea8698941769840c7257e951a9377048f7eff35be773", + "sha256:6d05c5a5baf829c70916c226ef3200650846a7227de226bca8a59efaf88bb973", + "sha256:6d7929b24e329d662fa43b657fddfee5260e2d35d0a543065cd755d4e17a9b2f", + "sha256:8dc74821e4bb6b21fb1ab35964e159391d99ee44981d07d57bf96e2395f3ef75", + "sha256:9225c83952d28f302cfc23c3d9a6f8231bfd581476d7aff1e3c7de49eecb4ee9", + "sha256:b6c5d5f03ba78e3f27c7188a00c4e09b6a4507fe3154ba40a294e09cb30ee016", + "sha256:c0908896e34b617ead40552cab03c1769bdc43d1da02419160dc900c5dfddde2", + "sha256:c41e04b526d0153c9246cfab87d7ddefdc9f165cb8886a8ec48ba7a2b73069f6", + "sha256:e2d2715bf92156bec5fb42e92e95dac1c4d9904f8a3d4e2d0c438758fe9092d7", + "sha256:e3bbfe0d294e08fdbb0cb05485435a2ceb4e168e98b5dc611f051c1864986b4b", + "sha256:f2d02a4af5a13b09d0b823cdd0317b54f3e0115e50b5ac4d9840c3a1b566817f", + "sha256:fcfc24a21594c071cc4588e84b7657a1f47ebcf6037c6c43fa15c4bbd3989ec2" + ], + "version": "==0.15.35" + }, + "six": { + "hashes": [ + "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", + "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" + ], + "version": "==1.11.0" + }, + "tqdm": { + "hashes": [ + "sha256:5ec0d4442358e55cdb4a0471d04c6c831518fd8837f259db5537d90feab380df", + "sha256:f66468c14ccd011a627734c9b3fd72f20ce16f8faecc47384eb2507af5924fb9" + ], + "version": "==4.19.6" + }, + "twine": { + "hashes": [ + "sha256:caa45b7987fc96321258cd7668e3be2ff34064f5c66d2d975b641adca659c1ab", + "sha256:d3ce5c480c22ccfb761cd358526e862b32546d2fe4bc93d46b5cf04ea3cc46ca" + ], + "version": "==1.9.1" + }, + "tzlocal": { + "hashes": [ + "sha256:4ebeb848845ac898da6519b9b31879cf13b6626f7184c496037b818e238f2c4e" + ], + "version": "==1.5.1" + }, + "urllib3": { + "hashes": [ + "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b", + "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" + ], + "version": "==1.22" + }, + "werkzeug": { + "hashes": [ + "sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c", + "sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b" + ], + "version": "==0.14.1" + }, + "whitenoise": { + "hashes": [ + "sha256:15f43b2e701821b95c9016cf469d29e2a546cb1c7dead584ba82c36f843995cf", + "sha256:9d81515f2b5b27051910996e1e860b1332e354d9e7bcf30c98f21dcb6713e0dd" + ], + "version": "==3.3.1" + } + } +} diff --git a/tests/pytest-pypi/README.md b/tests/pytest-pypi/README.md new file mode 100644 index 00000000..cb830b04 --- /dev/null +++ b/tests/pytest-pypi/README.md @@ -0,0 +1,194 @@ +# pytest-httpbin + +[![Build Status](https://travis-ci.org/kevin1024/pytest-httpbin.svg?branch=master)](https://travis-ci.org/kevin1024/pytest-httpbin) + +[httpbin](https://httpbin.org/) is an amazing web service for testing HTTP libraries. It has several great endpoints that can test pretty much everything you need in a HTTP library. The only problem is: maybe you don't want to wait for your tests to travel across the Internet and back to make assertions against a remote web service (speed), and maybe you want to work offline (convenience). + +Enter **pytest-httpbin**. Pytest-httpbin creates a [pytest fixture](http://pytest.org/latest/fixture.html) that is dependency-injected into your tests. It automatically starts up a HTTP server in a separate thread running httpbin and provides your test with the URL in the fixture. Check out this example: + +```python +def test_that_my_library_works_kinda_ok(httpbin): + assert requests.get(httpbin.url + '/get').status_code == 200 +``` + +This replaces a test that might have looked like this before: + +```python +def test_that_my_library_works_kinda_ok(): + assert requests.get('http://httpbin.org/get').status_code == 200 +``` + +If you're making a lot of requests to httpbin, it can radically speed up your tests. + +![demo](http://i.imgur.com/heNOQLP.gif) + + +# HTTPS support + +pytest-httpbin also supports HTTPS: + +```python +def test_that_my_library_works_kinda_ok(httpbin_secure): + assert requests.get(httpbin_secure.url + '/get/').status_code == 200 +``` + +It's actually starting 2 web servers in separate threads in the background: one HTTP and one HTTPS. The servers are started on a random port (see below for fixed port support), on the loopback interface on your machine. Pytest-httpbin includes a self-signed certificate. If your library verifies certificates against a CA (and it should), you'll have to add the CA from pytest-httpbin. The path to the pytest-httpbin CA bundle can by found like this `python -m pytest_httpbin.certs`. + +For example in requests, you can set the `REQUESTS_CA_BUNDLE` python path. You can run your tests like this: + +```bash +REQUESTS_CA_BUNDLE=`python -m pytest_httpbin.certs` py.test tests/ +``` + +# API of the injected object + +The injected object has the following attributes: + + * url + * port + * host + +and the following methods: + + * join(string): Returns the results of calling `urlparse.urljoin` with the url from the injected server automatically applied as the first argument. You supply the second argument + +Also, I defined `__add__` on the object to append to `httpbin.url`. This means you can do stuff like `httpbin + '/get'` instead of `httpbin.url + '/get'`. + +## Testing both HTTP and HTTPS endpoints with one test + +If you ever find yourself needing to test both the http and https version of and endpoint, you can use the `httpbin_both` funcarg like this: + + +```python +def test_that_my_library_works_kinda_ok(httpbin_both): + assert requests.get(httpbin_both.url + '/get/').status_code == 200 +``` + +Through the magic of pytest parametrization, this function will actually execute twice: once with an http url and once with an https url. + +## Using pytest-httpbin with unittest-style test cases + +I have provided 2 additional fixtures to make testing with class-based tests easier. I have also provided a couple decorators that provide some syntactic sugar around the pytest method of adding the fixtures to class-based tests. Just add the `use_class_based_httpbin` and/or `use_class_based_httpbin_secure` class decorators to your class, and then you can access httpbin using self.httpbin and self.httpbin_secure. + +```python +import pytest_httpbin + +@pytest_httpbin.use_class_based_httpbin +@pytest_httpbin.use_class_based_httpbin_secure +class TestClassBassedTests(unittest.TestCase): + def test_http(self): + assert requests.get(self.httpbin.url + '/get').response + + def test_http_secure(self): + assert requests.get(self.httpbin_secure.url + '/get').response +``` + +## Running the server on fixed port + +Sometimes a randomized port can be a problem. Worry not, you can fix the port number to a desired value with the `HTTPBIN_HTTP_PORT` and `HTTPBIN_HTTPS_PORT` environment variables. If those are defined during pytest plugins are loaded, `httbin` and `httpbin_secure` fixtures will run on given ports. You can run your tests like this: + +```bash +HTTPBIN_HTTP_PORT=8080 HTTPBIN_HTTPS_PORT=8443 py.test tests/ +``` + +## Installation + +All you need to do is this: + +```bash +pip install pytest-httpbin +``` + +and your tests executed by pytest all will have access to the `httpbin` and `httpbin_secure` funcargs. Cool right? + +## Support and dependencies + +pytest-httpbin suports Python 2.6, 2.7, 3.4, and pypy. It will automatically install httpbin and flask when you install it from pypi. + +[httpbin](https://github.com/kennethreitz/httpbin) itself does not support python 2.6 as of version 0.6.0, when the Flask-common dependency was added. If you need python 2.6 support pin the httpbin version to 0.5.0 + +## Running the pytest-httpbin test suite + +If you want to run pytest-httpbin's test suite, you'll need to install requests and pytest, and then use the ./runtests.sh script. + +```bash +pip install pytest +/.runtests.sh +``` + +Also, you can use tox to run the tests on all supported python versions: + +```bash +pip install tox +tox +``` + +## Changelog + +* 0.3.0 + * Allow to run httpbin on fixed port using environment variables (thanks @hroncok) + * Allow server to be thread.join()ed (thanks @graingert) + * Add support for Python 3.6 (thanks @graingert) +* 0.2.3: + * Another attempt to fix #32 (Rare bug, only happens on Travis) +* 0.2.2: + * Fix bug with python3 +* 0.2.1: + * Attempt to fix strange, impossible-to-reproduce bug with broken SSL certs + that only happens on Travis (#32) [Bad release, breaks py3] +* 0.2.0: + * Remove threaded HTTP server. I built it for Requests, but they deleted + their threaded test since it didn't really work very well. The threaded + server seems to cause some strange problems with HTTP chunking, so I'll + just remove it since nobody is using it (I hope) +* 0.1.1: + * Fix weird hang with SSL on pypy (again) +* 0.1.0: + * Update server to use multithreaded werkzeug server +* 0.0.7: + * Update the certificates (they expired) +* 0.0.6: + * Fix an issue where pypy was hanging when a request was made with an invalid + certificate +* 0.0.5: + * Fix broken version parsing in 0.0.4 +* 0.0.4: + * **Bad release: Broken version parsing** + * Fix `BadStatusLine` error that occurs when sending multiple requests + in a single session (PR #16). Thanks @msabramo! + * Fix #9 ("Can't be installed at the same time than pytest?") (PR + #14). Thanks @msabramo! + * Add `httpbin_ca_bundle` pytest fixture. With this fixture there is + no need to specify the bundle on every request, as it will + automatically set `REQUESTS_CA_BUNDLE` if using + [requests](http://docs.python-requests.org/). And you don't have to + care about where it is located (PR #8). Thanks @t-8ch! +* 0.0.3: Add a couple test fixtures to make testing old class-based test suites + easier +* 0.0.2: Fixed a couple bugs with the wsgiref server to bring behavior in line + with httpbin.org, thanks @jakubroztocil for the bug reports +* 0.0.1: Initial release + +## License + +The MIT License (MIT) + +Copyright (c) 2014-2015 Kevin McCarthy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tests/pytest-pypi/pypi/requests/requests-2.18.4-py2.py3-none-any.whl b/tests/pytest-pypi/pypi/requests/requests-2.18.4-py2.py3-none-any.whl new file mode 100644 index 00000000..cf3bdc07 Binary files /dev/null and b/tests/pytest-pypi/pypi/requests/requests-2.18.4-py2.py3-none-any.whl differ diff --git a/tests/pytest-pypi/pypi/requests/requests-2.18.4.tar.gz b/tests/pytest-pypi/pypi/requests/requests-2.18.4.tar.gz new file mode 100644 index 00000000..fce54795 Binary files /dev/null and b/tests/pytest-pypi/pypi/requests/requests-2.18.4.tar.gz differ diff --git a/tests/pytest-pypi/pytest_pypi.egg-info/PKG-INFO b/tests/pytest-pypi/pytest_pypi.egg-info/PKG-INFO new file mode 100644 index 00000000..966cd7ad --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi.egg-info/PKG-INFO @@ -0,0 +1,54 @@ +Metadata-Version: 1.1 +Name: pytest-pypi +Version: 0.1.1 +Summary: Easily test your HTTP library against a local copy of pypi +Home-page: https://github.com/kennethreitz/pytest-pypi +Author: Kenneth Reitz +Author-email: me@kennethreitz.org +License: MIT +Description-Content-Type: UNKNOWN +Description: pytest-httpbin + ============== + + httpbin is an amazing web service for testing HTTP libraries. It has several + great endpoints that can test pretty much everything you need in a HTTP + library. The only problem is: maybe you don't want to wait for your tests to + travel across the Internet and back to make assertions against a remote web + service. + + Enter pytest-httpbin. Pytest-httpbin creates a pytest "fixture" that is + dependency-injected into your tests. It automatically starts up a HTTP server + in a separate thread running httpbin and provides your test with the URL in the + fixture. Check out this example: + + .. code-block:: python + + def test_that_my_library_works_kinda_ok(httpbin): + assert requests.get(httpbin.url + '/get/').status_code == 200 + + This replaces a test that might have looked like this before: + + .. code-block:: python + + def test_that_my_library_works_kinda_ok(): + assert requests.get('http://httpbin.org/get').status_code == 200 + + pytest-httpbin also supports https and includes its own CA cert you can use. + Check out `the full documentation`_ on the github page. + + .. _the full documentation: https://github.com/kevin1024/pytest-httpbin + +Keywords: pytest-pypi testing pytest pypi +Platform: UNKNOWN +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Testing +Classifier: Topic :: Software Development :: Libraries +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 diff --git a/tests/pytest-pypi/pytest_pypi.egg-info/SOURCES.txt b/tests/pytest-pypi/pytest_pypi.egg-info/SOURCES.txt new file mode 100644 index 00000000..6725abbc --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi.egg-info/SOURCES.txt @@ -0,0 +1,17 @@ +DESCRIPTION.rst +MANIFEST.in +README.md +setup.cfg +setup.py +pytest_pypi/__init__.py +pytest_pypi/app.py +pytest_pypi/certs.py +pytest_pypi/plugin.py +pytest_pypi/serve.py +pytest_pypi/version.py +pytest_pypi.egg-info/PKG-INFO +pytest_pypi.egg-info/SOURCES.txt +pytest_pypi.egg-info/dependency_links.txt +pytest_pypi.egg-info/entry_points.txt +pytest_pypi.egg-info/requires.txt +pytest_pypi.egg-info/top_level.txt \ No newline at end of file diff --git a/tests/pytest-pypi/pytest_pypi.egg-info/dependency_links.txt b/tests/pytest-pypi/pytest_pypi.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/tests/pytest-pypi/pytest_pypi.egg-info/entry_points.txt b/tests/pytest-pypi/pytest_pypi.egg-info/entry_points.txt new file mode 100644 index 00000000..d0bfd64f --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi.egg-info/entry_points.txt @@ -0,0 +1,3 @@ +[pytest11] +pypi = pytest_pypi.plugin + diff --git a/tests/pytest-pypi/pytest_pypi.egg-info/requires.txt b/tests/pytest-pypi/pytest_pypi.egg-info/requires.txt new file mode 100644 index 00000000..53cec2f9 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi.egg-info/requires.txt @@ -0,0 +1,2 @@ +Flask +six diff --git a/tests/pytest-pypi/pytest_pypi.egg-info/top_level.txt b/tests/pytest-pypi/pytest_pypi.egg-info/top_level.txt new file mode 100644 index 00000000..81f34cb5 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi.egg-info/top_level.txt @@ -0,0 +1 @@ +pytest_pypi diff --git a/tests/pytest-pypi/pytest_pypi/__init__.py b/tests/pytest-pypi/pytest_pypi/__init__.py new file mode 100644 index 00000000..7f566e86 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/__init__.py @@ -0,0 +1,14 @@ +import os + +import pytest + + +here = os.path.dirname(__file__) +version_file = os.path.join(here, "version.py") + +with open(version_file) as f: + code = compile(f.read(), version_file, 'exec') + exec(code) + +use_class_based_httpbin = pytest.mark.usefixtures("class_based_pypi") +use_class_based_httpbin_secure = pytest.mark.usefixtures("class_based_pypi_secure") diff --git a/tests/pytest-pypi/pytest_pypi/app.py b/tests/pytest-pypi/pytest_pypi/app.py new file mode 100644 index 00000000..445e1f96 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/app.py @@ -0,0 +1,76 @@ +import os +from flask import Flask, redirect, abort, render_template, send_file + +PYPI_VENDOR_DIR = os.environ.get('PYPI_VENDOR_DIR', './pypi') +PYPI_VENDOR_DIR = os.path.abspath(PYPI_VENDOR_DIR) + +app = Flask(__name__) + +packages = {} + + +class Package(object): + """docstring for Package""" + + def __init__(self, name): + super(Package, self).__init__() + self.name = name + self._releases = [] + + @property + def releases(self): + r = [] + for release in self._releases: + release = release[len(PYPI_VENDOR_DIR):] + r.append(release) + return r + + def __repr__(self): + return "/') +def simple_package(package): + if package in packages: + return render_template('package.html', package=packages[package]) + else: + abort(404) + +@app.route('//') +def serve_package(package, release): + if package in packages: + package = packages[package] + + for _release in package.releases: + if _release.endswith(release): + return send_file(os.path.sep.join([PYPI_VENDOR_DIR, _release])) + + abort(404) + +if __name__ == '__main__': + app.run() \ No newline at end of file diff --git a/tests/pytest-pypi/pytest_pypi/certs.py b/tests/pytest-pypi/pytest_pypi/certs.py new file mode 100644 index 00000000..c099cfa2 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/certs.py @@ -0,0 +1,21 @@ +""" +certs.py +~~~~~~~~ + +This module returns the preferred default CA certificate bundle. + +If you are packaging pytest-httpbin, e.g., for a Linux distribution or a +managed environment, you can change the definition of where() to return a +separately packaged CA bundle. +""" + +import os.path + + +def where(): + """Return the preferred certificate bundle.""" + # vendored bundle inside Requests + return os.path.join(os.path.dirname(__file__), 'certs', 'cacert.pem') + +if __name__ == '__main__': + print(where()) diff --git a/tests/pytest-pypi/pytest_pypi/certs/cacert.pem b/tests/pytest-pypi/pytest_pypi/certs/cacert.pem new file mode 100644 index 00000000..d9a47aad --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/certs/cacert.pem @@ -0,0 +1,63 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + dd:39:30:16:60:55:90:7c + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Hawaii, O=kevin1024, CN=pytest-httpbin Certificate Authority + Validity + Not Before: Jun 26 18:16:59 2015 GMT + Not After : Jun 18 18:16:59 2045 GMT + Subject: C=US, ST=Hawaii, O=kevin1024, CN=pytest-httpbin Certificate Authority + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:bd:80:fd:e4:96:0e:3b:5e:35:9b:83:00:34:88: + 64:5a:50:53:0e:1d:94:76:c9:dc:e7:b5:59:1e:d4: + 82:55:36:a6:b4:41:2c:60:ad:76:f0:cd:42:a0:0f: + 4a:1c:0d:d7:29:da:c3:d9:c0:ea:f1:48:e0:66:4d: + 4b:7c:ff:d6:5e:e0:73:89:53:8b:6e:6c:57:7d:bd: + e9:d0:46:39:5d:85:a5:f1:3a:d4:3d:83:19:03:44: + 93:71:2c:5e:d7:61:8e:db:cc:80:d0:f1:c0:47:bf: + 98:8f:06:40:e1:f7:41:ee:ed:a7:57:0d:a6:4c:26: + 75:8e:f1:78:d3:80:ad:9c:e9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + AE:05:EF:BD:A9:CE:BB:A6:D8:0E:EB:C4:8C:72:2F:13:E5:CD:AA:CA + X509v3 Authority Key Identifier: + keyid:AE:05:EF:BD:A9:CE:BB:A6:D8:0E:EB:C4:8C:72:2F:13:E5:CD:AA:CA + DirName:/C=US/ST=Hawaii/O=kevin1024/CN=pytest-httpbin Certificate Authority + serial:DD:39:30:16:60:55:90:7C + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha1WithRSAEncryption + bc:0c:b4:21:03:bf:35:bf:88:9f:de:06:23:f4:e3:8f:bc:34: + b5:8b:af:bf:31:5d:17:44:2c:72:c9:88:25:d1:c7:d0:1c:70: + 06:82:a5:fa:fa:d7:b9:16:64:c2:08:54:1e:4c:93:9f:22:4e: + e5:4f:a7:71:e5:6e:14:31:e9:41:e2:33:23:8b:c8:01:c3:2a: + 66:a8:d8:df:ef:ee:7b:bb:84:f4:78:a6:ca:8f:29:aa:d5:fa: + 8a:73:94:0c:32:53:c8:93:bd:fc:c4:60:4d:9a:80:4f:c6:d4: + 27:44:a2:37:63:6c:97:04:ce:e3:6a:6f:d3:84:0d:b4:74:1f: + 49:eb +-----BEGIN CERTIFICATE----- +MIIDBzCCAnCgAwIBAgIJAN05MBZgVZB8MA0GCSqGSIb3DQEBBQUAMGExCzAJBgNV +BAYTAlVTMQ8wDQYDVQQIEwZIYXdhaWkxEjAQBgNVBAoTCWtldmluMTAyNDEtMCsG +A1UEAxMkcHl0ZXN0LWh0dHBiaW4gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE1 +MDYyNjE4MTY1OVoXDTQ1MDYxODE4MTY1OVowYTELMAkGA1UEBhMCVVMxDzANBgNV +BAgTBkhhd2FpaTESMBAGA1UEChMJa2V2aW4xMDI0MS0wKwYDVQQDEyRweXRlc3Qt +aHR0cGJpbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBAL2A/eSWDjteNZuDADSIZFpQUw4dlHbJ3Oe1WR7UglU2prRBLGCt +dvDNQqAPShwN1ynaw9nA6vFI4GZNS3z/1l7gc4lTi25sV3296dBGOV2FpfE61D2D +GQNEk3EsXtdhjtvMgNDxwEe/mI8GQOH3Qe7tp1cNpkwmdY7xeNOArZzpAgMBAAGj +gcYwgcMwHQYDVR0OBBYEFK4F772pzrum2A7rxIxyLxPlzarKMIGTBgNVHSMEgYsw +gYiAFK4F772pzrum2A7rxIxyLxPlzarKoWWkYzBhMQswCQYDVQQGEwJVUzEPMA0G +A1UECBMGSGF3YWlpMRIwEAYDVQQKEwlrZXZpbjEwMjQxLTArBgNVBAMTJHB5dGVz +dC1odHRwYmluIENlcnRpZmljYXRlIEF1dGhvcml0eYIJAN05MBZgVZB8MAwGA1Ud +EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAvAy0IQO/Nb+In94GI/Tjj7w0tYuv +vzFdF0QscsmIJdHH0BxwBoKl+vrXuRZkwghUHkyTnyJO5U+nceVuFDHpQeIzI4vI +AcMqZqjY3+/ue7uE9Himyo8pqtX6inOUDDJTyJO9/MRgTZqAT8bUJ0SiN2NslwTO +42pv04QNtHQfSes= +-----END CERTIFICATE----- diff --git a/tests/pytest-pypi/pytest_pypi/certs/cert.pem b/tests/pytest-pypi/pytest_pypi/certs/cert.pem new file mode 100644 index 00000000..5d4452b9 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/certs/cert.pem @@ -0,0 +1,73 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + dd:39:30:16:60:55:90:7e + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Hawaii, O=kevin1024, CN=pytest-httpbin Certificate Authority + Validity + Not Before: Jun 26 18:20:35 2015 GMT + Not After : Jun 23 18:20:35 2025 GMT + Subject: C=US, ST=Hawaii, O=kevin1024, OU=kevin1024, CN=127.0.0.1 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:b4:0f:0b:86:17:68:24:6f:7c:25:32:73:81: + bd:55:38:05:ae:09:29:00:c0:f1:99:30:5a:7f:05: + 9f:e7:e9:d3:ce:d0:dd:4f:73:c8:bf:65:04:94:e5: + 11:8e:1d:91:f0:88:85:3e:48:d3:09:5b:3f:8f:97: + 95:34:bf:8d:00:cb:70:d2:c1:2b:34:dd:99:1d:86: + 9b:90:54:a5:de:18:c4:03:3d:53:f0:dd:cc:6d:ec: + fb:b9:93:ab:19:85:05:63:2d:34:a6:47:42:71:3b: + e4:1e:4a:4c:d9:60:d4:6b:d6:51:a8:4a:30:70:2e: + 6c:62:a2:34:da:cf:30:34:97:a4:9d:17:72:0b:b2: + 37:69:e2:ca:b6:d5:9f:46:c5:eb:cf:dc:46:b0:fe: + ef:37:5e:4f:eb:f3:50:4d:2c:4e:c2:0c:e4:0c:63: + c2:d8:ab:a3:d6:a0:12:bf:d6:fc:3f:b6:4c:dc:2b: + 9b:c5:ae:83:4d:3b:3c:19:85:50:88:82:a2:5f:ff: + de:98:60:fc:12:3a:55:c3:4f:0a:e9:1f:aa:12:cb: + f8:ce:14:d6:ed:89:ff:c7:ea:3b:fe:97:87:54:eb: + 62:de:cd:ef:6b:e2:9e:47:82:77:55:59:4f:b8:ad: + 1b:e0:9d:1a:28:16:9f:6a:cb:b2:44:f9:65:c3:c4: + 03:09 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 1E:28:41:6B:12:03:41:29:64:0D:E5:C3:E3:F7:9E:82:0C:66:1E:B9 + X509v3 Authority Key Identifier: + keyid:AE:05:EF:BD:A9:CE:BB:A6:D8:0E:EB:C4:8C:72:2F:13:E5:CD:AA:CA + + Signature Algorithm: sha1WithRSAEncryption + 67:8c:6d:a1:2f:b3:35:87:a3:c0:04:92:5d:8a:8b:f8:51:6e: + 94:88:59:ed:66:b2:54:b0:a2:3d:7a:05:ee:19:17:a6:0b:3b: + 20:f7:d2:73:2c:f0:b9:ad:2e:5d:45:11:5d:8d:33:5c:69:7f: + 4a:c5:8c:10:3e:35:b4:39:d7:52:66:bc:02:d8:4d:d0:ba:a1: + ae:55:f5:36:01:17:97:40:1a:9d:6a:e0:b8:33:be:2d:98:b7: + 5b:92:6a:77:a7:d9:f5:5b:a4:5f:fa:aa:5b:c1:6b:4d:0c:b7: + 5a:4c:47:b2:f7:90:a3:ff:6f:8c:fd:f2:60:38:53:29:71:48: + d7:69 +-----BEGIN CERTIFICATE----- +MIIDODCCAqGgAwIBAgIJAN05MBZgVZB+MA0GCSqGSIb3DQEBBQUAMGExCzAJBgNV +BAYTAlVTMQ8wDQYDVQQIEwZIYXdhaWkxEjAQBgNVBAoTCWtldmluMTAyNDEtMCsG +A1UEAxMkcHl0ZXN0LWh0dHBiaW4gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE1 +MDYyNjE4MjAzNVoXDTI1MDYyMzE4MjAzNVowWjELMAkGA1UEBhMCVVMxDzANBgNV +BAgTBkhhd2FpaTESMBAGA1UEChMJa2V2aW4xMDI0MRIwEAYDVQQLEwlrZXZpbjEw +MjQxEjAQBgNVBAMTCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAM60DwuGF2gkb3wlMnOBvVU4Ba4JKQDA8ZkwWn8Fn+fp087Q3U9zyL9l +BJTlEY4dkfCIhT5I0wlbP4+XlTS/jQDLcNLBKzTdmR2Gm5BUpd4YxAM9U/DdzG3s ++7mTqxmFBWMtNKZHQnE75B5KTNlg1GvWUahKMHAubGKiNNrPMDSXpJ0XcguyN2ni +yrbVn0bF68/cRrD+7zdeT+vzUE0sTsIM5Axjwtiro9agEr/W/D+2TNwrm8Wug007 +PBmFUIiCol//3phg/BI6VcNPCukfqhLL+M4U1u2J/8fqO/6Xh1TrYt7N72vinkeC +d1VZT7itG+CdGigWn2rLskT5ZcPEAwkCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg +hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O +BBYEFB4oQWsSA0EpZA3lw+P3noIMZh65MB8GA1UdIwQYMBaAFK4F772pzrum2A7r +xIxyLxPlzarKMA0GCSqGSIb3DQEBBQUAA4GBAGeMbaEvszWHo8AEkl2Ki/hRbpSI +We1mslSwoj16Be4ZF6YLOyD30nMs8LmtLl1FEV2NM1xpf0rFjBA+NbQ511JmvALY +TdC6oa5V9TYBF5dAGp1q4Lgzvi2Yt1uSanen2fVbpF/6qlvBa00Mt1pMR7L3kKP/ +b4z98mA4UylxSNdp +-----END CERTIFICATE----- diff --git a/tests/pytest-pypi/pytest_pypi/certs/key.pem b/tests/pytest-pypi/pytest_pypi/certs/key.pem new file mode 100644 index 00000000..041c4b6d --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/certs/key.pem @@ -0,0 +1,28 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAzrQPC4YXaCRvfCUyc4G9VTgFrgkpAMDxmTBafwWf5+nTztDd +T3PIv2UElOURjh2R8IiFPkjTCVs/j5eVNL+NAMtw0sErNN2ZHYabkFSl3hjEAz1T +8N3Mbez7uZOrGYUFYy00pkdCcTvkHkpM2WDUa9ZRqEowcC5sYqI02s8wNJeknRdy +C7I3aeLKttWfRsXrz9xGsP7vN15P6/NQTSxOwgzkDGPC2Kuj1qASv9b8P7ZM3Cub +xa6DTTs8GYVQiIKiX//emGD8EjpVw08K6R+qEsv4zhTW7Yn/x+o7/peHVOti3s3v +a+KeR4J3VVlPuK0b4J0aKBafasuyRPllw8QDCQIDAQABAoIBAQCJ//iTbwCtjLXJ +omPebd3jyTUxjfgMAsTJy1h/uVea06ePSi6W3uxFq8G1ToG76c4HUn3yqVgLxRnY +WhFJWCFhSHGYo1KfRtr0tWuinoDmmI40w3sJMmtLcI5WxVnT/dUs839VC/o18xBH +kL9h2Z24KSv3OSDBpJzD9Rtogi7izK8DSQoANBMDEmPPJ5UJBLPjdZn04i6BYZCM +U/+ZADHKXbq6I+7RAcbPJbkvrbBEP234KZvIdw1eIAIZufQBQuDhnwS0Fi9iY/EP +awoYa9HLgFjh+iprhwh+2SDyIp8DA+4HrY1tXAyzCqjgLn/X8wifOUrZECYj1i65 +EOiryxMBAoGBAPjmvIwBRxnr1OsKX3gCFoZr+Zu5RjACD9IOSV17cv7glZQVfXBR +REDBoL7CmZrhsW4zBK0YWz30Dx7TGBniTFJ3e8IZJ7Th8PSOhIRYWqqFQ78YBHFi +VcpPOBswy1i8BM9FE0GyF1zusmz8Ak2hFr/IHVkIqHwWvkTI6gGhbJ2RAoGBANSZ +OqEWJKbRX9nuRqSdROqLOtUgWXZ78yvcQaaifyZHEFSKZZjc5MXT96lVd1PyGGAY +uyjAqdd5LiwsS9Rw1cuC5fix2ihH5KFq7EnEJA/zdy91YdO6xmAyBOtjuTHsNj93 +if4ilib290/mRKXeI1zpzzWHsvL9Az5spqlkljH5AoGAfln7ewMnCfSbCJoibrR4 +pNJpSvEZvUM+rr6L5cXGUbbGl/70x7CpekoRBOWavnI19SA3Dnvfzap4hohYosMr +RW3cSGMmsf9Ep5E1mk2T8R5njrltf/WQYXwnmj4B7FC+DE4fgWkbzRRrRUIFFU1i +VAcNRuZLSXruKdLoX92HWtECgYEAhpTlf3n0A8JBKkVjZOvF56/xs19CIvY+LsLE +sIbndMTBurLNs+IJ1I3llsVqv7Je6d5eBGNKYQPuTbpQ2o//V1Bq4m88CgnQ2rpE +EEJhDdPy3BEzt4Ph9p1Tbet4HflJMg4rRbyBTvNCBctgI5wmyLeeG2Xmy1mNhyPi +sRLi3YkCgYEAiHMsniJc1gZBevjtnqGTPdUo0syAnkZ7RUk/Piur/c0Altkgu5vK +I7p3DbkHBAMDjpAZs1kpfmR4sTYKke+IQDxj2pOZEyYnmQxlGdy8xxoE9dWQeDeg +Le+R83OAKjU4LHpH7hhJMR8X60MJaWC1BDACFO35kqIzvtCYxgEoOiI= +-----END RSA PRIVATE KEY----- + diff --git a/tests/pytest-pypi/pytest_pypi/plugin.py b/tests/pytest-pypi/pytest_pypi/plugin.py new file mode 100644 index 00000000..a17fcb24 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/plugin.py @@ -0,0 +1,41 @@ +from __future__ import absolute_import +import pytest +from .app import app as pypi_app +from . import serve, certs + +@pytest.fixture(scope='session') +def pypi(request): + server = serve.Server(application=pypi_app) + server.start() + request.addfinalizer(server.stop) + return server + + +@pytest.fixture(scope='session') +def pypi_secure(request): + server = serve.SecureServer(application=pypi_app) + server.start() + request.addfinalizer(server.stop) + return server + + +@pytest.fixture(scope='session', params=['http', 'https']) +def pypi_both(request, pypi, pypi_secure): + if request.param == 'http': + return pypi + elif request.param == 'https': + return pypi_secure + + +@pytest.fixture(scope='class') +def class_based_pypi(request, pypi): + request.cls.pypi = pypi + +@pytest.fixture(scope='class') +def class_based_pypi_secure(request, pypi_secure): + request.cls.pypi_secure = pypi_secure + + +@pytest.fixture(scope='function') +def pypi_ca_bundle(monkeypatch): + monkeypatch.setenv('REQUESTS_CA_BUNDLE', certs.where()) diff --git a/tests/pytest-pypi/pytest_pypi/serve.py b/tests/pytest-pypi/pytest_pypi/serve.py new file mode 100644 index 00000000..07a92dc0 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/serve.py @@ -0,0 +1,134 @@ +import os +import threading +import ssl +from wsgiref.simple_server import WSGIServer, make_server, WSGIRequestHandler +from wsgiref.handlers import SimpleHandler +from six.moves.urllib.parse import urljoin + + +CERT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'certs') + + +class ServerHandler(SimpleHandler): + + server_software = 'Pytest-HTTPBIN/0.1.0' + http_version = '1.1' + + def cleanup_headers(self): + SimpleHandler.cleanup_headers(self) + self.headers['Connection'] = 'Close' + + def close(self): + try: + self.request_handler.log_request( + self.status.split(' ', 1)[0], self.bytes_sent + ) + finally: + SimpleHandler.close(self) + + +class Handler(WSGIRequestHandler): + + def handle(self): + """Handle a single HTTP request""" + + self.raw_requestline = self.rfile.readline() + if not self.parse_request(): # An error code has been sent, just exit + return + + handler = ServerHandler( + self.rfile, self.wfile, self.get_stderr(), self.get_environ() + ) + handler.request_handler = self # backpointer for logging + handler.run(self.server.get_app()) + + def get_environ(self): + """ + wsgiref simple server adds content-type text/plain to everything, this + removes it if it's not actually in the headers. + """ + # Note: Can't use super since this is an oldstyle class in python 2.x + environ = WSGIRequestHandler.get_environ(self).copy() + if self.headers.get('content-type') is None: + del environ['CONTENT_TYPE'] + return environ + + +class SecureWSGIServer(WSGIServer): + + def finish_request(self, request, client_address): + """ + Negotiates SSL and then mimics BaseServer behavior. + """ + request.settimeout(1.0) + try: + ssock = ssl.wrap_socket( + request, + keyfile=os.path.join(CERT_DIR, 'key.pem'), + certfile=os.path.join(CERT_DIR, 'cert.pem'), + server_side=True, + suppress_ragged_eofs=False, + ) + self.RequestHandlerClass(ssock, client_address, self) + except Exception as e: + print("pytest-httpbin server hit an exception serving request: %s" % e) + print("attempting to ignore so the rest of the tests can run") + # WSGIRequestHandler seems to close the socket for us. + # Thanks, WSGIRequestHandler!! + + +class Server(object): + """ + HTTP server running a WSGI application in its own thread. + """ + + port_envvar = 'HTTPBIN_HTTP_PORT' + + def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs): + self.app = application + if self.port_envvar in os.environ: + port = int(os.environ[self.port_envvar]) + self._server = make_server( + host, + port, + self.app, + handler_class=Handler, + **kwargs + ) + self.host = self._server.server_address[0] + self.port = self._server.server_address[1] + self.protocol = 'http' + + self._thread = threading.Thread( + name=self.__class__, + target=self._server.serve_forever, + ) + + def __del__(self): + if hasattr(self, '_server'): + self.stop() + + def start(self): + self._thread.start() + + def __add__(self, other): + return self.url + other + + def stop(self): + self._server.shutdown() + + @property + def url(self): + return '{0}://{1}:{2}'.format(self.protocol, self.host, self.port) + + def join(self, url, allow_fragments=True): + return urljoin(self.url, url, allow_fragments=allow_fragments) + + +class SecureServer(Server): + port_envvar = 'HTTPBIN_HTTPS_PORT' + + def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs): + kwargs['server_class'] = SecureWSGIServer + super(SecureServer, self).__init__(host, port, application, **kwargs) + self.protocol = 'https' diff --git a/tests/pytest-pypi/pytest_pypi/templates/package.html b/tests/pytest-pypi/pytest_pypi/templates/package.html new file mode 100644 index 00000000..36e70a88 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/templates/package.html @@ -0,0 +1,14 @@ + + + + + Links for {{ package.name }} + + +

Links for {{ package.name }}

+ {% for release in package.releases %} + {{ release }} +
+ {% endfor %} + + \ No newline at end of file diff --git a/tests/pytest-pypi/pytest_pypi/templates/simple.html b/tests/pytest-pypi/pytest_pypi/templates/simple.html new file mode 100644 index 00000000..97f67558 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/templates/simple.html @@ -0,0 +1,13 @@ + + + + + Simple Index + + + {% for package in packages %} + {{ package.name }} +
+ {% endfor %} + + \ No newline at end of file diff --git a/tests/pytest-pypi/pytest_pypi/version.py b/tests/pytest-pypi/pytest_pypi/version.py new file mode 100644 index 00000000..df9144c5 --- /dev/null +++ b/tests/pytest-pypi/pytest_pypi/version.py @@ -0,0 +1 @@ +__version__ = '0.1.1' diff --git a/tests/pytest-pypi/runtests.sh b/tests/pytest-pypi/runtests.sh new file mode 100755 index 00000000..6115f03c --- /dev/null +++ b/tests/pytest-pypi/runtests.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +py.test $1 -v -s diff --git a/tests/pytest-pypi/setup.cfg b/tests/pytest-pypi/setup.cfg new file mode 100644 index 00000000..79bc6784 --- /dev/null +++ b/tests/pytest-pypi/setup.cfg @@ -0,0 +1,5 @@ +[bdist_wheel] +# This flag says that the code is written to work on both Python 2 and Python +# 3. If at all possible, it is good practice to do this. If you cannot, you +# will need to generate wheels for each Python version that you support. +universal=1 diff --git a/tests/pytest-pypi/setup.py b/tests/pytest-pypi/setup.py new file mode 100644 index 00000000..3341b098 --- /dev/null +++ b/tests/pytest-pypi/setup.py @@ -0,0 +1,104 @@ +from setuptools import setup, find_packages, Command +import codecs +import os +import re +import sys +from shutil import rmtree + +with open("pytest_pypi/version.py") as f: + code = compile(f.read(), "pytest_pypi/version.py", 'exec') + exec(code) + +here = os.path.abspath(os.path.dirname(__file__)) + +# Get the long description from the relevant file +with codecs.open(os.path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f: + long_description = f.read() + +class UploadCommand(Command): + """Support setup.py upload.""" + + description = 'Build and publish the package.' + user_options = [] + + @staticmethod + def status(s): + """Prints things in bold.""" + print('\033[1m{0}\033[0m'.format(s)) + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + try: + self.status('Removing previous builds…') + rmtree(os.path.join(here, 'dist')) + except OSError: + pass + + self.status('Building Source and Wheel (universal) distribution…') + os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable)) + + self.status('Uploading the package to PyPi via Twine…') + os.system('twine upload dist/*') + + self.status('Pushing git tags…') + os.system('git tag v{0}'.format(__version__)) + os.system('git push --tags') + + sys.exit() + +setup( + name="pytest-pypi", + + # There are various approaches to referencing the version. For a discussion, + # see http://packaging.python.org/en/latest/tutorial.html#version + version=__version__, + + description="Easily test your HTTP library against a local copy of pypi", + long_description=long_description, + + # The project URL. + url='https://github.com/kennethreitz/pytest-pypi', + + # Author details + author='Kenneth Reitz', + author_email='me@kennethreitz.org', + + # Choose your license + license='MIT', + + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Testing', + 'Topic :: Software Development :: Libraries', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + ], + + # What does your project relate to? + keywords='pytest-pypi testing pytest pypi', + packages=find_packages(exclude=["contrib", "docs", "tests*"]), + include_package_data = True, # include files listed in MANIFEST.in + install_requires = ['Flask', 'six'], + + # the following makes a plugin available to pytest + entry_points = { + 'pytest11': [ + 'pypi = pytest_pypi.plugin', + ] + }, + cmdclass={ + 'upload': UploadCommand, + }, +) diff --git a/tests/pytest-pypi/tox.ini b/tests/pytest-pypi/tox.ini new file mode 100644 index 00000000..9437a9e5 --- /dev/null +++ b/tests/pytest-pypi/tox.ini @@ -0,0 +1,10 @@ +# content of: tox.ini , put in same dir as setup.py + +[tox] +envlist = py26, py27, py33, py34, py35, py36, pypy, pypy3 + +[testenv] +deps = pytest + requests + py26: httpbin==0.5.0 +commands = ./runtests.sh {posargs:tests/} diff --git a/tests/test_pipenv.py b/tests/test_pipenv.py index 82f46263..8efb4c19 100644 --- a/tests/test_pipenv.py +++ b/tests/test_pipenv.py @@ -25,6 +25,15 @@ except: os.environ['PIPENV_DONT_USE_PYENV'] = '1' os.environ['PIPENV_IGNORE_VIRTUALENVS'] = '1' +os.environ['PYPI_VENDOR_DIR'] = os.path.sep.join([os.path.dirname(__file__), 'pypi']) + +from flask import Flask + +class PYPI(object): + """docstring for PYPI""" + def __init__(self, packages=None): + super(PYPI, self).__init__() + self.packages = packages or [] @pytest.fixture(scope='module') @@ -41,7 +50,8 @@ def pip_src_dir(request): class PipenvInstance(): """An instance of a Pipenv Project...""" - def __init__(self, pipfile=True, chdir=False): + def __init__(self, pypi=None, pipfile=True, chdir=False): + self.pypi = pypi self.original_umask = os.umask(0o007) self.original_dir = os.path.abspath(os.curdir) self._path = TemporaryDirectory(suffix='project', prefix='pipenv') @@ -50,6 +60,9 @@ class PipenvInstance(): self.pipfile_path = None self.chdir = chdir + if self.pypi: + os.environ['PIPENV_TEST_INDEX'] = '{0}/simple'.format(self.pypi.url) + if pipfile: p_path = os.sep.join([self.path, 'Pipfile']) with open(p_path, 'a'): @@ -111,8 +124,8 @@ class TestPipenv: """The ultimate testing class.""" @pytest.mark.cli - def test_pipenv_where(self): - with PipenvInstance() as p: + def test_pipenv_where(self, pypi_secure): + with PipenvInstance(pypi=pypi_secure) as p: assert normalize_drive(p.path) in p.pipenv('--where').out @pytest.mark.cli @@ -137,15 +150,15 @@ class TestPipenv: assert not os.path.isdir(venv_path) @pytest.mark.cli - def test_pipenv_graph(self): - with PipenvInstance() as p: + def test_pipenv_graph(self, pypi): + with PipenvInstance(pypi=pypi) as p: p.pipenv('install requests') assert 'requests' in p.pipenv('graph').out assert 'requests' in p.pipenv('graph --json').out @pytest.mark.cli - def test_pipenv_graph_reverse(self): - with PipenvInstance() as p: + def test_pipenv_graph_reverse(self, pypi): + with PipenvInstance(pypi=pypi) as p: p.pipenv('install requests==2.18.4') output = p.pipenv('graph --reverse').out @@ -168,8 +181,8 @@ class TestPipenv: assert 'Warning: Using both --reverse and --json together is not supported.' in c.err @pytest.mark.cli - def test_pipenv_check(self): - with PipenvInstance() as p: + def test_pipenv_check(self, pypi): + with PipenvInstance(pypi=pypi) as p: p.pipenv('install requests==1.0.0') assert 'requests' in p.pipenv('check').out @@ -201,19 +214,19 @@ class TestPipenv: @pytest.mark.cli @pytest.mark.install - def test_install_parse_error(self): - with PipenvInstance() as p: + def test_install_parse_error(self, pypi): + with PipenvInstance(pypi=pypi) as p: # Make sure unparseable packages don't wind up in the pipfile # Escape $ for shell input - c = p.pipenv('install tablib u/\\/p@r\$34b13+pkg') + c = p.pipenv('install requests u/\\/p@r\$34b13+pkg') assert c.return_code != 0 assert 'u/\\/p@r$34b13+pkg' not in p.pipfile['packages'] @pytest.mark.install @pytest.mark.setup @pytest.mark.skip(reason="this doesn't work on travis") - def test_basic_setup(self): - with PipenvInstance() as p: + def test_basic_setup(self, pypi): + with PipenvInstance(pypi=pypi) as p: with PipenvInstance(pipfile=False) as p: c = p.pipenv('install requests') assert c.return_code == 0 @@ -225,22 +238,9 @@ class TestPipenv: assert 'urllib3' in p.lockfile['default'] assert 'certifi' in p.lockfile['default'] - @pytest.mark.spelling - @pytest.mark.skip(reason="this is slightly non-deterministic") - def test_spell_checking(self): - with PipenvInstance() as p: - c = p.pipenv('install flaskcors', block=False) - c.expect(u'[Y//n]:') - c.send('y') - c.block() - - assert c.return_code == 0 - assert 'flask-cors' in p.pipfile['packages'] - assert 'flask' in p.lockfile['default'] - @pytest.mark.install - def test_basic_install(self): - with PipenvInstance() as p: + def test_basic_install(self, pypi): + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install requests') assert c.return_code == 0 assert 'requests' in p.pipfile['packages'] @@ -253,8 +253,8 @@ class TestPipenv: @pytest.mark.dev @pytest.mark.run @pytest.mark.install - def test_basic_dev_install(self): - with PipenvInstance() as p: + def test_basic_dev_install(self, pypi): + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install requests --dev') assert c.return_code == 0 assert 'requests' in p.pipfile['dev-packages'] @@ -269,9 +269,9 @@ class TestPipenv: @pytest.mark.dev @pytest.mark.install - def test_install_without_dev(self): + def test_install_without_dev(self, pypi): """Ensure that running `pipenv install` doesn't install dev packages""" - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -295,8 +295,8 @@ records = "*" @pytest.mark.run @pytest.mark.uninstall - def test_uninstall(self): - with PipenvInstance() as p: + def test_uninstall(self, pypi): + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install requests') assert c.return_code == 0 assert 'requests' in p.pipfile['packages'] @@ -338,9 +338,9 @@ records = "*" @pytest.mark.run @pytest.mark.uninstall - def test_uninstall_all_dev(self): - with PipenvInstance() as p: - c = p.pipenv('install --dev requests pytest') + def test_uninstall_all_dev(self, pypi): + with PipenvInstance(pypi=pypi) as p: + c = p.pipenv('install --dev requests flask') assert c.return_code == 0 c = p.pipenv('install tpfd') @@ -348,10 +348,10 @@ records = "*" assert 'tpfd' in p.pipfile['packages'] assert 'requests' in p.pipfile['dev-packages'] - assert 'pytest' in p.pipfile['dev-packages'] + assert 'flask' in p.pipfile['dev-packages'] assert 'tpfd' in p.lockfile['default'] assert 'requests' in p.lockfile['develop'] - assert 'pytest' in p.lockfile['develop'] + assert 'flask' in p.lockfile['develop'] c = p.pipenv('uninstall --all-dev') @@ -372,8 +372,8 @@ records = "*" @pytest.mark.extras @pytest.mark.install - def test_extras_install(self): - with PipenvInstance() as p: + def test_extras_install(self, pypi): + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install requests[socks]') assert c.return_code == 0 assert 'requests' in p.pipfile['packages'] @@ -388,8 +388,9 @@ records = "*" @pytest.mark.extras @pytest.mark.install @pytest.mark.local - def test_local_extras_install(self): - with PipenvInstance() as p: + @pytest.mark.skip(reason="I'm not mocking this.") + def test_local_extras_install(self, pypi): + with PipenvInstance(pypi=pypi) as p: setup_py = os.path.join(p.path, 'setup.py') with open(setup_py, 'w') as fh: contents = """ @@ -420,8 +421,8 @@ setup( @pytest.mark.vcs @pytest.mark.install - def test_basic_vcs_install(self): - with PipenvInstance() as p: + def test_basic_vcs_install(self, pypi): + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install git+https://github.com/requests/requests.git#egg=requests') assert c.return_code == 0 # edge case where normal package starts with VCS name shouldn't be flagged as vcs @@ -435,8 +436,8 @@ setup( @pytest.mark.e @pytest.mark.vcs @pytest.mark.install - def test_editable_vcs_install(self, pip_src_dir): - with PipenvInstance() as p: + def test_editable_vcs_install(self, pip_src_dir, pypi): + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install -e git+https://github.com/requests/requests.git#egg=requests') assert c.return_code == 0 assert 'requests' in p.pipfile['packages'] @@ -450,8 +451,8 @@ setup( @pytest.mark.install @pytest.mark.pin - def test_windows_pinned_pipfile(self): - with PipenvInstance() as p: + def test_windows_pinned_pipfile(self, pypi): + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -468,9 +469,9 @@ tablib = "<0.12" @pytest.mark.install @pytest.mark.vcs @pytest.mark.resolver - def test_editable_vcs_install_in_pipfile_with_dependency_resolution_doesnt_traceback(self): + def test_editable_vcs_install_in_pipfile_with_dependency_resolution_doesnt_traceback(self, pypi): # See https://github.com/pypa/pipenv/issues/1240 - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -490,11 +491,11 @@ idna = "==2.6.0" @pytest.mark.run @pytest.mark.install - def test_multiprocess_bug_and_install(self): + def test_multiprocess_bug_and_install(self, pypi): with temp_environ(): os.environ['PIPENV_MAX_SUBPROCESS'] = '2' - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -520,9 +521,9 @@ tpfd = "*" @pytest.mark.sequential @pytest.mark.install - def test_sequential_mode(self): + def test_sequential_mode(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -549,8 +550,8 @@ tpfd = "*" @pytest.mark.install @pytest.mark.resolver @pytest.mark.backup_resolver - def test_backup_resolver(self): - with PipenvInstance() as p: + def test_backup_resolver(self, pypi): + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -587,9 +588,9 @@ requests = {version = "*", markers="os_name=='splashwear'"} @pytest.mark.run @pytest.mark.alt @pytest.mark.install - def test_specific_package_environment_markers(self): + def test_specific_package_environment_markers(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -609,8 +610,8 @@ requests = {version = "*", os_name = "== 'splashwear'"} @pytest.mark.install @pytest.mark.vcs @pytest.mark.tablib - def test_install_editable_git_tag(self, pip_src_dir): - with PipenvInstance() as p: + def test_install_editable_git_tag(self, pip_src_dir, pypi): + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install -e git+https://github.com/kennethreitz/tablib.git@v0.12.1#egg=tablib') assert c.return_code == 0 assert 'tablib' in p.pipfile['packages'] @@ -622,9 +623,9 @@ requests = {version = "*", os_name = "== 'splashwear'"} @pytest.mark.run @pytest.mark.alt @pytest.mark.install - def test_alternative_version_specifier(self): + def test_alternative_version_specifier(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -646,26 +647,26 @@ requests = {version = "*"} @pytest.mark.bad @pytest.mark.install - def test_bad_packages(self): + def test_bad_packages(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install NotAPackage') assert c.return_code > 0 @pytest.mark.dotvenv - def test_venv_in_project(self): + def test_venv_in_project(self, pypi): with temp_environ(): os.environ['PIPENV_VENV_IN_PROJECT'] = '1' - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install requests') assert c.return_code == 0 assert normalize_drive(p.path) in p.pipenv('--venv').out @pytest.mark.dotvenv - def test_reuse_previous_venv(self): - with PipenvInstance(chdir=True) as p: + def test_reuse_previous_venv(self, pypi): + with PipenvInstance(chdir=True, pypi=pypi) as p: os.mkdir('.venv') c = p.pipenv('install requests') assert c.return_code == 0 @@ -678,13 +679,14 @@ requests = {version = "*"} @pytest.mark.shell @pytest.mark.windows @pytest.mark.pew - def test_shell_nested_venv_in_project(self): + @pytest.mark.skip('Not mocking this.') + def test_shell_nested_venv_in_project(self, pypi): import subprocess with temp_environ(): os.environ['PIPENV_VENV_IN_PROJECT'] = '1' os.environ['PIPENV_IGNORE_VIRTUALENVS'] = '1' os.environ['PIPENV_SHELL_COMPAT'] = '1' - with PipenvInstance(chdir=True) as p: + with PipenvInstance(chdir=True, pypi=pypi) as p: # Signal to pew to look in the project directory for the environment os.environ['WORKON_HOME'] = p.path project = Project() @@ -762,33 +764,32 @@ requests = {version = "*"} @pytest.mark.code @pytest.mark.check @pytest.mark.unused - def test_check_unused(self): + def test_check_unused(self, pypi): with PipenvInstance() as p: - with PipenvInstance(chdir=True) as p: + with PipenvInstance(chdir=True, pypi=pypi) as p: with open('__init__.py', 'w') as f: contents = """ import tablib import records """.strip() f.write(contents) - p.pipenv('install GitPython') p.pipenv('install requests') p.pipenv('install tablib') p.pipenv('install records') - assert all(pkg in p.pipfile['packages'] for pkg in ['requests', 'tablib', 'records', 'gitpython']) + assert all(pkg in p.pipfile['packages'] for pkg in ['requests', 'tablib', 'records']) c = p.pipenv('check --unused .') - assert 'gitpython' in c.out assert 'tablib' not in c.out @pytest.mark.extras @pytest.mark.install @pytest.mark.requirements - def test_requirements_to_pipfile(self): + @pytest.mark.skip(reason="Not mocking this.") + def test_requirements_to_pipfile(self, pypi): - with PipenvInstance(pipfile=False, chdir=True) as p: + with PipenvInstance(pipfile=False, chdir=True, pypi=pypi) as p: # Write a requirements file with open('requirements.txt', 'w') as f: @@ -821,22 +822,21 @@ import records @pytest.mark.lock @pytest.mark.requirements - def test_lock_requirements_file(self): + def test_lock_requirements_file(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] requests = "==2.14.0" -flask = "==0.12.2" [dev-packages] -pytest = "==3.1.1" +flask = "==0.12.2" """.strip() f.write(contents) - req_list = ("requests==2.14.0", "flask==0.12.2") + req_list = ("requests==2.14.0") - dev_req_list = ("pytest==3.1.1") + dev_req_list = ("flask==0.12.2") c = p.pipenv('lock -r') d = p.pipenv('lock -r -d') @@ -851,9 +851,9 @@ pytest = "==3.1.1" @pytest.mark.lock @pytest.mark.complex - def test_complex_lock_with_vcs_deps(self, pip_src_dir): + def test_complex_lock_with_vcs_deps(self, pip_src_dir, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -885,9 +885,9 @@ requests = {git = "https://github.com/requests/requests", egg = "requests"} @pytest.mark.requirements @pytest.mark.complex @pytest.mark.maya - def test_complex_deps_lock_and_install_properly(self): + def test_complex_deps_lock_and_install_properly(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -904,10 +904,10 @@ maya = "*" @pytest.mark.lock @pytest.mark.requirements @pytest.mark.complex - def test_complex_lock_changing_candidate(self): + def test_complex_lock_changing_candidate(self, pypi): # The requests candidate will change from latest to <2.12. - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -928,10 +928,10 @@ requests = "*" @pytest.mark.lock @pytest.mark.requirements @pytest.mark.complex - def test_complex_lock_deep_extras(self): + def test_complex_lock_deep_extras(self, pypi): # records[pandas] requires tablib[pandas] which requires pandas. - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -948,9 +948,9 @@ records = {extras = ["pandas"], version = "==0.5.2"} @pytest.mark.lock @pytest.mark.deploy - def test_deploy_works(self): + def test_deploy_works(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: with open(p.pipfile_path, 'w') as f: contents = """ [packages] @@ -976,9 +976,9 @@ requests = "==2.14.0" @pytest.mark.install @pytest.mark.files @pytest.mark.urls - def test_urls_work(self): + def test_urls_work(self, pypi): - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: c = p.pipenv('install https://github.com/divio/django-cms/archive/release/3.4.x.zip') key = [k for k in p.pipfile['packages'].keys()][0] @@ -1043,8 +1043,8 @@ requests = "==2.14.0" @pytest.mark.install @pytest.mark.files @pytest.mark.urls - def test_install_remote_requirements(self): - with PipenvInstance() as p: + def test_install_remote_requirements(self, pypi): + with PipenvInstance(pypi=pypi) as p: # using a github hosted requirements.txt file c = p.pipenv('install -r https://raw.githubusercontent.com/kennethreitz/pipenv/3688148ac7cfecefb085c474b092c31d791952c1/tests/test_artifacts/requirements.txt') @@ -1062,12 +1062,12 @@ requests = "==2.14.0" @pytest.mark.install @pytest.mark.files - def test_relative_paths(self): + def test_relative_paths(self, pypi): file_name = 'tablib-0.12.1.tar.gz' test_dir = os.path.join(os.path.dirname(os.path.abspath(__file__))) source_path = os.path.abspath(os.path.join(test_dir, 'test_artifacts', file_name)) - with PipenvInstance() as p: + with PipenvInstance(pypi=pypi) as p: artifact_dir = 'artifacts' artifact_path = os.path.join(p.path, artifact_dir) mkdir_p(artifact_path) @@ -1083,8 +1083,8 @@ requests = "==2.14.0" @pytest.mark.install @pytest.mark.local_file - def test_install_local_file_collision(self): - with PipenvInstance() as p: + def test_install_local_file_collision(self, pypi): + with PipenvInstance(pypi=pypi) as p: target_package = 'alembic' fake_file = os.path.join(p.path, target_package) with open(fake_file, 'w') as f: diff --git a/tests/test_project.py b/tests/test_project.py index d9a632b8..7b0d3895 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -1,5 +1,6 @@ import os +import pytest import pipenv.project import pipenv.core from pipenv.vendor import delegator @@ -7,16 +8,19 @@ from pipenv.vendor import delegator class TestProject(): + @pytest.mark.project def test_proper_names(self): proj = pipenv.project.Project() assert proj.virtualenv_location in proj.proper_names_location assert isinstance(proj.proper_names, list) + @pytest.mark.project def test_download_location(self): proj = pipenv.project.Project() assert proj.virtualenv_location in proj.download_location assert proj.download_location.endswith('downloads') + @pytest.mark.project def test_create_pipfile(self): proj = pipenv.project.Project(which=pipenv.core.which) @@ -52,6 +56,7 @@ class TestProject(): assert config_source_2['name'] == 'pip_index_1' assert config_source_2['verify_ssl'] is True + @pytest.mark.project def test_parsed_pipfile(self): proj = pipenv.project.Project() @@ -76,6 +81,7 @@ class TestProject(): assert 'packages' in pfile assert 'socks' in pfile['packages']['requests']['extras'] + @pytest.mark.project def test_add_package_to_pipfile(self): proj = pipenv.project.Project() @@ -107,6 +113,7 @@ class TestProject(): assert 'click-completion' in p['packages'] assert p['packages']['click-completion'] == '*' + @pytest.mark.project def test_remove_package_from_pipfile(self): proj = pipenv.project.Project() @@ -139,6 +146,7 @@ class TestProject(): # assert 'dev-packages' not in p + @pytest.mark.project def test_internal_pipfile(self): proj = pipenv.project.Project() @@ -161,6 +169,7 @@ class TestProject(): delegator.run('rm -fr test_internal_pipfile') + @pytest.mark.project def test_internal_lockfile(self): proj = pipenv.project.Project() diff --git a/tests/test_utils.py b/tests/test_utils.py index f25b1936..8e748cd1 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -11,6 +11,7 @@ class TestUtils: """Test utility functions in pipenv""" + @pytest.mark.utils def test_convert_deps_to_pip(self): # requests = '*' @@ -63,6 +64,7 @@ class TestUtils: deps = pipenv.utils.convert_deps_to_pip(deps, r=False) assert deps[0] == 'django==1.10' + @pytest.mark.utils def test_convert_from_pip(self): # requests @@ -107,6 +109,7 @@ class TestUtils: dep = pipenv.utils.convert_deps_from_pip(dep) assert 'pipenv requires an #egg fragment for vcs' in str(e) + @pytest.mark.utils @pytest.mark.parametrize('version, specified_ver, expected', [ ('*', '*', True), ('2.1.6', '==2.1.4', False), @@ -117,6 +120,7 @@ class TestUtils: def test_is_required_version(self, version, specified_ver, expected): assert pipenv.utils.is_required_version(version, specified_ver) is expected + @pytest.mark.utils @pytest.mark.parametrize('entry, expected', [ ({'git': 'package.git', 'ref': 'v0.0.1'}, True), ({'hg': 'https://package.com/package', 'ref': 'v1.2.3'}, True), @@ -131,6 +135,7 @@ class TestUtils: def test_is_vcs(self, entry, expected): assert pipenv.utils.is_vcs(entry) is expected + @pytest.mark.utils def test_split_file(self): pipfile_dict = { 'packages': { @@ -153,12 +158,15 @@ class TestUtils: assert 'click' in split_dict['dev-packages-vcs'] assert 'crayons' in split_dict['dev-packages-vcs'] + @pytest.mark.utils def test_python_version_from_bad_path(self): assert pipenv.utils.python_version("/fake/path") is None + @pytest.mark.utils def test_python_version_from_non_python(self): assert pipenv.utils.python_version("/dev/null") is None + @pytest.mark.utils @pytest.mark.parametrize('version_output, version', [ ('Python 3.6.2', '3.6.2'), ('Python 3.6.2 :: Continuum Analytics, Inc.', '3.6.2'), @@ -171,6 +179,7 @@ class TestUtils: mocked_delegator.return_value = run_ret assert pipenv.utils.python_version('some/path') == version + @pytest.mark.utils @pytest.mark.windows @pytest.mark.skipif(os.name != 'nt', reason='Windows test only') def test_windows_shellquote(self): @@ -178,12 +187,14 @@ class TestUtils: expected_path = '"C:\\\\Program Files\\\\Python36\\\\python.exe"' assert pipenv.utils.shellquote(test_path) == expected_path + @pytest.mark.utils def test_is_valid_url(self): url = "https://github.com/kennethreitz/requests.git" not_url = "something_else" assert pipenv.utils.is_valid_url(url) assert pipenv.utils.is_valid_url(not_url) is False + @pytest.mark.utils @pytest.mark.parametrize('input_path, expected', [ ('artifacts/file.zip', './artifacts/file.zip'), ('./artifacts/file.zip', './artifacts/file.zip'), @@ -193,6 +204,7 @@ class TestUtils: def test_nix_converted_relative_path(self, input_path, expected): assert pipenv.utils.get_converted_relative_path(input_path) == expected + @pytest.mark.utils @pytest.mark.parametrize('input_path, expected', [ ('artifacts/file.zip', '.\\artifacts\\file.zip'), ('./artifacts/file.zip', '.\\artifacts\\file.zip'), @@ -202,6 +214,7 @@ class TestUtils: def test_win_converted_relative_path(self, input_path, expected): assert pipenv.utils.get_converted_relative_path(input_path) == expected + @pytest.mark.utils def test_download_file(self): url = "https://github.com/kennethreitz/pipenv/blob/master/README.rst" output = "test_download.rst" @@ -209,6 +222,7 @@ class TestUtils: assert os.path.exists(output) os.remove(output) + @pytest.mark.utils def test_new_line_end_of_toml_file(this): # toml file that needs clean up toml = """ @@ -227,6 +241,7 @@ twine = "*" # testing if the end of the generated file contains a newline assert new_toml[-1] == '\n' + @pytest.mark.utils @pytest.mark.parametrize('input_path, expected', [ ('c:\\Program Files\\Python36\\python.exe', 'C:\\Program Files\\Python36\\python.exe'), @@ -241,6 +256,7 @@ twine = "*" def test_win_normalize_drive(self, input_path, expected): assert pipenv.utils.normalize_drive(input_path) == expected + @pytest.mark.utils @pytest.mark.parametrize('input_path, expected', [ ('/usr/local/bin/python', '/usr/local/bin/python'), ('artifacts/file.zip', 'artifacts/file.zip'), @@ -251,6 +267,7 @@ twine = "*" def test_nix_normalize_drive(self, input_path, expected): assert pipenv.utils.normalize_drive(input_path) == expected + @pytest.mark.utils @pytest.mark.requirements def test_get_requirements(self): # Test eggs in URLs