diff --git a/.gitignore b/.gitignore index 9c5d32a0..c5856256 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ dist httpie.egg-info build *.pyc +*.egg .tox README.html .coverage diff --git a/httpie/utils.py b/httpie/utils.py index 37ac745d..703a101c 100644 --- a/httpie/utils.py +++ b/httpie/utils.py @@ -10,20 +10,20 @@ def humanize_bytes(n, precision=2): Assumes `from __future__ import division`. >>> humanize_bytes(1) - '1 byte' - >>> humanize_bytes(1024) + '1 B' + >>> humanize_bytes(1024, precision=1) '1.0 kB' - >>> humanize_bytes(1024 * 123) + >>> humanize_bytes(1024 * 123, precision=1) '123.0 kB' - >>> humanize_bytes(1024 * 12342) + >>> humanize_bytes(1024 * 12342, precision=1) '12.1 MB' - >>> humanize_bytes(1024 * 12342, 2) + >>> humanize_bytes(1024 * 12342, precision=2) '12.05 MB' - >>> humanize_bytes(1024 * 1234, 2) + >>> humanize_bytes(1024 * 1234, precision=2) '1.21 MB' - >>> humanize_bytes(1024 * 1234 * 1111, 2) + >>> humanize_bytes(1024 * 1234 * 1111, precision=2) '1.31 GB' - >>> humanize_bytes(1024 * 1234 * 1111, 1) + >>> humanize_bytes(1024 * 1234 * 1111, precision=1) '1.3 GB' """ diff --git a/requirements-dev.txt b/requirements-dev.txt index c3b33209..f5698407 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,4 @@ tox +pytest git+git://github.com/kennethreitz/httpbin.git@7c96875e87a448f08fb1981e85eb79e77d592d98 docutils diff --git a/setup.py b/setup.py index c94cc5d8..0c479d1c 100644 --- a/setup.py +++ b/setup.py @@ -1,16 +1,32 @@ -import os import sys import codecs from setuptools import setup +from setuptools.command.test import test as TestCommand + import httpie -if sys.argv[-1] == 'test': - status = os.system('python tests/tests.py') - sys.exit(1 if status > 127 else status) +class PyTest(TestCommand): + def finalize_options(self): + TestCommand.finalize_options(self) + self.test_suite = True + self.test_args = [ + '--doctest-modules', + './httpie', './tests' + ] + self.test_suite = True + + def run_tests(self): + import pytest + sys.exit(pytest.main(self.test_args)) -requirements = [ +tests_require = [ + 'pytest', +] + + +install_requires = [ 'requests>=2.0.0', 'Pygments>=1.5' ] @@ -18,11 +34,11 @@ try: #noinspection PyUnresolvedReferences import argparse except ImportError: - requirements.append('argparse>=1.2.1') + install_requires.append('argparse>=1.2.1') if 'win32' in str(sys.platform).lower(): # Terminal colors for Windows - requirements.append('colorama>=0.2.4') + install_requires.append('colorama>=0.2.4') def long_description(): @@ -46,7 +62,11 @@ setup( 'http = httpie.__main__:main', ], }, - install_requires=requirements, + install_requires=install_requires, + cmdclass={'test': PyTest}, + tests_require=tests_require, + extras_require={'tests': tests_require}, + classifiers=[ 'Development Status :: 5 - Production/Stable', 'Programming Language :: Python', diff --git a/tests/__init__.py b/tests/__init__.py index c9984e92..9782b755 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -5,15 +5,13 @@ import json import shutil import tempfile -# HACK: Prepend ../ to PYTHONPATH so that we can import httpie form there. -TESTS_ROOT = os.path.abspath(os.path.dirname(__file__)) -sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..'))) from httpie import ExitStatus from httpie.models import Environment from httpie.core import main from httpie.compat import bytes, str +TESTS_ROOT = os.path.abspath(os.path.dirname(__file__)) HTTPBIN_URL = os.environ.get('HTTPBIN_URL', 'http://httpbin.org').rstrip('/') diff --git a/tests/test_downloads.py b/tests/test_downloads.py index a82b1d6e..7661cdc1 100644 --- a/tests/test_downloads.py +++ b/tests/test_downloads.py @@ -2,6 +2,7 @@ import os import time from unittest import TestCase +import pytest from requests.structures import CaseInsensitiveDict from httpie.compat import urlopen @@ -32,22 +33,22 @@ class DownloadUtilsTest(TestCase): assert parse('bytes 100-199/*', 100) == 200 # missing - self.assertRaises(ContentRangeError, parse, None, 100) + pytest.raises(ContentRangeError, parse, None, 100) # syntax error - self.assertRaises(ContentRangeError, parse, 'beers 100-199/*', 100) + pytest.raises(ContentRangeError, parse, 'beers 100-199/*', 100) # unexpected range - self.assertRaises(ContentRangeError, parse, 'bytes 100-199/*', 99) + pytest.raises(ContentRangeError, parse, 'bytes 100-199/*', 99) # invalid instance-length - self.assertRaises(ContentRangeError, parse, 'bytes 100-199/199', 100) + pytest.raises(ContentRangeError, parse, 'bytes 100-199/199', 100) # invalid byte-range-resp-spec - self.assertRaises(ContentRangeError, parse, 'bytes 100-99/199', 100) + pytest.raises(ContentRangeError, parse, 'bytes 100-99/199', 100) # invalid byte-range-resp-spec - self.assertRaises(ContentRangeError, parse, 'bytes 100-100/*', 100) + pytest.raises(ContentRangeError, parse, 'bytes 100-100/*', 100) def test_Content_Disposition_parsing(self): parse = filename_from_content_disposition diff --git a/tests/test_output.py b/tests/test_output.py index 7b091950..b5ebd6e8 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -17,9 +17,10 @@ class VerboseFlagTest(TestCase): def test_verbose_form(self): # https://github.com/jkbr/httpie/issues/53 r = http('--verbose', '--form', 'POST', httpbin('/post'), - 'foo=bar', 'baz=bar') + 'A=B', 'C=D') assert HTTP_OK in r - assert 'foo=bar&baz=bar' in r + # Python 2.6 has no ordered dict, so we test for both orders here. + assert 'A=B&C=D' in r or 'C=D&A=B', r def test_verbose_json(self): r = http('--verbose', 'POST', httpbin('/post'), 'foo=bar', 'baz=bar') diff --git a/tests/test_uploads.py b/tests/test_uploads.py index b81c60dd..0a1df331 100644 --- a/tests/test_uploads.py +++ b/tests/test_uploads.py @@ -1,6 +1,8 @@ import os from unittest import TestCase +import pytest + from httpie.input import ParseError from tests import TestEnvironment, http, httpbin, HTTP_OK from tests.fixtures import FILE_PATH_ARG, FILE_PATH, FILE_CONTENT @@ -8,7 +10,7 @@ from tests.fixtures import FILE_PATH_ARG, FILE_PATH, FILE_CONTENT class MultipartFormDataFileUploadTest(TestCase): def test_non_existent_file_raises_parse_error(self): - with self.assertRaises(ParseError): + with pytest.raises(ParseError): http('--form', 'POST', httpbin('/post'), 'foo@/__does_not_exist__') def test_upload_ok(self): diff --git a/tox.ini b/tox.ini index 65461037..7ce95a13 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, py33, pypy +envlist = py26, py27, py34, pypy [testenv] commands = {envpython} setup.py test