diff --git a/.github/workflows/lint-test-docs.yaml b/.github/workflows/lint-test-docs.yaml index a420158..ed40684 100644 --- a/.github/workflows/lint-test-docs.yaml +++ b/.github/workflows/lint-test-docs.yaml @@ -29,32 +29,14 @@ jobs: strategy: fail-fast: false matrix: - python: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9"] - flask: ["0.12.5", "1.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", "1.1.0", "1.1.1", - "1.1.2", "1.1.3", "1.1.4", "2.0.0", "2.0.1", "2.0.2"] + python: ["3.7", "3.8", "3.9", "3.10"] + requirements: + - "flask>=1.0,<1.1 werkzeug<2.1 jinja2<3 markupsafe<2.1 itsdangerous<2.1" + - "flask>=1.1,<1.2 markupsafe==2.0.1" + - "flask>=2.0,<2.1" + - "flask>=2.1,<2.2" + - "flask>=2.2,<2.3" experimental: [false] - # include: - # - python: "3.10" - # # known issue: https://github.com/nose-devs/nose/issues/1099 - # experimental: true - exclude: - # excludes flask versions from unsupported python versions - - python: "2.7" - flask: "1.1.3" - - python: "2.7" - flask: "2.0.0" - - python: "2.7" - flask: "2.0.1" - - python: "2.7" - flask: "2.0.2" - - python: "3.5" - flask: "1.1.3" - - python: "3.5" - flask: "2.0.0" - - python: "3.5" - flask: "2.0.1" - - python: "3.5" - flask: "2.0.2" runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -63,9 +45,9 @@ jobs: run: | docker-compose run --rm dev env: + REQUIREMENTS: ${{ matrix.requirements }} CHECK_STYLE: no DEV_IMAGE: python:${{ matrix.python }} - FLASK: ${{ matrix.flask }} # build and publish docs docs: @@ -92,7 +74,7 @@ jobs: TARGET_FOLDER=develop elif [[ $GIT_BRANCH =~ ^v[0-9.]+[0-9.a-z\-]*$ ]]; then TARGET_FOLDER=${GIT_BRANCH:1} - elif [[ $GIT_BRANCH =~ ^[0-9.]+[0-9.a-z\-]*$ || $GIT_BRANCH =~ ^releases\/[0-9.]+[0-9.a-z\-]*$ ]]; then + elif [[ $GIT_BRANCH =~ ^[0-9.]+[0-9.a-z\-]*$ || $GIT_BRANCH =~ ^releases\/[v0-9.]+[0-9.a-z\-]*$ ]]; then TARGET_FOLDER=$GIT_BRANCH fi echo "\$TARGET_FOLDER: $TARGET_FOLDER" diff --git a/CHANGELOG.md b/CHANGELOG.md index a641d07..b112f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +2023-08-28 F.N. Claessen +----------------------------------------- + + Version: 0.16.0 + + - Tasks: + * Compatibility with werkzeug 2.2 #145 + + 2021-12-25 Hoat Le -------------------------------------- diff --git a/Makefile b/Makefile index 2a0a07d..0715c4f 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ test-clean: coverage erase test-intg: - coverage run --branch --source=. `which nosetests` -v --exe + coverage run --branch --source=. -m pytest test: | test-clean test-intg diff --git a/dev-setup/README.md b/dev-setup/README.md index f708827..1d12c74 100644 --- a/dev-setup/README.md +++ b/dev-setup/README.md @@ -56,7 +56,7 @@ Stop the watching files by using `Ctrl + c`. ## How to develop -- `$ docker-compose up` will check code style and run tests with defaul Python image. +- `$ docker-compose up` will check code style and run tests with default Python image. There are environment variables to run and check with different versions of Python: diff --git a/docker-compose.yml b/docker-compose.yml index 9b85086..be7724a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ services: working_dir: /opt/app command: sh run-dev.sh environment: - FLASK: ${FLASK:-1.1.1} + REQUIREMENTS: ${REQUIREMENTS:-flask==2.0.0} CHECK_STYLE: ${CHECK_STYLE:-yes} RUN_TEST: ${RUN_TEST:-yes} volumes: diff --git a/docs/conf.py b/docs/conf.py index 3a6aba2..04d0c92 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,9 +49,9 @@ # built documents. # # The short X.Y version. -version = '0.15' +version = '0.16' # The full version, including alpha/beta/rc tags. -release = '0.15.0-b1' +release = '0.16.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/flask_classful.py b/flask_classful.py index 5f2c436..4b8c248 100644 --- a/flask_classful.py +++ b/flask_classful.py @@ -12,14 +12,14 @@ import functools import inspect from uuid import UUID -from werkzeug.routing import parse_rule +from werkzeug.routing import Rule, Map from flask import request, make_response from flask.wrappers import ResponseBase import re _py2 = sys.version_info[0] == 2 -__version__ = "0.15.0-b1" +__version__ = "0.16.0" def route(rule, **options): @@ -66,6 +66,7 @@ class FlaskView(object): route_base = None route_prefix = None trailing_slash = True + base_args = [] excluded_methods = [] # specify the class methods to be explicitly excluded from routing creation # TODO(hoatle): make method_dashified=True as default instead, # this is not a compatible change @@ -165,6 +166,7 @@ def register(cls, app, route_base=None, subdomain=None, route_prefix=None, if hasattr(value, "_rule_cache") and name in value._rule_cache: for idx, cached_rule in enumerate(value._rule_cache[name]): rule, options = cached_rule + options.update(rule_options) rule = cls.build_rule(rule) sub, ep, options = cls.parse_options(options) @@ -370,9 +372,8 @@ def build_rule(cls, rule, method=None): rule_parts.append(route_base) if len(rule) > 0: # the case of rule='' empty string rule_parts.append(rule) - ignored_rule_args = ['self'] - if hasattr(cls, 'base_args'): - ignored_rule_args += cls.base_args + + ignored_rule_args = ['self'] + cls.base_args if method and getattr(cls, 'inspect_args', True): argspec = get_true_argspec(method) @@ -400,13 +401,13 @@ def get_route_base(cls): if cls.route_base is not None: route_base = cls.route_base - base_rule = parse_rule(route_base) - # see: https://github.com/teracyhq/flask-classful/issues/50 - if hasattr(cls, 'base_args'): - # thanks to: https://github.com/teracyhq/flask-classful/pull/56#issuecomment-328985183 - cls.base_args = list(set(cls.base_args).union(r[2] for r in base_rule)) - else: - cls.base_args = [r[2] for r in base_rule] + if not route_base.startswith('/'): + route_base = '/' + route_base + base_rule = Rule(route_base) + # Add rule to a dummy map and bind that map so that + # the Rule's arguments field is populated + Map(rules=[base_rule]).bind('') + cls.base_args.extend(base_rule.arguments) else: route_base = cls.default_route_base() @@ -524,4 +525,3 @@ def unpack(value): class DecoratorCompatibilityError(Exception): pass - diff --git a/requirements.txt b/requirements.txt index 83fa719..362eaa4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ # test -nose -tox +pytest # code style, coverage coverage diff --git a/run-dev.sh b/run-dev.sh index c758e3c..daed50c 100644 --- a/run-dev.sh +++ b/run-dev.sh @@ -4,8 +4,7 @@ set -eu pipefail make resolve; -pip install Flask==$FLASK; -pip install webargs!=5.0.0; +pip install $REQUIREMENTS; python setup.py install; if [ "$CHECK_STYLE" = "yes" ] || [ "$CHECK_STYLE" = "1" ]; then @@ -13,6 +12,7 @@ if [ "$CHECK_STYLE" = "yes" ] || [ "$CHECK_STYLE" = "1" ]; then fi if [ "$RUN_TEST" = "yes" ] || [ "$RUN_TEST" = "1" ]; then + pip install webargs make test; make report-coverage; fi diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index da714c7..0000000 --- a/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[nosetests] -where=test_classful -py3where=. diff --git a/test_classful/__init__.py b/test_classful/__init__.py index cb06308..e69de29 100644 --- a/test_classful/__init__.py +++ b/test_classful/__init__.py @@ -1,9 +0,0 @@ -import nose - - -if __name__ == "__main__": - # nose.run() - nose.run(env={ - 'NOSE_INCLUDE_EXE': True, - 'NOSE_VERBOSE': 2 - }) diff --git a/test_classful/test_base_args.py b/test_classful/test_base_args.py index 0e4edca..47e5826 100644 --- a/test_classful/test_base_args.py +++ b/test_classful/test_base_args.py @@ -6,7 +6,6 @@ from marshmallow import Schema, fields from webargs.flaskparser import use_args from webargs import fields -from nose.tools import eq_ # we'll make a list to hold some quotes for our app quotes = [ @@ -138,69 +137,68 @@ def put(self, args, id): def test_users_post(): resp = client.post('users/', headers=input_headers, data=json.dumps({'email':'test@example.com'})) - eq_(resp.status_code, 200) - eq_("test@example.com", resp.data.decode('ascii')) + assert resp.status_code == 200 + assert "test@example.com" == resp.data.decode('ascii') def test_users_put(): resp = client.put('users/1/', headers=input_headers, data=json.dumps({'email':'test@example.com'})) - eq_(resp.status_code, 200) - eq_("test@example.com", resp.data.decode('ascii')) + assert resp.status_code == 200 + assert "test@example.com" == resp.data.decode('ascii') def test_users_patch(): resp = client.patch('users/1/', headers=input_headers, data=json.dumps({'email':'test@example.com'})) - eq_(resp.status_code, 200) - eq_("test@example.com", resp.data.decode('ascii')) + assert resp.status_code == 200 + assert "test@example.com" == resp.data.decode('ascii') def test_quotes_index(): resp = client.get("/quotes/") num = len(str(resp.data).split("
")) - eq_(3, num) + assert 3 == num resp = client.get("/quotes") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_quotes_get(): resp = client.get("/quotes/0/") - eq_(quotes[0], resp.data.decode('ascii')) + assert quotes[0] == resp.data.decode('ascii') def test_quotes_put(): resp = client.put("/quotes/1/", headers=input_headers, data=json.dumps(input_data)) - eq_(input_data["text"], resp.data.decode('ascii')) + assert input_data["text"] == resp.data.decode('ascii') def test_quotes_factory(): resp = client.patch("/quotes/1/", headers=input_headers, data=json.dumps(input_data)) - eq_(input_data["text"], resp.data.decode('ascii')) + assert input_data["text"] == resp.data.decode('ascii') def test_quotes2_index(): resp = client.get("/quotes-2/") num = len(str(resp.data).split("
")) - eq_(3, num) + assert 3 == num resp = client.get("/quotes-2") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_quotes2_get(): resp = client.get("/quotes-2/0/") - eq_(quotes[0], resp.data.decode('ascii')) - eq_(UglyNameView.base_args.count(UglyNameView.route_base), 1) + assert quotes[0] == resp.data.decode('ascii') + assert UglyNameView.base_args.count(UglyNameView.route_base) == 0 def test_quotes2_put(): resp = client.put("/quotes-2/1/", headers=input_headers, data=json.dumps(input_data)) - eq_(input_data["text"], resp.data.decode('ascii')) - eq_(UglyNameView.base_args.count(UglyNameView.route_base), 1) + assert input_data["text"] == resp.data.decode('ascii') + assert UglyNameView.base_args.count(UglyNameView.route_base) == 0 # see: https://github.com/teracyhq/flask-classful/pull/56#issuecomment-328985183 def test_unique_elements(): client.put("/quotes-2/1/", headers=input_headers, data=json.dumps(input_data)) - eq_(UglyNameView.base_args.count(UglyNameView.route_base), 1) - + assert UglyNameView.base_args.count(UglyNameView.route_base) == 0 diff --git a/test_classful/test_blueprints.py b/test_classful/test_blueprints.py index 00b2e0d..b5eb5df 100644 --- a/test_classful/test_blueprints.py +++ b/test_classful/test_blueprints.py @@ -2,7 +2,6 @@ from flask import Flask, Blueprint from .view_classes import BasicView, IndexView, JSONifyTestView -from nose.tools import eq_ app = Flask("blueprints") bp = Blueprint("bptest", "bptest") @@ -16,123 +15,125 @@ def test_bp_index(): resp = client.get("/basic/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_bp_get(): resp = client.get("/basic/1234/") - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get("/basic/1234") print(resp) - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_bp_put(): resp = client.put("/basic/1234/") - eq_(b"Put 1234", resp.data) + assert b"Put 1234" == resp.data resp = client.put("/basic/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_bp_patch(): resp = client.patch("/basic/1234/") - eq_(b"Patch 1234", resp.data) + assert b"Patch 1234" == resp.data resp = client.patch("/basic/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_bp_post(): resp = client.post("/basic/") - eq_(b"Post", resp.data) + assert b"Post" == resp.data def test_bp_delete(): resp = client.delete("/basic/1234/") - eq_(b"Delete 1234", resp.data) + assert b"Delete 1234" == resp.data resp = client.delete("/basic/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_bp_custom_method(): resp = client.get("/basic/custom_method/") - eq_(b"Custom Method", resp.data) + assert b"Custom Method" == resp.data resp = client.get("/basic/custom_method") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_bp_custom_method_with_params(): resp = client.get("/basic/custom_method_with_params/1234/abcd/") - eq_(b"Custom Method 1234 abcd", resp.data) + assert b"Custom Method 1234 abcd" == resp.data resp = client.get("/basic/custom_method_with_params/1234/abcd") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_bp_routed_method(): resp = client.get("/basic/routed/") - eq_(b"Routed Method", resp.data) + assert b"Routed Method" == resp.data def test_bp_multi_routed_method(): resp = client.get("/basic/route1/") - eq_(b"Multi Routed Method", resp.data) + assert b"Multi Routed Method" == resp.data resp = client.get("/basic/route2/") - eq_(b"Multi Routed Method", resp.data) + assert b"Multi Routed Method" == resp.data def test_bp_no_slash(): resp = client.get("/basic/noslash") - eq_(b"No Slash Method", resp.data) + assert b"No Slash Method" == resp.data resp = client.get("/basic/noslash/") # matches get(id) - eq_(b"Get noslash", resp.data) + assert b"Get noslash" == resp.data def test_bp_index_view_index(): resp = client.get("/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_bp_custom_http_method(): resp = client.post("/basic/route3/") - eq_(b"Custom HTTP Method", resp.data) + assert b"Custom HTTP Method" == resp.data def test_bp_url_prefix(): + app = Flask("blueprints") foo = Blueprint('foo', __name__) BasicView.register(foo, route_base="/") app.register_blueprint(foo, url_prefix='/foo') + client = app.test_client() resp = client.get('/foo/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_jsonify_normal_index(): resp = client.get('/jsonify') - eq_(resp.status_code, 200) - eq_(json.loads(resp.data.decode('utf-8')), dict(success=True)) + assert resp.status_code == 200 + assert json.loads(resp.data.decode('utf-8')) == dict(success=True) def test_jsonify_post_custom_status_code(): resp = client.post('/jsonify') - eq_(resp.status_code, 201) - eq_(json.loads(resp.data.decode('utf-8')), dict(success=True)) + assert resp.status_code == 201 + assert json.loads(resp.data.decode('utf-8')) == dict(success=True) def test_jsonify_not_found(): resp = client.get('/jsonify/not-found') - eq_(resp.status_code, 404) - eq_(json.loads(resp.data.decode('utf-8')), dict(success=False)) + assert resp.status_code == 404 + assert json.loads(resp.data.decode('utf-8')) == dict(success=False) def test_custom_header(): resp = client.get('/jsonify/custom-header') - eq_(resp.status_code, 418) - eq_(resp.headers['X-TEAPOT'], '1') - eq_(json.loads(resp.data.decode('utf-8')), dict(success=True)) + assert resp.status_code == 418 + assert resp.headers['X-TEAPOT'] == '1' + assert json.loads(resp.data.decode('utf-8')) == dict(success=True) def test_normal_jsonify(): resp = client.get('/jsonify/normal') - eq_(resp.status_code, 200) - eq_(resp.headers is not None, True) - eq_(json.loads(resp.data.decode('utf-8')), dict(success=True)) + assert resp.status_code == 200 + assert resp.headers is not None + assert json.loads(resp.data.decode('utf-8')) == dict(success=True) diff --git a/test_classful/test_bp_subdomains.py b/test_classful/test_bp_subdomains.py index 9331dc0..e35552e 100644 --- a/test_classful/test_bp_subdomains.py +++ b/test_classful/test_bp_subdomains.py @@ -1,6 +1,5 @@ from flask import Flask, Blueprint from .view_classes import BasicView, SubdomainAttributeView, SubdomainRouteView -from nose.tools import eq_ app = Flask("blueprints") app.config["SERVER_NAME"] = "test.test" @@ -22,19 +21,19 @@ def test_bp_attr_subdomain(): resp = client.get( "/subdomain-attribute/", base_url="http://sub1.test.test") - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_bp_route_subdomain(): resp = client.get("/subdomain-route/", base_url="http://sub2.test.test") - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_bp_register_subdomain(): resp = client.get("/basic/", base_url="http://sub3.test.test") - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_bp_bp_subdomain(): resp = client.get("/basic/", base_url="http://sub4.test.test") - eq_(b"Index", resp.data) + assert b"Index" == resp.data diff --git a/test_classful/test_common.py b/test_classful/test_common.py index b9e28f3..7e1a6c6 100644 --- a/test_classful/test_common.py +++ b/test_classful/test_common.py @@ -1,181 +1,183 @@ from flask import Flask from flask_classful import unpack, get_true_argspec, method, route, DecoratorCompatibilityError from .view_classes import BasicView, IndexView -from nose.tools import eq_, raises +from pytest import raises + app = Flask("common") BasicView.register(app) IndexView.register(app) + client = app.test_client() def test_index(): resp = client.get("/basic/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_get(): resp = client.get("/basic/1234/") - eq_(resp.status_code, 404) - eq_(b"Get 1234", resp.data) + assert resp.status_code == 404 + assert b"Get 1234" == resp.data resp = client.get("/basic/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_put(): resp = client.put("/basic/1234/") - eq_(resp.status_code, 403) - eq_(resp.headers['say'], 'hello') - eq_(b"Put 1234", resp.data) + assert resp.status_code == 403 + assert resp.headers['say'] == 'hello' + assert b"Put 1234" == resp.data resp = client.put("/basic/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_patch(): resp = client.patch("/basic/1234/") - eq_(b"Patch 1234", resp.data) + assert b"Patch 1234" == resp.data resp = client.patch("/basic/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_post(): resp = client.post("/basic/") - eq_(b"Post", resp.data) + assert b"Post" == resp.data resp = client.post("/basic") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_delete(): resp = client.delete("/basic/1234/") - eq_(b"Delete 1234", resp.data) + assert b"Delete 1234" == resp.data resp = client.delete("/basic/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_custom_method(): resp = client.get("/basic/custom_method/") - eq_(b"Custom Method", resp.data) + assert b"Custom Method" == resp.data resp = client.get("/basic/custom_method") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_custom_method_with_params(): resp = client.get("/basic/custom_method_with_params/1234/abcd/") - eq_(b"Custom Method 1234 abcd", resp.data) + assert b"Custom Method 1234 abcd" == resp.data resp = client.get("/basic/custom_method_with_params/1234/abcd") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_routed_method(): resp = client.get("/basic/routed/") - eq_(b"Routed Method", resp.data) + assert b"Routed Method" == resp.data resp = client.get("/basic/routed") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_multi_routed_method(): resp = client.get("/basic/route1/") - eq_(b"Multi Routed Method", resp.data) + assert b"Multi Routed Method" == resp.data resp = client.get("/basic/route1") - eq_(resp.status_code, 308) + assert resp.status_code == 308 resp = client.get("/basic/route2/") - eq_(b"Multi Routed Method", resp.data) + assert b"Multi Routed Method" == resp.data resp = client.get("/basic/route2") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_no_slash(): resp = client.get("/basic/noslash") - eq_(b"No Slash Method", resp.data) + assert b"No Slash Method" == resp.data resp = client.get("/basic/noslash/") # matches get(id) - eq_(b"Get noslash", resp.data) + assert b"Get noslash" == resp.data def test_index_view_index(): resp = client.get("/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_custom_http_method(): resp = client.post("/basic/route3/") - eq_(b"Custom HTTP Method", resp.data) + assert b"Custom HTTP Method" == resp.data resp = client.post("/basic/route3") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_method_decorator_simple(): resp = client.post("/basic/methoddecorated/") - eq_(b"POST", resp.data) + assert b"POST" == resp.data resp = client.post("/basic/methoddecorated") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_method_decorator_twice(): resp = client.post('/basic/methodtwicedecorated/') - eq_(b"POST", resp.data) + assert b"POST" == resp.data resp = client.patch('/basic/methodtwicedecorated/') - eq_(b"PATCH", resp.data) + assert b"PATCH" == resp.data def test_method_route(): """Test that the @method decorator does not come into play when a route is set explicitly""" resp = client.post('/basic/methodroute') - eq_(resp.status_code, 405) + assert resp.status_code == 405 resp = client.get('/basic/methodroute') - eq_(b"GET", resp.data) + assert b"GET" == resp.data def test_docstrings(): proxy_func = app.view_functions["BasicView:index"] - eq_(proxy_func.__doc__, BasicView.index.__doc__) + assert proxy_func.__doc__ == BasicView.index.__doc__ def test_unpack_tuple(): """Test unpack tuple data""" response, code, headers = unpack(("response", 100, "c")) - eq_("response", response) - eq_(100, code) - eq_("c", headers) + assert "response" == response + assert 100 == code + assert "c" == headers response, code, headers = unpack(('response', 404)) - eq_("response", response) - eq_(404, code) - eq_({}, headers) + assert "response" == response + assert 404 == code + assert {} == headers response, code, headers = unpack(('response')) - eq_("response", response) - eq_(200, code) - eq_({}, headers) + assert "response" == response + assert 200 == code + assert {} == headers def test_unpack_not_tuple(): """Test unpack not tuple data""" response, code, headers = unpack(None) - eq_(None, response) - eq_(200, code) - eq_({}, headers) + assert None == response + assert 200 == code + assert {} == headers response, code, headers = unpack({}) - eq_({}, response) - eq_(200, code) - eq_({}, headers) + assert {} == response + assert 200 == code + assert {} == headers response, code, headers = unpack("string") - eq_("string", response) - eq_(200, code) - eq_({}, headers) + assert "string" == response + assert 200 == code + assert {} == headers response, code, headers = unpack(('response', 1, 2, 3, 4, 5)) - eq_(('response', 1, 2, 3, 4, 5), response) - eq_(200, code) - eq_({}, headers) + assert ('response', 1, 2, 3, 4, 5) == response + assert 200 == code + assert {} == headers -@raises(TypeError) def test_get_true_argspec_raise_error(): """Test get_true_argspec will raise error if method is not correct""" - get_true_argspec(None) + with raises(TypeError): + get_true_argspec(None) def test_get_true_argspec_func(): @@ -193,5 +195,5 @@ def _inner(): response = get_true_argspec(_method) - eq_(None, response) + assert None == response diff --git a/test_classful/test_decorators.py b/test_classful/test_decorators.py index 3984b04..e21918a 100644 --- a/test_classful/test_decorators.py +++ b/test_classful/test_decorators.py @@ -6,7 +6,6 @@ from .view_classes import DecoratedListFunctionAttributesView from .view_classes import DecoratedListMemberFunctionAttributesView from .view_classes import DecoratedAppendClassAttributeView -from nose.tools import eq_ app = Flask("decorated") DecoratedView.register(app) @@ -21,106 +20,106 @@ def test_func_decorator_index(): resp = client.get('/decorated/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get('/decorated') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_func_decorator_get(): resp = client.get('/decorated/1234/') - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get('/decorated/1234') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_recursive_decorator_post(): resp = client.post('/decorated/') - eq_(b"Post", resp.data) + assert b"Post" == resp.data resp = client.post('/decorated') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_more_recursive_decorator_get(): resp = client.get('/decorated/get_some/') - eq_(b"Get Some", resp.data) + assert b"Get Some" == resp.data resp = client.get('/decorated/get_some') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_multiple_recursive_decorators_get(): resp = client.get('/decorated/get_this/') - eq_(b"Get This", resp.data) + assert b"Get This" == resp.data resp = client.get('/decorated/get_this') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_routes_with_recursive_decorators(): resp = client.get('/decorated/mixitup/') - eq_(b"Mix It Up", resp.data) + assert b"Mix It Up" == resp.data resp = client.get('/decorated/mixitup') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_recursive_with_parameter(): resp = client.get('/decorated/someval/1234/') - eq_(b"Someval 1234", resp.data) + assert b"Someval 1234" == resp.data def test_recursive_with_route_with_parameter(): resp = client.get('/decorated/anotherval/1234/') - eq_(b"Anotherval 1234", resp.data) + assert b"Anotherval 1234" == resp.data def test_params_decorator(): resp = client.get('/decorated/params_decorator_method/') - eq_(b"Params Decorator", resp.data) + assert b"Params Decorator" == resp.data def test_params_decorator_delete(): resp = client.delete('/decorated/1234/') - eq_(b"Params Decorator Delete 1234", resp.data) + assert b"Params Decorator Delete 1234" == resp.data resp = client.delete('/decorated/1234') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_decorator_bold_list_get(): """Tests that the get route is wrapped in bold""" resp = client.get('/decorated_bold_list_view/1234/') - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'Get 1234', resp.data) + assert b'' in resp.data + assert b'' in resp.data + assert b'Get 1234' == resp.data resp = client.get('/decorated_bold_list_view/1234') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_decorator_bold_list_index(): """Tests that the index route is wrapped in bold""" resp = client.get('/decorated_bold_list_view/') - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'Index', resp.data) + assert b'' in resp.data + assert b'' in resp.data + assert b'Index' == resp.data def test_decorator_bold_italics_list_get(): """Tests that the get route is wrapped in bold and italics""" resp = client.get('/decorated_bold_italics_list_view/1234/') - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'Get 1234', resp.data) + assert b'' in resp.data + assert b'' in resp.data + assert b'' in resp.data + assert b'' in resp.data + assert b'Get 1234' == resp.data resp = client.get('/decorated_bold_italics_list_view/1234') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_decorator_bold_italics_list_index(): """Tests that the index route is wrapped in bold and italics""" resp = client.get('/decorated_bold_italics_list_view/') - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'Index', resp.data) + assert b'' in resp.data + assert b'' in resp.data + assert b'' in resp.data + assert b'' in resp.data + assert b'Index' == resp.data def test_decorator_list_member_index(): @@ -129,27 +128,27 @@ def test_decorator_list_member_index(): italics and paragraph """ resp = client.get('/decorated_list_member_view/') - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'' in resp.data, True) - eq_(b'

' not in resp.data, True) - eq_(b'

' not in resp.data, True) - eq_(b'Index', resp.data) + assert b'' in resp.data + assert b'' in resp.data + assert b'' in resp.data + assert b'' in resp.data + assert b'

' not in resp.data + assert b'

' not in resp.data + assert b'Index' == resp.data def test_decorator_list_member_get(): """Tests the ordering of decorators""" resp = client.get('/decorated_list_member_view/1234/') - eq_(b'', resp.data[:3]) - eq_(b'', resp.data[3:6]) - eq_(b'

', resp.data[6:9]) - eq_(b'

', resp.data[-12:-8]) - eq_(b'
', resp.data[-8:-4]) - eq_(b'
', resp.data[-4:]) - eq_(b'

Get 1234

', resp.data) + assert b'' == resp.data[:3] + assert b'' == resp.data[3:6] + assert b'

' == resp.data[6:9] + assert b'

' == resp.data[-12:-8] + assert b'
' == resp.data[-8:-4] + assert b'
' == resp.data[-4:] + assert b'

Get 1234

' == resp.data resp = client.get('/decorated_list_member_view/1234') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_decorator_list_function_attributes_get(): @@ -157,16 +156,15 @@ def test_decorator_list_function_attributes_get(): Verify list of decorators with attributes modify all functions in FlaskView """ resp = client.get('/decorated_list_function_attributes_view/1234/') - eq_(b'Get 1234' in resp.data, True) - eq_(b'Get 1234', resp.data) - eq_(hasattr( - app.view_functions['DecoratedListFunctionAttributesView:get'], - 'eggs'), - True) - eq_('scrambled', - app.view_functions['DecoratedListFunctionAttributesView:get'].eggs) + assert b'Get 1234' in resp.data + assert b'Get 1234' == resp.data + assert hasattr( + app.view_functions['DecoratedListFunctionAttributesView:get'], + 'eggs') + assert 'scrambled' == \ + app.view_functions['DecoratedListFunctionAttributesView:get'].eggs resp = client.get('/decorated_list_function_attributes_view/1234') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_decorator_list_function_attributes_index(): @@ -174,47 +172,43 @@ def test_decorator_list_function_attributes_index(): Verify list of decorators with attributes modify all functions in FlaskView """ resp = client.get('/decorated_list_function_attributes_view/') - eq_(b'Index' in resp.data, True) - eq_(b'Index', resp.data) - eq_(hasattr( - app.view_functions['DecoratedListFunctionAttributesView:index'], - 'eggs'), - True) - eq_('scrambled', - app.view_functions['DecoratedListFunctionAttributesView:index'].eggs) + assert b'Index' in resp.data + assert b'Index' == resp.data + assert hasattr( + app.view_functions['DecoratedListFunctionAttributesView:index'], + 'eggs') + assert 'scrambled' == \ + app.view_functions['DecoratedListFunctionAttributesView:index'].eggs def test_decorator_list_member_function_attributes_get(): """Verify decorator with attributes does not modify other members""" resp = client.get('/decorated_list_member_function_attributes_view/4321/') - eq_(b'Get 4321' in resp.data, True) - eq_(b'Get 4321', resp.data) - eq_( - hasattr( + assert b'Get 4321' in resp.data + assert b'Get 4321' == resp.data + assert hasattr( app.view_functions[ 'DecoratedListMemberFunctionAttributesView:get' - ], 'eggs'), - False) + ], 'eggs') is False resp = client.get('/decorated_list_member_function_attributes_view/4321') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_decorator_list_member_function_attributes_index(): """Verify decorator with attributes modify decorated memeber functions""" resp = client.get('/decorated_list_member_function_attributes_view/') - eq_(b'Index' in resp.data, True) - eq_(b'Index', resp.data) - eq_(hasattr( + assert b'Index' in resp.data + assert b'Index' == resp.data + assert hasattr( app.view_functions[ 'DecoratedListMemberFunctionAttributesView:index' - ], 'eggs'), - True) - eq_('scrambled', + ], 'eggs') + assert 'scrambled' == \ app.view_functions[ 'DecoratedListMemberFunctionAttributesView:index' - ].eggs) + ].eggs def test_decorator_append_class_attribute_index(): resp = client.get('/decorated_append_class_attribute_view/') - eq_(b'Index (this is a test)', resp.data) + assert b'Index (this is a test)' == resp.data diff --git a/test_classful/test_default_methods.py b/test_classful/test_default_methods.py index 32459f2..8b695fe 100644 --- a/test_classful/test_default_methods.py +++ b/test_classful/test_default_methods.py @@ -1,6 +1,5 @@ from flask import Flask from .view_classes import DefaultMethodsView, NoDefaultMethodsView -from nose.tools import eq_ app = Flask('default_methods') @@ -11,14 +10,14 @@ def test_default_methods(): client = app.test_client() resp = client.get('/default-methods/foo/') - eq_(b"GET", resp.data) + assert b"GET" == resp.data resp = client.post('/default-methods/foo/') - eq_(b"POST", resp.data) + assert b"POST" == resp.data def test_no_default_methods(): client = app.test_client() resp = client.get('/no-default-methods/foo/') - eq_(b"GET", resp.data) + assert b"GET" == resp.data resp = client.post('/no-default-methods/foo/') - eq_(resp.status_code, 405) + assert resp.status_code == 405 diff --git a/test_classful/test_endpoints.py b/test_classful/test_endpoints.py index 1e7b894..28d362c 100644 --- a/test_classful/test_endpoints.py +++ b/test_classful/test_endpoints.py @@ -1,6 +1,5 @@ from flask import Flask, url_for from .view_classes import BasicView, IndexView, RouteBaseView, VarBaseView -from nose.tools import eq_ app = Flask("common") BasicView.register(app) @@ -14,40 +13,40 @@ def test_index_url(): with app.test_request_context(): url = url_for("IndexView:index") - eq_("/", url) + assert "/" == url def test_basic_index_url(): with app.test_request_context(): url = url_for("BasicView:index") - eq_("/basic/", url) + assert "/basic/" == url def test_custom_endpoint_url(): with app.test_request_context(): url = url_for("basic_endpoint") - eq_("/basic/endpoint/", url) + assert "/basic/endpoint/" == url def test_custom_route_base(): with app.test_request_context(): url = url_for('RouteBaseView:index') - eq_("/base-routed/", url) + assert "/base-routed/" == url def test_variable_route_popped_base(): with app.test_request_context(): url = url_for('VarBaseView:index', route='bar') - eq_('/var-base-route/bar/', url) + assert '/var-base-route/bar/' == url def test_variable_route_base(): with app.test_request_context(): url = url_for('VarBaseView:with_base_arg', route='bar') - eq_('/var-base-route/bar/with_base_arg/', url) + assert '/var-base-route/bar/with_base_arg/' == url def test_variable_route_base_with_local_route_var(): client = app.test_client() resp = client.get('/var-base-route/bar/local/baz') - eq_(resp.data, b"bar baz") + assert resp.data == b"bar baz" diff --git a/test_classful/test_excluded_methods.py b/test_classful/test_excluded_methods.py index 9dbada2..991a04f 100644 --- a/test_classful/test_excluded_methods.py +++ b/test_classful/test_excluded_methods.py @@ -1,7 +1,6 @@ from flask import Flask from flask_classful import FlaskView -from nose.tools import eq_ class NormalMethodsView(FlaskView): @@ -43,16 +42,16 @@ def copy_form_data(self): def test_normal_methods_copy_form_data(): resp = client.get("/normal-methods/copy_form_data/") - eq_(b"copy form data", resp.data) + assert b"copy form data" == resp.data def test_excluded_methods_copy_form_data(): resp = client.get("/excluded-methods/copy_form_data/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_static_method_view(): resp = client.get("/static-method/setup/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 resp = client.get("/static-method/copy_form_data/") - eq_(b"copy form data", resp.data) + assert b"copy form data" == resp.data diff --git a/test_classful/test_inheritance.py b/test_classful/test_inheritance.py index a87b7d4..50b43f3 100644 --- a/test_classful/test_inheritance.py +++ b/test_classful/test_inheritance.py @@ -1,6 +1,5 @@ from flask import Flask from .view_classes import InheritanceView, DecoratedInheritanceView -from nose.tools import eq_ app = Flask('inheritance') InheritanceView.register(app) @@ -11,43 +10,43 @@ def test_index(): resp = client.get('/inheritance/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_override(): resp = client.get("/inheritance/1234/") - eq_(b"Inheritance Get 1234", resp.data) + assert b"Inheritance Get 1234" == resp.data resp = client.get("/inheritance/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_inherited(): resp = client.post('/inheritance/') - eq_(b"Post", resp.data) + assert b"Post" == resp.data def test_with_route(): resp = client.get("/inheritance/with_route") - eq_(b"Inheritance with route", resp.data) + assert b"Inheritance with route" == resp.data def test_override_with_route(): resp = client.delete("/inheritance/1234/delete") - eq_(b"Inheritance Delete 1234", resp.data) + assert b"Inheritance Delete 1234" == resp.data def test_inherited_base_route(): resp = client.get("/inheritance/routed/") - eq_(b"Routed Method", resp.data) + assert b"Routed Method" == resp.data def test_decorated_inherited_mixitup(): resp = client.get("/decorated-inheritance/mixitup/") - eq_(b"Mix It Up", resp.data) + assert b"Mix It Up" == resp.data def test_decorated_inheritance_get(): resp = client.get("/decorated-inheritance/1234/") - eq_(b"Decorated Inheritance Get 1234", resp.data) + assert b"Decorated Inheritance Get 1234" == resp.data resp = client.get("/decorated-inheritance/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 diff --git a/test_classful/test_init_argument.py b/test_classful/test_init_argument.py index c84145e..785683d 100644 --- a/test_classful/test_init_argument.py +++ b/test_classful/test_init_argument.py @@ -1,6 +1,5 @@ from flask import Flask from .view_classes import WithInitArgument, WithoutInitArgument -from nose.tools import eq_ import json app = Flask("init_argument") @@ -12,11 +11,11 @@ def test_init_argument_used(): resp = client.get("/with_init_argument/") - eq_("fistro de la praderarrr", json.loads(resp.data.decode('utf-8'))["init_argument"]) - eq_(resp.status_code, 200) + assert "fistro de la praderarrr" == json.loads(resp.data.decode('utf-8'))["init_argument"] + assert resp.status_code == 200 def test_init_argument_not_used(): resp = client.get("/without_init_argument/") - eq_("not sent", json.loads(resp.data.decode('utf-8'))["init_argument"]) - eq_(resp.status_code, 200) + assert "not sent" == json.loads(resp.data.decode('utf-8'))["init_argument"] + assert resp.status_code == 200 diff --git a/test_classful/test_inspect_args.py b/test_classful/test_inspect_args.py index 4bb01db..ce1aafe 100644 --- a/test_classful/test_inspect_args.py +++ b/test_classful/test_inspect_args.py @@ -1,8 +1,9 @@ import sys from flask import Flask from .view_classes import InspectArgsView, NoInspectArgsView, InspectArgsFalseView -from nose.tools import eq_, raises from flask_classful import DecoratorCompatibilityError +from pytest import raises + _py2 = sys.version_info[0] == 2 @@ -19,18 +20,18 @@ def test_inspect_args(): if _py2: expected = b"foo unicode(123) unicode(456) int(678)" - eq_(expected, resp.data) + assert expected == resp.data resp = client.get('/inspect-args/foo/123/456') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_no_inspect_args(): client = app.test_client() resp = client.get('/no-inspect-args/foo/', query_string={'arg1': 123, 'arg2': 456}) - eq_(b"foo int(123) int(456) int(678)", resp.data) + assert b"foo int(123) int(456) int(678)" == resp.data -@raises(DecoratorCompatibilityError) def test_inspect_args_error(): - InspectArgsFalseView.register(app) + with raises(DecoratorCompatibilityError): + InspectArgsFalseView.register(app) diff --git a/test_classful/test_method_dashified.py b/test_classful/test_method_dashified.py index 240ce12..3dfbeab 100644 --- a/test_classful/test_method_dashified.py +++ b/test_classful/test_method_dashified.py @@ -1,6 +1,5 @@ from flask import Flask from flask_classful import FlaskView -from nose.tools import eq_ class DashifiedDefaultView(FlaskView): @@ -31,21 +30,21 @@ def yet_another_route(self): def test_original_method_dashifield(): - eq_(False, DashifiedDefaultView.method_dashified) - eq_(True, DashifiedAttributeView.method_dashified) - eq_(True, DashifiedAttributeOverrideView.method_dashified) + assert False == DashifiedDefaultView.method_dashified + assert True == DashifiedAttributeView.method_dashified + assert True == DashifiedAttributeOverrideView.method_dashified def test_some_route(): resp = client.get('/dashified-default/some-route/') - eq_(b"some route", resp.data) + assert b"some route" == resp.data def test_another_route(): resp = client.get('/dashified-attribute/another-route/') - eq_(b"another route", resp.data) + assert b"another route" == resp.data def test_yet_another_route(): resp = client.get('/dashified-attribute-override/yet_another_route/') - eq_(b"yet another route", resp.data) + assert b"yet another route" == resp.data diff --git a/test_classful/test_register.py b/test_classful/test_register.py index b20147f..b9ac5d7 100644 --- a/test_classful/test_register.py +++ b/test_classful/test_register.py @@ -1,6 +1,7 @@ from flask import Flask, request -from flask_classful import get_interesting_members, FlaskView -from nose.tools import eq_, raises +from flask_classful import FlaskView +from pytest import raises + class BaseClass(): def put(self): @@ -17,18 +18,19 @@ def put(self): app = Flask('register') ChildClassView.register(app, base_class=BaseClass) -@raises(TypeError) + def test_register_is_not_correct(): - FlaskView.register(app) + with raises(TypeError): + FlaskView.register(app) def test_child_class(): """It can use method of child class normally""" client = app.test_client() resp = client.post('/child-class/') - eq_(b"POST", resp.data) + assert b"POST" == resp.data def test_base_class(): """It filter out the method has in base class""" client = app.test_client() resp = client.put('/child-class/') - eq_(resp.status_code, 405) + assert resp.status_code == 405 diff --git a/test_classful/test_representations.py b/test_classful/test_representations.py index c2dd4a8..cd59db9 100644 --- a/test_classful/test_representations.py +++ b/test_classful/test_representations.py @@ -1,7 +1,6 @@ from flask import Flask, make_response, redirect, request from flask_classful import FlaskView import json -from nose.tools import eq_, ok_ def output_json(data, code, headers=None): @@ -113,49 +112,49 @@ def post(self): def test_index_representation(): resp = client.get("/representation/", headers=input_headers) - eq_(json.dumps([response_1, response_2]), resp.data.decode('ascii')) + assert json.dumps([response_1, response_2]) == resp.data.decode('ascii') def test_get_representation(): resp = client.get("/representation/1/", headers=input_headers) - eq_(json.dumps(response_get), resp.data.decode('ascii')) + assert json.dumps(response_get) == resp.data.decode('ascii') resp = client.get("/representation/1") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_post_representation(): resp = client.post("/representation/", headers=input_headers, data=json.dumps(input_data)) - eq_(resp.status_code, 404, 'should return 404 status code') - eq_(resp.headers['say'], 'hello') - eq_(json.dumps(response_post), resp.data.decode('ascii')) + assert resp.status_code, 404 == 'should return 404 status code' + assert resp.headers['say'] == 'hello' + assert json.dumps(response_post) == resp.data.decode('ascii') def test_put_representation(): resp = client.put("/representation/1/", headers=input_headers, data=json.dumps(input_data)) - eq_(resp.status_code, 403, 'should return 403 status code') - eq_(json.dumps(response_put), resp.data.decode('ascii')) + assert resp.status_code, 403 == 'should return 403 status code' + assert json.dumps(response_put) == resp.data.decode('ascii') resp = client.put("/representation/1", headers=input_headers, data=json.dumps(input_data)) - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_delete_representation(): resp = client.delete("/representation/1/", headers=input_headers) - eq_(json.dumps(response_delete), resp.data.decode('ascii')) + assert json.dumps(response_delete) == resp.data.decode('ascii') resp = client.delete("/representation/1") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_skip_representation_matching_if_response_is_returned(): resp = client.get("/representation/redirect/") - eq_(resp.status_code, 302) - eq_(resp.location, "http://google.com") + assert resp.status_code == 302 + assert resp.location == "http://google.com" def test_representations_no_match_return_string(): @@ -163,9 +162,9 @@ def test_representations_no_match_return_string(): resp = client.get("/representation/mirror/", query_string={'q': 'foobar'}, headers={'Accept': 'foo/bar'}) - eq_(resp.data, b'foobar') - eq_(resp.headers['Content-Type'], 'foo/bar') - eq_(resp.status_code, 201) + assert resp.data == b'foobar' + assert resp.headers['Content-Type'] == 'foo/bar' + assert resp.status_code == 201 def test_default_representation(): @@ -175,10 +174,10 @@ def test_default_representation(): headers={'Accept': 'foo/bar', 'Content-Type': 'application/json'}) - eq_(resp.status_code, 201) - eq_(resp.headers['say'], 'hello') - eq_(resp.data, b'{"foo": "bar"}') - eq_(resp.headers['Content-Type'], 'flask-classful/default') + assert resp.status_code == 201 + assert resp.headers['say'] == 'hello' + assert resp.data == b'{"foo": "bar"}' + assert resp.headers['Content-Type'] == 'flask-classful/default' def test_representation_with_default(): @@ -187,7 +186,7 @@ def test_representation_with_default(): data=json.dumps({'foo': 'bar'}), headers=input_headers) - eq_(resp.status_code, 201) - eq_(resp.headers['say'], 'hello') - eq_(resp.data, b'{"foo": "bar"}') - eq_(resp.headers['Content-Type'], 'application/json') + assert resp.status_code == 201 + assert resp.headers['say'] == 'hello' + assert resp.data == b'{"foo": "bar"}' + assert resp.headers['Content-Type'] == 'application/json' diff --git a/test_classful/test_route_base.py b/test_classful/test_route_base.py index d09b96c..b540c5b 100644 --- a/test_classful/test_route_base.py +++ b/test_classful/test_route_base.py @@ -1,6 +1,5 @@ from flask import Flask from .view_classes import RouteBaseView, RouteBaseViewIsNotLatest -from nose.tools import eq_ app = Flask('route_base') RouteBaseView.register(app, route_base="/rb_test2/") @@ -10,10 +9,10 @@ def test_route_base_override(): client = app.test_client() resp = client.get('/rb_test2/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_route_base_no_view(): """Use class name as route""" client = app.test_client() resp = client.get('/route-base-view-is-not-latest/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data diff --git a/test_classful/test_route_prefix.py b/test_classful/test_route_prefix.py index 03fe399..f4dd361 100644 --- a/test_classful/test_route_prefix.py +++ b/test_classful/test_route_prefix.py @@ -1,6 +1,5 @@ from flask import Flask from .view_classes import BasicView, RoutePrefixView, RouteBaseView -from nose.tools import eq_ app = Flask('route_base') @@ -12,16 +11,16 @@ def test_route_prefix(): client = app.test_client() resp = client.get('/my_prefix/route-prefix/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_route_prefix_override(): client = app.test_client() resp = client.get('/prefix/basic/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_route_prefix_with_route_base(): client = app.test_client() resp = client.get('/prefix/base-routed/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data diff --git a/test_classful/test_rule_options.py b/test_classful/test_rule_options.py index b98745f..5c09c94 100644 --- a/test_classful/test_rule_options.py +++ b/test_classful/test_rule_options.py @@ -1,78 +1,15 @@ -from .view_classes import BasicView, IndexView +from .view_classes import BasicView from flask import Flask -from nose.tools import eq_ +from unittest.mock import patch -app = Flask("rules_options") -BasicView.register(app, strict_slashes=False) -IndexView.register(app, strict_slashes=False) -client = app.test_client() +@patch('flask.Flask.add_url_rule') +def test_rule_options(rule): + app = Flask("rules_options", static_folder=None) + BasicView.register(app, strict_slashes=False) -def test_rule_options_index(): - resp = client.get("/basic/") - eq_(b"Index", resp.data) - - resp = client.get("/basic") - eq_(b"Index", resp.data) - - -def test_rule_options_get(): - resp = client.get("/basic/1234/") - eq_(resp.status_code, 404) - eq_(b"Get 1234", resp.data) - - resp = client.get("/basic/1234") - eq_(resp.status_code, 404) - eq_(b"Get 1234", resp.data) - - -def test_rule_options_put(): - resp = client.put("/basic/1234/") - eq_(resp.status_code, 403) - eq_(resp.headers['say'], 'hello') - eq_(b"Put 1234", resp.data) - - resp = client.put("/basic/1234") - eq_(resp.status_code, 403) - eq_(resp.headers['say'], 'hello') - eq_(b"Put 1234", resp.data) - - -def test_rule_options_patch(): - resp = client.patch("/basic/1234/") - eq_(b"Patch 1234", resp.data) - - resp = client.patch("/basic/1234") - eq_(b"Patch 1234", resp.data) - - -def test_rule_options_post(): - resp = client.post("/basic/") - eq_(b"Post", resp.data) - - resp = client.post("/basic") - eq_(b"Post", resp.data) - - -def test_rule_options_delete(): - resp = client.delete("/basic/1234/") - eq_(b"Delete 1234", resp.data) - - resp = client.delete("/basic/1234") - eq_(b"Delete 1234", resp.data) - -def test_rule_options_custom_method(): - resp = client.get("/basic/custom_method/") - eq_(b"Custom Method", resp.data) - - resp = client.get("/basic/custom_method") - eq_(b"Custom Method", resp.data) - - -def test_rule_options_custom_method_with_params(): - resp = client.get("/basic/custom_method_with_params/1234/abcd/") - eq_(b"Custom Method 1234 abcd", resp.data) - - resp = client.get("/basic/custom_method_with_params/1234/abcd") - eq_(b"Custom Method 1234 abcd", resp.data) + client = app.test_client() + client.get("/basic/") + for args, kwargs in rule.call_args_list: + assert kwargs.get('strict_slashes') is False, (args, kwargs) diff --git a/test_classful/test_subdomains.py b/test_classful/test_subdomains.py index 7595d64..3ead5a1 100644 --- a/test_classful/test_subdomains.py +++ b/test_classful/test_subdomains.py @@ -1,6 +1,5 @@ from flask import Flask from .view_classes import BasicView -from nose.tools import eq_ app = Flask("common") app.config["SERVER_NAME"] = "test.test" @@ -11,70 +10,70 @@ def test_index_subdomain(): resp = client.get("/basic/", base_url="http://basic.test.test") - eq_(b"Index", resp.data) + assert b"Index" == resp.data def test_get(): resp = client.get("/basic/1234/", base_url="http://basic.test.test") - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get("/basic/1234", base_url="http://basic.test.test") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_put(): resp = client.put("/basic/1234/", base_url="http://basic.test.test") - eq_(b"Put 1234", resp.data) + assert b"Put 1234" == resp.data resp = client.put("/basic/1234", base_url="http://basic.test.test") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_patch(): resp = client.patch("/basic/1234/", base_url="http://basic.test.test") - eq_(b"Patch 1234", resp.data) + assert b"Patch 1234" == resp.data resp = client.patch("/basic/1234", base_url="http://basic.test.test") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_post(): resp = client.post("/basic/", base_url="http://basic.test.test") - eq_(b"Post", resp.data) + assert b"Post" == resp.data def test_delete(): resp = client.delete("/basic/1234/", base_url="http://basic.test.test") - eq_(b"Delete 1234", resp.data) + assert b"Delete 1234" == resp.data resp = client.delete("/basic/1234", base_url="http://basic.test.test") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_custom_method(): resp = client.get("/basic/custom_method/", base_url="http://basic.test.test") - eq_(b"Custom Method", resp.data) + assert b"Custom Method" == resp.data def test_custom_method_with_params(): resp = client.get("/basic/custom_method_with_params/1234/abcd/", base_url="http://basic.test.test") - eq_(b"Custom Method 1234 abcd", resp.data) + assert b"Custom Method 1234 abcd" == resp.data resp = client.get("/basic/custom_method_with_params/1234/abcd", base_url="http://basic.test.test") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_routed_method(): resp = client.get("/basic/routed/", base_url="http://basic.test.test") - eq_(b"Routed Method", resp.data) + assert b"Routed Method" == resp.data def test_multi_routed_method(): resp = client.get("/basic/route1/", base_url="http://basic.test.test") - eq_(b"Multi Routed Method", resp.data) + assert b"Multi Routed Method" == resp.data resp = client.get("/basic/route2/", base_url="http://basic.test.test") - eq_(b"Multi Routed Method", resp.data) + assert b"Multi Routed Method" == resp.data def test_no_slash(): resp = client.get("/basic/noslash", base_url="http://basic.test.test") - eq_(b"No Slash Method", resp.data) + assert b"No Slash Method" == resp.data diff --git a/test_classful/test_trailing_slash.py b/test_classful/test_trailing_slash.py index ad5185b..db8e259 100644 --- a/test_classful/test_trailing_slash.py +++ b/test_classful/test_trailing_slash.py @@ -8,7 +8,6 @@ EnabledNoTrailingSlashView, IndexView ) -from nose.tools import eq_ app = Flask('trailing_slash') BasicView.register(app, trailing_slash=False) @@ -24,184 +23,184 @@ def test_index(): resp = client.get("/basic") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("/basic/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_get(): resp = client.get("/basic/1234") - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get("/basic/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_put(): resp = client.put("/basic/1234") - eq_(b"Put 1234", resp.data) + assert b"Put 1234" == resp.data resp = client.put("/basic/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_patch(): resp = client.patch("/basic/1234") - eq_(b"Patch 1234", resp.data) + assert b"Patch 1234" == resp.data resp = client.patch("/basic/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_post(): resp = client.post("/basic") - eq_(b"Post", resp.data) + assert b"Post" == resp.data resp = client.post("/basic/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_delete(): resp = client.delete("/basic/1234") - eq_(b"Delete 1234", resp.data) + assert b"Delete 1234" == resp.data resp = client.delete("/basic/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_custom_method(): resp = client.get("/basic/custom_method") - eq_(b"Custom Method", resp.data) + assert b"Custom Method" == resp.data resp = client.get("/basic/custom_method/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_custom_method_with_params(): resp = client.get("/basic/custom_method_with_params/1234/abcd") - eq_(b"Custom Method 1234 abcd", resp.data) + assert b"Custom Method 1234 abcd" == resp.data resp = client.get("/basic/custom_method_with_params/1234/abcd/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_routed_method(): resp = client.get("/basic/routed/") - eq_(b"Routed Method", resp.data) + assert b"Routed Method" == resp.data resp = client.get("/basic/routed") - eq_(resp.status_code, 308) + assert resp.status_code == 308 # TrailingSlashView def test_trailing_index(): resp = client.get("/trailing") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("/trailing/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_get(): resp = client.get("/trailing/1234") - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get("/trailing/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_put(): resp = client.put("/trailing/1234") - eq_(b"Put 1234", resp.data) + assert b"Put 1234" == resp.data resp = client.put("/trailing/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_patch(): resp = client.patch("/trailing/1234") - eq_(b"Patch 1234", resp.data) + assert b"Patch 1234" == resp.data resp = client.patch("/trailing/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_post(): resp = client.post("/trailing") - eq_(b"Post", resp.data) + assert b"Post" == resp.data resp = client.post("/trailing/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_delete(): resp = client.delete("/trailing/1234") - eq_(b"Delete 1234", resp.data) + assert b"Delete 1234" == resp.data resp = client.delete("/trailing/1234/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_custom_method(): resp = client.get("/trailing/custom_method") - eq_(b"Custom Method", resp.data) + assert b"Custom Method" == resp.data resp = client.get("/trailing/custom_method/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_custom_method_with_params(): resp = client.get("/trailing/custom_method_with_params/1234/abcd") - eq_(b"Custom Method 1234 abcd", resp.data) + assert b"Custom Method 1234 abcd" == resp.data resp = client.get("/trailing/custom_method_with_params/1234/abcd/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 def test_trailing_routed_method(): resp = client.get("/trailing/routed/") - eq_(b"Routed Method", resp.data) + assert b"Routed Method" == resp.data resp = client.get("/trailing/routed") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_trailing_routed_method2(): resp = client.get("/trailing/routed2") - eq_(b"Routed Method 2", resp.data) + assert b"Routed Method 2" == resp.data resp = client.get("/trailing/routed2/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 # InheritedTrailingSlashView def test_inherited_trailing_slash(): resp = client.get("/inherited/trailing") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("/inherited/trailing/") - eq_(resp.status_code, 404) + assert resp.status_code == 404 # OverrideInheritedTrailingSlashView def test_inherited_trailing_slash_override(): resp = client.get("/override/trailing/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("/override/trailing") - eq_(resp.status_code, 308) + assert resp.status_code == 308 # EnabledHasTrailingSlashView def test_enabled_has_trailing_slash_view_index(): resp = client.get("/enabled-trailing-yes/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("/enabled-trailing-yes") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_enabled_has_trailing_slash_view_get(): resp = client.get("/enabled-trailing-yes/1234/") - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get("/enabled-trailing-yes/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 # EnabledNoTrailingSlashView def test_enabled_no_trailing_slash_view_index(): resp = client.get("/enabled-trailing-no/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("/enabled-trailing-no") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_enabled_no_trailing_slash_view_get(): resp = client.get("/enabled-trailing-no/1234/") - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get("/enabled-trailing-no/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 # IndexView route_base '/' and trailing slash False def test_index_trailing_slash(): resp = client.get("/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("") - eq_(resp.status_code, 308) + assert resp.status_code == 308 diff --git a/test_classful/test_view_wrappers.py b/test_classful/test_view_wrappers.py index 73cbf5e..9271bd7 100644 --- a/test_classful/test_view_wrappers.py +++ b/test_classful/test_view_wrappers.py @@ -8,7 +8,6 @@ BeforeRequestReturnsView, BeforeViewReturnsView ) -from nose.tools import eq_ app = Flask("wrappers") BeforeRequestView.register(app) @@ -24,39 +23,39 @@ def test_before_request(): resp = client.get("/before-request/") - eq_(b"Before Request", resp.data) + assert b"Before Request" == resp.data def test_before_view(): resp = client.get("/before-view/") - eq_(b"Before View", resp.data) + assert b"Before View" == resp.data def test_after_view(): resp = client.get("/after-view/") - eq_(b"After View", resp.data) + assert b"After View" == resp.data def test_after_request(): resp = client.get("/after-request/") - eq_(b"After Request", resp.data) + assert b"After Request" == resp.data def test_decorated_view(): resp = client.get("/decorated/") - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get("/decorated/1234/") - eq_(b"Get 1234", resp.data) + assert b"Get 1234" == resp.data resp = client.get("/decorated/1234") - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_before_request_returns(): resp = client.get("/before-request-returns/") - eq_(b"BEFORE", resp.data) + assert b"BEFORE" == resp.data def test_before_view_returns(): resp = client.get("/before-view-returns/") - eq_(b"BEFORE", resp.data) + assert b"BEFORE" == resp.data diff --git a/test_classful_py3/test_type_hints.py b/test_classful_py3/test_type_hints.py index 3974dc4..999c233 100644 --- a/test_classful_py3/test_type_hints.py +++ b/test_classful_py3/test_type_hints.py @@ -1,7 +1,6 @@ from uuid import UUID from flask import Flask from flask_classful import FlaskView, route -from nose.tools import eq_ # python3 only @@ -34,23 +33,23 @@ def uuid(self, arg: UUID): def test_index(): resp = client.get('/typing/') - eq_(b"Index", resp.data) + assert b"Index" == resp.data resp = client.get('/typing') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_post(): resp = client.post('/typing/123') - eq_(b"Post", resp.data) + assert b"Post" == resp.data resp = client.post('/typing/123/') - eq_(resp.status_code, 405) + assert resp.status_code == 405 def test_patch(): resp = client.patch('/typing/123/') - eq_(b"Patch", resp.data) + assert b"Patch" == resp.data resp = client.patch('/typing/123') - eq_(resp.status_code, 308) + assert resp.status_code == 308 def test_url_converter(): @@ -62,7 +61,7 @@ def test_url_converter(): url = '/typing/{}/{}/' resp = client.get(url.format(type_, wrong_var)) # should not match the endpoint if url variable type mismatches - eq_(resp.status_code, 404) + assert resp.status_code == 404 resp = client.get(url.format(type_, correct_var)) - eq_(resp.status_code, 200) - eq_(bytes(correct_var, 'utf-8'), resp.data) + assert resp.status_code == 200 + assert bytes(correct_var, 'utf-8') == resp.data diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 823ce00..0000000 --- a/tox.ini +++ /dev/null @@ -1,5 +0,0 @@ -[tox] -envlist = python2.6,python2.7,python3.3 -[testenv] -deps=nose -commands=nosetests