mirror of https://github.com/pallets/flask.git
				
				
				
			Merge pull request #1165 from untitaker/new_testsuite
Port testsuite to py.test
This commit is contained in:
		
						commit
						bb94a612fd
					
				|  | @ -1,6 +0,0 @@ | ||||||
| git+git://github.com/mitsuhiko/werkzeug.git#egg=Werkzeug |  | ||||||
| git+git://github.com/mitsuhiko/jinja2.git#egg=Jinja2 |  | ||||||
| git+git://github.com/mitsuhiko/itsdangerous.git#egg=itsdangerous |  | ||||||
| 
 |  | ||||||
| # extra dependencies |  | ||||||
| git+git://github.com/jek/blinker.git#egg=blinker |  | ||||||
|  | @ -1,6 +0,0 @@ | ||||||
| Werkzeug==0.7 |  | ||||||
| Jinja2==2.4 |  | ||||||
| itsdangerous==0.21 |  | ||||||
| 
 |  | ||||||
| # extra dependencies |  | ||||||
| blinker==1.0 |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| # extra dependencies |  | ||||||
| blinker |  | ||||||
							
								
								
									
										11
									
								
								.travis.yml
								
								
								
								
							
							
						
						
									
										11
									
								
								.travis.yml
								
								
								
								
							|  | @ -5,6 +5,7 @@ python: | ||||||
|   - "2.7" |   - "2.7" | ||||||
|   - "pypy" |   - "pypy" | ||||||
|   - "3.3" |   - "3.3" | ||||||
|  |   - "3.4" | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|   - REQUIREMENTS=lowest |   - REQUIREMENTS=lowest | ||||||
|  | @ -16,12 +17,16 @@ matrix: | ||||||
|     # Python 3 support currently does not work with lowest requirements |     # Python 3 support currently does not work with lowest requirements | ||||||
|     - python: "3.3" |     - python: "3.3" | ||||||
|       env: REQUIREMENTS=lowest |       env: REQUIREMENTS=lowest | ||||||
|  |     - python: "3.4" | ||||||
|  |       env: REQUIREMENTS=lowest | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| install: | install: | ||||||
|   - pip install -r .travis-$REQUIREMENTS-requirements.txt |     - pip install hg+https://bitbucket.org/hpk42/tox | ||||||
|   - pip install --editable . |  | ||||||
| 
 | 
 | ||||||
| script: make test | script: | ||||||
|  |     - tox -e \ | ||||||
|  |       $(echo py$TRAVIS_PYTHON_VERSION | tr -d . | sed -e 's/pypypy/pypy/')-$REQUIREMENTS | ||||||
| 
 | 
 | ||||||
| branches: | branches: | ||||||
|   except: |   except: | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| include Makefile CHANGES LICENSE AUTHORS run-tests.py | include Makefile CHANGES LICENSE AUTHORS | ||||||
| recursive-include artwork * | recursive-include artwork * | ||||||
| recursive-include tests * | recursive-include tests * | ||||||
| recursive-include examples * | recursive-include examples * | ||||||
|  | @ -9,8 +9,5 @@ recursive-exclude tests *.pyc | ||||||
| recursive-exclude tests *.pyo | recursive-exclude tests *.pyo | ||||||
| recursive-exclude examples *.pyc | recursive-exclude examples *.pyc | ||||||
| recursive-exclude examples *.pyo | recursive-exclude examples *.pyo | ||||||
| recursive-include flask/testsuite/static * |  | ||||||
| recursive-include flask/testsuite/templates * |  | ||||||
| recursive-include flask/testsuite/test_apps * |  | ||||||
| prune docs/_build | prune docs/_build | ||||||
| prune docs/_themes/.git | prune docs/_themes/.git | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							|  | @ -3,7 +3,7 @@ | ||||||
| all: clean-pyc test | all: clean-pyc test | ||||||
| 
 | 
 | ||||||
| test: | test: | ||||||
| 	python run-tests.py | 	py.test | ||||||
| 
 | 
 | ||||||
| tox-test: | tox-test: | ||||||
| 	tox | 	tox | ||||||
|  |  | ||||||
|  | @ -1,36 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     Blueprint Example Tests |  | ||||||
|     ~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests the Blueprint example app |  | ||||||
| """ |  | ||||||
| import blueprintexample |  | ||||||
| import unittest |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class BlueprintExampleTestCase(unittest.TestCase): |  | ||||||
| 
 |  | ||||||
|     def setUp(self): |  | ||||||
|         self.app = blueprintexample.app.test_client() |  | ||||||
|          |  | ||||||
|     def test_urls(self): |  | ||||||
|         r = self.app.get('/') |  | ||||||
|         self.assertEquals(r.status_code, 200) |  | ||||||
|          |  | ||||||
|         r = self.app.get('/hello') |  | ||||||
|         self.assertEquals(r.status_code, 200) |  | ||||||
|          |  | ||||||
|         r = self.app.get('/world') |  | ||||||
|         self.assertEquals(r.status_code, 200) |  | ||||||
|          |  | ||||||
|         #second blueprint instance |  | ||||||
|         r = self.app.get('/pages/hello') |  | ||||||
|         self.assertEquals(r.status_code, 200) |  | ||||||
|          |  | ||||||
|         r = self.app.get('/pages/world') |  | ||||||
|         self.assertEquals(r.status_code, 200) |  | ||||||
|          |  | ||||||
|          |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     unittest.main() |  | ||||||
|  | @ -0,0 +1,33 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     Blueprint Example Tests | ||||||
|  |     ~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests the Blueprint example app | ||||||
|  | """ | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import blueprintexample | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def client(): | ||||||
|  |     return blueprintexample.app.test_client() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_urls(client): | ||||||
|  |     r = client.get('/') | ||||||
|  |     assert r.status_code == 200 | ||||||
|  | 
 | ||||||
|  |     r = client.get('/hello') | ||||||
|  |     assert r.status_code == 200 | ||||||
|  | 
 | ||||||
|  |     r = client.get('/world') | ||||||
|  |     assert r.status_code == 200 | ||||||
|  | 
 | ||||||
|  |     # second blueprint instance | ||||||
|  |     r = client.get('/pages/hello') | ||||||
|  |     assert r.status_code == 200 | ||||||
|  | 
 | ||||||
|  |     r = client.get('/pages/world') | ||||||
|  |     assert r.status_code == 200 | ||||||
|  | @ -1,76 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     Flaskr Tests |  | ||||||
|     ~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests the Flaskr application. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| import os |  | ||||||
| import flaskr |  | ||||||
| import unittest |  | ||||||
| import tempfile |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class FlaskrTestCase(unittest.TestCase): |  | ||||||
| 
 |  | ||||||
|     def setUp(self): |  | ||||||
|         """Before each test, set up a blank database""" |  | ||||||
|         self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp() |  | ||||||
|         flaskr.app.config['TESTING'] = True |  | ||||||
|         self.app = flaskr.app.test_client() |  | ||||||
|         with flaskr.app.app_context(): |  | ||||||
|             flaskr.init_db() |  | ||||||
| 
 |  | ||||||
|     def tearDown(self): |  | ||||||
|         """Get rid of the database again after each test.""" |  | ||||||
|         os.close(self.db_fd) |  | ||||||
|         os.unlink(flaskr.app.config['DATABASE']) |  | ||||||
| 
 |  | ||||||
|     def login(self, username, password): |  | ||||||
|         return self.app.post('/login', data=dict( |  | ||||||
|             username=username, |  | ||||||
|             password=password |  | ||||||
|         ), follow_redirects=True) |  | ||||||
| 
 |  | ||||||
|     def logout(self): |  | ||||||
|         return self.app.get('/logout', follow_redirects=True) |  | ||||||
| 
 |  | ||||||
|     # testing functions |  | ||||||
| 
 |  | ||||||
|     def test_empty_db(self): |  | ||||||
|         """Start with a blank database.""" |  | ||||||
|         rv = self.app.get('/') |  | ||||||
|         assert b'No entries here so far' in rv.data |  | ||||||
| 
 |  | ||||||
|     def test_login_logout(self): |  | ||||||
|         """Make sure login and logout works""" |  | ||||||
|         rv = self.login(flaskr.app.config['USERNAME'], |  | ||||||
|                         flaskr.app.config['PASSWORD']) |  | ||||||
|         assert b'You were logged in' in rv.data |  | ||||||
|         rv = self.logout() |  | ||||||
|         assert b'You were logged out' in rv.data |  | ||||||
|         rv = self.login(flaskr.app.config['USERNAME'] + 'x', |  | ||||||
|                         flaskr.app.config['PASSWORD']) |  | ||||||
|         assert b'Invalid username' in rv.data |  | ||||||
|         rv = self.login(flaskr.app.config['USERNAME'], |  | ||||||
|                         flaskr.app.config['PASSWORD'] + 'x') |  | ||||||
|         assert b'Invalid password' in rv.data |  | ||||||
| 
 |  | ||||||
|     def test_messages(self): |  | ||||||
|         """Test that messages work""" |  | ||||||
|         self.login(flaskr.app.config['USERNAME'], |  | ||||||
|                    flaskr.app.config['PASSWORD']) |  | ||||||
|         rv = self.app.post('/add', data=dict( |  | ||||||
|             title='<Hello>', |  | ||||||
|             text='<strong>HTML</strong> allowed here' |  | ||||||
|         ), follow_redirects=True) |  | ||||||
|         assert b'No entries here so far' not in rv.data |  | ||||||
|         assert b'<Hello>' in rv.data |  | ||||||
|         assert b'<strong>HTML</strong> allowed here' in rv.data |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     unittest.main() |  | ||||||
|  | @ -0,0 +1,77 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     Flaskr Tests | ||||||
|  |     ~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests the Flaskr application. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import os | ||||||
|  | import flaskr | ||||||
|  | import tempfile | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def client(request): | ||||||
|  |     db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp() | ||||||
|  |     flaskr.app.config['TESTING'] = True | ||||||
|  |     client = flaskr.app.test_client() | ||||||
|  |     with flaskr.app.app_context(): | ||||||
|  |         flaskr.init_db() | ||||||
|  | 
 | ||||||
|  |     def teardown(): | ||||||
|  |         os.close(db_fd) | ||||||
|  |         os.unlink(flaskr.app.config['DATABASE']) | ||||||
|  |     request.addfinalizer(teardown) | ||||||
|  | 
 | ||||||
|  |     return client | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def login(client, username, password): | ||||||
|  |     return client.post('/login', data=dict( | ||||||
|  |         username=username, | ||||||
|  |         password=password | ||||||
|  |     ), follow_redirects=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def logout(client): | ||||||
|  |     return client.get('/logout', follow_redirects=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_empty_db(client): | ||||||
|  |     """Start with a blank database.""" | ||||||
|  |     rv = client.get('/') | ||||||
|  |     assert b'No entries here so far' in rv.data | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_login_logout(client): | ||||||
|  |     """Make sure login and logout works""" | ||||||
|  |     rv = login(client, flaskr.app.config['USERNAME'], | ||||||
|  |                flaskr.app.config['PASSWORD']) | ||||||
|  |     assert b'You were logged in' in rv.data | ||||||
|  |     rv = logout(client) | ||||||
|  |     assert b'You were logged out' in rv.data | ||||||
|  |     rv = login(client, flaskr.app.config['USERNAME'] + 'x', | ||||||
|  |                flaskr.app.config['PASSWORD']) | ||||||
|  |     assert b'Invalid username' in rv.data | ||||||
|  |     rv = login(client, flaskr.app.config['USERNAME'], | ||||||
|  |                flaskr.app.config['PASSWORD'] + 'x') | ||||||
|  |     assert b'Invalid password' in rv.data | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_messages(client): | ||||||
|  |     """Test that messages work""" | ||||||
|  |     login(client, flaskr.app.config['USERNAME'], | ||||||
|  |           flaskr.app.config['PASSWORD']) | ||||||
|  |     rv = client.post('/add', data=dict( | ||||||
|  |         title='<Hello>', | ||||||
|  |         text='<strong>HTML</strong> allowed here' | ||||||
|  |     ), follow_redirects=True) | ||||||
|  |     assert b'No entries here so far' not in rv.data | ||||||
|  |     assert b'<Hello>' in rv.data | ||||||
|  |     assert b'<strong>HTML</strong> allowed here' in rv.data | ||||||
|  | @ -1,150 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     MiniTwit Tests |  | ||||||
|     ~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests the MiniTwit application. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| import os |  | ||||||
| import minitwit |  | ||||||
| import unittest |  | ||||||
| import tempfile |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class MiniTwitTestCase(unittest.TestCase): |  | ||||||
| 
 |  | ||||||
|     def setUp(self): |  | ||||||
|         """Before each test, set up a blank database""" |  | ||||||
|         self.db_fd, minitwit.app.config['DATABASE'] = tempfile.mkstemp() |  | ||||||
|         self.app = minitwit.app.test_client() |  | ||||||
|         with minitwit.app.app_context(): |  | ||||||
|             minitwit.init_db() |  | ||||||
| 
 |  | ||||||
|     def tearDown(self): |  | ||||||
|         """Get rid of the database again after each test.""" |  | ||||||
|         os.close(self.db_fd) |  | ||||||
|         os.unlink(minitwit.app.config['DATABASE']) |  | ||||||
| 
 |  | ||||||
|     # helper functions |  | ||||||
| 
 |  | ||||||
|     def register(self, username, password, password2=None, email=None): |  | ||||||
|         """Helper function to register a user""" |  | ||||||
|         if password2 is None: |  | ||||||
|             password2 = password |  | ||||||
|         if email is None: |  | ||||||
|             email = username + '@example.com' |  | ||||||
|         return self.app.post('/register', data={ |  | ||||||
|             'username':     username, |  | ||||||
|             'password':     password, |  | ||||||
|             'password2':    password2, |  | ||||||
|             'email':        email, |  | ||||||
|         }, follow_redirects=True) |  | ||||||
| 
 |  | ||||||
|     def login(self, username, password): |  | ||||||
|         """Helper function to login""" |  | ||||||
|         return self.app.post('/login', data={ |  | ||||||
|             'username': username, |  | ||||||
|             'password': password |  | ||||||
|         }, follow_redirects=True) |  | ||||||
| 
 |  | ||||||
|     def register_and_login(self, username, password): |  | ||||||
|         """Registers and logs in in one go""" |  | ||||||
|         self.register(username, password) |  | ||||||
|         return self.login(username, password) |  | ||||||
| 
 |  | ||||||
|     def logout(self): |  | ||||||
|         """Helper function to logout""" |  | ||||||
|         return self.app.get('/logout', follow_redirects=True) |  | ||||||
| 
 |  | ||||||
|     def add_message(self, text): |  | ||||||
|         """Records a message""" |  | ||||||
|         rv = self.app.post('/add_message', data={'text': text}, |  | ||||||
|                                     follow_redirects=True) |  | ||||||
|         if text: |  | ||||||
|             assert b'Your message was recorded' in rv.data |  | ||||||
|         return rv |  | ||||||
| 
 |  | ||||||
|     # testing functions |  | ||||||
| 
 |  | ||||||
|     def test_register(self): |  | ||||||
|         """Make sure registering works""" |  | ||||||
|         rv = self.register('user1', 'default') |  | ||||||
|         assert b'You were successfully registered ' \ |  | ||||||
|                b'and can login now' in rv.data |  | ||||||
|         rv = self.register('user1', 'default') |  | ||||||
|         assert b'The username is already taken' in rv.data |  | ||||||
|         rv = self.register('', 'default') |  | ||||||
|         assert b'You have to enter a username' in rv.data |  | ||||||
|         rv = self.register('meh', '') |  | ||||||
|         assert b'You have to enter a password' in rv.data |  | ||||||
|         rv = self.register('meh', 'x', 'y') |  | ||||||
|         assert b'The two passwords do not match' in rv.data |  | ||||||
|         rv = self.register('meh', 'foo', email='broken') |  | ||||||
|         assert b'You have to enter a valid email address' in rv.data |  | ||||||
| 
 |  | ||||||
|     def test_login_logout(self): |  | ||||||
|         """Make sure logging in and logging out works""" |  | ||||||
|         rv = self.register_and_login('user1', 'default') |  | ||||||
|         assert b'You were logged in' in rv.data |  | ||||||
|         rv = self.logout() |  | ||||||
|         assert b'You were logged out' in rv.data |  | ||||||
|         rv = self.login('user1', 'wrongpassword') |  | ||||||
|         assert b'Invalid password' in rv.data |  | ||||||
|         rv = self.login('user2', 'wrongpassword') |  | ||||||
|         assert b'Invalid username' in rv.data |  | ||||||
| 
 |  | ||||||
|     def test_message_recording(self): |  | ||||||
|         """Check if adding messages works""" |  | ||||||
|         self.register_and_login('foo', 'default') |  | ||||||
|         self.add_message('test message 1') |  | ||||||
|         self.add_message('<test message 2>') |  | ||||||
|         rv = self.app.get('/') |  | ||||||
|         assert b'test message 1' in rv.data |  | ||||||
|         assert b'<test message 2>' in rv.data |  | ||||||
| 
 |  | ||||||
|     def test_timelines(self): |  | ||||||
|         """Make sure that timelines work""" |  | ||||||
|         self.register_and_login('foo', 'default') |  | ||||||
|         self.add_message('the message by foo') |  | ||||||
|         self.logout() |  | ||||||
|         self.register_and_login('bar', 'default') |  | ||||||
|         self.add_message('the message by bar') |  | ||||||
|         rv = self.app.get('/public') |  | ||||||
|         assert b'the message by foo' in rv.data |  | ||||||
|         assert b'the message by bar' in rv.data |  | ||||||
| 
 |  | ||||||
|         # bar's timeline should just show bar's message |  | ||||||
|         rv = self.app.get('/') |  | ||||||
|         assert b'the message by foo' not in rv.data |  | ||||||
|         assert b'the message by bar' in rv.data |  | ||||||
| 
 |  | ||||||
|         # now let's follow foo |  | ||||||
|         rv = self.app.get('/foo/follow', follow_redirects=True) |  | ||||||
|         assert b'You are now following "foo"' in rv.data |  | ||||||
| 
 |  | ||||||
|         # we should now see foo's message |  | ||||||
|         rv = self.app.get('/') |  | ||||||
|         assert b'the message by foo' in rv.data |  | ||||||
|         assert b'the message by bar' in rv.data |  | ||||||
| 
 |  | ||||||
|         # but on the user's page we only want the user's message |  | ||||||
|         rv = self.app.get('/bar') |  | ||||||
|         assert b'the message by foo' not in rv.data |  | ||||||
|         assert b'the message by bar' in rv.data |  | ||||||
|         rv = self.app.get('/foo') |  | ||||||
|         assert b'the message by foo' in rv.data |  | ||||||
|         assert b'the message by bar' not in rv.data |  | ||||||
| 
 |  | ||||||
|         # now unfollow and check if that worked |  | ||||||
|         rv = self.app.get('/foo/unfollow', follow_redirects=True) |  | ||||||
|         assert b'You are no longer following "foo"' in rv.data |  | ||||||
|         rv = self.app.get('/') |  | ||||||
|         assert b'the message by foo' not in rv.data |  | ||||||
|         assert b'the message by bar' in rv.data |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     unittest.main() |  | ||||||
|  | @ -0,0 +1,151 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     MiniTwit Tests | ||||||
|  |     ~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests the MiniTwit application. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | import os | ||||||
|  | import minitwit | ||||||
|  | import tempfile | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def client(request): | ||||||
|  |     db_fd, minitwit.app.config['DATABASE'] = tempfile.mkstemp() | ||||||
|  |     client = minitwit.app.test_client() | ||||||
|  |     with minitwit.app.app_context(): | ||||||
|  |         minitwit.init_db() | ||||||
|  | 
 | ||||||
|  |     def teardown(): | ||||||
|  |         """Get rid of the database again after each test.""" | ||||||
|  |         os.close(db_fd) | ||||||
|  |         os.unlink(minitwit.app.config['DATABASE']) | ||||||
|  |     request.addfinalizer(teardown) | ||||||
|  |     return client | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def register(client, username, password, password2=None, email=None): | ||||||
|  |     """Helper function to register a user""" | ||||||
|  |     if password2 is None: | ||||||
|  |         password2 = password | ||||||
|  |     if email is None: | ||||||
|  |         email = username + '@example.com' | ||||||
|  |     return client.post('/register', data={ | ||||||
|  |         'username':     username, | ||||||
|  |         'password':     password, | ||||||
|  |         'password2':    password2, | ||||||
|  |         'email':        email, | ||||||
|  |     }, follow_redirects=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def login(client, username, password): | ||||||
|  |     """Helper function to login""" | ||||||
|  |     return client.post('/login', data={ | ||||||
|  |         'username': username, | ||||||
|  |         'password': password | ||||||
|  |     }, follow_redirects=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def register_and_login(client, username, password): | ||||||
|  |     """Registers and logs in in one go""" | ||||||
|  |     register(client, username, password) | ||||||
|  |     return login(client, username, password) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def logout(client): | ||||||
|  |     """Helper function to logout""" | ||||||
|  |     return client.get('/logout', follow_redirects=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def add_message(client, text): | ||||||
|  |     """Records a message""" | ||||||
|  |     rv = client.post('/add_message', data={'text': text}, | ||||||
|  |                      follow_redirects=True) | ||||||
|  |     if text: | ||||||
|  |         assert b'Your message was recorded' in rv.data | ||||||
|  |     return rv | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_register(client): | ||||||
|  |     """Make sure registering works""" | ||||||
|  |     rv = register(client, 'user1', 'default') | ||||||
|  |     assert b'You were successfully registered ' \ | ||||||
|  |            b'and can login now' in rv.data | ||||||
|  |     rv = register(client, 'user1', 'default') | ||||||
|  |     assert b'The username is already taken' in rv.data | ||||||
|  |     rv = register(client, '', 'default') | ||||||
|  |     assert b'You have to enter a username' in rv.data | ||||||
|  |     rv = register(client, 'meh', '') | ||||||
|  |     assert b'You have to enter a password' in rv.data | ||||||
|  |     rv = register(client, 'meh', 'x', 'y') | ||||||
|  |     assert b'The two passwords do not match' in rv.data | ||||||
|  |     rv = register(client, 'meh', 'foo', email='broken') | ||||||
|  |     assert b'You have to enter a valid email address' in rv.data | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_login_logout(client): | ||||||
|  |     """Make sure logging in and logging out works""" | ||||||
|  |     rv = register_and_login(client, 'user1', 'default') | ||||||
|  |     assert b'You were logged in' in rv.data | ||||||
|  |     rv = logout(client) | ||||||
|  |     assert b'You were logged out' in rv.data | ||||||
|  |     rv = login(client, 'user1', 'wrongpassword') | ||||||
|  |     assert b'Invalid password' in rv.data | ||||||
|  |     rv = login(client, 'user2', 'wrongpassword') | ||||||
|  |     assert b'Invalid username' in rv.data | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_message_recording(client): | ||||||
|  |     """Check if adding messages works""" | ||||||
|  |     register_and_login(client, 'foo', 'default') | ||||||
|  |     add_message(client, 'test message 1') | ||||||
|  |     add_message(client, '<test message 2>') | ||||||
|  |     rv = client.get('/') | ||||||
|  |     assert b'test message 1' in rv.data | ||||||
|  |     assert b'<test message 2>' in rv.data | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_timelines(client): | ||||||
|  |     """Make sure that timelines work""" | ||||||
|  |     register_and_login(client, 'foo', 'default') | ||||||
|  |     add_message(client, 'the message by foo') | ||||||
|  |     logout(client) | ||||||
|  |     register_and_login(client, 'bar', 'default') | ||||||
|  |     add_message(client, 'the message by bar') | ||||||
|  |     rv = client.get('/public') | ||||||
|  |     assert b'the message by foo' in rv.data | ||||||
|  |     assert b'the message by bar' in rv.data | ||||||
|  | 
 | ||||||
|  |     # bar's timeline should just show bar's message | ||||||
|  |     rv = client.get('/') | ||||||
|  |     assert b'the message by foo' not in rv.data | ||||||
|  |     assert b'the message by bar' in rv.data | ||||||
|  | 
 | ||||||
|  |     # now let's follow foo | ||||||
|  |     rv = client.get('/foo/follow', follow_redirects=True) | ||||||
|  |     assert b'You are now following "foo"' in rv.data | ||||||
|  | 
 | ||||||
|  |     # we should now see foo's message | ||||||
|  |     rv = client.get('/') | ||||||
|  |     assert b'the message by foo' in rv.data | ||||||
|  |     assert b'the message by bar' in rv.data | ||||||
|  | 
 | ||||||
|  |     # but on the user's page we only want the user's message | ||||||
|  |     rv = client.get('/bar') | ||||||
|  |     assert b'the message by foo' not in rv.data | ||||||
|  |     assert b'the message by bar' in rv.data | ||||||
|  |     rv = client.get('/foo') | ||||||
|  |     assert b'the message by foo' in rv.data | ||||||
|  |     assert b'the message by bar' not in rv.data | ||||||
|  | 
 | ||||||
|  |     # now unfollow and check if that worked | ||||||
|  |     rv = client.get('/foo/unfollow', follow_redirects=True) | ||||||
|  |     assert b'You are no longer following "foo"' in rv.data | ||||||
|  |     rv = client.get('/') | ||||||
|  |     assert b'the message by foo' not in rv.data | ||||||
|  |     assert b'the message by bar' in rv.data | ||||||
|  | @ -1,253 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite |  | ||||||
|     ~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests Flask itself.  The majority of Flask is already tested |  | ||||||
|     as part of Werkzeug. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| from __future__ import print_function |  | ||||||
| 
 |  | ||||||
| import os |  | ||||||
| import sys |  | ||||||
| import flask |  | ||||||
| import warnings |  | ||||||
| import unittest |  | ||||||
| from functools import update_wrapper |  | ||||||
| from contextlib import contextmanager |  | ||||||
| from werkzeug.utils import import_string, find_modules |  | ||||||
| from flask._compat import reraise, StringIO |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def add_to_path(path): |  | ||||||
|     """Adds an entry to sys.path if it's not already there.  This does |  | ||||||
|     not append it but moves it to the front so that we can be sure it |  | ||||||
|     is loaded. |  | ||||||
|     """ |  | ||||||
|     if not os.path.isdir(path): |  | ||||||
|         raise RuntimeError('Tried to add nonexisting path') |  | ||||||
| 
 |  | ||||||
|     def _samefile(x, y): |  | ||||||
|         if x == y: |  | ||||||
|             return True |  | ||||||
|         try: |  | ||||||
|             return os.path.samefile(x, y) |  | ||||||
|         except (IOError, OSError, AttributeError): |  | ||||||
|             # Windows has no samefile |  | ||||||
|             return False |  | ||||||
|     sys.path[:] = [x for x in sys.path if not _samefile(path, x)] |  | ||||||
|     sys.path.insert(0, path) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def iter_suites(): |  | ||||||
|     """Yields all testsuites.""" |  | ||||||
|     for module in find_modules(__name__): |  | ||||||
|         mod = import_string(module) |  | ||||||
|         if hasattr(mod, 'suite'): |  | ||||||
|             yield mod.suite() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def find_all_tests(suite): |  | ||||||
|     """Yields all the tests and their names from a given suite.""" |  | ||||||
|     suites = [suite] |  | ||||||
|     while suites: |  | ||||||
|         s = suites.pop() |  | ||||||
|         try: |  | ||||||
|             suites.extend(s) |  | ||||||
|         except TypeError: |  | ||||||
|             yield s, '%s.%s.%s' % ( |  | ||||||
|                 s.__class__.__module__, |  | ||||||
|                 s.__class__.__name__, |  | ||||||
|                 s._testMethodName |  | ||||||
|             ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @contextmanager |  | ||||||
| def catch_warnings(): |  | ||||||
|     """Catch warnings in a with block in a list""" |  | ||||||
|     # make sure deprecation warnings are active in tests |  | ||||||
|     warnings.simplefilter('default', category=DeprecationWarning) |  | ||||||
| 
 |  | ||||||
|     filters = warnings.filters |  | ||||||
|     warnings.filters = filters[:] |  | ||||||
|     old_showwarning = warnings.showwarning |  | ||||||
|     log = [] |  | ||||||
|     def showwarning(message, category, filename, lineno, file=None, line=None): |  | ||||||
|         log.append(locals()) |  | ||||||
|     try: |  | ||||||
|         warnings.showwarning = showwarning |  | ||||||
|         yield log |  | ||||||
|     finally: |  | ||||||
|         warnings.filters = filters |  | ||||||
|         warnings.showwarning = old_showwarning |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @contextmanager |  | ||||||
| def catch_stderr(): |  | ||||||
|     """Catch stderr in a StringIO""" |  | ||||||
|     old_stderr = sys.stderr |  | ||||||
|     sys.stderr = rv = StringIO() |  | ||||||
|     try: |  | ||||||
|         yield rv |  | ||||||
|     finally: |  | ||||||
|         sys.stderr = old_stderr |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def emits_module_deprecation_warning(f): |  | ||||||
|     def new_f(self, *args, **kwargs): |  | ||||||
|         with catch_warnings() as log: |  | ||||||
|             f(self, *args, **kwargs) |  | ||||||
|             self.assert_true(log, 'expected deprecation warning') |  | ||||||
|             for entry in log: |  | ||||||
|                 self.assert_in('Modules are deprecated', str(entry['message'])) |  | ||||||
|     return update_wrapper(new_f, f) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class FlaskTestCase(unittest.TestCase): |  | ||||||
|     """Baseclass for all the tests that Flask uses.  Use these methods |  | ||||||
|     for testing instead of the camelcased ones in the baseclass for |  | ||||||
|     consistency. |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     def ensure_clean_request_context(self): |  | ||||||
|         # make sure we're not leaking a request context since we are |  | ||||||
|         # testing flask internally in debug mode in a few cases |  | ||||||
|         leaks = [] |  | ||||||
|         while flask._request_ctx_stack.top is not None: |  | ||||||
|             leaks.append(flask._request_ctx_stack.pop()) |  | ||||||
|         self.assert_equal(leaks, []) |  | ||||||
| 
 |  | ||||||
|     def setup(self): |  | ||||||
|         pass |  | ||||||
| 
 |  | ||||||
|     def teardown(self): |  | ||||||
|         pass |  | ||||||
| 
 |  | ||||||
|     def setUp(self): |  | ||||||
|         self.setup() |  | ||||||
| 
 |  | ||||||
|     def tearDown(self): |  | ||||||
|         unittest.TestCase.tearDown(self) |  | ||||||
|         self.ensure_clean_request_context() |  | ||||||
|         self.teardown() |  | ||||||
| 
 |  | ||||||
|     def assert_equal(self, x, y): |  | ||||||
|         return self.assertEqual(x, y) |  | ||||||
| 
 |  | ||||||
|     def assert_raises(self, exc_type, callable=None, *args, **kwargs): |  | ||||||
|         catcher = _ExceptionCatcher(self, exc_type) |  | ||||||
|         if callable is None: |  | ||||||
|             return catcher |  | ||||||
|         with catcher: |  | ||||||
|             callable(*args, **kwargs) |  | ||||||
| 
 |  | ||||||
|     def assert_true(self, x, msg=None): |  | ||||||
|         self.assertTrue(x, msg) |  | ||||||
|     assert_ = assert_true |  | ||||||
| 
 |  | ||||||
|     def assert_false(self, x, msg=None): |  | ||||||
|         self.assertFalse(x, msg) |  | ||||||
| 
 |  | ||||||
|     def assert_in(self, x, y): |  | ||||||
|         self.assertIn(x, y) |  | ||||||
| 
 |  | ||||||
|     def assert_not_in(self, x, y): |  | ||||||
|         self.assertNotIn(x, y) |  | ||||||
| 
 |  | ||||||
|     def assert_isinstance(self, obj, cls): |  | ||||||
|         self.assertIsInstance(obj, cls) |  | ||||||
| 
 |  | ||||||
|     if sys.version_info[:2] == (2, 6): |  | ||||||
|         def assertIn(self, x, y): |  | ||||||
|             assert x in y, "%r unexpectedly not in %r" % (x, y) |  | ||||||
| 
 |  | ||||||
|         def assertNotIn(self, x, y): |  | ||||||
|             assert x not in y, "%r unexpectedly in %r" % (x, y) |  | ||||||
| 
 |  | ||||||
|         def assertIsInstance(self, x, y): |  | ||||||
|             assert isinstance(x, y), "not isinstance(%r, %r)" % (x, y) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class _ExceptionCatcher(object): |  | ||||||
| 
 |  | ||||||
|     def __init__(self, test_case, exc_type): |  | ||||||
|         self.test_case = test_case |  | ||||||
|         self.exc_type = exc_type |  | ||||||
| 
 |  | ||||||
|     def __enter__(self): |  | ||||||
|         return self |  | ||||||
| 
 |  | ||||||
|     def __exit__(self, exc_type, exc_value, tb): |  | ||||||
|         exception_name = self.exc_type.__name__ |  | ||||||
|         if exc_type is None: |  | ||||||
|             self.test_case.fail('Expected exception of type %r' % |  | ||||||
|                                 exception_name) |  | ||||||
|         elif not issubclass(exc_type, self.exc_type): |  | ||||||
|             reraise(exc_type, exc_value, tb) |  | ||||||
|         return True |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class BetterLoader(unittest.TestLoader): |  | ||||||
|     """A nicer loader that solves two problems.  First of all we are setting |  | ||||||
|     up tests from different sources and we're doing this programmatically |  | ||||||
|     which breaks the default loading logic so this is required anyways. |  | ||||||
|     Secondly this loader has a nicer interpolation for test names than the |  | ||||||
|     default one so you can just do ``run-tests.py ViewTestCase`` and it |  | ||||||
|     will work. |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     def getRootSuite(self): |  | ||||||
|         return suite() |  | ||||||
| 
 |  | ||||||
|     def loadTestsFromName(self, name, module=None): |  | ||||||
|         root = self.getRootSuite() |  | ||||||
|         if name == 'suite': |  | ||||||
|             return root |  | ||||||
| 
 |  | ||||||
|         all_tests = [] |  | ||||||
|         for testcase, testname in find_all_tests(root): |  | ||||||
|             if testname == name or \ |  | ||||||
|                testname.endswith('.' + name) or \ |  | ||||||
|                ('.' + name + '.') in testname or \ |  | ||||||
|                testname.startswith(name + '.'): |  | ||||||
|                 all_tests.append(testcase) |  | ||||||
| 
 |  | ||||||
|         if not all_tests: |  | ||||||
|             raise LookupError('could not find test case for "%s"' % name) |  | ||||||
| 
 |  | ||||||
|         if len(all_tests) == 1: |  | ||||||
|             return all_tests[0] |  | ||||||
|         rv = unittest.TestSuite() |  | ||||||
|         for test in all_tests: |  | ||||||
|             rv.addTest(test) |  | ||||||
|         return rv |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def setup_path(): |  | ||||||
|     add_to_path(os.path.abspath(os.path.join( |  | ||||||
|         os.path.dirname(__file__), 'test_apps'))) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     """A testsuite that has all the Flask tests.  You can use this |  | ||||||
|     function to integrate the Flask tests into your own testsuite |  | ||||||
|     in case you want to test that monkeypatches to Flask do not |  | ||||||
|     break it. |  | ||||||
|     """ |  | ||||||
|     setup_path() |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     for other_suite in iter_suites(): |  | ||||||
|         suite.addTest(other_suite) |  | ||||||
|     return suite |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def main(): |  | ||||||
|     """Runs the testsuite as command line application.""" |  | ||||||
|     try: |  | ||||||
|         unittest.main(testLoader=BetterLoader(), defaultTest='suite') |  | ||||||
|     except Exception as e: |  | ||||||
|         print('Error: %s' % e) |  | ||||||
|  | @ -1,118 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.appctx |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests the application context. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class AppContextTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_basic_url_generation(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config['SERVER_NAME'] = 'localhost' |  | ||||||
|         app.config['PREFERRED_URL_SCHEME'] = 'https' |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         with app.app_context(): |  | ||||||
|             rv = flask.url_for('index') |  | ||||||
|             self.assert_equal(rv, 'https://localhost/') |  | ||||||
| 
 |  | ||||||
|     def test_url_generation_requires_server_name(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         with app.app_context(): |  | ||||||
|             with self.assert_raises(RuntimeError): |  | ||||||
|                 flask.url_for('index') |  | ||||||
| 
 |  | ||||||
|     def test_url_generation_without_context_fails(self): |  | ||||||
|         with self.assert_raises(RuntimeError): |  | ||||||
|             flask.url_for('index') |  | ||||||
| 
 |  | ||||||
|     def test_request_context_means_app_context(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         with app.test_request_context(): |  | ||||||
|             self.assert_equal(flask.current_app._get_current_object(), app) |  | ||||||
|         self.assert_equal(flask._app_ctx_stack.top, None) |  | ||||||
| 
 |  | ||||||
|     def test_app_context_provides_current_app(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         with app.app_context(): |  | ||||||
|             self.assert_equal(flask.current_app._get_current_object(), app) |  | ||||||
|         self.assert_equal(flask._app_ctx_stack.top, None) |  | ||||||
| 
 |  | ||||||
|     def test_app_tearing_down(self): |  | ||||||
|         cleanup_stuff = [] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.teardown_appcontext |  | ||||||
|         def cleanup(exception): |  | ||||||
|             cleanup_stuff.append(exception) |  | ||||||
| 
 |  | ||||||
|         with app.app_context(): |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(cleanup_stuff, [None]) |  | ||||||
| 
 |  | ||||||
|     def test_app_tearing_down_with_previous_exception(self): |  | ||||||
|         cleanup_stuff = [] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.teardown_appcontext |  | ||||||
|         def cleanup(exception): |  | ||||||
|             cleanup_stuff.append(exception) |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             raise Exception('dummy') |  | ||||||
|         except Exception: |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         with app.app_context(): |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(cleanup_stuff, [None]) |  | ||||||
| 
 |  | ||||||
|     def test_custom_app_ctx_globals_class(self): |  | ||||||
|         class CustomRequestGlobals(object): |  | ||||||
|             def __init__(self): |  | ||||||
|                 self.spam = 'eggs' |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.app_ctx_globals_class = CustomRequestGlobals |  | ||||||
|         with app.app_context(): |  | ||||||
|             self.assert_equal( |  | ||||||
|                 flask.render_template_string('{{ g.spam }}'), 'eggs') |  | ||||||
| 
 |  | ||||||
|     def test_context_refcounts(self): |  | ||||||
|         called = [] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.teardown_request |  | ||||||
|         def teardown_req(error=None): |  | ||||||
|             called.append('request') |  | ||||||
|         @app.teardown_appcontext |  | ||||||
|         def teardown_app(error=None): |  | ||||||
|             called.append('app') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             with flask._app_ctx_stack.top: |  | ||||||
|                 with flask._request_ctx_stack.top: |  | ||||||
|                     pass |  | ||||||
|             self.assert_true(flask._request_ctx_stack.top.request.environ |  | ||||||
|                 ['werkzeug.request'] is not None) |  | ||||||
|             return u'' |  | ||||||
|         c = app.test_client() |  | ||||||
|         c.get('/') |  | ||||||
|         self.assertEqual(called, ['request', 'app']) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(AppContextTestCase)) |  | ||||||
|     return suite |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -1,585 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.blueprints |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Blueprints (and currently modules) |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| from flask._compat import text_type |  | ||||||
| from werkzeug.http import parse_cache_control_header |  | ||||||
| from jinja2 import TemplateNotFound |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class BlueprintTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_blueprint_specific_error_handling(self): |  | ||||||
|         frontend = flask.Blueprint('frontend', __name__) |  | ||||||
|         backend = flask.Blueprint('backend', __name__) |  | ||||||
|         sideend = flask.Blueprint('sideend', __name__) |  | ||||||
| 
 |  | ||||||
|         @frontend.errorhandler(403) |  | ||||||
|         def frontend_forbidden(e): |  | ||||||
|             return 'frontend says no', 403 |  | ||||||
| 
 |  | ||||||
|         @frontend.route('/frontend-no') |  | ||||||
|         def frontend_no(): |  | ||||||
|             flask.abort(403) |  | ||||||
| 
 |  | ||||||
|         @backend.errorhandler(403) |  | ||||||
|         def backend_forbidden(e): |  | ||||||
|             return 'backend says no', 403 |  | ||||||
| 
 |  | ||||||
|         @backend.route('/backend-no') |  | ||||||
|         def backend_no(): |  | ||||||
|             flask.abort(403) |  | ||||||
| 
 |  | ||||||
|         @sideend.route('/what-is-a-sideend') |  | ||||||
|         def sideend_no(): |  | ||||||
|             flask.abort(403) |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(frontend) |  | ||||||
|         app.register_blueprint(backend) |  | ||||||
|         app.register_blueprint(sideend) |  | ||||||
| 
 |  | ||||||
|         @app.errorhandler(403) |  | ||||||
|         def app_forbidden(e): |  | ||||||
|             return 'application itself says no', 403 |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(c.get('/frontend-no').data, b'frontend says no') |  | ||||||
|         self.assert_equal(c.get('/backend-no').data, b'backend says no') |  | ||||||
|         self.assert_equal(c.get('/what-is-a-sideend').data, b'application itself says no') |  | ||||||
| 
 |  | ||||||
|     def test_blueprint_specific_user_error_handling(self): |  | ||||||
|         class MyDecoratorException(Exception): |  | ||||||
|             pass |  | ||||||
|         class MyFunctionException(Exception): |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         blue = flask.Blueprint('blue', __name__) |  | ||||||
| 
 |  | ||||||
|         @blue.errorhandler(MyDecoratorException) |  | ||||||
|         def my_decorator_exception_handler(e): |  | ||||||
|             self.assert_true(isinstance(e, MyDecoratorException)) |  | ||||||
|             return 'boom' |  | ||||||
| 
 |  | ||||||
|         def my_function_exception_handler(e): |  | ||||||
|             self.assert_true(isinstance(e, MyFunctionException)) |  | ||||||
|             return 'bam' |  | ||||||
|         blue.register_error_handler(MyFunctionException, my_function_exception_handler) |  | ||||||
| 
 |  | ||||||
|         @blue.route('/decorator') |  | ||||||
|         def blue_deco_test(): |  | ||||||
|             raise MyDecoratorException() |  | ||||||
|         @blue.route('/function') |  | ||||||
|         def blue_func_test(): |  | ||||||
|             raise MyFunctionException() |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(blue) |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(c.get('/decorator').data, b'boom') |  | ||||||
|         self.assert_equal(c.get('/function').data, b'bam') |  | ||||||
| 
 |  | ||||||
|     def test_blueprint_url_definitions(self): |  | ||||||
|         bp = flask.Blueprint('test', __name__) |  | ||||||
| 
 |  | ||||||
|         @bp.route('/foo', defaults={'baz': 42}) |  | ||||||
|         def foo(bar, baz): |  | ||||||
|             return '%s/%d' % (bar, baz) |  | ||||||
| 
 |  | ||||||
|         @bp.route('/bar') |  | ||||||
|         def bar(bar): |  | ||||||
|             return text_type(bar) |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/1', url_defaults={'bar': 23}) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/2', url_defaults={'bar': 19}) |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
|         self.assert_equal(c.get('/1/foo').data, b'23/42') |  | ||||||
|         self.assert_equal(c.get('/2/foo').data, b'19/42') |  | ||||||
|         self.assert_equal(c.get('/1/bar').data, b'23') |  | ||||||
|         self.assert_equal(c.get('/2/bar').data, b'19') |  | ||||||
| 
 |  | ||||||
|     def test_blueprint_url_processors(self): |  | ||||||
|         bp = flask.Blueprint('frontend', __name__, url_prefix='/<lang_code>') |  | ||||||
| 
 |  | ||||||
|         @bp.url_defaults |  | ||||||
|         def add_language_code(endpoint, values): |  | ||||||
|             values.setdefault('lang_code', flask.g.lang_code) |  | ||||||
| 
 |  | ||||||
|         @bp.url_value_preprocessor |  | ||||||
|         def pull_lang_code(endpoint, values): |  | ||||||
|             flask.g.lang_code = values.pop('lang_code') |  | ||||||
| 
 |  | ||||||
|         @bp.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.url_for('.about') |  | ||||||
| 
 |  | ||||||
|         @bp.route('/about') |  | ||||||
|         def about(): |  | ||||||
|             return flask.url_for('.index') |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp) |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(c.get('/de/').data, b'/de/about') |  | ||||||
|         self.assert_equal(c.get('/de/about').data, b'/de/') |  | ||||||
| 
 |  | ||||||
|     def test_templates_and_static(self): |  | ||||||
|         from blueprintapp import app |  | ||||||
|         c = app.test_client() |  | ||||||
| 
 |  | ||||||
|         rv = c.get('/') |  | ||||||
|         self.assert_equal(rv.data, b'Hello from the Frontend') |  | ||||||
|         rv = c.get('/admin/') |  | ||||||
|         self.assert_equal(rv.data, b'Hello from the Admin') |  | ||||||
|         rv = c.get('/admin/index2') |  | ||||||
|         self.assert_equal(rv.data, b'Hello from the Admin') |  | ||||||
|         rv = c.get('/admin/static/test.txt') |  | ||||||
|         self.assert_equal(rv.data.strip(), b'Admin File') |  | ||||||
|         rv.close() |  | ||||||
|         rv = c.get('/admin/static/css/test.css') |  | ||||||
|         self.assert_equal(rv.data.strip(), b'/* nested file */') |  | ||||||
|         rv.close() |  | ||||||
| 
 |  | ||||||
|         # try/finally, in case other tests use this app for Blueprint tests. |  | ||||||
|         max_age_default = app.config['SEND_FILE_MAX_AGE_DEFAULT'] |  | ||||||
|         try: |  | ||||||
|             expected_max_age = 3600 |  | ||||||
|             if app.config['SEND_FILE_MAX_AGE_DEFAULT'] == expected_max_age: |  | ||||||
|                 expected_max_age = 7200 |  | ||||||
|             app.config['SEND_FILE_MAX_AGE_DEFAULT'] = expected_max_age |  | ||||||
|             rv = c.get('/admin/static/css/test.css') |  | ||||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) |  | ||||||
|             self.assert_equal(cc.max_age, expected_max_age) |  | ||||||
|             rv.close() |  | ||||||
|         finally: |  | ||||||
|             app.config['SEND_FILE_MAX_AGE_DEFAULT'] = max_age_default |  | ||||||
| 
 |  | ||||||
|         with app.test_request_context(): |  | ||||||
|             self.assert_equal(flask.url_for('admin.static', filename='test.txt'), |  | ||||||
|                               '/admin/static/test.txt') |  | ||||||
| 
 |  | ||||||
|         with app.test_request_context(): |  | ||||||
|             try: |  | ||||||
|                 flask.render_template('missing.html') |  | ||||||
|             except TemplateNotFound as e: |  | ||||||
|                 self.assert_equal(e.name, 'missing.html') |  | ||||||
|             else: |  | ||||||
|                 self.assert_true(0, 'expected exception') |  | ||||||
| 
 |  | ||||||
|         with flask.Flask(__name__).test_request_context(): |  | ||||||
|             self.assert_equal(flask.render_template('nested/nested.txt'), 'I\'m nested') |  | ||||||
| 
 |  | ||||||
|     def test_default_static_cache_timeout(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         class MyBlueprint(flask.Blueprint): |  | ||||||
|             def get_send_file_max_age(self, filename): |  | ||||||
|                 return 100 |  | ||||||
| 
 |  | ||||||
|         blueprint = MyBlueprint('blueprint', __name__, static_folder='static') |  | ||||||
|         app.register_blueprint(blueprint) |  | ||||||
| 
 |  | ||||||
|         # try/finally, in case other tests use this app for Blueprint tests. |  | ||||||
|         max_age_default = app.config['SEND_FILE_MAX_AGE_DEFAULT'] |  | ||||||
|         try: |  | ||||||
|             with app.test_request_context(): |  | ||||||
|                 unexpected_max_age = 3600 |  | ||||||
|                 if app.config['SEND_FILE_MAX_AGE_DEFAULT'] == unexpected_max_age: |  | ||||||
|                     unexpected_max_age = 7200 |  | ||||||
|                 app.config['SEND_FILE_MAX_AGE_DEFAULT'] = unexpected_max_age |  | ||||||
|                 rv = blueprint.send_static_file('index.html') |  | ||||||
|                 cc = parse_cache_control_header(rv.headers['Cache-Control']) |  | ||||||
|                 self.assert_equal(cc.max_age, 100) |  | ||||||
|                 rv.close() |  | ||||||
|         finally: |  | ||||||
|             app.config['SEND_FILE_MAX_AGE_DEFAULT'] = max_age_default |  | ||||||
| 
 |  | ||||||
|     def test_templates_list(self): |  | ||||||
|         from blueprintapp import app |  | ||||||
|         templates = sorted(app.jinja_env.list_templates()) |  | ||||||
|         self.assert_equal(templates, ['admin/index.html', |  | ||||||
|                                      'frontend/index.html']) |  | ||||||
| 
 |  | ||||||
|     def test_dotted_names(self): |  | ||||||
|         frontend = flask.Blueprint('myapp.frontend', __name__) |  | ||||||
|         backend = flask.Blueprint('myapp.backend', __name__) |  | ||||||
| 
 |  | ||||||
|         @frontend.route('/fe') |  | ||||||
|         def frontend_index(): |  | ||||||
|             return flask.url_for('myapp.backend.backend_index') |  | ||||||
| 
 |  | ||||||
|         @frontend.route('/fe2') |  | ||||||
|         def frontend_page2(): |  | ||||||
|             return flask.url_for('.frontend_index') |  | ||||||
| 
 |  | ||||||
|         @backend.route('/be') |  | ||||||
|         def backend_index(): |  | ||||||
|             return flask.url_for('myapp.frontend.frontend_index') |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(frontend) |  | ||||||
|         app.register_blueprint(backend) |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
|         self.assert_equal(c.get('/fe').data.strip(), b'/be') |  | ||||||
|         self.assert_equal(c.get('/fe2').data.strip(), b'/fe') |  | ||||||
|         self.assert_equal(c.get('/be').data.strip(), b'/fe') |  | ||||||
| 
 |  | ||||||
|     def test_dotted_names_from_app(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
|         test = flask.Blueprint('test', __name__) |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def app_index(): |  | ||||||
|             return flask.url_for('test.index') |  | ||||||
| 
 |  | ||||||
|         @test.route('/test/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.url_for('app_index') |  | ||||||
| 
 |  | ||||||
|         app.register_blueprint(test) |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             rv = c.get('/') |  | ||||||
|             self.assert_equal(rv.data, b'/test/') |  | ||||||
| 
 |  | ||||||
|     def test_empty_url_defaults(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
| 
 |  | ||||||
|         @bp.route('/', defaults={'page': 1}) |  | ||||||
|         @bp.route('/page/<int:page>') |  | ||||||
|         def something(page): |  | ||||||
|             return str(page) |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp) |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
|         self.assert_equal(c.get('/').data, b'1') |  | ||||||
|         self.assert_equal(c.get('/page/2').data, b'2') |  | ||||||
| 
 |  | ||||||
|     def test_route_decorator_custom_endpoint(self): |  | ||||||
| 
 |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
| 
 |  | ||||||
|         @bp.route('/foo') |  | ||||||
|         def foo(): |  | ||||||
|             return flask.request.endpoint |  | ||||||
| 
 |  | ||||||
|         @bp.route('/bar', endpoint='bar') |  | ||||||
|         def foo_bar(): |  | ||||||
|             return flask.request.endpoint |  | ||||||
| 
 |  | ||||||
|         @bp.route('/bar/123', endpoint='123') |  | ||||||
|         def foo_bar_foo(): |  | ||||||
|             return flask.request.endpoint |  | ||||||
| 
 |  | ||||||
|         @bp.route('/bar/foo') |  | ||||||
|         def bar_foo(): |  | ||||||
|             return flask.request.endpoint |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.request.endpoint |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
|         self.assertEqual(c.get('/').data, b'index') |  | ||||||
|         self.assertEqual(c.get('/py/foo').data, b'bp.foo') |  | ||||||
|         self.assertEqual(c.get('/py/bar').data, b'bp.bar') |  | ||||||
|         self.assertEqual(c.get('/py/bar/123').data, b'bp.123') |  | ||||||
|         self.assertEqual(c.get('/py/bar/foo').data, b'bp.bar_foo') |  | ||||||
| 
 |  | ||||||
|     def test_route_decorator_custom_endpoint_with_dots(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
| 
 |  | ||||||
|         @bp.route('/foo') |  | ||||||
|         def foo(): |  | ||||||
|             return flask.request.endpoint |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             @bp.route('/bar', endpoint='bar.bar') |  | ||||||
|             def foo_bar(): |  | ||||||
|                 return flask.request.endpoint |  | ||||||
|         except AssertionError: |  | ||||||
|             pass |  | ||||||
|         else: |  | ||||||
|             raise AssertionError('expected AssertionError not raised') |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             @bp.route('/bar/123', endpoint='bar.123') |  | ||||||
|             def foo_bar_foo(): |  | ||||||
|                 return flask.request.endpoint |  | ||||||
|         except AssertionError: |  | ||||||
|             pass |  | ||||||
|         else: |  | ||||||
|             raise AssertionError('expected AssertionError not raised') |  | ||||||
| 
 |  | ||||||
|         def foo_foo_foo(): |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         self.assertRaises( |  | ||||||
|             AssertionError, |  | ||||||
|             lambda: bp.add_url_rule( |  | ||||||
|                 '/bar/123', endpoint='bar.123', view_func=foo_foo_foo |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|         self.assertRaises( |  | ||||||
|             AssertionError, |  | ||||||
|             bp.route('/bar/123', endpoint='bar.123'), |  | ||||||
|             lambda: None |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
| 
 |  | ||||||
|         c = app.test_client() |  | ||||||
|         self.assertEqual(c.get('/py/foo').data, b'bp.foo') |  | ||||||
|         # The rule's didn't actually made it through |  | ||||||
|         rv = c.get('/py/bar') |  | ||||||
|         assert rv.status_code == 404 |  | ||||||
|         rv = c.get('/py/bar/123') |  | ||||||
|         assert rv.status_code == 404 |  | ||||||
| 
 |  | ||||||
|     def test_template_filter(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_filter() |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('my_reverse', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         bp.add_app_template_filter(my_reverse) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('my_reverse', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter_with_name(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_filter('strrev') |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('strrev', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter_with_name(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         bp.add_app_template_filter(my_reverse, 'strrev') |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('strrev', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter_with_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_filter() |  | ||||||
|         def super_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter_after_route_with_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_filter() |  | ||||||
|         def super_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter_with_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def super_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         bp.add_app_template_filter(super_reverse) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter_with_name_and_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_filter('super_reverse') |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter_with_name_and_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         bp.add_app_template_filter(my_reverse, 'super_reverse') |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_test(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_test() |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('is_boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['is_boolean'], is_boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['is_boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         bp.add_app_template_test(is_boolean) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('is_boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['is_boolean'], is_boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['is_boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_template_test_with_name(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_test('boolean') |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['boolean'], is_boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test_with_name(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         bp.add_app_template_test(is_boolean, 'boolean') |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         self.assert_in('boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['boolean'], is_boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_template_test_with_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_test() |  | ||||||
|         def boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_template_test_after_route_with_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_test() |  | ||||||
|         def boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test_with_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         bp.add_app_template_test(boolean) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_template_test_with_name_and_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         @bp.app_template_test('boolean') |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test_with_name_and_template(self): |  | ||||||
|         bp = flask.Blueprint('bp', __name__) |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         bp.add_app_template_test(is_boolean, 'boolean') |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.register_blueprint(bp, url_prefix='/py') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(BlueprintTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,384 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.config |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Configuration and instances. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import os |  | ||||||
| import sys |  | ||||||
| import flask |  | ||||||
| import pkgutil |  | ||||||
| import unittest |  | ||||||
| from contextlib import contextmanager |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| from flask._compat import PY2 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # config keys used for the ConfigTestCase |  | ||||||
| TEST_KEY = 'foo' |  | ||||||
| SECRET_KEY = 'devkey' |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class ConfigTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def common_object_test(self, app): |  | ||||||
|         self.assert_equal(app.secret_key, 'devkey') |  | ||||||
|         self.assert_equal(app.config['TEST_KEY'], 'foo') |  | ||||||
|         self.assert_not_in('ConfigTestCase', app.config) |  | ||||||
| 
 |  | ||||||
|     def test_config_from_file(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config.from_pyfile(__file__.rsplit('.', 1)[0] + '.py') |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_config_from_object(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config.from_object(__name__) |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_config_from_json(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         current_dir = os.path.dirname(os.path.abspath(__file__)) |  | ||||||
|         app.config.from_json(os.path.join(current_dir, 'static', 'config.json')) |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_config_from_mapping(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config.from_mapping({ |  | ||||||
|             'SECRET_KEY': 'devkey', |  | ||||||
|             'TEST_KEY': 'foo' |  | ||||||
|         }) |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config.from_mapping([ |  | ||||||
|             ('SECRET_KEY', 'devkey'), |  | ||||||
|             ('TEST_KEY', 'foo') |  | ||||||
|         ]) |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config.from_mapping( |  | ||||||
|             SECRET_KEY='devkey', |  | ||||||
|             TEST_KEY='foo' |  | ||||||
|         ) |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         with self.assert_raises(TypeError): |  | ||||||
|             app.config.from_mapping( |  | ||||||
|                 {}, {} |  | ||||||
|             ) |  | ||||||
| 
 |  | ||||||
|     def test_config_from_class(self): |  | ||||||
|         class Base(object): |  | ||||||
|             TEST_KEY = 'foo' |  | ||||||
|         class Test(Base): |  | ||||||
|             SECRET_KEY = 'devkey' |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config.from_object(Test) |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_config_from_envvar(self): |  | ||||||
|         env = os.environ |  | ||||||
|         try: |  | ||||||
|             os.environ = {} |  | ||||||
|             app = flask.Flask(__name__) |  | ||||||
|             try: |  | ||||||
|                 app.config.from_envvar('FOO_SETTINGS') |  | ||||||
|             except RuntimeError as e: |  | ||||||
|                 self.assert_true("'FOO_SETTINGS' is not set" in str(e)) |  | ||||||
|             else: |  | ||||||
|                 self.assert_true(0, 'expected exception') |  | ||||||
|             self.assert_false(app.config.from_envvar('FOO_SETTINGS', silent=True)) |  | ||||||
| 
 |  | ||||||
|             os.environ = {'FOO_SETTINGS': __file__.rsplit('.', 1)[0] + '.py'} |  | ||||||
|             self.assert_true(app.config.from_envvar('FOO_SETTINGS')) |  | ||||||
|             self.common_object_test(app) |  | ||||||
|         finally: |  | ||||||
|             os.environ = env |  | ||||||
| 
 |  | ||||||
|     def test_config_from_envvar_missing(self): |  | ||||||
|         env = os.environ |  | ||||||
|         try: |  | ||||||
|             os.environ = {'FOO_SETTINGS': 'missing.cfg'} |  | ||||||
|             try: |  | ||||||
|                 app = flask.Flask(__name__) |  | ||||||
|                 app.config.from_envvar('FOO_SETTINGS') |  | ||||||
|             except IOError as e: |  | ||||||
|                 msg = str(e) |  | ||||||
|                 self.assert_true(msg.startswith('[Errno 2] Unable to load configuration ' |  | ||||||
|                                             'file (No such file or directory):')) |  | ||||||
|                 self.assert_true(msg.endswith("missing.cfg'")) |  | ||||||
|             else: |  | ||||||
|                 self.fail('expected IOError') |  | ||||||
|             self.assertFalse(app.config.from_envvar('FOO_SETTINGS', silent=True)) |  | ||||||
|         finally: |  | ||||||
|             os.environ = env |  | ||||||
| 
 |  | ||||||
|     def test_config_missing(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         try: |  | ||||||
|             app.config.from_pyfile('missing.cfg') |  | ||||||
|         except IOError as e: |  | ||||||
|             msg = str(e) |  | ||||||
|             self.assert_true(msg.startswith('[Errno 2] Unable to load configuration ' |  | ||||||
|                                         'file (No such file or directory):')) |  | ||||||
|             self.assert_true(msg.endswith("missing.cfg'")) |  | ||||||
|         else: |  | ||||||
|             self.assert_true(0, 'expected config') |  | ||||||
|         self.assert_false(app.config.from_pyfile('missing.cfg', silent=True)) |  | ||||||
| 
 |  | ||||||
|     def test_config_missing_json(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         try: |  | ||||||
|             app.config.from_json('missing.json') |  | ||||||
|         except IOError as e: |  | ||||||
|             msg = str(e) |  | ||||||
|             self.assert_true(msg.startswith('[Errno 2] Unable to load configuration ' |  | ||||||
|                                             'file (No such file or directory):')) |  | ||||||
|             self.assert_true(msg.endswith("missing.json'")) |  | ||||||
|         else: |  | ||||||
|             self.assert_true(0, 'expected config') |  | ||||||
|         self.assert_false(app.config.from_json('missing.json', silent=True)) |  | ||||||
| 
 |  | ||||||
|     def test_custom_config_class(self): |  | ||||||
|         class Config(flask.Config): |  | ||||||
|             pass |  | ||||||
|         class Flask(flask.Flask): |  | ||||||
|             config_class = Config |  | ||||||
|         app = Flask(__name__) |  | ||||||
|         self.assert_isinstance(app.config, Config) |  | ||||||
|         app.config.from_object(__name__) |  | ||||||
|         self.common_object_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_session_lifetime(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config['PERMANENT_SESSION_LIFETIME'] = 42 |  | ||||||
|         self.assert_equal(app.permanent_session_lifetime.seconds, 42) |  | ||||||
| 
 |  | ||||||
|     def test_get_namespace(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config['FOO_OPTION_1'] = 'foo option 1' |  | ||||||
|         app.config['FOO_OPTION_2'] = 'foo option 2' |  | ||||||
|         app.config['BAR_STUFF_1'] = 'bar stuff 1' |  | ||||||
|         app.config['BAR_STUFF_2'] = 'bar stuff 2' |  | ||||||
|         foo_options = app.config.get_namespace('FOO_') |  | ||||||
|         self.assert_equal(2, len(foo_options)) |  | ||||||
|         self.assert_equal('foo option 1', foo_options['option_1']) |  | ||||||
|         self.assert_equal('foo option 2', foo_options['option_2']) |  | ||||||
|         bar_options = app.config.get_namespace('BAR_', lowercase=False) |  | ||||||
|         self.assert_equal(2, len(bar_options)) |  | ||||||
|         self.assert_equal('bar stuff 1', bar_options['STUFF_1']) |  | ||||||
|         self.assert_equal('bar stuff 2', bar_options['STUFF_2']) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class LimitedLoaderMockWrapper(object): |  | ||||||
|     def __init__(self, loader): |  | ||||||
|         self.loader = loader |  | ||||||
| 
 |  | ||||||
|     def __getattr__(self, name): |  | ||||||
|         if name in ('archive', 'get_filename'): |  | ||||||
|             msg = 'Mocking a loader which does not have `%s.`' % name |  | ||||||
|             raise AttributeError(msg) |  | ||||||
|         return getattr(self.loader, name) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @contextmanager |  | ||||||
| def patch_pkgutil_get_loader(wrapper_class=LimitedLoaderMockWrapper): |  | ||||||
|     """Patch pkgutil.get_loader to give loader without get_filename or archive. |  | ||||||
| 
 |  | ||||||
|     This provides for tests where a system has custom loaders, e.g. Google App |  | ||||||
|     Engine's HardenedModulesHook, which have neither the `get_filename` method |  | ||||||
|     nor the `archive` attribute. |  | ||||||
|     """ |  | ||||||
|     old_get_loader = pkgutil.get_loader |  | ||||||
|     def get_loader(*args, **kwargs): |  | ||||||
|         return wrapper_class(old_get_loader(*args, **kwargs)) |  | ||||||
|     try: |  | ||||||
|         pkgutil.get_loader = get_loader |  | ||||||
|         yield |  | ||||||
|     finally: |  | ||||||
|         pkgutil.get_loader = old_get_loader |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class InstanceTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_explicit_instance_paths(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         try: |  | ||||||
|             flask.Flask(__name__, instance_path='instance') |  | ||||||
|         except ValueError as e: |  | ||||||
|             self.assert_in('must be absolute', str(e)) |  | ||||||
|         else: |  | ||||||
|             self.fail('Expected value error') |  | ||||||
| 
 |  | ||||||
|         app = flask.Flask(__name__, instance_path=here) |  | ||||||
|         self.assert_equal(app.instance_path, here) |  | ||||||
| 
 |  | ||||||
|     def test_main_module_paths(self): |  | ||||||
|         # Test an app with '__main__' as the import name, uses cwd. |  | ||||||
|         from main_app import app |  | ||||||
|         here = os.path.abspath(os.getcwd()) |  | ||||||
|         self.assert_equal(app.instance_path, os.path.join(here, 'instance')) |  | ||||||
|         if 'main_app' in sys.modules: |  | ||||||
|             del sys.modules['main_app'] |  | ||||||
| 
 |  | ||||||
|     def test_uninstalled_module_paths(self): |  | ||||||
|         from config_module_app import app |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         self.assert_equal(app.instance_path, os.path.join(here, 'test_apps', 'instance')) |  | ||||||
| 
 |  | ||||||
|     def test_uninstalled_package_paths(self): |  | ||||||
|         from config_package_app import app |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         self.assert_equal(app.instance_path, os.path.join(here, 'test_apps', 'instance')) |  | ||||||
| 
 |  | ||||||
|     def test_installed_module_paths(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         expected_prefix = os.path.join(here, 'test_apps') |  | ||||||
|         real_prefix, sys.prefix = sys.prefix, expected_prefix |  | ||||||
|         site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages') |  | ||||||
|         sys.path.append(site_packages) |  | ||||||
|         try: |  | ||||||
|             import site_app |  | ||||||
|             self.assert_equal(site_app.app.instance_path, |  | ||||||
|                               os.path.join(expected_prefix, 'var', |  | ||||||
|                                            'site_app-instance')) |  | ||||||
|         finally: |  | ||||||
|             sys.prefix = real_prefix |  | ||||||
|             sys.path.remove(site_packages) |  | ||||||
|             if 'site_app' in sys.modules: |  | ||||||
|                 del sys.modules['site_app'] |  | ||||||
| 
 |  | ||||||
|     def test_installed_module_paths_with_limited_loader(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         expected_prefix = os.path.join(here, 'test_apps') |  | ||||||
|         real_prefix, sys.prefix = sys.prefix, expected_prefix |  | ||||||
|         site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages') |  | ||||||
|         sys.path.append(site_packages) |  | ||||||
|         with patch_pkgutil_get_loader(): |  | ||||||
|             try: |  | ||||||
|                 import site_app |  | ||||||
|                 self.assert_equal(site_app.app.instance_path, |  | ||||||
|                                   os.path.join(expected_prefix, 'var', |  | ||||||
|                                                'site_app-instance')) |  | ||||||
|             finally: |  | ||||||
|                 sys.prefix = real_prefix |  | ||||||
|                 sys.path.remove(site_packages) |  | ||||||
|                 if 'site_app' in sys.modules: |  | ||||||
|                     del sys.modules['site_app'] |  | ||||||
| 
 |  | ||||||
|     def test_installed_package_paths(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         expected_prefix = os.path.join(here, 'test_apps') |  | ||||||
|         real_prefix, sys.prefix = sys.prefix, expected_prefix |  | ||||||
|         installed_path = os.path.join(expected_prefix, 'path') |  | ||||||
|         sys.path.append(installed_path) |  | ||||||
|         try: |  | ||||||
|             import installed_package |  | ||||||
|             self.assert_equal(installed_package.app.instance_path, |  | ||||||
|                               os.path.join(expected_prefix, 'var', |  | ||||||
|                                            'installed_package-instance')) |  | ||||||
|         finally: |  | ||||||
|             sys.prefix = real_prefix |  | ||||||
|             sys.path.remove(installed_path) |  | ||||||
|             if 'installed_package' in sys.modules: |  | ||||||
|                 del sys.modules['installed_package'] |  | ||||||
| 
 |  | ||||||
|     def test_installed_package_paths_with_limited_loader(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         expected_prefix = os.path.join(here, 'test_apps') |  | ||||||
|         real_prefix, sys.prefix = sys.prefix, expected_prefix |  | ||||||
|         installed_path = os.path.join(expected_prefix, 'path') |  | ||||||
|         sys.path.append(installed_path) |  | ||||||
|         with patch_pkgutil_get_loader(): |  | ||||||
|             try: |  | ||||||
|                 import installed_package |  | ||||||
|                 self.assert_equal(installed_package.app.instance_path, |  | ||||||
|                                   os.path.join(expected_prefix, 'var', |  | ||||||
|                                                'installed_package-instance')) |  | ||||||
|             finally: |  | ||||||
|                 sys.prefix = real_prefix |  | ||||||
|                 sys.path.remove(installed_path) |  | ||||||
|                 if 'installed_package' in sys.modules: |  | ||||||
|                     del sys.modules['installed_package'] |  | ||||||
| 
 |  | ||||||
|     def test_prefix_package_paths(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         expected_prefix = os.path.join(here, 'test_apps') |  | ||||||
|         real_prefix, sys.prefix = sys.prefix, expected_prefix |  | ||||||
|         site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages') |  | ||||||
|         sys.path.append(site_packages) |  | ||||||
|         try: |  | ||||||
|             import site_package |  | ||||||
|             self.assert_equal(site_package.app.instance_path, |  | ||||||
|                               os.path.join(expected_prefix, 'var', |  | ||||||
|                                            'site_package-instance')) |  | ||||||
|         finally: |  | ||||||
|             sys.prefix = real_prefix |  | ||||||
|             sys.path.remove(site_packages) |  | ||||||
|             if 'site_package' in sys.modules: |  | ||||||
|                 del sys.modules['site_package'] |  | ||||||
| 
 |  | ||||||
|     def test_prefix_package_paths_with_limited_loader(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         expected_prefix = os.path.join(here, 'test_apps') |  | ||||||
|         real_prefix, sys.prefix = sys.prefix, expected_prefix |  | ||||||
|         site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages') |  | ||||||
|         sys.path.append(site_packages) |  | ||||||
|         with patch_pkgutil_get_loader(): |  | ||||||
|             try: |  | ||||||
|                 import site_package |  | ||||||
|                 self.assert_equal(site_package.app.instance_path, |  | ||||||
|                                   os.path.join(expected_prefix, 'var', |  | ||||||
|                                                'site_package-instance')) |  | ||||||
|             finally: |  | ||||||
|                 sys.prefix = real_prefix |  | ||||||
|                 sys.path.remove(site_packages) |  | ||||||
|                 if 'site_package' in sys.modules: |  | ||||||
|                     del sys.modules['site_package'] |  | ||||||
| 
 |  | ||||||
|     def test_egg_installed_paths(self): |  | ||||||
|         here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
|         expected_prefix = os.path.join(here, 'test_apps') |  | ||||||
|         real_prefix, sys.prefix = sys.prefix, expected_prefix |  | ||||||
|         site_packages = os.path.join(expected_prefix, 'lib', 'python2.5', 'site-packages') |  | ||||||
|         egg_path = os.path.join(site_packages, 'SiteEgg.egg') |  | ||||||
|         sys.path.append(site_packages) |  | ||||||
|         sys.path.append(egg_path) |  | ||||||
|         try: |  | ||||||
|             import site_egg # in SiteEgg.egg |  | ||||||
|             self.assert_equal(site_egg.app.instance_path, |  | ||||||
|                               os.path.join(expected_prefix, 'var', |  | ||||||
|                                            'site_egg-instance')) |  | ||||||
|         finally: |  | ||||||
|             sys.prefix = real_prefix |  | ||||||
|             sys.path.remove(site_packages) |  | ||||||
|             sys.path.remove(egg_path) |  | ||||||
|             if 'site_egg' in sys.modules: |  | ||||||
|                 del sys.modules['site_egg'] |  | ||||||
| 
 |  | ||||||
|     if PY2: |  | ||||||
|         def test_meta_path_loader_without_is_package(self): |  | ||||||
|             class Loader(object): |  | ||||||
|                 def find_module(self, name): |  | ||||||
|                     return self |  | ||||||
|             sys.meta_path.append(Loader()) |  | ||||||
|             try: |  | ||||||
|                 with self.assert_raises(AttributeError): |  | ||||||
|                     flask.Flask(__name__) |  | ||||||
|             finally: |  | ||||||
|                 sys.meta_path.pop() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(ConfigTestCase)) |  | ||||||
|     suite.addTest(unittest.makeSuite(InstanceTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,24 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.deprecations |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests deprecation support. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| from flask.testsuite import FlaskTestCase, catch_warnings |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DeprecationsTestCase(FlaskTestCase): |  | ||||||
|     """not used currently""" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(DeprecationsTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,38 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.examples |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests the examples. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| import os |  | ||||||
| import unittest |  | ||||||
| from flask.testsuite import add_to_path |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def setup_path(): |  | ||||||
|     example_path = os.path.join(os.path.dirname(__file__), |  | ||||||
|                                 os.pardir, os.pardir, 'examples') |  | ||||||
|     add_to_path(os.path.join(example_path, 'flaskr')) |  | ||||||
|     add_to_path(os.path.join(example_path, 'minitwit')) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     setup_path() |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     try: |  | ||||||
|         from minitwit_tests import MiniTwitTestCase |  | ||||||
|     except ImportError: |  | ||||||
|         pass |  | ||||||
|     else: |  | ||||||
|         suite.addTest(unittest.makeSuite(MiniTwitTestCase)) |  | ||||||
|     try: |  | ||||||
|         from flaskr_tests import FlaskrTestCase |  | ||||||
|     except ImportError: |  | ||||||
|         pass |  | ||||||
|     else: |  | ||||||
|         suite.addTest(unittest.makeSuite(FlaskrTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,136 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.ext |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests the extension import thing. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import sys |  | ||||||
| import unittest |  | ||||||
| try: |  | ||||||
|     from imp import reload as reload_module |  | ||||||
| except ImportError: |  | ||||||
|     reload_module = reload |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| from flask._compat import PY2 |  | ||||||
| 
 |  | ||||||
| class ExtImportHookTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def setup(self): |  | ||||||
|         # we clear this out for various reasons.  The most important one is |  | ||||||
|         # that a real flaskext could be in there which would disable our |  | ||||||
|         # fake package.  Secondly we want to make sure that the flaskext |  | ||||||
|         # import hook does not break on reloading. |  | ||||||
|         for entry, value in list(sys.modules.items()): |  | ||||||
|             if (entry.startswith('flask.ext.') or |  | ||||||
|                 entry.startswith('flask_') or |  | ||||||
|                 entry.startswith('flaskext.') or |  | ||||||
|                 entry == 'flaskext') and value is not None: |  | ||||||
|                 sys.modules.pop(entry, None) |  | ||||||
|         from flask import ext |  | ||||||
|         reload_module(ext) |  | ||||||
| 
 |  | ||||||
|         # reloading must not add more hooks |  | ||||||
|         import_hooks = 0 |  | ||||||
|         for item in sys.meta_path: |  | ||||||
|             cls = type(item) |  | ||||||
|             if cls.__module__ == 'flask.exthook' and \ |  | ||||||
|                cls.__name__ == 'ExtensionImporter': |  | ||||||
|                 import_hooks += 1 |  | ||||||
|         self.assert_equal(import_hooks, 1) |  | ||||||
| 
 |  | ||||||
|     def teardown(self): |  | ||||||
|         from flask import ext |  | ||||||
|         for key in ext.__dict__: |  | ||||||
|             self.assert_not_in('.', key) |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_new_simple_import_normal(self): |  | ||||||
|         from flask.ext.newext_simple import ext_id |  | ||||||
|         self.assert_equal(ext_id, 'newext_simple') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_new_simple_import_module(self): |  | ||||||
|         from flask.ext import newext_simple |  | ||||||
|         self.assert_equal(newext_simple.ext_id, 'newext_simple') |  | ||||||
|         self.assert_equal(newext_simple.__name__, 'flask_newext_simple') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_new_package_import_normal(self): |  | ||||||
|         from flask.ext.newext_package import ext_id |  | ||||||
|         self.assert_equal(ext_id, 'newext_package') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_new_package_import_module(self): |  | ||||||
|         from flask.ext import newext_package |  | ||||||
|         self.assert_equal(newext_package.ext_id, 'newext_package') |  | ||||||
|         self.assert_equal(newext_package.__name__, 'flask_newext_package') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_new_package_import_submodule_function(self): |  | ||||||
|         from flask.ext.newext_package.submodule import test_function |  | ||||||
|         self.assert_equal(test_function(), 42) |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_new_package_import_submodule(self): |  | ||||||
|         from flask.ext.newext_package import submodule |  | ||||||
|         self.assert_equal(submodule.__name__, 'flask_newext_package.submodule') |  | ||||||
|         self.assert_equal(submodule.test_function(), 42) |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_old_simple_import_normal(self): |  | ||||||
|         from flask.ext.oldext_simple import ext_id |  | ||||||
|         self.assert_equal(ext_id, 'oldext_simple') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_old_simple_import_module(self): |  | ||||||
|         from flask.ext import oldext_simple |  | ||||||
|         self.assert_equal(oldext_simple.ext_id, 'oldext_simple') |  | ||||||
|         self.assert_equal(oldext_simple.__name__, 'flaskext.oldext_simple') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_old_package_import_normal(self): |  | ||||||
|         from flask.ext.oldext_package import ext_id |  | ||||||
|         self.assert_equal(ext_id, 'oldext_package') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_old_package_import_module(self): |  | ||||||
|         from flask.ext import oldext_package |  | ||||||
|         self.assert_equal(oldext_package.ext_id, 'oldext_package') |  | ||||||
|         self.assert_equal(oldext_package.__name__, 'flaskext.oldext_package') |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_old_package_import_submodule(self): |  | ||||||
|         from flask.ext.oldext_package import submodule |  | ||||||
|         self.assert_equal(submodule.__name__, 'flaskext.oldext_package.submodule') |  | ||||||
|         self.assert_equal(submodule.test_function(), 42) |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_old_package_import_submodule_function(self): |  | ||||||
|         from flask.ext.oldext_package.submodule import test_function |  | ||||||
|         self.assert_equal(test_function(), 42) |  | ||||||
| 
 |  | ||||||
|     def test_flaskext_broken_package_no_module_caching(self): |  | ||||||
|         for x in range(2): |  | ||||||
|             with self.assert_raises(ImportError): |  | ||||||
|                 import flask.ext.broken |  | ||||||
| 
 |  | ||||||
|     def test_no_error_swallowing(self): |  | ||||||
|         try: |  | ||||||
|             import flask.ext.broken |  | ||||||
|         except ImportError: |  | ||||||
|             exc_type, exc_value, tb = sys.exc_info() |  | ||||||
|             self.assert_true(exc_type is ImportError) |  | ||||||
|             if PY2: |  | ||||||
|                 message = 'No module named missing_module' |  | ||||||
|             else: |  | ||||||
|                 message = 'No module named \'missing_module\'' |  | ||||||
|             self.assert_equal(str(exc_value), message) |  | ||||||
|             self.assert_true(tb.tb_frame.f_globals is globals()) |  | ||||||
| 
 |  | ||||||
|             # reraise() adds a second frame so we need to skip that one too. |  | ||||||
|             # On PY3 we even have another one :( |  | ||||||
|             next = tb.tb_next.tb_next |  | ||||||
|             if not PY2: |  | ||||||
|                 next = next.tb_next |  | ||||||
|              |  | ||||||
|             import os.path |  | ||||||
|             self.assert_in(os.path.join('flask_broken', '__init__.py'), next.tb_frame.f_code.co_filename) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(ExtImportHookTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,116 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.regression |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests regressions. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import os |  | ||||||
| import gc |  | ||||||
| import sys |  | ||||||
| import flask |  | ||||||
| import threading |  | ||||||
| import unittest |  | ||||||
| from werkzeug.exceptions import NotFound |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| _gc_lock = threading.Lock() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class _NoLeakAsserter(object): |  | ||||||
| 
 |  | ||||||
|     def __init__(self, testcase): |  | ||||||
|         self.testcase = testcase |  | ||||||
| 
 |  | ||||||
|     def __enter__(self): |  | ||||||
|         gc.disable() |  | ||||||
|         _gc_lock.acquire() |  | ||||||
|         loc = flask._request_ctx_stack._local |  | ||||||
| 
 |  | ||||||
|         # Force Python to track this dictionary at all times. |  | ||||||
|         # This is necessary since Python only starts tracking |  | ||||||
|         # dicts if they contain mutable objects.  It's a horrible, |  | ||||||
|         # horrible hack but makes this kinda testable. |  | ||||||
|         loc.__storage__['FOOO'] = [1, 2, 3] |  | ||||||
| 
 |  | ||||||
|         gc.collect() |  | ||||||
|         self.old_objects = len(gc.get_objects()) |  | ||||||
| 
 |  | ||||||
|     def __exit__(self, exc_type, exc_value, tb): |  | ||||||
|         if not hasattr(sys, 'getrefcount'): |  | ||||||
|             gc.collect() |  | ||||||
|         new_objects = len(gc.get_objects()) |  | ||||||
|         if new_objects > self.old_objects: |  | ||||||
|             self.testcase.fail('Example code leaked') |  | ||||||
|         _gc_lock.release() |  | ||||||
|         gc.enable() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class MemoryTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def assert_no_leak(self): |  | ||||||
|         return _NoLeakAsserter(self) |  | ||||||
| 
 |  | ||||||
|     def test_memory_consumption(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('simple_template.html', whiskey=42) |  | ||||||
| 
 |  | ||||||
|         def fire(): |  | ||||||
|             with app.test_client() as c: |  | ||||||
|                 rv = c.get('/') |  | ||||||
|                 self.assert_equal(rv.status_code, 200) |  | ||||||
|                 self.assert_equal(rv.data, b'<h1>42</h1>') |  | ||||||
| 
 |  | ||||||
|         # Trigger caches |  | ||||||
|         fire() |  | ||||||
| 
 |  | ||||||
|         # This test only works on CPython 2.7. |  | ||||||
|         if sys.version_info >= (2, 7) and \ |  | ||||||
|                 not hasattr(sys, 'pypy_translation_info'): |  | ||||||
|             with self.assert_no_leak(): |  | ||||||
|                 for x in range(10): |  | ||||||
|                     fire() |  | ||||||
| 
 |  | ||||||
|     def test_safe_join_toplevel_pardir(self): |  | ||||||
|         from flask.helpers import safe_join |  | ||||||
|         with self.assert_raises(NotFound): |  | ||||||
|             safe_join('/foo', '..') |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class ExceptionTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_aborting(self): |  | ||||||
|         class Foo(Exception): |  | ||||||
|             whatever = 42 |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
|         @app.errorhandler(Foo) |  | ||||||
|         def handle_foo(e): |  | ||||||
|             return str(e.whatever) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             raise flask.abort(flask.redirect(flask.url_for('test'))) |  | ||||||
|         @app.route('/test') |  | ||||||
|         def test(): |  | ||||||
|             raise Foo() |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             rv = c.get('/') |  | ||||||
|             self.assertEqual(rv.headers['Location'], 'http://localhost/test') |  | ||||||
|             rv = c.get('/test') |  | ||||||
|             self.assertEqual(rv.data, b'42') |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     if os.environ.get('RUN_FLASK_MEMORY_TESTS') == '1': |  | ||||||
|         suite.addTest(unittest.makeSuite(MemoryTestCase)) |  | ||||||
|     suite.addTest(unittest.makeSuite(ExceptionTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,201 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.reqctx |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Tests the request context. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| try: |  | ||||||
|     from greenlet import greenlet |  | ||||||
| except ImportError: |  | ||||||
|     greenlet = None |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class RequestContextTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_teardown_on_pop(self): |  | ||||||
|         buffer = [] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.teardown_request |  | ||||||
|         def end_of_request(exception): |  | ||||||
|             buffer.append(exception) |  | ||||||
| 
 |  | ||||||
|         ctx = app.test_request_context() |  | ||||||
|         ctx.push() |  | ||||||
|         self.assert_equal(buffer, []) |  | ||||||
|         ctx.pop() |  | ||||||
|         self.assert_equal(buffer, [None]) |  | ||||||
| 
 |  | ||||||
|     def test_teardown_with_previous_exception(self): |  | ||||||
|         buffer = [] |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.teardown_request |  | ||||||
|         def end_of_request(exception): |  | ||||||
|             buffer.append(exception) |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             raise Exception('dummy') |  | ||||||
|         except Exception: |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         with app.test_request_context(): |  | ||||||
|             self.assert_equal(buffer, []) |  | ||||||
|         self.assert_equal(buffer, [None]) |  | ||||||
| 
 |  | ||||||
|     def test_proper_test_request_context(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config.update( |  | ||||||
|             SERVER_NAME='localhost.localdomain:5000' |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return None |  | ||||||
| 
 |  | ||||||
|         @app.route('/', subdomain='foo') |  | ||||||
|         def sub(): |  | ||||||
|             return None |  | ||||||
| 
 |  | ||||||
|         with app.test_request_context('/'): |  | ||||||
|             self.assert_equal(flask.url_for('index', _external=True), 'http://localhost.localdomain:5000/') |  | ||||||
| 
 |  | ||||||
|         with app.test_request_context('/'): |  | ||||||
|             self.assert_equal(flask.url_for('sub', _external=True), 'http://foo.localhost.localdomain:5000/') |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}): |  | ||||||
|                 pass |  | ||||||
|         except Exception as e: |  | ||||||
|             self.assert_true(isinstance(e, ValueError)) |  | ||||||
|             self.assert_equal(str(e), "the server name provided " + |  | ||||||
|                     "('localhost.localdomain:5000') does not match the " + \ |  | ||||||
|                     "server name from the WSGI environment ('localhost')") |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             app.config.update(SERVER_NAME='localhost') |  | ||||||
|             with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost'}): |  | ||||||
|                 pass |  | ||||||
|         except ValueError as e: |  | ||||||
|             raise ValueError( |  | ||||||
|                 "No ValueError exception should have been raised \"%s\"" % e |  | ||||||
|             ) |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             app.config.update(SERVER_NAME='localhost:80') |  | ||||||
|             with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost:80'}): |  | ||||||
|                 pass |  | ||||||
|         except ValueError as e: |  | ||||||
|             raise ValueError( |  | ||||||
|                 "No ValueError exception should have been raised \"%s\"" % e |  | ||||||
|             ) |  | ||||||
| 
 |  | ||||||
|     def test_context_binding(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return 'Hello %s!' % flask.request.args['name'] |  | ||||||
|         @app.route('/meh') |  | ||||||
|         def meh(): |  | ||||||
|             return flask.request.url |  | ||||||
| 
 |  | ||||||
|         with app.test_request_context('/?name=World'): |  | ||||||
|             self.assert_equal(index(), 'Hello World!') |  | ||||||
|         with app.test_request_context('/meh'): |  | ||||||
|             self.assert_equal(meh(), 'http://localhost/meh') |  | ||||||
|         self.assert_true(flask._request_ctx_stack.top is None) |  | ||||||
| 
 |  | ||||||
|     def test_context_test(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         self.assert_false(flask.request) |  | ||||||
|         self.assert_false(flask.has_request_context()) |  | ||||||
|         ctx = app.test_request_context() |  | ||||||
|         ctx.push() |  | ||||||
|         try: |  | ||||||
|             self.assert_true(flask.request) |  | ||||||
|             self.assert_true(flask.has_request_context()) |  | ||||||
|         finally: |  | ||||||
|             ctx.pop() |  | ||||||
| 
 |  | ||||||
|     def test_manual_context_binding(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return 'Hello %s!' % flask.request.args['name'] |  | ||||||
| 
 |  | ||||||
|         ctx = app.test_request_context('/?name=World') |  | ||||||
|         ctx.push() |  | ||||||
|         self.assert_equal(index(), 'Hello World!') |  | ||||||
|         ctx.pop() |  | ||||||
|         try: |  | ||||||
|             index() |  | ||||||
|         except RuntimeError: |  | ||||||
|             pass |  | ||||||
|         else: |  | ||||||
|             self.assert_true(0, 'expected runtime error') |  | ||||||
| 
 |  | ||||||
|     def test_greenlet_context_copying(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         greenlets = [] |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             reqctx = flask._request_ctx_stack.top.copy() |  | ||||||
|             def g(): |  | ||||||
|                 self.assert_false(flask.request) |  | ||||||
|                 self.assert_false(flask.current_app) |  | ||||||
|                 with reqctx: |  | ||||||
|                     self.assert_true(flask.request) |  | ||||||
|                     self.assert_equal(flask.current_app, app) |  | ||||||
|                     self.assert_equal(flask.request.path, '/') |  | ||||||
|                     self.assert_equal(flask.request.args['foo'], 'bar') |  | ||||||
|                 self.assert_false(flask.request) |  | ||||||
|                 return 42 |  | ||||||
|             greenlets.append(greenlet(g)) |  | ||||||
|             return 'Hello World!' |  | ||||||
| 
 |  | ||||||
|         rv = app.test_client().get('/?foo=bar') |  | ||||||
|         self.assert_equal(rv.data, b'Hello World!') |  | ||||||
| 
 |  | ||||||
|         result = greenlets[0].run() |  | ||||||
|         self.assert_equal(result, 42) |  | ||||||
| 
 |  | ||||||
|     def test_greenlet_context_copying_api(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         greenlets = [] |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             reqctx = flask._request_ctx_stack.top.copy() |  | ||||||
|             @flask.copy_current_request_context |  | ||||||
|             def g(): |  | ||||||
|                 self.assert_true(flask.request) |  | ||||||
|                 self.assert_equal(flask.current_app, app) |  | ||||||
|                 self.assert_equal(flask.request.path, '/') |  | ||||||
|                 self.assert_equal(flask.request.args['foo'], 'bar') |  | ||||||
|                 return 42 |  | ||||||
|             greenlets.append(greenlet(g)) |  | ||||||
|             return 'Hello World!' |  | ||||||
| 
 |  | ||||||
|         rv = app.test_client().get('/?foo=bar') |  | ||||||
|         self.assert_equal(rv.data, b'Hello World!') |  | ||||||
| 
 |  | ||||||
|         result = greenlets[0].run() |  | ||||||
|         self.assert_equal(result, 42) |  | ||||||
| 
 |  | ||||||
|     # Disable test if we don't have greenlets available |  | ||||||
|     if greenlet is None: |  | ||||||
|         test_greenlet_context_copying = None |  | ||||||
|         test_greenlet_context_copying_api = None |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(RequestContextTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,153 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.signals |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Signalling. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class SignalsTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_template_rendered(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('simple_template.html', whiskey=42) |  | ||||||
| 
 |  | ||||||
|         recorded = [] |  | ||||||
|         def record(sender, template, context): |  | ||||||
|             recorded.append((template, context)) |  | ||||||
| 
 |  | ||||||
|         flask.template_rendered.connect(record, app) |  | ||||||
|         try: |  | ||||||
|             app.test_client().get('/') |  | ||||||
|             self.assert_equal(len(recorded), 1) |  | ||||||
|             template, context = recorded[0] |  | ||||||
|             self.assert_equal(template.name, 'simple_template.html') |  | ||||||
|             self.assert_equal(context['whiskey'], 42) |  | ||||||
|         finally: |  | ||||||
|             flask.template_rendered.disconnect(record, app) |  | ||||||
| 
 |  | ||||||
|     def test_request_signals(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         calls = [] |  | ||||||
| 
 |  | ||||||
|         def before_request_signal(sender): |  | ||||||
|             calls.append('before-signal') |  | ||||||
| 
 |  | ||||||
|         def after_request_signal(sender, response): |  | ||||||
|             self.assert_equal(response.data, b'stuff') |  | ||||||
|             calls.append('after-signal') |  | ||||||
| 
 |  | ||||||
|         @app.before_request |  | ||||||
|         def before_request_handler(): |  | ||||||
|             calls.append('before-handler') |  | ||||||
| 
 |  | ||||||
|         @app.after_request |  | ||||||
|         def after_request_handler(response): |  | ||||||
|             calls.append('after-handler') |  | ||||||
|             response.data = 'stuff' |  | ||||||
|             return response |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             calls.append('handler') |  | ||||||
|             return 'ignored anyway' |  | ||||||
| 
 |  | ||||||
|         flask.request_started.connect(before_request_signal, app) |  | ||||||
|         flask.request_finished.connect(after_request_signal, app) |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             rv = app.test_client().get('/') |  | ||||||
|             self.assert_equal(rv.data, b'stuff') |  | ||||||
| 
 |  | ||||||
|             self.assert_equal(calls, ['before-signal', 'before-handler', |  | ||||||
|                              'handler', 'after-handler', |  | ||||||
|                              'after-signal']) |  | ||||||
|         finally: |  | ||||||
|             flask.request_started.disconnect(before_request_signal, app) |  | ||||||
|             flask.request_finished.disconnect(after_request_signal, app) |  | ||||||
| 
 |  | ||||||
|     def test_request_exception_signal(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         recorded = [] |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             1 // 0 |  | ||||||
| 
 |  | ||||||
|         def record(sender, exception): |  | ||||||
|             recorded.append(exception) |  | ||||||
| 
 |  | ||||||
|         flask.got_request_exception.connect(record, app) |  | ||||||
|         try: |  | ||||||
|             self.assert_equal(app.test_client().get('/').status_code, 500) |  | ||||||
|             self.assert_equal(len(recorded), 1) |  | ||||||
|             self.assert_true(isinstance(recorded[0], ZeroDivisionError)) |  | ||||||
|         finally: |  | ||||||
|             flask.got_request_exception.disconnect(record, app) |  | ||||||
| 
 |  | ||||||
|     def test_appcontext_signals(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         recorded = [] |  | ||||||
|         def record_push(sender, **kwargs): |  | ||||||
|             recorded.append('push') |  | ||||||
|         def record_pop(sender, **kwargs): |  | ||||||
|             recorded.append('pop') |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return 'Hello' |  | ||||||
| 
 |  | ||||||
|         flask.appcontext_pushed.connect(record_push, app) |  | ||||||
|         flask.appcontext_popped.connect(record_pop, app) |  | ||||||
|         try: |  | ||||||
|             with app.test_client() as c: |  | ||||||
|                 rv = c.get('/') |  | ||||||
|                 self.assert_equal(rv.data, b'Hello') |  | ||||||
|                 self.assert_equal(recorded, ['push']) |  | ||||||
|             self.assert_equal(recorded, ['push', 'pop']) |  | ||||||
|         finally: |  | ||||||
|             flask.appcontext_pushed.disconnect(record_push, app) |  | ||||||
|             flask.appcontext_popped.disconnect(record_pop, app) |  | ||||||
| 
 |  | ||||||
|     def test_flash_signal(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config['SECRET_KEY'] = 'secret' |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             flask.flash('This is a flash message', category='notice') |  | ||||||
|             return flask.redirect('/other') |  | ||||||
| 
 |  | ||||||
|         recorded = [] |  | ||||||
|         def record(sender, message, category): |  | ||||||
|             recorded.append((message, category)) |  | ||||||
| 
 |  | ||||||
|         flask.message_flashed.connect(record, app) |  | ||||||
|         try: |  | ||||||
|             client = app.test_client() |  | ||||||
|             with client.session_transaction(): |  | ||||||
|                 client.get('/') |  | ||||||
|                 self.assert_equal(len(recorded), 1) |  | ||||||
|                 message, category = recorded[0] |  | ||||||
|                 self.assert_equal(message, 'This is a flash message') |  | ||||||
|                 self.assert_equal(category, 'notice') |  | ||||||
|         finally: |  | ||||||
|             flask.message_flashed.disconnect(record, app) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     if flask.signals_available: |  | ||||||
|         suite.addTest(unittest.makeSuite(SignalsTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,46 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.subclassing |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Test that certain behavior of flask can be customized by |  | ||||||
|     subclasses. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| from logging import StreamHandler |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| from flask._compat import StringIO |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class FlaskSubclassingTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_suppressed_exception_logging(self): |  | ||||||
|         class SuppressedFlask(flask.Flask): |  | ||||||
|             def log_exception(self, exc_info): |  | ||||||
|                 pass |  | ||||||
| 
 |  | ||||||
|         out = StringIO() |  | ||||||
|         app = SuppressedFlask(__name__) |  | ||||||
|         app.logger_name = 'flask_tests/test_suppressed_exception_logging' |  | ||||||
|         app.logger.addHandler(StreamHandler(out)) |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             1 // 0 |  | ||||||
| 
 |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.status_code, 500) |  | ||||||
|         self.assert_in(b'Internal Server Error', rv.data) |  | ||||||
| 
 |  | ||||||
|         err = out.getvalue() |  | ||||||
|         self.assert_equal(err, '') |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(FlaskSubclassingTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,352 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.templating |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Template functionality |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| import logging |  | ||||||
| from jinja2 import TemplateNotFound |  | ||||||
| 
 |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class TemplatingTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_context_processing(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.context_processor |  | ||||||
|         def context_processor(): |  | ||||||
|             return {'injected_value': 42} |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('context_template.html', value=23) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'<p>23|42') |  | ||||||
| 
 |  | ||||||
|     def test_original_win(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template_string('{{ config }}', config=42) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'42') |  | ||||||
| 
 |  | ||||||
|     def test_request_less_rendering(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config['WORLD_NAME'] = 'Special World' |  | ||||||
|         @app.context_processor |  | ||||||
|         def context_processor(): |  | ||||||
|             return dict(foo=42) |  | ||||||
| 
 |  | ||||||
|         with app.app_context(): |  | ||||||
|             rv = flask.render_template_string('Hello {{ config.WORLD_NAME }} ' |  | ||||||
|                                               '{{ foo }}') |  | ||||||
|             self.assert_equal(rv, 'Hello Special World 42') |  | ||||||
| 
 |  | ||||||
|     def test_standard_context(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.secret_key = 'development key' |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             flask.g.foo = 23 |  | ||||||
|             flask.session['test'] = 'aha' |  | ||||||
|             return flask.render_template_string(''' |  | ||||||
|                 {{ request.args.foo }} |  | ||||||
|                 {{ g.foo }} |  | ||||||
|                 {{ config.DEBUG }} |  | ||||||
|                 {{ session.test }} |  | ||||||
|             ''') |  | ||||||
|         rv = app.test_client().get('/?foo=42') |  | ||||||
|         self.assert_equal(rv.data.split(), [b'42', b'23', b'False', b'aha']) |  | ||||||
| 
 |  | ||||||
|     def test_escaping(self): |  | ||||||
|         text = '<p>Hello World!' |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('escaping_template.html', text=text, |  | ||||||
|                                          html=flask.Markup(text)) |  | ||||||
|         lines = app.test_client().get('/').data.splitlines() |  | ||||||
|         self.assert_equal(lines, [ |  | ||||||
|             b'<p>Hello World!', |  | ||||||
|             b'<p>Hello World!', |  | ||||||
|             b'<p>Hello World!', |  | ||||||
|             b'<p>Hello World!', |  | ||||||
|             b'<p>Hello World!', |  | ||||||
|             b'<p>Hello World!' |  | ||||||
|         ]) |  | ||||||
| 
 |  | ||||||
|     def test_no_escaping(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         with app.test_request_context(): |  | ||||||
|             self.assert_equal(flask.render_template_string('{{ foo }}', |  | ||||||
|                               foo='<test>'), '<test>') |  | ||||||
|             self.assert_equal(flask.render_template('mail.txt', foo='<test>'), |  | ||||||
|                               '<test> Mail') |  | ||||||
| 
 |  | ||||||
|     def test_macros(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         with app.test_request_context(): |  | ||||||
|             macro = flask.get_template_attribute('_macro.html', 'hello') |  | ||||||
|             self.assert_equal(macro('World'), 'Hello World!') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_filter() |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         self.assert_in('my_reverse', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app.add_template_filter(my_reverse) |  | ||||||
|         self.assert_in('my_reverse', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['my_reverse']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter_with_name(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_filter('strrev') |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         self.assert_in('strrev', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter_with_name(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app.add_template_filter(my_reverse, 'strrev') |  | ||||||
|         self.assert_in('strrev', app.jinja_env.filters.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev'], my_reverse) |  | ||||||
|         self.assert_equal(app.jinja_env.filters['strrev']('abcd'), 'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter_with_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_filter() |  | ||||||
|         def super_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter_with_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def super_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app.add_template_filter(super_reverse) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_filter_with_name_and_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_filter('super_reverse') |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_add_template_filter_with_name_and_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def my_reverse(s): |  | ||||||
|             return s[::-1] |  | ||||||
|         app.add_template_filter(my_reverse, 'super_reverse') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_filter.html', value='abcd') |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'dcba') |  | ||||||
| 
 |  | ||||||
|     def test_template_test(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_test() |  | ||||||
|         def boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         self.assert_in('boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['boolean'], boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app.add_template_test(boolean) |  | ||||||
|         self.assert_in('boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['boolean'], boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_template_test_with_name(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_test('boolean') |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         self.assert_in('boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['boolean'], is_boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test_with_name(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app.add_template_test(is_boolean, 'boolean') |  | ||||||
|         self.assert_in('boolean', app.jinja_env.tests.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.tests['boolean'], is_boolean) |  | ||||||
|         self.assert_true(app.jinja_env.tests['boolean'](False)) |  | ||||||
| 
 |  | ||||||
|     def test_template_test_with_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_test() |  | ||||||
|         def boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test_with_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app.add_template_test(boolean) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_template_test_with_name_and_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_test('boolean') |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_test_with_name_and_template(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         def is_boolean(value): |  | ||||||
|             return isinstance(value, bool) |  | ||||||
|         app.add_template_test(is_boolean, 'boolean') |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('template_test.html', value=False) |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_in(b'Success!', rv.data) |  | ||||||
| 
 |  | ||||||
|     def test_add_template_global(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.template_global() |  | ||||||
|         def get_stuff(): |  | ||||||
|             return 42 |  | ||||||
|         self.assert_in('get_stuff', app.jinja_env.globals.keys()) |  | ||||||
|         self.assert_equal(app.jinja_env.globals['get_stuff'], get_stuff) |  | ||||||
|         self.assert_true(app.jinja_env.globals['get_stuff'](), 42) |  | ||||||
|         with app.app_context(): |  | ||||||
|             rv = flask.render_template_string('{{ get_stuff() }}') |  | ||||||
|             self.assert_equal(rv, '42') |  | ||||||
| 
 |  | ||||||
|     def test_custom_template_loader(self): |  | ||||||
|         class MyFlask(flask.Flask): |  | ||||||
|             def create_global_jinja_loader(self): |  | ||||||
|                 from jinja2 import DictLoader |  | ||||||
|                 return DictLoader({'index.html': 'Hello Custom World!'}) |  | ||||||
|         app = MyFlask(__name__) |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template('index.html') |  | ||||||
|         c = app.test_client() |  | ||||||
|         rv = c.get('/') |  | ||||||
|         self.assert_equal(rv.data, b'Hello Custom World!') |  | ||||||
| 
 |  | ||||||
|     def test_iterable_loader(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         @app.context_processor |  | ||||||
|         def context_processor(): |  | ||||||
|             return {'whiskey': 'Jameson'} |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.render_template( |  | ||||||
|                 ['no_template.xml', # should skip this one |  | ||||||
|                 'simple_template.html', # should render this |  | ||||||
|                 'context_template.html'], |  | ||||||
|                 value=23) |  | ||||||
| 
 |  | ||||||
|         rv = app.test_client().get('/') |  | ||||||
|         self.assert_equal(rv.data, b'<h1>Jameson</h1>') |  | ||||||
| 
 |  | ||||||
|     def test_templates_auto_reload(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         self.assert_true(app.config['TEMPLATES_AUTO_RELOAD']) |  | ||||||
|         self.assert_true(app.jinja_env.auto_reload) |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config['TEMPLATES_AUTO_RELOAD'] = False |  | ||||||
|         self.assert_false(app.jinja_env.auto_reload) |  | ||||||
| 
 |  | ||||||
|     def test_template_loader_debugging(self): |  | ||||||
|         from blueprintapp import app |  | ||||||
| 
 |  | ||||||
|         called = [] |  | ||||||
|         class _TestHandler(logging.Handler): |  | ||||||
|             def handle(x, record): |  | ||||||
|                 called.append(True) |  | ||||||
|                 text = str(record.msg) |  | ||||||
|                 self.assert_('1: trying loader of application ' |  | ||||||
|                              '"blueprintapp"' in text) |  | ||||||
|                 self.assert_('2: trying loader of blueprint "admin" ' |  | ||||||
|                              '(blueprintapp.apps.admin)' in text) |  | ||||||
|                 self.assert_('trying loader of blueprint "frontend" ' |  | ||||||
|                              '(blueprintapp.apps.frontend)' in text) |  | ||||||
|                 self.assert_('Error: the template could not be found' in text) |  | ||||||
|                 self.assert_('looked up from an endpoint that belongs to ' |  | ||||||
|                              'the blueprint "frontend"' in text) |  | ||||||
|                 self.assert_( |  | ||||||
|                     'See http://flask.pocoo.org/docs/blueprints/#templates' in text) |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             try: |  | ||||||
|                 old_load_setting = app.config['EXPLAIN_TEMPLATE_LOADING'] |  | ||||||
|                 old_handlers = app.logger.handlers[:] |  | ||||||
|                 app.logger.handlers = [_TestHandler()] |  | ||||||
|                 app.config['EXPLAIN_TEMPLATE_LOADING'] = True |  | ||||||
| 
 |  | ||||||
|                 try: |  | ||||||
|                     c.get('/missing') |  | ||||||
|                 except TemplateNotFound as e: |  | ||||||
|                     self.assert_('missing_template.html' in str(e)) |  | ||||||
|                 else: |  | ||||||
|                     self.fail('Expected template not found exception.') |  | ||||||
|             finally: |  | ||||||
|                 app.logger.handlers[:] = old_handlers |  | ||||||
|                 app.config['EXPLAIN_TEMPLATE_LOADING'] = old_load_setting |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(len(called), 1) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(TemplatingTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,4 +0,0 @@ | ||||||
| import os |  | ||||||
| import flask |  | ||||||
| here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
| app = flask.Flask(__name__) |  | ||||||
|  | @ -1,4 +0,0 @@ | ||||||
| import os |  | ||||||
| import flask |  | ||||||
| here = os.path.abspath(os.path.dirname(__file__)) |  | ||||||
| app = flask.Flask(__name__) |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| import flask.ext.broken.b |  | ||||||
| import missing_module |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| ext_id = 'newext_package' |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| def test_function(): |  | ||||||
|     return 42 |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| ext_id = 'newext_simple' |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| ext_id = 'oldext_package' |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| def test_function(): |  | ||||||
|     return 42 |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| ext_id = 'oldext_simple' |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| # NoImportsTestCase |  | ||||||
| raise NotImplementedError |  | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -1,3 +0,0 @@ | ||||||
| import flask |  | ||||||
| 
 |  | ||||||
| app = flask.Flask(__name__) |  | ||||||
|  | @ -1,3 +0,0 @@ | ||||||
| import flask |  | ||||||
| 
 |  | ||||||
| app = flask.Flask(__name__) |  | ||||||
|  | @ -1,4 +0,0 @@ | ||||||
| import flask |  | ||||||
| 
 |  | ||||||
| # Test Flask initialization with main module. |  | ||||||
| app = flask.Flask('__main__') |  | ||||||
|  | @ -1,3 +0,0 @@ | ||||||
| import flask |  | ||||||
| 
 |  | ||||||
| app = flask.Flask(__name__) |  | ||||||
|  | @ -1,257 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.testing |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Test client and more. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import unittest |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| from flask._compat import text_type |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class TestToolsTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def test_environ_defaults_from_config(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
|         app.config['SERVER_NAME'] = 'example.com:1234' |  | ||||||
|         app.config['APPLICATION_ROOT'] = '/foo' |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.request.url |  | ||||||
| 
 |  | ||||||
|         ctx = app.test_request_context() |  | ||||||
|         self.assert_equal(ctx.request.url, 'http://example.com:1234/foo/') |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             rv = c.get('/') |  | ||||||
|             self.assert_equal(rv.data, b'http://example.com:1234/foo/') |  | ||||||
| 
 |  | ||||||
|     def test_environ_defaults(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return flask.request.url |  | ||||||
| 
 |  | ||||||
|         ctx = app.test_request_context() |  | ||||||
|         self.assert_equal(ctx.request.url, 'http://localhost/') |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             rv = c.get('/') |  | ||||||
|             self.assert_equal(rv.data, b'http://localhost/') |  | ||||||
| 
 |  | ||||||
|     def test_redirect_keep_session(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.secret_key = 'testing' |  | ||||||
| 
 |  | ||||||
|         @app.route('/', methods=['GET', 'POST']) |  | ||||||
|         def index(): |  | ||||||
|             if flask.request.method == 'POST': |  | ||||||
|                 return flask.redirect('/getsession') |  | ||||||
|             flask.session['data'] = 'foo' |  | ||||||
|             return 'index' |  | ||||||
| 
 |  | ||||||
|         @app.route('/getsession') |  | ||||||
|         def get_session(): |  | ||||||
|             return flask.session.get('data', '<missing>') |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             rv = c.get('/getsession') |  | ||||||
|             assert rv.data == b'<missing>' |  | ||||||
| 
 |  | ||||||
|             rv = c.get('/') |  | ||||||
|             assert rv.data == b'index' |  | ||||||
|             assert flask.session.get('data') == 'foo' |  | ||||||
|             rv = c.post('/', data={}, follow_redirects=True) |  | ||||||
|             assert rv.data == b'foo' |  | ||||||
| 
 |  | ||||||
|             # This support requires a new Werkzeug version |  | ||||||
|             if not hasattr(c, 'redirect_client'): |  | ||||||
|                 assert flask.session.get('data') == 'foo' |  | ||||||
| 
 |  | ||||||
|             rv = c.get('/getsession') |  | ||||||
|             assert rv.data == b'foo' |  | ||||||
| 
 |  | ||||||
|     def test_session_transactions(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
|         app.secret_key = 'testing' |  | ||||||
| 
 |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             return text_type(flask.session['foo']) |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             with c.session_transaction() as sess: |  | ||||||
|                 self.assert_equal(len(sess), 0) |  | ||||||
|                 sess['foo'] = [42] |  | ||||||
|                 self.assert_equal(len(sess), 1) |  | ||||||
|             rv = c.get('/') |  | ||||||
|             self.assert_equal(rv.data, b'[42]') |  | ||||||
|             with c.session_transaction() as sess: |  | ||||||
|                 self.assert_equal(len(sess), 1) |  | ||||||
|                 self.assert_equal(sess['foo'], [42]) |  | ||||||
| 
 |  | ||||||
|     def test_session_transactions_no_null_sessions(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             try: |  | ||||||
|                 with c.session_transaction() as sess: |  | ||||||
|                     pass |  | ||||||
|             except RuntimeError as e: |  | ||||||
|                 self.assert_in('Session backend did not open a session', str(e)) |  | ||||||
|             else: |  | ||||||
|                 self.fail('Expected runtime error') |  | ||||||
| 
 |  | ||||||
|     def test_session_transactions_keep_context(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
|         app.secret_key = 'testing' |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             rv = c.get('/') |  | ||||||
|             req = flask.request._get_current_object() |  | ||||||
|             self.assert_true(req is not None) |  | ||||||
|             with c.session_transaction(): |  | ||||||
|                 self.assert_true(req is flask.request._get_current_object()) |  | ||||||
| 
 |  | ||||||
|     def test_session_transaction_needs_cookies(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
|         c = app.test_client(use_cookies=False) |  | ||||||
|         try: |  | ||||||
|             with c.session_transaction() as s: |  | ||||||
|                 pass |  | ||||||
|         except RuntimeError as e: |  | ||||||
|             self.assert_in('cookies', str(e)) |  | ||||||
|         else: |  | ||||||
|             self.fail('Expected runtime error') |  | ||||||
| 
 |  | ||||||
|     def test_test_client_context_binding(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.config['LOGGER_HANDLER_POLICY'] = 'never' |  | ||||||
|         @app.route('/') |  | ||||||
|         def index(): |  | ||||||
|             flask.g.value = 42 |  | ||||||
|             return 'Hello World!' |  | ||||||
| 
 |  | ||||||
|         @app.route('/other') |  | ||||||
|         def other(): |  | ||||||
|             1 // 0 |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             resp = c.get('/') |  | ||||||
|             self.assert_equal(flask.g.value, 42) |  | ||||||
|             self.assert_equal(resp.data, b'Hello World!') |  | ||||||
|             self.assert_equal(resp.status_code, 200) |  | ||||||
| 
 |  | ||||||
|             resp = c.get('/other') |  | ||||||
|             self.assert_false(hasattr(flask.g, 'value')) |  | ||||||
|             self.assert_in(b'Internal Server Error', resp.data) |  | ||||||
|             self.assert_equal(resp.status_code, 500) |  | ||||||
|             flask.g.value = 23 |  | ||||||
| 
 |  | ||||||
|         try: |  | ||||||
|             flask.g.value |  | ||||||
|         except (AttributeError, RuntimeError): |  | ||||||
|             pass |  | ||||||
|         else: |  | ||||||
|             raise AssertionError('some kind of exception expected') |  | ||||||
| 
 |  | ||||||
|     def test_reuse_client(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         c = app.test_client() |  | ||||||
| 
 |  | ||||||
|         with c: |  | ||||||
|             self.assert_equal(c.get('/').status_code, 404) |  | ||||||
| 
 |  | ||||||
|         with c: |  | ||||||
|             self.assert_equal(c.get('/').status_code, 404) |  | ||||||
| 
 |  | ||||||
|     def test_test_client_calls_teardown_handlers(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         called = [] |  | ||||||
|         @app.teardown_request |  | ||||||
|         def remember(error): |  | ||||||
|             called.append(error) |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             self.assert_equal(called, []) |  | ||||||
|             c.get('/') |  | ||||||
|             self.assert_equal(called, []) |  | ||||||
|         self.assert_equal(called, [None]) |  | ||||||
| 
 |  | ||||||
|         del called[:] |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             self.assert_equal(called, []) |  | ||||||
|             c.get('/') |  | ||||||
|             self.assert_equal(called, []) |  | ||||||
|             c.get('/') |  | ||||||
|             self.assert_equal(called, [None]) |  | ||||||
|         self.assert_equal(called, [None, None]) |  | ||||||
| 
 |  | ||||||
|     def test_full_url_request(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.testing = True |  | ||||||
| 
 |  | ||||||
|         @app.route('/action', methods=['POST']) |  | ||||||
|         def action(): |  | ||||||
|             return 'x' |  | ||||||
| 
 |  | ||||||
|         with app.test_client() as c: |  | ||||||
|             rv = c.post('http://domain.com/action?vodka=42', data={'gin': 43}) |  | ||||||
|             self.assert_equal(rv.status_code, 200) |  | ||||||
|             self.assert_true('gin' in flask.request.form) |  | ||||||
|             self.assert_true('vodka' in flask.request.args) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class SubdomainTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def setUp(self): |  | ||||||
|         self.app = flask.Flask(__name__) |  | ||||||
|         self.app.config['SERVER_NAME'] = 'example.com' |  | ||||||
|         self.client = self.app.test_client() |  | ||||||
| 
 |  | ||||||
|         self._ctx = self.app.test_request_context() |  | ||||||
|         self._ctx.push() |  | ||||||
| 
 |  | ||||||
|     def tearDown(self): |  | ||||||
|         if self._ctx is not None: |  | ||||||
|             self._ctx.pop() |  | ||||||
| 
 |  | ||||||
|     def test_subdomain(self): |  | ||||||
|         @self.app.route('/', subdomain='<company_id>') |  | ||||||
|         def view(company_id): |  | ||||||
|             return company_id |  | ||||||
| 
 |  | ||||||
|         url = flask.url_for('view', company_id='xxx') |  | ||||||
|         response = self.client.get(url) |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(200, response.status_code) |  | ||||||
|         self.assert_equal(b'xxx', response.data) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     def test_nosubdomain(self): |  | ||||||
|         @self.app.route('/<company_id>') |  | ||||||
|         def view(company_id): |  | ||||||
|             return company_id |  | ||||||
| 
 |  | ||||||
|         url = flask.url_for('view', company_id='xxx') |  | ||||||
|         response = self.client.get(url) |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(200, response.status_code) |  | ||||||
|         self.assert_equal(b'xxx', response.data) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(TestToolsTestCase)) |  | ||||||
|     suite.addTest(unittest.makeSuite(SubdomainTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,169 +0,0 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """ |  | ||||||
|     flask.testsuite.views |  | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
|     Pluggable views. |  | ||||||
| 
 |  | ||||||
|     :copyright: (c) 2014 by Armin Ronacher. |  | ||||||
|     :license: BSD, see LICENSE for more details. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import flask |  | ||||||
| import flask.views |  | ||||||
| import unittest |  | ||||||
| from flask.testsuite import FlaskTestCase |  | ||||||
| from werkzeug.http import parse_set_header |  | ||||||
| 
 |  | ||||||
| class ViewTestCase(FlaskTestCase): |  | ||||||
| 
 |  | ||||||
|     def common_test(self, app): |  | ||||||
|         c = app.test_client() |  | ||||||
| 
 |  | ||||||
|         self.assert_equal(c.get('/').data, b'GET') |  | ||||||
|         self.assert_equal(c.post('/').data, b'POST') |  | ||||||
|         self.assert_equal(c.put('/').status_code, 405) |  | ||||||
|         meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow']) |  | ||||||
|         self.assert_equal(sorted(meths), ['GET', 'HEAD', 'OPTIONS', 'POST']) |  | ||||||
| 
 |  | ||||||
|     def test_basic_view(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.View): |  | ||||||
|             methods = ['GET', 'POST'] |  | ||||||
|             def dispatch_request(self): |  | ||||||
|                 return flask.request.method |  | ||||||
| 
 |  | ||||||
|         app.add_url_rule('/', view_func=Index.as_view('index')) |  | ||||||
|         self.common_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_method_based_view(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.MethodView): |  | ||||||
|             def get(self): |  | ||||||
|                 return 'GET' |  | ||||||
|             def post(self): |  | ||||||
|                 return 'POST' |  | ||||||
| 
 |  | ||||||
|         app.add_url_rule('/', view_func=Index.as_view('index')) |  | ||||||
| 
 |  | ||||||
|         self.common_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_view_patching(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.MethodView): |  | ||||||
|             def get(self): |  | ||||||
|                 1 // 0 |  | ||||||
|             def post(self): |  | ||||||
|                 1 // 0 |  | ||||||
| 
 |  | ||||||
|         class Other(Index): |  | ||||||
|             def get(self): |  | ||||||
|                 return 'GET' |  | ||||||
|             def post(self): |  | ||||||
|                 return 'POST' |  | ||||||
| 
 |  | ||||||
|         view = Index.as_view('index') |  | ||||||
|         view.view_class = Other |  | ||||||
|         app.add_url_rule('/', view_func=view) |  | ||||||
|         self.common_test(app) |  | ||||||
| 
 |  | ||||||
|     def test_view_inheritance(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.MethodView): |  | ||||||
|             def get(self): |  | ||||||
|                 return 'GET' |  | ||||||
|             def post(self): |  | ||||||
|                 return 'POST' |  | ||||||
| 
 |  | ||||||
|         class BetterIndex(Index): |  | ||||||
|             def delete(self): |  | ||||||
|                 return 'DELETE' |  | ||||||
| 
 |  | ||||||
|         app.add_url_rule('/', view_func=BetterIndex.as_view('index')) |  | ||||||
|         c = app.test_client() |  | ||||||
| 
 |  | ||||||
|         meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow']) |  | ||||||
|         self.assert_equal(sorted(meths), ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST']) |  | ||||||
| 
 |  | ||||||
|     def test_view_decorators(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         def add_x_parachute(f): |  | ||||||
|             def new_function(*args, **kwargs): |  | ||||||
|                 resp = flask.make_response(f(*args, **kwargs)) |  | ||||||
|                 resp.headers['X-Parachute'] = 'awesome' |  | ||||||
|                 return resp |  | ||||||
|             return new_function |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.View): |  | ||||||
|             decorators = [add_x_parachute] |  | ||||||
|             def dispatch_request(self): |  | ||||||
|                 return 'Awesome' |  | ||||||
| 
 |  | ||||||
|         app.add_url_rule('/', view_func=Index.as_view('index')) |  | ||||||
|         c = app.test_client() |  | ||||||
|         rv = c.get('/') |  | ||||||
|         self.assert_equal(rv.headers['X-Parachute'], 'awesome') |  | ||||||
|         self.assert_equal(rv.data, b'Awesome') |  | ||||||
| 
 |  | ||||||
|     def test_implicit_head(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.MethodView): |  | ||||||
|             def get(self): |  | ||||||
|                 return flask.Response('Blub', headers={ |  | ||||||
|                     'X-Method': flask.request.method |  | ||||||
|                 }) |  | ||||||
| 
 |  | ||||||
|         app.add_url_rule('/', view_func=Index.as_view('index')) |  | ||||||
|         c = app.test_client() |  | ||||||
|         rv = c.get('/') |  | ||||||
|         self.assert_equal(rv.data, b'Blub') |  | ||||||
|         self.assert_equal(rv.headers['X-Method'], 'GET') |  | ||||||
|         rv = c.head('/') |  | ||||||
|         self.assert_equal(rv.data, b'') |  | ||||||
|         self.assert_equal(rv.headers['X-Method'], 'HEAD') |  | ||||||
| 
 |  | ||||||
|     def test_explicit_head(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.MethodView): |  | ||||||
|             def get(self): |  | ||||||
|                 return 'GET' |  | ||||||
|             def head(self): |  | ||||||
|                 return flask.Response('', headers={'X-Method': 'HEAD'}) |  | ||||||
| 
 |  | ||||||
|         app.add_url_rule('/', view_func=Index.as_view('index')) |  | ||||||
|         c = app.test_client() |  | ||||||
|         rv = c.get('/') |  | ||||||
|         self.assert_equal(rv.data, b'GET') |  | ||||||
|         rv = c.head('/') |  | ||||||
|         self.assert_equal(rv.data, b'') |  | ||||||
|         self.assert_equal(rv.headers['X-Method'], 'HEAD') |  | ||||||
| 
 |  | ||||||
|     def test_endpoint_override(self): |  | ||||||
|         app = flask.Flask(__name__) |  | ||||||
|         app.debug = True |  | ||||||
| 
 |  | ||||||
|         class Index(flask.views.View): |  | ||||||
|             methods = ['GET', 'POST'] |  | ||||||
|             def dispatch_request(self): |  | ||||||
|                 return flask.request.method |  | ||||||
| 
 |  | ||||||
|         app.add_url_rule('/', view_func=Index.as_view('index')) |  | ||||||
| 
 |  | ||||||
|         with self.assert_raises(AssertionError): |  | ||||||
|             app.add_url_rule('/', view_func=Index.as_view('index')) |  | ||||||
| 
 |  | ||||||
|         # But these tests should still pass. We just log a warning. |  | ||||||
|         self.common_test(app) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     suite.addTest(unittest.makeSuite(ViewTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -1,5 +0,0 @@ | ||||||
| #!/usr/bin/env python |  | ||||||
| import sys, os |  | ||||||
| sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) |  | ||||||
| from flask.testsuite import main |  | ||||||
| main() |  | ||||||
							
								
								
									
										42
									
								
								setup.py
								
								
								
								
							
							
						
						
									
										42
									
								
								setup.py
								
								
								
								
							|  | @ -46,42 +46,6 @@ from __future__ import print_function | ||||||
| from setuptools import Command, setup | from setuptools import Command, setup | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class run_audit(Command): |  | ||||||
|     """Audits source code using PyFlakes for following issues: |  | ||||||
|         - Names which are used but not defined or used before they are defined. |  | ||||||
|         - Names which are redefined without having been used. |  | ||||||
|     """ |  | ||||||
|     description = "Audit source code with PyFlakes" |  | ||||||
|     user_options = [] |  | ||||||
| 
 |  | ||||||
|     def initialize_options(self): |  | ||||||
|         pass |  | ||||||
| 
 |  | ||||||
|     def finalize_options(self): |  | ||||||
|         pass |  | ||||||
| 
 |  | ||||||
|     def run(self): |  | ||||||
|         import os |  | ||||||
|         import sys |  | ||||||
|         try: |  | ||||||
|             import pyflakes.scripts.pyflakes as flakes |  | ||||||
|         except ImportError: |  | ||||||
|             print("Audit requires PyFlakes installed in your system.") |  | ||||||
|             sys.exit(-1) |  | ||||||
| 
 |  | ||||||
|         warns = 0 |  | ||||||
|         # Define top-level directories |  | ||||||
|         dirs = ('flask', 'examples', 'scripts') |  | ||||||
|         for dir in dirs: |  | ||||||
|             for root, _, files in os.walk(dir): |  | ||||||
|                 for file in files: |  | ||||||
|                     if file != '__init__.py' and file.endswith('.py'): |  | ||||||
|                         warns += flakes.checkPath(os.path.join(root, file)) |  | ||||||
|         if warns > 0: |  | ||||||
|             print("Audit finished with total %d warnings." % warns) |  | ||||||
|         else: |  | ||||||
|             print("No problems found in sourcecode.") |  | ||||||
| 
 |  | ||||||
| setup( | setup( | ||||||
|     name='Flask', |     name='Flask', | ||||||
|     version='0.11-dev', |     version='0.11-dev', | ||||||
|  | @ -92,7 +56,7 @@ setup( | ||||||
|     description='A microframework based on Werkzeug, Jinja2 ' |     description='A microframework based on Werkzeug, Jinja2 ' | ||||||
|                 'and good intentions', |                 'and good intentions', | ||||||
|     long_description=__doc__, |     long_description=__doc__, | ||||||
|     packages=['flask', 'flask.ext', 'flask.testsuite'], |     packages=['flask', 'flask.ext'], | ||||||
|     include_package_data=True, |     include_package_data=True, | ||||||
|     zip_safe=False, |     zip_safe=False, | ||||||
|     platforms='any', |     platforms='any', | ||||||
|  | @ -116,7 +80,5 @@ setup( | ||||||
|     entry_points=''' |     entry_points=''' | ||||||
|         [console_scripts] |         [console_scripts] | ||||||
|         flask=flask.cli:main |         flask=flask.cli:main | ||||||
|     ''', |     ''' | ||||||
|     cmdclass={'audit': run_audit}, |  | ||||||
|     test_suite='flask.testsuite.suite' |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,134 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.conftest | ||||||
|  |     ~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by the Flask Team, see AUTHORS for more details. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | import flask | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | import pkgutil | ||||||
|  | import pytest | ||||||
|  | import textwrap | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def test_apps(monkeypatch): | ||||||
|  |     monkeypatch.syspath_prepend( | ||||||
|  |         os.path.abspath(os.path.join( | ||||||
|  |             os.path.dirname(__file__), 'test_apps')) | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | @pytest.fixture(autouse=True) | ||||||
|  | def leak_detector(request): | ||||||
|  |     def ensure_clean_request_context(): | ||||||
|  |         # make sure we're not leaking a request context since we are | ||||||
|  |         # testing flask internally in debug mode in a few cases | ||||||
|  |         leaks = [] | ||||||
|  |         while flask._request_ctx_stack.top is not None: | ||||||
|  |             leaks.append(flask._request_ctx_stack.pop()) | ||||||
|  |         assert leaks == [] | ||||||
|  |     request.addfinalizer(ensure_clean_request_context) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture(params=(True, False)) | ||||||
|  | def limit_loader(request, monkeypatch): | ||||||
|  |     """Patch pkgutil.get_loader to give loader without get_filename or archive. | ||||||
|  | 
 | ||||||
|  |     This provides for tests where a system has custom loaders, e.g. Google App | ||||||
|  |     Engine's HardenedModulesHook, which have neither the `get_filename` method | ||||||
|  |     nor the `archive` attribute. | ||||||
|  | 
 | ||||||
|  |     This fixture will run the testcase twice, once with and once without the | ||||||
|  |     limitation/mock. | ||||||
|  |     """ | ||||||
|  |     if not request.param: | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     class LimitedLoader(object): | ||||||
|  |         def __init__(self, loader): | ||||||
|  |             self.loader = loader | ||||||
|  | 
 | ||||||
|  |         def __getattr__(self, name): | ||||||
|  |             if name in ('archive', 'get_filename'): | ||||||
|  |                 msg = 'Mocking a loader which does not have `%s.`' % name | ||||||
|  |                 raise AttributeError(msg) | ||||||
|  |             return getattr(self.loader, name) | ||||||
|  | 
 | ||||||
|  |     old_get_loader = pkgutil.get_loader | ||||||
|  | 
 | ||||||
|  |     def get_loader(*args, **kwargs): | ||||||
|  |         return LimitedLoader(old_get_loader(*args, **kwargs)) | ||||||
|  |     monkeypatch.setattr(pkgutil, 'get_loader', get_loader) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def modules_tmpdir(tmpdir, monkeypatch): | ||||||
|  |     '''A tmpdir added to sys.path''' | ||||||
|  |     rv = tmpdir.mkdir('modules_tmpdir') | ||||||
|  |     monkeypatch.syspath_prepend(str(rv)) | ||||||
|  |     return rv | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def modules_tmpdir_prefix(modules_tmpdir, monkeypatch): | ||||||
|  |     monkeypatch.setattr(sys, 'prefix', str(modules_tmpdir)) | ||||||
|  |     return modules_tmpdir | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def site_packages(modules_tmpdir, monkeypatch): | ||||||
|  |     '''Create a fake site-packages''' | ||||||
|  |     rv = modules_tmpdir \ | ||||||
|  |         .mkdir('lib')\ | ||||||
|  |         .mkdir('python{x[0]}.{x[1]}'.format(x=sys.version_info))\ | ||||||
|  |         .mkdir('site-packages') | ||||||
|  |     monkeypatch.syspath_prepend(str(rv)) | ||||||
|  |     return rv | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def install_egg(modules_tmpdir, monkeypatch): | ||||||
|  |     '''Generate egg from package name inside base and put the egg into | ||||||
|  |     sys.path''' | ||||||
|  |     def inner(name, base=modules_tmpdir): | ||||||
|  |         if not isinstance(name, str): | ||||||
|  |             raise ValueError(name) | ||||||
|  |         base.join(name).ensure_dir() | ||||||
|  |         base.join(name).join('__init__.py').ensure() | ||||||
|  | 
 | ||||||
|  |         egg_setup = base.join('setup.py') | ||||||
|  |         egg_setup.write(textwrap.dedent(""" | ||||||
|  |         from setuptools import setup | ||||||
|  |         setup(name='{0}', | ||||||
|  |               version='1.0', | ||||||
|  |               packages=['site_egg'], | ||||||
|  |               zip_safe=True) | ||||||
|  |         """.format(name))) | ||||||
|  | 
 | ||||||
|  |         import subprocess | ||||||
|  |         subprocess.check_call( | ||||||
|  |             [sys.executable, 'setup.py', 'bdist_egg'], | ||||||
|  |             cwd=str(modules_tmpdir) | ||||||
|  |         ) | ||||||
|  |         egg_path, = modules_tmpdir.join('dist/').listdir() | ||||||
|  |         monkeypatch.syspath_prepend(str(egg_path)) | ||||||
|  |         return egg_path | ||||||
|  |     return inner | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def purge_module(request): | ||||||
|  |     def inner(name): | ||||||
|  |         request.addfinalizer(lambda: sys.modules.pop(name, None)) | ||||||
|  |     return inner | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def catch_deprecation_warnings(): | ||||||
|  |     import warnings | ||||||
|  |     warnings.simplefilter('default', category=DeprecationWarning) | ||||||
|  |     return lambda: warnings.catch_warnings(record=True) | ||||||
|  | @ -0,0 +1,113 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.appctx | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests the application context. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import flask | ||||||
|  | import unittest | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_basic_url_generation(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['SERVER_NAME'] = 'localhost' | ||||||
|  |     app.config['PREFERRED_URL_SCHEME'] = 'https' | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     with app.app_context(): | ||||||
|  |         rv = flask.url_for('index') | ||||||
|  |         assert rv == 'https://localhost/' | ||||||
|  | 
 | ||||||
|  | def test_url_generation_requires_server_name(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     with app.app_context(): | ||||||
|  |         with pytest.raises(RuntimeError): | ||||||
|  |             flask.url_for('index') | ||||||
|  | 
 | ||||||
|  | def test_url_generation_without_context_fails(): | ||||||
|  |     with pytest.raises(RuntimeError): | ||||||
|  |         flask.url_for('index') | ||||||
|  | 
 | ||||||
|  | def test_request_context_means_app_context(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         assert flask.current_app._get_current_object() == app | ||||||
|  |     assert flask._app_ctx_stack.top == None | ||||||
|  | 
 | ||||||
|  | def test_app_context_provides_current_app(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     with app.app_context(): | ||||||
|  |         assert flask.current_app._get_current_object() == app | ||||||
|  |     assert flask._app_ctx_stack.top == None | ||||||
|  | 
 | ||||||
|  | def test_app_tearing_down(): | ||||||
|  |     cleanup_stuff = [] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.teardown_appcontext | ||||||
|  |     def cleanup(exception): | ||||||
|  |         cleanup_stuff.append(exception) | ||||||
|  | 
 | ||||||
|  |     with app.app_context(): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     assert cleanup_stuff == [None] | ||||||
|  | 
 | ||||||
|  | def test_app_tearing_down_with_previous_exception(): | ||||||
|  |     cleanup_stuff = [] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.teardown_appcontext | ||||||
|  |     def cleanup(exception): | ||||||
|  |         cleanup_stuff.append(exception) | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         raise Exception('dummy') | ||||||
|  |     except Exception: | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     with app.app_context(): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     assert cleanup_stuff == [None] | ||||||
|  | 
 | ||||||
|  | def test_custom_app_ctx_globals_class(): | ||||||
|  |     class CustomRequestGlobals(object): | ||||||
|  |         def __init__(self): | ||||||
|  |             self.spam = 'eggs' | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.app_ctx_globals_class = CustomRequestGlobals | ||||||
|  |     with app.app_context(): | ||||||
|  |         assert flask.render_template_string('{{ g.spam }}') == 'eggs' | ||||||
|  | 
 | ||||||
|  | def test_context_refcounts(): | ||||||
|  |     called = [] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.teardown_request | ||||||
|  |     def teardown_req(error=None): | ||||||
|  |         called.append('request') | ||||||
|  |     @app.teardown_appcontext | ||||||
|  |     def teardown_app(error=None): | ||||||
|  |         called.append('app') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         with flask._app_ctx_stack.top: | ||||||
|  |             with flask._request_ctx_stack.top: | ||||||
|  |                 pass | ||||||
|  |         env = flask._request_ctx_stack.top.request.environ | ||||||
|  |         assert env['werkzeug.request'] is not None | ||||||
|  |         return u'' | ||||||
|  |     c = app.test_client() | ||||||
|  |     res = c.get('/') | ||||||
|  |     assert res.status_code == 200 | ||||||
|  |     assert res.data == b'' | ||||||
|  |     assert called == ['request', 'app'] | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,578 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.blueprints | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Blueprints (and currently modules) | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import flask | ||||||
|  | import unittest | ||||||
|  | 
 | ||||||
|  | from flask._compat import text_type | ||||||
|  | from werkzeug.http import parse_cache_control_header | ||||||
|  | from jinja2 import TemplateNotFound | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_blueprint_specific_error_handling(): | ||||||
|  |     frontend = flask.Blueprint('frontend', __name__) | ||||||
|  |     backend = flask.Blueprint('backend', __name__) | ||||||
|  |     sideend = flask.Blueprint('sideend', __name__) | ||||||
|  | 
 | ||||||
|  |     @frontend.errorhandler(403) | ||||||
|  |     def frontend_forbidden(e): | ||||||
|  |         return 'frontend says no', 403 | ||||||
|  | 
 | ||||||
|  |     @frontend.route('/frontend-no') | ||||||
|  |     def frontend_no(): | ||||||
|  |         flask.abort(403) | ||||||
|  | 
 | ||||||
|  |     @backend.errorhandler(403) | ||||||
|  |     def backend_forbidden(e): | ||||||
|  |         return 'backend says no', 403 | ||||||
|  | 
 | ||||||
|  |     @backend.route('/backend-no') | ||||||
|  |     def backend_no(): | ||||||
|  |         flask.abort(403) | ||||||
|  | 
 | ||||||
|  |     @sideend.route('/what-is-a-sideend') | ||||||
|  |     def sideend_no(): | ||||||
|  |         flask.abort(403) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(frontend) | ||||||
|  |     app.register_blueprint(backend) | ||||||
|  |     app.register_blueprint(sideend) | ||||||
|  | 
 | ||||||
|  |     @app.errorhandler(403) | ||||||
|  |     def app_forbidden(e): | ||||||
|  |         return 'application itself says no', 403 | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  | 
 | ||||||
|  |     assert c.get('/frontend-no').data == b'frontend says no' | ||||||
|  |     assert c.get('/backend-no').data == b'backend says no' | ||||||
|  |     assert c.get('/what-is-a-sideend').data == b'application itself says no' | ||||||
|  | 
 | ||||||
|  | def test_blueprint_specific_user_error_handling(): | ||||||
|  |     class MyDecoratorException(Exception): | ||||||
|  |         pass | ||||||
|  |     class MyFunctionException(Exception): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     blue = flask.Blueprint('blue', __name__) | ||||||
|  | 
 | ||||||
|  |     @blue.errorhandler(MyDecoratorException) | ||||||
|  |     def my_decorator_exception_handler(e): | ||||||
|  |         assert isinstance(e, MyDecoratorException) | ||||||
|  |         return 'boom' | ||||||
|  | 
 | ||||||
|  |     def my_function_exception_handler(e): | ||||||
|  |         assert isinstance(e, MyFunctionException) | ||||||
|  |         return 'bam' | ||||||
|  |     blue.register_error_handler(MyFunctionException, my_function_exception_handler) | ||||||
|  | 
 | ||||||
|  |     @blue.route('/decorator') | ||||||
|  |     def blue_deco_test(): | ||||||
|  |         raise MyDecoratorException() | ||||||
|  |     @blue.route('/function') | ||||||
|  |     def blue_func_test(): | ||||||
|  |         raise MyFunctionException() | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(blue) | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  | 
 | ||||||
|  |     assert c.get('/decorator').data == b'boom' | ||||||
|  |     assert c.get('/function').data == b'bam' | ||||||
|  | 
 | ||||||
|  | def test_blueprint_url_definitions(): | ||||||
|  |     bp = flask.Blueprint('test', __name__) | ||||||
|  | 
 | ||||||
|  |     @bp.route('/foo', defaults={'baz': 42}) | ||||||
|  |     def foo(bar, baz): | ||||||
|  |         return '%s/%d' % (bar, baz) | ||||||
|  | 
 | ||||||
|  |     @bp.route('/bar') | ||||||
|  |     def bar(bar): | ||||||
|  |         return text_type(bar) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/1', url_defaults={'bar': 23}) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/2', url_defaults={'bar': 19}) | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  |     assert c.get('/1/foo').data == b'23/42' | ||||||
|  |     assert c.get('/2/foo').data == b'19/42' | ||||||
|  |     assert c.get('/1/bar').data == b'23' | ||||||
|  |     assert c.get('/2/bar').data == b'19' | ||||||
|  | 
 | ||||||
|  | def test_blueprint_url_processors(): | ||||||
|  |     bp = flask.Blueprint('frontend', __name__, url_prefix='/<lang_code>') | ||||||
|  | 
 | ||||||
|  |     @bp.url_defaults | ||||||
|  |     def add_language_code(endpoint, values): | ||||||
|  |         values.setdefault('lang_code', flask.g.lang_code) | ||||||
|  | 
 | ||||||
|  |     @bp.url_value_preprocessor | ||||||
|  |     def pull_lang_code(endpoint, values): | ||||||
|  |         flask.g.lang_code = values.pop('lang_code') | ||||||
|  | 
 | ||||||
|  |     @bp.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.url_for('.about') | ||||||
|  | 
 | ||||||
|  |     @bp.route('/about') | ||||||
|  |     def about(): | ||||||
|  |         return flask.url_for('.index') | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp) | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  | 
 | ||||||
|  |     assert c.get('/de/').data == b'/de/about' | ||||||
|  |     assert c.get('/de/about').data == b'/de/' | ||||||
|  | 
 | ||||||
|  | def test_templates_and_static(test_apps): | ||||||
|  |     from blueprintapp import app | ||||||
|  |     c = app.test_client() | ||||||
|  | 
 | ||||||
|  |     rv = c.get('/') | ||||||
|  |     assert rv.data == b'Hello from the Frontend' | ||||||
|  |     rv = c.get('/admin/') | ||||||
|  |     assert rv.data == b'Hello from the Admin' | ||||||
|  |     rv = c.get('/admin/index2') | ||||||
|  |     assert rv.data == b'Hello from the Admin' | ||||||
|  |     rv = c.get('/admin/static/test.txt') | ||||||
|  |     assert rv.data.strip() == b'Admin File' | ||||||
|  |     rv.close() | ||||||
|  |     rv = c.get('/admin/static/css/test.css') | ||||||
|  |     assert rv.data.strip() == b'/* nested file */' | ||||||
|  |     rv.close() | ||||||
|  | 
 | ||||||
|  |     # try/finally, in case other tests use this app for Blueprint tests. | ||||||
|  |     max_age_default = app.config['SEND_FILE_MAX_AGE_DEFAULT'] | ||||||
|  |     try: | ||||||
|  |         expected_max_age = 3600 | ||||||
|  |         if app.config['SEND_FILE_MAX_AGE_DEFAULT'] == expected_max_age: | ||||||
|  |             expected_max_age = 7200 | ||||||
|  |         app.config['SEND_FILE_MAX_AGE_DEFAULT'] = expected_max_age | ||||||
|  |         rv = c.get('/admin/static/css/test.css') | ||||||
|  |         cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|  |         assert cc.max_age == expected_max_age | ||||||
|  |         rv.close() | ||||||
|  |     finally: | ||||||
|  |         app.config['SEND_FILE_MAX_AGE_DEFAULT'] = max_age_default | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         assert flask.url_for('admin.static', filename='test.txt') == '/admin/static/test.txt' | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         try: | ||||||
|  |             flask.render_template('missing.html') | ||||||
|  |         except TemplateNotFound as e: | ||||||
|  |             assert e.name == 'missing.html' | ||||||
|  |         else: | ||||||
|  |             assert 0, 'expected exception' | ||||||
|  | 
 | ||||||
|  |     with flask.Flask(__name__).test_request_context(): | ||||||
|  |         assert flask.render_template('nested/nested.txt') == 'I\'m nested' | ||||||
|  | 
 | ||||||
|  | def test_default_static_cache_timeout(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     class MyBlueprint(flask.Blueprint): | ||||||
|  |         def get_send_file_max_age(self, filename): | ||||||
|  |             return 100 | ||||||
|  | 
 | ||||||
|  |     blueprint = MyBlueprint('blueprint', __name__, static_folder='static') | ||||||
|  |     app.register_blueprint(blueprint) | ||||||
|  | 
 | ||||||
|  |     # try/finally, in case other tests use this app for Blueprint tests. | ||||||
|  |     max_age_default = app.config['SEND_FILE_MAX_AGE_DEFAULT'] | ||||||
|  |     try: | ||||||
|  |         with app.test_request_context(): | ||||||
|  |             unexpected_max_age = 3600 | ||||||
|  |             if app.config['SEND_FILE_MAX_AGE_DEFAULT'] == unexpected_max_age: | ||||||
|  |                 unexpected_max_age = 7200 | ||||||
|  |             app.config['SEND_FILE_MAX_AGE_DEFAULT'] = unexpected_max_age | ||||||
|  |             rv = blueprint.send_static_file('index.html') | ||||||
|  |             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|  |             assert cc.max_age == 100 | ||||||
|  |             rv.close() | ||||||
|  |     finally: | ||||||
|  |         app.config['SEND_FILE_MAX_AGE_DEFAULT'] = max_age_default | ||||||
|  | 
 | ||||||
|  | def test_templates_list(test_apps): | ||||||
|  |     from blueprintapp import app | ||||||
|  |     templates = sorted(app.jinja_env.list_templates()) | ||||||
|  |     assert templates == ['admin/index.html', 'frontend/index.html'] | ||||||
|  | 
 | ||||||
|  | def test_dotted_names(): | ||||||
|  |     frontend = flask.Blueprint('myapp.frontend', __name__) | ||||||
|  |     backend = flask.Blueprint('myapp.backend', __name__) | ||||||
|  | 
 | ||||||
|  |     @frontend.route('/fe') | ||||||
|  |     def frontend_index(): | ||||||
|  |         return flask.url_for('myapp.backend.backend_index') | ||||||
|  | 
 | ||||||
|  |     @frontend.route('/fe2') | ||||||
|  |     def frontend_page2(): | ||||||
|  |         return flask.url_for('.frontend_index') | ||||||
|  | 
 | ||||||
|  |     @backend.route('/be') | ||||||
|  |     def backend_index(): | ||||||
|  |         return flask.url_for('myapp.frontend.frontend_index') | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(frontend) | ||||||
|  |     app.register_blueprint(backend) | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  |     assert c.get('/fe').data.strip() == b'/be' | ||||||
|  |     assert c.get('/fe2').data.strip() == b'/fe' | ||||||
|  |     assert c.get('/be').data.strip() == b'/fe' | ||||||
|  | 
 | ||||||
|  | def test_dotted_names_from_app(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  |     test = flask.Blueprint('test', __name__) | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def app_index(): | ||||||
|  |         return flask.url_for('test.index') | ||||||
|  | 
 | ||||||
|  |     @test.route('/test/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.url_for('app_index') | ||||||
|  | 
 | ||||||
|  |     app.register_blueprint(test) | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         rv = c.get('/') | ||||||
|  |         assert rv.data == b'/test/' | ||||||
|  | 
 | ||||||
|  | def test_empty_url_defaults(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  | 
 | ||||||
|  |     @bp.route('/', defaults={'page': 1}) | ||||||
|  |     @bp.route('/page/<int:page>') | ||||||
|  |     def something(page): | ||||||
|  |         return str(page) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp) | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  |     assert c.get('/').data == b'1' | ||||||
|  |     assert c.get('/page/2').data == b'2' | ||||||
|  | 
 | ||||||
|  | def test_route_decorator_custom_endpoint(): | ||||||
|  | 
 | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  | 
 | ||||||
|  |     @bp.route('/foo') | ||||||
|  |     def foo(): | ||||||
|  |         return flask.request.endpoint | ||||||
|  | 
 | ||||||
|  |     @bp.route('/bar', endpoint='bar') | ||||||
|  |     def foo_bar(): | ||||||
|  |         return flask.request.endpoint | ||||||
|  | 
 | ||||||
|  |     @bp.route('/bar/123', endpoint='123') | ||||||
|  |     def foo_bar_foo(): | ||||||
|  |         return flask.request.endpoint | ||||||
|  | 
 | ||||||
|  |     @bp.route('/bar/foo') | ||||||
|  |     def bar_foo(): | ||||||
|  |         return flask.request.endpoint | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.request.endpoint | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  |     assert c.get('/').data == b'index' | ||||||
|  |     assert c.get('/py/foo').data == b'bp.foo' | ||||||
|  |     assert c.get('/py/bar').data == b'bp.bar' | ||||||
|  |     assert c.get('/py/bar/123').data == b'bp.123' | ||||||
|  |     assert c.get('/py/bar/foo').data == b'bp.bar_foo' | ||||||
|  | 
 | ||||||
|  | def test_route_decorator_custom_endpoint_with_dots(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  | 
 | ||||||
|  |     @bp.route('/foo') | ||||||
|  |     def foo(): | ||||||
|  |         return flask.request.endpoint | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         @bp.route('/bar', endpoint='bar.bar') | ||||||
|  |         def foo_bar(): | ||||||
|  |             return flask.request.endpoint | ||||||
|  |     except AssertionError: | ||||||
|  |         pass | ||||||
|  |     else: | ||||||
|  |         raise AssertionError('expected AssertionError not raised') | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         @bp.route('/bar/123', endpoint='bar.123') | ||||||
|  |         def foo_bar_foo(): | ||||||
|  |             return flask.request.endpoint | ||||||
|  |     except AssertionError: | ||||||
|  |         pass | ||||||
|  |     else: | ||||||
|  |         raise AssertionError('expected AssertionError not raised') | ||||||
|  | 
 | ||||||
|  |     def foo_foo_foo(): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     pytest.raises( | ||||||
|  |         AssertionError, | ||||||
|  |         lambda: bp.add_url_rule( | ||||||
|  |             '/bar/123', endpoint='bar.123', view_func=foo_foo_foo | ||||||
|  |         ) | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     pytest.raises( | ||||||
|  |         AssertionError, | ||||||
|  |         bp.route('/bar/123', endpoint='bar.123'), | ||||||
|  |         lambda: None | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  | 
 | ||||||
|  |     c = app.test_client() | ||||||
|  |     assert c.get('/py/foo').data == b'bp.foo' | ||||||
|  |     # The rule's didn't actually made it through | ||||||
|  |     rv = c.get('/py/bar') | ||||||
|  |     assert rv.status_code == 404 | ||||||
|  |     rv = c.get('/py/bar/123') | ||||||
|  |     assert rv.status_code == 404 | ||||||
|  | 
 | ||||||
|  | def test_template_filter(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_filter() | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'my_reverse' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['my_reverse'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     bp.add_app_template_filter(my_reverse) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'my_reverse' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['my_reverse'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_filter_with_name(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_filter('strrev') | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'strrev' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['strrev'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['strrev']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter_with_name(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     bp.add_app_template_filter(my_reverse, 'strrev') | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'strrev' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['strrev'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['strrev']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_filter_with_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_filter() | ||||||
|  |     def super_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_filter_after_route_with_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_filter() | ||||||
|  |     def super_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter_with_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def super_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     bp.add_app_template_filter(super_reverse) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_filter_with_name_and_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_filter('super_reverse') | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter_with_name_and_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     bp.add_app_template_filter(my_reverse, 'super_reverse') | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_test(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_test() | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'is_boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['is_boolean'] == is_boolean | ||||||
|  |     assert app.jinja_env.tests['is_boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_add_template_test(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     bp.add_app_template_test(is_boolean) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'is_boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['is_boolean'] == is_boolean | ||||||
|  |     assert app.jinja_env.tests['is_boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_template_test_with_name(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_test('boolean') | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['boolean'] == is_boolean | ||||||
|  |     assert app.jinja_env.tests['boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_add_template_test_with_name(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     bp.add_app_template_test(is_boolean, 'boolean') | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     assert 'boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['boolean'] == is_boolean | ||||||
|  |     assert app.jinja_env.tests['boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_template_test_with_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_test() | ||||||
|  |     def boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_template_test_after_route_with_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_test() | ||||||
|  |     def boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_add_template_test_with_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     bp.add_app_template_test(boolean) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_template_test_with_name_and_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     @bp.app_template_test('boolean') | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_add_template_test_with_name_and_template(): | ||||||
|  |     bp = flask.Blueprint('bp', __name__) | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     bp.add_app_template_test(is_boolean, 'boolean') | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.register_blueprint(bp, url_prefix='/py') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | @ -0,0 +1,184 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.test_config | ||||||
|  |     ~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by the Flask Team, see AUTHORS for more details. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import os | ||||||
|  | import flask | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # config keys used for the TestConfig | ||||||
|  | TEST_KEY = 'foo' | ||||||
|  | SECRET_KEY = 'devkey' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def common_object_test(app): | ||||||
|  |     assert app.secret_key == 'devkey' | ||||||
|  |     assert app.config['TEST_KEY'] == 'foo' | ||||||
|  |     assert 'TestConfig' not in app.config | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_from_file(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config.from_pyfile(__file__.rsplit('.', 1)[0] + '.py') | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_from_object(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config.from_object(__name__) | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_from_json(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     current_dir = os.path.dirname(os.path.abspath(__file__)) | ||||||
|  |     app.config.from_json(os.path.join(current_dir, 'static', 'config.json')) | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_from_mapping(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config.from_mapping({ | ||||||
|  |         'SECRET_KEY': 'devkey', | ||||||
|  |         'TEST_KEY': 'foo' | ||||||
|  |     }) | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config.from_mapping([ | ||||||
|  |         ('SECRET_KEY', 'devkey'), | ||||||
|  |         ('TEST_KEY', 'foo') | ||||||
|  |     ]) | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config.from_mapping( | ||||||
|  |         SECRET_KEY='devkey', | ||||||
|  |         TEST_KEY='foo' | ||||||
|  |     ) | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     with pytest.raises(TypeError): | ||||||
|  |         app.config.from_mapping( | ||||||
|  |             {}, {} | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_from_class(): | ||||||
|  |     class Base(object): | ||||||
|  |         TEST_KEY = 'foo' | ||||||
|  | 
 | ||||||
|  |     class Test(Base): | ||||||
|  |         SECRET_KEY = 'devkey' | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config.from_object(Test) | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_from_envvar(): | ||||||
|  |     env = os.environ | ||||||
|  |     try: | ||||||
|  |         os.environ = {} | ||||||
|  |         app = flask.Flask(__name__) | ||||||
|  |         try: | ||||||
|  |             app.config.from_envvar('FOO_SETTINGS') | ||||||
|  |         except RuntimeError as e: | ||||||
|  |             assert "'FOO_SETTINGS' is not set" in str(e) | ||||||
|  |         else: | ||||||
|  |             assert 0, 'expected exception' | ||||||
|  |         assert not app.config.from_envvar('FOO_SETTINGS', silent=True) | ||||||
|  | 
 | ||||||
|  |         os.environ = {'FOO_SETTINGS': __file__.rsplit('.', 1)[0] + '.py'} | ||||||
|  |         assert app.config.from_envvar('FOO_SETTINGS') | ||||||
|  |         common_object_test(app) | ||||||
|  |     finally: | ||||||
|  |         os.environ = env | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_from_envvar_missing(): | ||||||
|  |     env = os.environ | ||||||
|  |     try: | ||||||
|  |         os.environ = {'FOO_SETTINGS': 'missing.cfg'} | ||||||
|  |         try: | ||||||
|  |             app = flask.Flask(__name__) | ||||||
|  |             app.config.from_envvar('FOO_SETTINGS') | ||||||
|  |         except IOError as e: | ||||||
|  |             msg = str(e) | ||||||
|  |             assert msg.startswith('[Errno 2] Unable to load configuration ' | ||||||
|  |                                   'file (No such file or directory):') | ||||||
|  |             assert msg.endswith("missing.cfg'") | ||||||
|  |         else: | ||||||
|  |             assert False, 'expected IOError' | ||||||
|  |         assert not app.config.from_envvar('FOO_SETTINGS', silent=True) | ||||||
|  |     finally: | ||||||
|  |         os.environ = env | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_missing(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     try: | ||||||
|  |         app.config.from_pyfile('missing.cfg') | ||||||
|  |     except IOError as e: | ||||||
|  |         msg = str(e) | ||||||
|  |         assert msg.startswith('[Errno 2] Unable to load configuration ' | ||||||
|  |                               'file (No such file or directory):') | ||||||
|  |         assert msg.endswith("missing.cfg'") | ||||||
|  |     else: | ||||||
|  |         assert 0, 'expected config' | ||||||
|  |     assert not app.config.from_pyfile('missing.cfg', silent=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_config_missing_json(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     try: | ||||||
|  |         app.config.from_json('missing.json') | ||||||
|  |     except IOError as e: | ||||||
|  |         msg = str(e) | ||||||
|  |         assert msg.startswith('[Errno 2] Unable to load configuration ' | ||||||
|  |                               'file (No such file or directory):') | ||||||
|  |         assert msg.endswith("missing.json'") | ||||||
|  |     else: | ||||||
|  |         assert 0, 'expected config' | ||||||
|  |     assert not app.config.from_json('missing.json', silent=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_custom_config_class(): | ||||||
|  |     class Config(flask.Config): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     class Flask(flask.Flask): | ||||||
|  |         config_class = Config | ||||||
|  |     app = Flask(__name__) | ||||||
|  |     assert isinstance(app.config, Config) | ||||||
|  |     app.config.from_object(__name__) | ||||||
|  |     common_object_test(app) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_session_lifetime(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['PERMANENT_SESSION_LIFETIME'] = 42 | ||||||
|  |     assert app.permanent_session_lifetime.seconds == 42 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_get_namespace(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['FOO_OPTION_1'] = 'foo option 1' | ||||||
|  |     app.config['FOO_OPTION_2'] = 'foo option 2' | ||||||
|  |     app.config['BAR_STUFF_1'] = 'bar stuff 1' | ||||||
|  |     app.config['BAR_STUFF_2'] = 'bar stuff 2' | ||||||
|  |     foo_options = app.config.get_namespace('FOO_') | ||||||
|  |     assert 2 == len(foo_options) | ||||||
|  |     assert 'foo option 1' == foo_options['option_1'] | ||||||
|  |     assert 'foo option 2' == foo_options['option_2'] | ||||||
|  |     bar_options = app.config.get_namespace('BAR_', lowercase=False) | ||||||
|  |     assert 2 == len(bar_options) | ||||||
|  |     assert 'bar stuff 1' == bar_options['STUFF_1'] | ||||||
|  |     assert 'bar stuff 2' == bar_options['STUFF_2'] | ||||||
|  | @ -0,0 +1,10 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.deprecations | ||||||
|  |     ~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests deprecation support. Not used currently. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | @ -0,0 +1,187 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.ext | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests the extension import thing. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import sys | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | try: | ||||||
|  |     from imp import reload as reload_module | ||||||
|  | except ImportError: | ||||||
|  |     reload_module = reload | ||||||
|  | 
 | ||||||
|  | from flask._compat import PY2 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture(autouse=True) | ||||||
|  | def importhook_setup(monkeypatch, request): | ||||||
|  |     # we clear this out for various reasons.  The most important one is | ||||||
|  |     # that a real flaskext could be in there which would disable our | ||||||
|  |     # fake package.  Secondly we want to make sure that the flaskext | ||||||
|  |     # import hook does not break on reloading. | ||||||
|  |     for entry, value in list(sys.modules.items()): | ||||||
|  |         if ( | ||||||
|  |             entry.startswith('flask.ext.') or | ||||||
|  |             entry.startswith('flask_') or | ||||||
|  |             entry.startswith('flaskext.') or | ||||||
|  |             entry == 'flaskext' | ||||||
|  |         ) and value is not None: | ||||||
|  |             monkeypatch.delitem(sys.modules, entry) | ||||||
|  |     from flask import ext | ||||||
|  |     reload_module(ext) | ||||||
|  | 
 | ||||||
|  |     # reloading must not add more hooks | ||||||
|  |     import_hooks = 0 | ||||||
|  |     for item in sys.meta_path: | ||||||
|  |         cls = type(item) | ||||||
|  |         if cls.__module__ == 'flask.exthook' and \ | ||||||
|  |            cls.__name__ == 'ExtensionImporter': | ||||||
|  |             import_hooks += 1 | ||||||
|  |     assert import_hooks == 1 | ||||||
|  | 
 | ||||||
|  |     def teardown(): | ||||||
|  |         from flask import ext | ||||||
|  |         for key in ext.__dict__: | ||||||
|  |             assert '.' not in key | ||||||
|  | 
 | ||||||
|  |     request.addfinalizer(teardown) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def newext_simple(modules_tmpdir): | ||||||
|  |     x = modules_tmpdir.join('flask_newext_simple.py') | ||||||
|  |     x.write('ext_id = "newext_simple"') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def oldext_simple(modules_tmpdir): | ||||||
|  |     flaskext = modules_tmpdir.mkdir('flaskext') | ||||||
|  |     flaskext.join('__init__.py').write('\n') | ||||||
|  |     flaskext.join('oldext_simple.py').write('ext_id = "oldext_simple"') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def newext_package(modules_tmpdir): | ||||||
|  |     pkg = modules_tmpdir.mkdir('flask_newext_package') | ||||||
|  |     pkg.join('__init__.py').write('ext_id = "newext_package"') | ||||||
|  |     pkg.join('submodule.py').write('def test_function():\n    return 42\n') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def oldext_package(modules_tmpdir): | ||||||
|  |     flaskext = modules_tmpdir.mkdir('flaskext') | ||||||
|  |     flaskext.join('__init__.py').write('\n') | ||||||
|  |     oldext = flaskext.mkdir('oldext_package') | ||||||
|  |     oldext.join('__init__.py').write('ext_id = "oldext_package"') | ||||||
|  |     oldext.join('submodule.py').write('def test_function():\n' | ||||||
|  |                                       '    return 42') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.fixture | ||||||
|  | def flaskext_broken(modules_tmpdir): | ||||||
|  |     ext = modules_tmpdir.mkdir('flask_broken') | ||||||
|  |     ext.join('b.py').write('\n') | ||||||
|  |     ext.join('__init__.py').write('import flask.ext.broken.b\n' | ||||||
|  |                                   'import missing_module') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_new_simple_import_normal(newext_simple): | ||||||
|  |     from flask.ext.newext_simple import ext_id | ||||||
|  |     assert ext_id == 'newext_simple' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_new_simple_import_module(newext_simple): | ||||||
|  |     from flask.ext import newext_simple | ||||||
|  |     assert newext_simple.ext_id == 'newext_simple' | ||||||
|  |     assert newext_simple.__name__ == 'flask_newext_simple' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_new_package_import_normal(newext_package): | ||||||
|  |     from flask.ext.newext_package import ext_id | ||||||
|  |     assert ext_id == 'newext_package' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_new_package_import_module(newext_package): | ||||||
|  |     from flask.ext import newext_package | ||||||
|  |     assert newext_package.ext_id == 'newext_package' | ||||||
|  |     assert newext_package.__name__ == 'flask_newext_package' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_new_package_import_submodule_function(newext_package): | ||||||
|  |     from flask.ext.newext_package.submodule import test_function | ||||||
|  |     assert test_function() == 42 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_new_package_import_submodule(newext_package): | ||||||
|  |     from flask.ext.newext_package import submodule | ||||||
|  |     assert submodule.__name__ == 'flask_newext_package.submodule' | ||||||
|  |     assert submodule.test_function() == 42 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_old_simple_import_normal(oldext_simple): | ||||||
|  |     from flask.ext.oldext_simple import ext_id | ||||||
|  |     assert ext_id == 'oldext_simple' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_old_simple_import_module(oldext_simple): | ||||||
|  |     from flask.ext import oldext_simple | ||||||
|  |     assert oldext_simple.ext_id == 'oldext_simple' | ||||||
|  |     assert oldext_simple.__name__ == 'flaskext.oldext_simple' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_old_package_import_normal(oldext_package): | ||||||
|  |     from flask.ext.oldext_package import ext_id | ||||||
|  |     assert ext_id == 'oldext_package' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_old_package_import_module(oldext_package): | ||||||
|  |     from flask.ext import oldext_package | ||||||
|  |     assert oldext_package.ext_id == 'oldext_package' | ||||||
|  |     assert oldext_package.__name__ == 'flaskext.oldext_package' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_old_package_import_submodule(oldext_package): | ||||||
|  |     from flask.ext.oldext_package import submodule | ||||||
|  |     assert submodule.__name__ == 'flaskext.oldext_package.submodule' | ||||||
|  |     assert submodule.test_function() == 42 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_old_package_import_submodule_function(oldext_package): | ||||||
|  |     from flask.ext.oldext_package.submodule import test_function | ||||||
|  |     assert test_function() == 42 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_flaskext_broken_package_no_module_caching(flaskext_broken): | ||||||
|  |     for x in range(2): | ||||||
|  |         with pytest.raises(ImportError): | ||||||
|  |             import flask.ext.broken | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_no_error_swallowing(flaskext_broken): | ||||||
|  |     with pytest.raises(ImportError) as excinfo: | ||||||
|  |         import flask.ext.broken | ||||||
|  | 
 | ||||||
|  |     assert excinfo.type is ImportError | ||||||
|  |     if PY2: | ||||||
|  |         message = 'No module named missing_module' | ||||||
|  |     else: | ||||||
|  |         message = 'No module named \'missing_module\'' | ||||||
|  |     assert str(excinfo.value) == message | ||||||
|  |     assert excinfo.tb.tb_frame.f_globals is globals() | ||||||
|  | 
 | ||||||
|  |     # reraise() adds a second frame so we need to skip that one too. | ||||||
|  |     # On PY3 we even have another one :( | ||||||
|  |     next = excinfo.tb.tb_next.tb_next | ||||||
|  |     if not PY2: | ||||||
|  |         next = next.tb_next | ||||||
|  | 
 | ||||||
|  |     import os.path | ||||||
|  |     assert os.path.join('flask_broken', '__init__.py') in \ | ||||||
|  |         next.tb_frame.f_code.co_filename | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| """ | """ | ||||||
|     flask.testsuite.helpers |     tests.helpers | ||||||
|     ~~~~~~~~~~~~~~~~~~~~~~~ |     ~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
| 
 | 
 | ||||||
|     Various helpers. |     Various helpers. | ||||||
|  | @ -9,11 +9,11 @@ | ||||||
|     :license: BSD, see LICENSE for more details. |     :license: BSD, see LICENSE for more details. | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
| import os | import os | ||||||
| import flask | import flask | ||||||
| import unittest |  | ||||||
| from logging import StreamHandler | from logging import StreamHandler | ||||||
| from flask.testsuite import FlaskTestCase, catch_warnings, catch_stderr |  | ||||||
| from werkzeug.http import parse_cache_control_header, parse_options_header | from werkzeug.http import parse_cache_control_header, parse_options_header | ||||||
| from flask._compat import StringIO, text_type | from flask._compat import StringIO, text_type | ||||||
| 
 | 
 | ||||||
|  | @ -27,7 +27,7 @@ def has_encoding(name): | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class JSONTestCase(FlaskTestCase): | class TestJSON(object): | ||||||
| 
 | 
 | ||||||
|     def test_json_bad_requests(self): |     def test_json_bad_requests(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -36,7 +36,7 @@ class JSONTestCase(FlaskTestCase): | ||||||
|             return flask.jsonify(foo=text_type(flask.request.get_json())) |             return flask.jsonify(foo=text_type(flask.request.get_json())) | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         rv = c.post('/json', data='malformed', content_type='application/json') |         rv = c.post('/json', data='malformed', content_type='application/json') | ||||||
|         self.assert_equal(rv.status_code, 400) |         assert rv.status_code == 400 | ||||||
| 
 | 
 | ||||||
|     def test_json_custom_mimetypes(self): |     def test_json_custom_mimetypes(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -45,7 +45,7 @@ class JSONTestCase(FlaskTestCase): | ||||||
|             return flask.request.get_json() |             return flask.request.get_json() | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         rv = c.post('/json', data='"foo"', content_type='application/x+json') |         rv = c.post('/json', data='"foo"', content_type='application/x+json') | ||||||
|         self.assert_equal(rv.data, b'foo') |         assert rv.data == b'foo' | ||||||
| 
 | 
 | ||||||
|     def test_json_body_encoding(self): |     def test_json_body_encoding(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -57,7 +57,7 @@ class JSONTestCase(FlaskTestCase): | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         resp = c.get('/', data=u'"Hällo Wörld"'.encode('iso-8859-15'), |         resp = c.get('/', data=u'"Hällo Wörld"'.encode('iso-8859-15'), | ||||||
|                      content_type='application/json; charset=iso-8859-15') |                      content_type='application/json; charset=iso-8859-15') | ||||||
|         self.assert_equal(resp.data, u'Hällo Wörld'.encode('utf-8')) |         assert resp.data == u'Hällo Wörld'.encode('utf-8') | ||||||
| 
 | 
 | ||||||
|     def test_jsonify(self): |     def test_jsonify(self): | ||||||
|         d = dict(a=23, b=42, c=[1, 2, 3]) |         d = dict(a=23, b=42, c=[1, 2, 3]) | ||||||
|  | @ -71,8 +71,8 @@ class JSONTestCase(FlaskTestCase): | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         for url in '/kw', '/dict': |         for url in '/kw', '/dict': | ||||||
|             rv = c.get(url) |             rv = c.get(url) | ||||||
|             self.assert_equal(rv.mimetype, 'application/json') |             assert rv.mimetype == 'application/json' | ||||||
|             self.assert_equal(flask.json.loads(rv.data), d) |             assert flask.json.loads(rv.data) == d | ||||||
| 
 | 
 | ||||||
|     def test_json_as_unicode(self): |     def test_json_as_unicode(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -80,12 +80,12 @@ class JSONTestCase(FlaskTestCase): | ||||||
|         app.config['JSON_AS_ASCII'] = True |         app.config['JSON_AS_ASCII'] = True | ||||||
|         with app.app_context(): |         with app.app_context(): | ||||||
|             rv = flask.json.dumps(u'\N{SNOWMAN}') |             rv = flask.json.dumps(u'\N{SNOWMAN}') | ||||||
|             self.assert_equal(rv, '"\\u2603"') |             assert rv == '"\\u2603"' | ||||||
| 
 | 
 | ||||||
|         app.config['JSON_AS_ASCII'] = False |         app.config['JSON_AS_ASCII'] = False | ||||||
|         with app.app_context(): |         with app.app_context(): | ||||||
|             rv = flask.json.dumps(u'\N{SNOWMAN}') |             rv = flask.json.dumps(u'\N{SNOWMAN}') | ||||||
|             self.assert_equal(rv, u'"\u2603"') |             assert rv == u'"\u2603"' | ||||||
| 
 | 
 | ||||||
|     def test_json_attr(self): |     def test_json_attr(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -96,29 +96,28 @@ class JSONTestCase(FlaskTestCase): | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}), |         rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}), | ||||||
|                             content_type='application/json') |                             content_type='application/json') | ||||||
|         self.assert_equal(rv.data, b'3') |         assert rv.data == b'3' | ||||||
| 
 | 
 | ||||||
|     def test_template_escaping(self): |     def test_template_escaping(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         render = flask.render_template_string |         render = flask.render_template_string | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             rv = flask.json.htmlsafe_dumps('</script>') |             rv = flask.json.htmlsafe_dumps('</script>') | ||||||
|             self.assert_equal(rv, u'"\\u003c/script\\u003e"') |             assert rv == u'"\\u003c/script\\u003e"' | ||||||
|             self.assert_equal(type(rv), text_type) |             assert type(rv) == text_type | ||||||
|             rv = render('{{ "</script>"|tojson }}') |             rv = render('{{ "</script>"|tojson }}') | ||||||
|             self.assert_equal(rv, '"\\u003c/script\\u003e"') |             assert rv == '"\\u003c/script\\u003e"' | ||||||
|             rv = render('{{ "<\0/script>"|tojson }}') |             rv = render('{{ "<\0/script>"|tojson }}') | ||||||
|             self.assert_equal(rv, '"\\u003c\\u0000/script\\u003e"') |             assert rv == '"\\u003c\\u0000/script\\u003e"' | ||||||
|             rv = render('{{ "<!--<script>"|tojson }}') |             rv = render('{{ "<!--<script>"|tojson }}') | ||||||
|             self.assert_equal(rv, '"\\u003c!--\\u003cscript\\u003e"') |             assert rv == '"\\u003c!--\\u003cscript\\u003e"' | ||||||
|             rv = render('{{ "&"|tojson }}') |             rv = render('{{ "&"|tojson }}') | ||||||
|             self.assert_equal(rv, '"\\u0026"') |             assert rv == '"\\u0026"' | ||||||
|             rv = render('{{ "\'"|tojson }}') |             rv = render('{{ "\'"|tojson }}') | ||||||
|             self.assert_equal(rv, '"\\u0027"') |             assert rv == '"\\u0027"' | ||||||
|             rv = render("<a ng-data='{{ data|tojson }}'></a>", |             rv = render("<a ng-data='{{ data|tojson }}'></a>", | ||||||
|                 data={'x': ["foo", "bar", "baz'"]}) |                 data={'x': ["foo", "bar", "baz'"]}) | ||||||
|             self.assert_equal(rv, |             assert rv == '<a ng-data=\'{"x": ["foo", "bar", "baz\\u0027"]}\'></a>' | ||||||
|                 '<a ng-data=\'{"x": ["foo", "bar", "baz\\u0027"]}\'></a>') |  | ||||||
| 
 | 
 | ||||||
|     def test_json_customization(self): |     def test_json_customization(self): | ||||||
|         class X(object): |         class X(object): | ||||||
|  | @ -148,7 +147,7 @@ class JSONTestCase(FlaskTestCase): | ||||||
|         rv = c.post('/', data=flask.json.dumps({ |         rv = c.post('/', data=flask.json.dumps({ | ||||||
|             'x': {'_foo': 42} |             'x': {'_foo': 42} | ||||||
|         }), content_type='application/json') |         }), content_type='application/json') | ||||||
|         self.assertEqual(rv.data, b'"<42>"') |         assert rv.data == b'"<42>"' | ||||||
| 
 | 
 | ||||||
|     def test_modified_url_encoding(self): |     def test_modified_url_encoding(self): | ||||||
|         class ModifiedRequest(flask.Request): |         class ModifiedRequest(flask.Request): | ||||||
|  | @ -163,8 +162,8 @@ class JSONTestCase(FlaskTestCase): | ||||||
|             return flask.request.args['foo'] |             return flask.request.args['foo'] | ||||||
| 
 | 
 | ||||||
|         rv = app.test_client().get(u'/?foo=정상처리'.encode('euc-kr')) |         rv = app.test_client().get(u'/?foo=정상처리'.encode('euc-kr')) | ||||||
|         self.assert_equal(rv.status_code, 200) |         assert rv.status_code == 200 | ||||||
|         self.assert_equal(rv.data, u'정상처리'.encode('utf-8')) |         assert rv.data == u'정상처리'.encode('utf-8') | ||||||
| 
 | 
 | ||||||
|     if not has_encoding('euc-kr'): |     if not has_encoding('euc-kr'): | ||||||
|         test_modified_url_encoding = None |         test_modified_url_encoding = None | ||||||
|  | @ -172,7 +171,7 @@ class JSONTestCase(FlaskTestCase): | ||||||
|     def test_json_key_sorting(self): |     def test_json_key_sorting(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         app.testing = True |         app.testing = True | ||||||
|         self.assert_equal(app.config['JSON_SORT_KEYS'], True) |         assert app.config['JSON_SORT_KEYS'] == True | ||||||
|         d = dict.fromkeys(range(20), 'foo') |         d = dict.fromkeys(range(20), 'foo') | ||||||
| 
 | 
 | ||||||
|         @app.route('/') |         @app.route('/') | ||||||
|  | @ -236,21 +235,21 @@ class JSONTestCase(FlaskTestCase): | ||||||
|         ] |         ] | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             self.assert_equal(lines, sorted_by_int) |             assert lines == sorted_by_int | ||||||
|         except AssertionError: |         except AssertionError: | ||||||
|             self.assert_equal(lines, sorted_by_str) |             assert lines == sorted_by_str | ||||||
| 
 | 
 | ||||||
| class SendfileTestCase(FlaskTestCase): | class TestSendfile(object): | ||||||
| 
 | 
 | ||||||
|     def test_send_file_regular(self): |     def test_send_file_regular(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             rv = flask.send_file('static/index.html') |             rv = flask.send_file('static/index.html') | ||||||
|             self.assert_true(rv.direct_passthrough) |             assert rv.direct_passthrough | ||||||
|             self.assert_equal(rv.mimetype, 'text/html') |             assert rv.mimetype == 'text/html' | ||||||
|             with app.open_resource('static/index.html') as f: |             with app.open_resource('static/index.html') as f: | ||||||
|                 rv.direct_passthrough = False |                 rv.direct_passthrough = False | ||||||
|                 self.assert_equal(rv.data, f.read()) |                 assert rv.data == f.read() | ||||||
|             rv.close() |             rv.close() | ||||||
| 
 | 
 | ||||||
|     def test_send_file_xsendfile(self): |     def test_send_file_xsendfile(self): | ||||||
|  | @ -258,52 +257,52 @@ class SendfileTestCase(FlaskTestCase): | ||||||
|         app.use_x_sendfile = True |         app.use_x_sendfile = True | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             rv = flask.send_file('static/index.html') |             rv = flask.send_file('static/index.html') | ||||||
|             self.assert_true(rv.direct_passthrough) |             assert rv.direct_passthrough | ||||||
|             self.assert_in('x-sendfile', rv.headers) |             assert 'x-sendfile' in rv.headers | ||||||
|             self.assert_equal(rv.headers['x-sendfile'], |             assert rv.headers['x-sendfile'] == \ | ||||||
|                 os.path.join(app.root_path, 'static/index.html')) |                 os.path.join(app.root_path, 'static/index.html') | ||||||
|             self.assert_equal(rv.mimetype, 'text/html') |             assert rv.mimetype == 'text/html' | ||||||
|             rv.close() |             rv.close() | ||||||
| 
 | 
 | ||||||
|     def test_send_file_object(self): |     def test_send_file_object(self, catch_deprecation_warnings): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         with catch_warnings() as captured: |         with catch_deprecation_warnings() as captured: | ||||||
|             with app.test_request_context(): |             with app.test_request_context(): | ||||||
|                 f = open(os.path.join(app.root_path, 'static/index.html'), mode='rb') |                 f = open(os.path.join(app.root_path, 'static/index.html'), mode='rb') | ||||||
|                 rv = flask.send_file(f) |                 rv = flask.send_file(f) | ||||||
|                 rv.direct_passthrough = False |                 rv.direct_passthrough = False | ||||||
|                 with app.open_resource('static/index.html') as f: |                 with app.open_resource('static/index.html') as f: | ||||||
|                     self.assert_equal(rv.data, f.read()) |                     assert rv.data == f.read() | ||||||
|                 self.assert_equal(rv.mimetype, 'text/html') |                 assert rv.mimetype == 'text/html' | ||||||
|                 rv.close() |                 rv.close() | ||||||
|             # mimetypes + etag |             # mimetypes + etag | ||||||
|             self.assert_equal(len(captured), 2) |             assert len(captured) == 2 | ||||||
| 
 | 
 | ||||||
|         app.use_x_sendfile = True |         app.use_x_sendfile = True | ||||||
|         with catch_warnings() as captured: |         with catch_deprecation_warnings() as captured: | ||||||
|             with app.test_request_context(): |             with app.test_request_context(): | ||||||
|                 f = open(os.path.join(app.root_path, 'static/index.html')) |                 f = open(os.path.join(app.root_path, 'static/index.html')) | ||||||
|                 rv = flask.send_file(f) |                 rv = flask.send_file(f) | ||||||
|                 self.assert_equal(rv.mimetype, 'text/html') |                 assert rv.mimetype == 'text/html' | ||||||
|                 self.assert_in('x-sendfile', rv.headers) |                 assert 'x-sendfile' in rv.headers | ||||||
|                 self.assert_equal(rv.headers['x-sendfile'], |                 assert rv.headers['x-sendfile'] == \ | ||||||
|                     os.path.join(app.root_path, 'static/index.html')) |                     os.path.join(app.root_path, 'static/index.html') | ||||||
|                 rv.close() |                 rv.close() | ||||||
|             # mimetypes + etag |             # mimetypes + etag | ||||||
|             self.assert_equal(len(captured), 2) |             assert len(captured) == 2 | ||||||
| 
 | 
 | ||||||
|         app.use_x_sendfile = False |         app.use_x_sendfile = False | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             with catch_warnings() as captured: |             with catch_deprecation_warnings() as captured: | ||||||
|                 f = StringIO('Test') |                 f = StringIO('Test') | ||||||
|                 rv = flask.send_file(f) |                 rv = flask.send_file(f) | ||||||
|                 rv.direct_passthrough = False |                 rv.direct_passthrough = False | ||||||
|                 self.assert_equal(rv.data, b'Test') |                 assert rv.data == b'Test' | ||||||
|                 self.assert_equal(rv.mimetype, 'application/octet-stream') |                 assert rv.mimetype == 'application/octet-stream' | ||||||
|                 rv.close() |                 rv.close() | ||||||
|             # etags |             # etags | ||||||
|             self.assert_equal(len(captured), 1) |             assert len(captured) == 1 | ||||||
|             with catch_warnings() as captured: |             with catch_deprecation_warnings() as captured: | ||||||
|                 class PyStringIO(object): |                 class PyStringIO(object): | ||||||
|                     def __init__(self, *args, **kwargs): |                     def __init__(self, *args, **kwargs): | ||||||
|                         self._io = StringIO(*args, **kwargs) |                         self._io = StringIO(*args, **kwargs) | ||||||
|  | @ -313,59 +312,59 @@ class SendfileTestCase(FlaskTestCase): | ||||||
|                 f.name = 'test.txt' |                 f.name = 'test.txt' | ||||||
|                 rv = flask.send_file(f) |                 rv = flask.send_file(f) | ||||||
|                 rv.direct_passthrough = False |                 rv.direct_passthrough = False | ||||||
|                 self.assert_equal(rv.data, b'Test') |                 assert rv.data == b'Test' | ||||||
|                 self.assert_equal(rv.mimetype, 'text/plain') |                 assert rv.mimetype == 'text/plain' | ||||||
|                 rv.close() |                 rv.close() | ||||||
|             # attachment_filename and etags |             # attachment_filename and etags | ||||||
|             self.assert_equal(len(captured), 3) |             assert len(captured) == 3 | ||||||
|             with catch_warnings() as captured: |             with catch_deprecation_warnings() as captured: | ||||||
|                 f = StringIO('Test') |                 f = StringIO('Test') | ||||||
|                 rv = flask.send_file(f, mimetype='text/plain') |                 rv = flask.send_file(f, mimetype='text/plain') | ||||||
|                 rv.direct_passthrough = False |                 rv.direct_passthrough = False | ||||||
|                 self.assert_equal(rv.data, b'Test') |                 assert rv.data == b'Test' | ||||||
|                 self.assert_equal(rv.mimetype, 'text/plain') |                 assert rv.mimetype == 'text/plain' | ||||||
|                 rv.close() |                 rv.close() | ||||||
|             # etags |             # etags | ||||||
|             self.assert_equal(len(captured), 1) |             assert len(captured) == 1 | ||||||
| 
 | 
 | ||||||
|         app.use_x_sendfile = True |         app.use_x_sendfile = True | ||||||
|         with catch_warnings() as captured: |         with catch_deprecation_warnings() as captured: | ||||||
|             with app.test_request_context(): |             with app.test_request_context(): | ||||||
|                 f = StringIO('Test') |                 f = StringIO('Test') | ||||||
|                 rv = flask.send_file(f) |                 rv = flask.send_file(f) | ||||||
|                 self.assert_not_in('x-sendfile', rv.headers) |                 assert 'x-sendfile' not in rv.headers | ||||||
|                 rv.close() |                 rv.close() | ||||||
|             # etags |             # etags | ||||||
|             self.assert_equal(len(captured), 1) |             assert len(captured) == 1 | ||||||
| 
 | 
 | ||||||
|     def test_attachment(self): |     def test_attachment(self, catch_deprecation_warnings): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         with catch_warnings() as captured: |         with catch_deprecation_warnings() as captured: | ||||||
|             with app.test_request_context(): |             with app.test_request_context(): | ||||||
|                 f = open(os.path.join(app.root_path, 'static/index.html')) |                 f = open(os.path.join(app.root_path, 'static/index.html')) | ||||||
|                 rv = flask.send_file(f, as_attachment=True) |                 rv = flask.send_file(f, as_attachment=True) | ||||||
|                 value, options = parse_options_header(rv.headers['Content-Disposition']) |                 value, options = parse_options_header(rv.headers['Content-Disposition']) | ||||||
|                 self.assert_equal(value, 'attachment') |                 assert value == 'attachment' | ||||||
|                 rv.close() |                 rv.close() | ||||||
|             # mimetypes + etag |             # mimetypes + etag | ||||||
|             self.assert_equal(len(captured), 2) |             assert len(captured) == 2 | ||||||
| 
 | 
 | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             self.assert_equal(options['filename'], 'index.html') |             assert options['filename'] == 'index.html' | ||||||
|             rv = flask.send_file('static/index.html', as_attachment=True) |             rv = flask.send_file('static/index.html', as_attachment=True) | ||||||
|             value, options = parse_options_header(rv.headers['Content-Disposition']) |             value, options = parse_options_header(rv.headers['Content-Disposition']) | ||||||
|             self.assert_equal(value, 'attachment') |             assert value == 'attachment' | ||||||
|             self.assert_equal(options['filename'], 'index.html') |             assert options['filename'] == 'index.html' | ||||||
|             rv.close() |             rv.close() | ||||||
| 
 | 
 | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             rv = flask.send_file(StringIO('Test'), as_attachment=True, |             rv = flask.send_file(StringIO('Test'), as_attachment=True, | ||||||
|                                  attachment_filename='index.txt', |                                  attachment_filename='index.txt', | ||||||
|                                  add_etags=False) |                                  add_etags=False) | ||||||
|             self.assert_equal(rv.mimetype, 'text/plain') |             assert rv.mimetype == 'text/plain' | ||||||
|             value, options = parse_options_header(rv.headers['Content-Disposition']) |             value, options = parse_options_header(rv.headers['Content-Disposition']) | ||||||
|             self.assert_equal(value, 'attachment') |             assert value == 'attachment' | ||||||
|             self.assert_equal(options['filename'], 'index.txt') |             assert options['filename'] == 'index.txt' | ||||||
|             rv.close() |             rv.close() | ||||||
| 
 | 
 | ||||||
|     def test_static_file(self): |     def test_static_file(self): | ||||||
|  | @ -375,24 +374,24 @@ class SendfileTestCase(FlaskTestCase): | ||||||
|             # Test with static file handler. |             # Test with static file handler. | ||||||
|             rv = app.send_static_file('index.html') |             rv = app.send_static_file('index.html') | ||||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) |             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|             self.assert_equal(cc.max_age, 12 * 60 * 60) |             assert cc.max_age == 12 * 60 * 60 | ||||||
|             rv.close() |             rv.close() | ||||||
|             # Test again with direct use of send_file utility. |             # Test again with direct use of send_file utility. | ||||||
|             rv = flask.send_file('static/index.html') |             rv = flask.send_file('static/index.html') | ||||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) |             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|             self.assert_equal(cc.max_age, 12 * 60 * 60) |             assert cc.max_age == 12 * 60 * 60 | ||||||
|             rv.close() |             rv.close() | ||||||
|         app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3600 |         app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3600 | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             # Test with static file handler. |             # Test with static file handler. | ||||||
|             rv = app.send_static_file('index.html') |             rv = app.send_static_file('index.html') | ||||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) |             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|             self.assert_equal(cc.max_age, 3600) |             assert cc.max_age == 3600 | ||||||
|             rv.close() |             rv.close() | ||||||
|             # Test again with direct use of send_file utility. |             # Test again with direct use of send_file utility. | ||||||
|             rv = flask.send_file('static/index.html') |             rv = flask.send_file('static/index.html') | ||||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) |             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|             self.assert_equal(cc.max_age, 3600) |             assert cc.max_age == 3600 | ||||||
|             rv.close() |             rv.close() | ||||||
|         class StaticFileApp(flask.Flask): |         class StaticFileApp(flask.Flask): | ||||||
|             def get_send_file_max_age(self, filename): |             def get_send_file_max_age(self, filename): | ||||||
|  | @ -402,12 +401,12 @@ class SendfileTestCase(FlaskTestCase): | ||||||
|             # Test with static file handler. |             # Test with static file handler. | ||||||
|             rv = app.send_static_file('index.html') |             rv = app.send_static_file('index.html') | ||||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) |             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|             self.assert_equal(cc.max_age, 10) |             assert cc.max_age == 10 | ||||||
|             rv.close() |             rv.close() | ||||||
|             # Test again with direct use of send_file utility. |             # Test again with direct use of send_file utility. | ||||||
|             rv = flask.send_file('static/index.html') |             rv = flask.send_file('static/index.html') | ||||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) |             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||||
|             self.assert_equal(cc.max_age, 10) |             assert cc.max_age == 10 | ||||||
|             rv.close() |             rv.close() | ||||||
| 
 | 
 | ||||||
|     def test_send_from_directory(self): |     def test_send_from_directory(self): | ||||||
|  | @ -418,21 +417,21 @@ class SendfileTestCase(FlaskTestCase): | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             rv = flask.send_from_directory('static', 'hello.txt') |             rv = flask.send_from_directory('static', 'hello.txt') | ||||||
|             rv.direct_passthrough = False |             rv.direct_passthrough = False | ||||||
|             self.assert_equal(rv.data.strip(), b'Hello Subdomain') |             assert rv.data.strip() == b'Hello Subdomain' | ||||||
|             rv.close() |             rv.close() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class LoggingTestCase(FlaskTestCase): | class TestLogging(object): | ||||||
| 
 | 
 | ||||||
|     def test_logger_cache(self): |     def test_logger_cache(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         logger1 = app.logger |         logger1 = app.logger | ||||||
|         self.assert_true(app.logger is logger1) |         assert app.logger is logger1 | ||||||
|         self.assert_equal(logger1.name, __name__) |         assert logger1.name == __name__ | ||||||
|         app.logger_name = __name__ + '/test_logger_cache' |         app.logger_name = __name__ + '/test_logger_cache' | ||||||
|         self.assert_true(app.logger is not logger1) |         assert app.logger is not logger1 | ||||||
| 
 | 
 | ||||||
|     def test_debug_log(self): |     def test_debug_log(self, capsys): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         app.debug = True |         app.debug = True | ||||||
| 
 | 
 | ||||||
|  | @ -447,28 +446,22 @@ class LoggingTestCase(FlaskTestCase): | ||||||
|             1 // 0 |             1 // 0 | ||||||
| 
 | 
 | ||||||
|         with app.test_client() as c: |         with app.test_client() as c: | ||||||
|             with catch_stderr() as err: |             c.get('/') | ||||||
|                 c.get('/') |             out, err = capsys.readouterr() | ||||||
|                 out = err.getvalue() |             assert 'WARNING in test_helpers [' in err | ||||||
|                 self.assert_in('WARNING in helpers [', out) |             assert os.path.basename(__file__.rsplit('.', 1)[0] + '.py') in err | ||||||
|                 self.assert_in(os.path.basename(__file__.rsplit('.', 1)[0] + '.py'), out) |             assert 'the standard library is dead' in err | ||||||
|                 self.assert_in('the standard library is dead', out) |             assert 'this is a debug statement' in err | ||||||
|                 self.assert_in('this is a debug statement', out) |  | ||||||
| 
 | 
 | ||||||
|             with catch_stderr() as err: |             with pytest.raises(ZeroDivisionError): | ||||||
|                 try: |                 c.get('/exc') | ||||||
|                     c.get('/exc') |  | ||||||
|                 except ZeroDivisionError: |  | ||||||
|                     pass |  | ||||||
|                 else: |  | ||||||
|                     self.assert_true(False, 'debug log ate the exception') |  | ||||||
| 
 | 
 | ||||||
|     def test_debug_log_override(self): |     def test_debug_log_override(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|         app.debug = True |         app.debug = True | ||||||
|         app.logger_name = 'flask_tests/test_debug_log_override' |         app.logger_name = 'flask_tests/test_debug_log_override' | ||||||
|         app.logger.level = 10 |         app.logger.level = 10 | ||||||
|         self.assert_equal(app.logger.level, 10) |         assert app.logger.level == 10 | ||||||
| 
 | 
 | ||||||
|     def test_exception_logging(self): |     def test_exception_logging(self): | ||||||
|         out = StringIO() |         out = StringIO() | ||||||
|  | @ -482,14 +475,14 @@ class LoggingTestCase(FlaskTestCase): | ||||||
|             1 // 0 |             1 // 0 | ||||||
| 
 | 
 | ||||||
|         rv = app.test_client().get('/') |         rv = app.test_client().get('/') | ||||||
|         self.assert_equal(rv.status_code, 500) |         assert rv.status_code == 500 | ||||||
|         self.assert_in(b'Internal Server Error', rv.data) |         assert b'Internal Server Error' in rv.data | ||||||
| 
 | 
 | ||||||
|         err = out.getvalue() |         err = out.getvalue() | ||||||
|         self.assert_in('Exception on / [GET]', err) |         assert 'Exception on / [GET]' in err | ||||||
|         self.assert_in('Traceback (most recent call last):', err) |         assert 'Traceback (most recent call last):' in err | ||||||
|         self.assert_in('1 // 0', err) |         assert '1 // 0' in err | ||||||
|         self.assert_in('ZeroDivisionError:', err) |         assert 'ZeroDivisionError:' in err | ||||||
| 
 | 
 | ||||||
|     def test_processor_exceptions(self): |     def test_processor_exceptions(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -511,8 +504,8 @@ class LoggingTestCase(FlaskTestCase): | ||||||
|             return 'Hello Server Error', 500 |             return 'Hello Server Error', 500 | ||||||
|         for trigger in 'before', 'after': |         for trigger in 'before', 'after': | ||||||
|             rv = app.test_client().get('/') |             rv = app.test_client().get('/') | ||||||
|             self.assert_equal(rv.status_code, 500) |             assert rv.status_code == 500 | ||||||
|             self.assert_equal(rv.data, b'Hello Server Error') |             assert rv.data == b'Hello Server Error' | ||||||
| 
 | 
 | ||||||
|     def test_url_for_with_anchor(self): |     def test_url_for_with_anchor(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -520,8 +513,7 @@ class LoggingTestCase(FlaskTestCase): | ||||||
|         def index(): |         def index(): | ||||||
|             return '42' |             return '42' | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             self.assert_equal(flask.url_for('index', _anchor='x y'), |             assert flask.url_for('index', _anchor='x y') == '/#x%20y' | ||||||
|                               '/#x%20y') |  | ||||||
| 
 | 
 | ||||||
|     def test_url_for_with_scheme(self): |     def test_url_for_with_scheme(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -529,10 +521,7 @@ class LoggingTestCase(FlaskTestCase): | ||||||
|         def index(): |         def index(): | ||||||
|             return '42' |             return '42' | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             self.assert_equal(flask.url_for('index', |             assert flask.url_for('index', _external=True, _scheme='https') == 'https://localhost/' | ||||||
|                                             _external=True, |  | ||||||
|                                             _scheme='https'), |  | ||||||
|                               'https://localhost/') |  | ||||||
| 
 | 
 | ||||||
|     def test_url_for_with_scheme_not_external(self): |     def test_url_for_with_scheme_not_external(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -540,7 +529,7 @@ class LoggingTestCase(FlaskTestCase): | ||||||
|         def index(): |         def index(): | ||||||
|             return '42' |             return '42' | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             self.assert_raises(ValueError, |             pytest.raises(ValueError, | ||||||
|                                flask.url_for, |                                flask.url_for, | ||||||
|                                'index', |                                'index', | ||||||
|                                _scheme='https') |                                _scheme='https') | ||||||
|  | @ -564,15 +553,12 @@ class LoggingTestCase(FlaskTestCase): | ||||||
|                          view_func=myview) |                          view_func=myview) | ||||||
| 
 | 
 | ||||||
|         with app.test_request_context(): |         with app.test_request_context(): | ||||||
|             self.assert_equal(flask.url_for('myview', _method='GET'), |             assert flask.url_for('myview', _method='GET') == '/myview/' | ||||||
|                               '/myview/') |             assert flask.url_for('myview', id=42, _method='GET') == '/myview/42' | ||||||
|             self.assert_equal(flask.url_for('myview', id=42, _method='GET'), |             assert flask.url_for('myview', _method='POST') == '/myview/create' | ||||||
|                               '/myview/42') |  | ||||||
|             self.assert_equal(flask.url_for('myview', _method='POST'), |  | ||||||
|                               '/myview/create') |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class NoImportsTestCase(FlaskTestCase): | class TestNoImports(object): | ||||||
|     """Test Flasks are created without import. |     """Test Flasks are created without import. | ||||||
| 
 | 
 | ||||||
|     Avoiding ``__import__`` helps create Flask instances where there are errors |     Avoiding ``__import__`` helps create Flask instances where there are errors | ||||||
|  | @ -583,14 +569,15 @@ class NoImportsTestCase(FlaskTestCase): | ||||||
|     imp modules in the Python standard library. |     imp modules in the Python standard library. | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     def test_name_with_import_error(self): |     def test_name_with_import_error(self, modules_tmpdir): | ||||||
|  |         modules_tmpdir.join('importerror.py').write('raise NotImplementedError()') | ||||||
|         try: |         try: | ||||||
|             flask.Flask('importerror') |             flask.Flask('importerror') | ||||||
|         except NotImplementedError: |         except NotImplementedError: | ||||||
|             self.fail('Flask(import_name) is importing import_name.') |             assert False, 'Flask(import_name) is importing import_name.' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class StreamingTestCase(FlaskTestCase): | class TestStreaming(object): | ||||||
| 
 | 
 | ||||||
|     def test_streaming_with_context(self): |     def test_streaming_with_context(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -604,7 +591,7 @@ class StreamingTestCase(FlaskTestCase): | ||||||
|             return flask.Response(flask.stream_with_context(generate())) |             return flask.Response(flask.stream_with_context(generate())) | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         rv = c.get('/?name=World') |         rv = c.get('/?name=World') | ||||||
|         self.assertEqual(rv.data, b'Hello World!') |         assert rv.data == b'Hello World!' | ||||||
| 
 | 
 | ||||||
|     def test_streaming_with_context_as_decorator(self): |     def test_streaming_with_context_as_decorator(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -619,7 +606,7 @@ class StreamingTestCase(FlaskTestCase): | ||||||
|             return flask.Response(generate()) |             return flask.Response(generate()) | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         rv = c.get('/?name=World') |         rv = c.get('/?name=World') | ||||||
|         self.assertEqual(rv.data, b'Hello World!') |         assert rv.data == b'Hello World!' | ||||||
| 
 | 
 | ||||||
|     def test_streaming_with_context_and_custom_close(self): |     def test_streaming_with_context_and_custom_close(self): | ||||||
|         app = flask.Flask(__name__) |         app = flask.Flask(__name__) | ||||||
|  | @ -645,16 +632,5 @@ class StreamingTestCase(FlaskTestCase): | ||||||
|                 Wrapper(generate()))) |                 Wrapper(generate()))) | ||||||
|         c = app.test_client() |         c = app.test_client() | ||||||
|         rv = c.get('/?name=World') |         rv = c.get('/?name=World') | ||||||
|         self.assertEqual(rv.data, b'Hello World!') |         assert rv.data == b'Hello World!' | ||||||
|         self.assertEqual(called, [42]) |         assert called == [42] | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def suite(): |  | ||||||
|     suite = unittest.TestSuite() |  | ||||||
|     if flask.json_available: |  | ||||||
|         suite.addTest(unittest.makeSuite(JSONTestCase)) |  | ||||||
|     suite.addTest(unittest.makeSuite(SendfileTestCase)) |  | ||||||
|     suite.addTest(unittest.makeSuite(LoggingTestCase)) |  | ||||||
|     suite.addTest(unittest.makeSuite(NoImportsTestCase)) |  | ||||||
|     suite.addTest(unittest.makeSuite(StreamingTestCase)) |  | ||||||
|     return suite |  | ||||||
|  | @ -0,0 +1,134 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.test_instance | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by the Flask Team, see AUTHORS for more details. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | import flask | ||||||
|  | from flask._compat import PY2 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_explicit_instance_paths(modules_tmpdir): | ||||||
|  |     with pytest.raises(ValueError) as excinfo: | ||||||
|  |         flask.Flask(__name__, instance_path='instance') | ||||||
|  |     assert 'must be absolute' in str(excinfo.value) | ||||||
|  | 
 | ||||||
|  |     app = flask.Flask(__name__, instance_path=str(modules_tmpdir)) | ||||||
|  |     assert app.instance_path == str(modules_tmpdir) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_main_module_paths(modules_tmpdir, purge_module): | ||||||
|  |     app = modules_tmpdir.join('main_app.py') | ||||||
|  |     app.write('import flask\n\napp = flask.Flask("__main__")') | ||||||
|  |     purge_module('main_app') | ||||||
|  | 
 | ||||||
|  |     from main_app import app | ||||||
|  |     here = os.path.abspath(os.getcwd()) | ||||||
|  |     assert app.instance_path == os.path.join(here, 'instance') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_uninstalled_module_paths(modules_tmpdir, purge_module): | ||||||
|  |     app = modules_tmpdir.join('config_module_app.py').write( | ||||||
|  |         'import os\n' | ||||||
|  |         'import flask\n' | ||||||
|  |         'here = os.path.abspath(os.path.dirname(__file__))\n' | ||||||
|  |         'app = flask.Flask(__name__)\n' | ||||||
|  |     ) | ||||||
|  |     purge_module('config_module_app') | ||||||
|  | 
 | ||||||
|  |     from config_module_app import app | ||||||
|  |     assert app.instance_path == str(modules_tmpdir.join('instance')) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_uninstalled_package_paths(modules_tmpdir, purge_module): | ||||||
|  |     app = modules_tmpdir.mkdir('config_package_app') | ||||||
|  |     init = app.join('__init__.py') | ||||||
|  |     init.write( | ||||||
|  |         'import os\n' | ||||||
|  |         'import flask\n' | ||||||
|  |         'here = os.path.abspath(os.path.dirname(__file__))\n' | ||||||
|  |         'app = flask.Flask(__name__)\n' | ||||||
|  |     ) | ||||||
|  |     purge_module('config_package_app') | ||||||
|  | 
 | ||||||
|  |     from config_package_app import app | ||||||
|  |     assert app.instance_path == str(modules_tmpdir.join('instance')) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_installed_module_paths(modules_tmpdir, modules_tmpdir_prefix, | ||||||
|  |                                 purge_module, site_packages, limit_loader): | ||||||
|  |     site_packages.join('site_app.py').write( | ||||||
|  |         'import flask\n' | ||||||
|  |         'app = flask.Flask(__name__)\n' | ||||||
|  |     ) | ||||||
|  |     purge_module('site_app') | ||||||
|  | 
 | ||||||
|  |     from site_app import app | ||||||
|  |     assert app.instance_path == \ | ||||||
|  |         modules_tmpdir.join('var').join('site_app-instance') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_installed_package_paths(limit_loader, modules_tmpdir, | ||||||
|  |                                  modules_tmpdir_prefix, purge_module, | ||||||
|  |                                  monkeypatch): | ||||||
|  |     installed_path = modules_tmpdir.mkdir('path') | ||||||
|  |     monkeypatch.syspath_prepend(installed_path) | ||||||
|  | 
 | ||||||
|  |     app = installed_path.mkdir('installed_package') | ||||||
|  |     init = app.join('__init__.py') | ||||||
|  |     init.write('import flask\napp = flask.Flask(__name__)') | ||||||
|  |     purge_module('installed_package') | ||||||
|  | 
 | ||||||
|  |     from installed_package import app | ||||||
|  |     assert app.instance_path == \ | ||||||
|  |         modules_tmpdir.join('var').join('installed_package-instance') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_prefix_package_paths(limit_loader, modules_tmpdir, | ||||||
|  |                               modules_tmpdir_prefix, purge_module, | ||||||
|  |                               site_packages): | ||||||
|  |     app = site_packages.mkdir('site_package') | ||||||
|  |     init = app.join('__init__.py') | ||||||
|  |     init.write('import flask\napp = flask.Flask(__name__)') | ||||||
|  |     purge_module('site_package') | ||||||
|  | 
 | ||||||
|  |     import site_package | ||||||
|  |     assert site_package.app.instance_path == \ | ||||||
|  |         modules_tmpdir.join('var').join('site_package-instance') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_egg_installed_paths(install_egg, modules_tmpdir, | ||||||
|  |                              modules_tmpdir_prefix): | ||||||
|  |     modules_tmpdir.mkdir('site_egg').join('__init__.py').write( | ||||||
|  |         'import flask\n\napp = flask.Flask(__name__)' | ||||||
|  |     ) | ||||||
|  |     install_egg('site_egg') | ||||||
|  |     try: | ||||||
|  |         import site_egg | ||||||
|  |         assert site_egg.app.instance_path == \ | ||||||
|  |             str(modules_tmpdir.join('var/').join('site_egg-instance')) | ||||||
|  |     finally: | ||||||
|  |         if 'site_egg' in sys.modules: | ||||||
|  |             del sys.modules['site_egg'] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.mark.skipif(not PY2, reason='This only works under Python 2.') | ||||||
|  | def test_meta_path_loader_without_is_package(request, modules_tmpdir): | ||||||
|  |     app = modules_tmpdir.join('unimportable.py') | ||||||
|  |     app.write('import flask\napp = flask.Flask(__name__)') | ||||||
|  | 
 | ||||||
|  |     class Loader(object): | ||||||
|  |         def find_module(self, name, path=None): | ||||||
|  |             return self | ||||||
|  | 
 | ||||||
|  |     sys.meta_path.append(Loader()) | ||||||
|  |     request.addfinalizer(sys.meta_path.pop) | ||||||
|  | 
 | ||||||
|  |     with pytest.raises(AttributeError): | ||||||
|  |         import unimportable | ||||||
|  | @ -0,0 +1,107 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.regression | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests regressions. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import os | ||||||
|  | import gc | ||||||
|  | import sys | ||||||
|  | import flask | ||||||
|  | import threading | ||||||
|  | from werkzeug.exceptions import NotFound | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | _gc_lock = threading.Lock() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class assert_no_leak(object): | ||||||
|  | 
 | ||||||
|  |     def __enter__(self): | ||||||
|  |         gc.disable() | ||||||
|  |         _gc_lock.acquire() | ||||||
|  |         loc = flask._request_ctx_stack._local | ||||||
|  | 
 | ||||||
|  |         # Force Python to track this dictionary at all times. | ||||||
|  |         # This is necessary since Python only starts tracking | ||||||
|  |         # dicts if they contain mutable objects.  It's a horrible, | ||||||
|  |         # horrible hack but makes this kinda testable. | ||||||
|  |         loc.__storage__['FOOO'] = [1, 2, 3] | ||||||
|  | 
 | ||||||
|  |         gc.collect() | ||||||
|  |         self.old_objects = len(gc.get_objects()) | ||||||
|  | 
 | ||||||
|  |     def __exit__(self, exc_type, exc_value, tb): | ||||||
|  |         if not hasattr(sys, 'getrefcount'): | ||||||
|  |             gc.collect() | ||||||
|  |         new_objects = len(gc.get_objects()) | ||||||
|  |         if new_objects > self.old_objects: | ||||||
|  |             pytest.fail('Example code leaked') | ||||||
|  |         _gc_lock.release() | ||||||
|  |         gc.enable() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # XXX: untitaker: These tests need to be revised. They broke around the time we | ||||||
|  | # ported Flask to Python 3. | ||||||
|  | @pytest.mark.skipif(os.environ.get('RUN_FLASK_MEMORY_TESTS') != '1', | ||||||
|  |                     reason='Turned off due to envvar.') | ||||||
|  | def test_memory_consumption(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('simple_template.html', whiskey=42) | ||||||
|  | 
 | ||||||
|  |     def fire(): | ||||||
|  |         with app.test_client() as c: | ||||||
|  |             rv = c.get('/') | ||||||
|  |             assert rv.status_code == 200 | ||||||
|  |             assert rv.data == b'<h1>42</h1>' | ||||||
|  | 
 | ||||||
|  |     # Trigger caches | ||||||
|  |     fire() | ||||||
|  | 
 | ||||||
|  |     # This test only works on CPython 2.7. | ||||||
|  |     if sys.version_info >= (2, 7) and \ | ||||||
|  |             not hasattr(sys, 'pypy_translation_info'): | ||||||
|  |         with assert_no_leak(): | ||||||
|  |             for x in range(10): | ||||||
|  |                 fire() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_safe_join_toplevel_pardir(): | ||||||
|  |     from flask.helpers import safe_join | ||||||
|  |     with pytest.raises(NotFound): | ||||||
|  |         safe_join('/foo', '..') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_aborting(): | ||||||
|  |     class Foo(Exception): | ||||||
|  |         whatever = 42 | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  | 
 | ||||||
|  |     @app.errorhandler(Foo) | ||||||
|  |     def handle_foo(e): | ||||||
|  |         return str(e.whatever) | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         raise flask.abort(flask.redirect(flask.url_for('test'))) | ||||||
|  | 
 | ||||||
|  |     @app.route('/test') | ||||||
|  |     def test(): | ||||||
|  |         raise Foo() | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         rv = c.get('/') | ||||||
|  |         assert rv.headers['Location'] == 'http://localhost/test' | ||||||
|  |         rv = c.get('/test') | ||||||
|  |         assert rv.data == b'42' | ||||||
|  | @ -0,0 +1,185 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.reqctx | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Tests the request context. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import flask | ||||||
|  | import unittest | ||||||
|  | try: | ||||||
|  |     from greenlet import greenlet | ||||||
|  | except ImportError: | ||||||
|  |     greenlet = None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_teardown_on_pop(): | ||||||
|  |     buffer = [] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.teardown_request | ||||||
|  |     def end_of_request(exception): | ||||||
|  |         buffer.append(exception) | ||||||
|  | 
 | ||||||
|  |     ctx = app.test_request_context() | ||||||
|  |     ctx.push() | ||||||
|  |     assert buffer == [] | ||||||
|  |     ctx.pop() | ||||||
|  |     assert buffer == [None] | ||||||
|  | 
 | ||||||
|  | def test_teardown_with_previous_exception(): | ||||||
|  |     buffer = [] | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.teardown_request | ||||||
|  |     def end_of_request(exception): | ||||||
|  |         buffer.append(exception) | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         raise Exception('dummy') | ||||||
|  |     except Exception: | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         assert buffer == [] | ||||||
|  |     assert buffer == [None] | ||||||
|  | 
 | ||||||
|  | def test_proper_test_request_context(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config.update( | ||||||
|  |         SERVER_NAME='localhost.localdomain:5000' | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|  |     @app.route('/', subdomain='foo') | ||||||
|  |     def sub(): | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context('/'): | ||||||
|  |         assert flask.url_for('index', _external=True) == \ | ||||||
|  |             'http://localhost.localdomain:5000/' | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context('/'): | ||||||
|  |         assert flask.url_for('sub', _external=True) == \ | ||||||
|  |             'http://foo.localhost.localdomain:5000/' | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}): | ||||||
|  |             pass | ||||||
|  |     except ValueError as e: | ||||||
|  |         assert str(e) == ( | ||||||
|  |             "the server name provided " | ||||||
|  |             "('localhost.localdomain:5000') does not match the " | ||||||
|  |             "server name from the WSGI environment ('localhost')" | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     app.config.update(SERVER_NAME='localhost') | ||||||
|  |     with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost'}): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     app.config.update(SERVER_NAME='localhost:80') | ||||||
|  |     with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost:80'}): | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  | def test_context_binding(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return 'Hello %s!' % flask.request.args['name'] | ||||||
|  |     @app.route('/meh') | ||||||
|  |     def meh(): | ||||||
|  |         return flask.request.url | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context('/?name=World'): | ||||||
|  |         assert index() == 'Hello World!' | ||||||
|  |     with app.test_request_context('/meh'): | ||||||
|  |         assert meh() == 'http://localhost/meh' | ||||||
|  |     assert flask._request_ctx_stack.top is None | ||||||
|  | 
 | ||||||
|  | def test_context_test(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     assert not flask.request | ||||||
|  |     assert not flask.has_request_context() | ||||||
|  |     ctx = app.test_request_context() | ||||||
|  |     ctx.push() | ||||||
|  |     try: | ||||||
|  |         assert flask.request | ||||||
|  |         assert flask.has_request_context() | ||||||
|  |     finally: | ||||||
|  |         ctx.pop() | ||||||
|  | 
 | ||||||
|  | def test_manual_context_binding(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return 'Hello %s!' % flask.request.args['name'] | ||||||
|  | 
 | ||||||
|  |     ctx = app.test_request_context('/?name=World') | ||||||
|  |     ctx.push() | ||||||
|  |     assert index() == 'Hello World!' | ||||||
|  |     ctx.pop() | ||||||
|  |     try: | ||||||
|  |         index() | ||||||
|  |     except RuntimeError: | ||||||
|  |         pass | ||||||
|  |     else: | ||||||
|  |         assert 0, 'expected runtime error' | ||||||
|  | 
 | ||||||
|  | @pytest.mark.skipif(greenlet is None, reason='greenlet not installed') | ||||||
|  | def test_greenlet_context_copying(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     greenlets = [] | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         reqctx = flask._request_ctx_stack.top.copy() | ||||||
|  |         def g(): | ||||||
|  |             assert not flask.request | ||||||
|  |             assert not flask.current_app | ||||||
|  |             with reqctx: | ||||||
|  |                 assert flask.request | ||||||
|  |                 assert flask.current_app == app | ||||||
|  |                 assert flask.request.path == '/' | ||||||
|  |                 assert flask.request.args['foo'] == 'bar' | ||||||
|  |             assert not flask.request | ||||||
|  |             return 42 | ||||||
|  |         greenlets.append(greenlet(g)) | ||||||
|  |         return 'Hello World!' | ||||||
|  | 
 | ||||||
|  |     rv = app.test_client().get('/?foo=bar') | ||||||
|  |     assert rv.data == b'Hello World!' | ||||||
|  | 
 | ||||||
|  |     result = greenlets[0].run() | ||||||
|  |     assert result == 42 | ||||||
|  | 
 | ||||||
|  | @pytest.mark.skipif(greenlet is None, reason='greenlet not installed') | ||||||
|  | def test_greenlet_context_copying_api(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     greenlets = [] | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         reqctx = flask._request_ctx_stack.top.copy() | ||||||
|  |         @flask.copy_current_request_context | ||||||
|  |         def g(): | ||||||
|  |             assert flask.request | ||||||
|  |             assert flask.current_app == app | ||||||
|  |             assert flask.request.path == '/' | ||||||
|  |             assert flask.request.args['foo'] == 'bar' | ||||||
|  |             return 42 | ||||||
|  |         greenlets.append(greenlet(g)) | ||||||
|  |         return 'Hello World!' | ||||||
|  | 
 | ||||||
|  |     rv = app.test_client().get('/?foo=bar') | ||||||
|  |     assert rv.data == b'Hello World!' | ||||||
|  | 
 | ||||||
|  |     result = greenlets[0].run() | ||||||
|  |     assert result == 42 | ||||||
|  | @ -0,0 +1,158 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.signals | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Signalling. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | try: | ||||||
|  |     import blinker | ||||||
|  | except ImportError: | ||||||
|  |     blinker = None | ||||||
|  | 
 | ||||||
|  | import flask | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | pytestmark = pytest.mark.skipif( | ||||||
|  |     blinker is None, | ||||||
|  |     reason='Signals require the blinker library.' | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | def test_template_rendered(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('simple_template.html', whiskey=42) | ||||||
|  | 
 | ||||||
|  |     recorded = [] | ||||||
|  | 
 | ||||||
|  |     def record(sender, template, context): | ||||||
|  |         recorded.append((template, context)) | ||||||
|  | 
 | ||||||
|  |     flask.template_rendered.connect(record, app) | ||||||
|  |     try: | ||||||
|  |         app.test_client().get('/') | ||||||
|  |         assert len(recorded) == 1 | ||||||
|  |         template, context = recorded[0] | ||||||
|  |         assert template.name == 'simple_template.html' | ||||||
|  |         assert context['whiskey'] == 42 | ||||||
|  |     finally: | ||||||
|  |         flask.template_rendered.disconnect(record, app) | ||||||
|  | 
 | ||||||
|  | def test_request_signals(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     calls = [] | ||||||
|  | 
 | ||||||
|  |     def before_request_signal(sender): | ||||||
|  |         calls.append('before-signal') | ||||||
|  | 
 | ||||||
|  |     def after_request_signal(sender, response): | ||||||
|  |         assert response.data == b'stuff' | ||||||
|  |         calls.append('after-signal') | ||||||
|  | 
 | ||||||
|  |     @app.before_request | ||||||
|  |     def before_request_handler(): | ||||||
|  |         calls.append('before-handler') | ||||||
|  | 
 | ||||||
|  |     @app.after_request | ||||||
|  |     def after_request_handler(response): | ||||||
|  |         calls.append('after-handler') | ||||||
|  |         response.data = 'stuff' | ||||||
|  |         return response | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         calls.append('handler') | ||||||
|  |         return 'ignored anyway' | ||||||
|  | 
 | ||||||
|  |     flask.request_started.connect(before_request_signal, app) | ||||||
|  |     flask.request_finished.connect(after_request_signal, app) | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         rv = app.test_client().get('/') | ||||||
|  |         assert rv.data == b'stuff' | ||||||
|  | 
 | ||||||
|  |         assert calls == ['before-signal', 'before-handler', 'handler', | ||||||
|  |                          'after-handler', 'after-signal'] | ||||||
|  |     finally: | ||||||
|  |         flask.request_started.disconnect(before_request_signal, app) | ||||||
|  |         flask.request_finished.disconnect(after_request_signal, app) | ||||||
|  | 
 | ||||||
|  | def test_request_exception_signal(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     recorded = [] | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         1 // 0 | ||||||
|  | 
 | ||||||
|  |     def record(sender, exception): | ||||||
|  |         recorded.append(exception) | ||||||
|  | 
 | ||||||
|  |     flask.got_request_exception.connect(record, app) | ||||||
|  |     try: | ||||||
|  |         assert app.test_client().get('/').status_code == 500 | ||||||
|  |         assert len(recorded) == 1 | ||||||
|  |         assert isinstance(recorded[0], ZeroDivisionError) | ||||||
|  |     finally: | ||||||
|  |         flask.got_request_exception.disconnect(record, app) | ||||||
|  | 
 | ||||||
|  | def test_appcontext_signals(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     recorded = [] | ||||||
|  | 
 | ||||||
|  |     def record_push(sender, **kwargs): | ||||||
|  |         recorded.append('push') | ||||||
|  | 
 | ||||||
|  |     def record_pop(sender, **kwargs): | ||||||
|  |         recorded.append('pop') | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return 'Hello' | ||||||
|  | 
 | ||||||
|  |     flask.appcontext_pushed.connect(record_push, app) | ||||||
|  |     flask.appcontext_popped.connect(record_pop, app) | ||||||
|  |     try: | ||||||
|  |         with app.test_client() as c: | ||||||
|  |             rv = c.get('/') | ||||||
|  |             assert rv.data == b'Hello' | ||||||
|  |             assert recorded == ['push'] | ||||||
|  |         assert recorded == ['push', 'pop'] | ||||||
|  |     finally: | ||||||
|  |         flask.appcontext_pushed.disconnect(record_push, app) | ||||||
|  |         flask.appcontext_popped.disconnect(record_pop, app) | ||||||
|  | 
 | ||||||
|  | def test_flash_signal(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['SECRET_KEY'] = 'secret' | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         flask.flash('This is a flash message', category='notice') | ||||||
|  |         return flask.redirect('/other') | ||||||
|  | 
 | ||||||
|  |     recorded = [] | ||||||
|  | 
 | ||||||
|  |     def record(sender, message, category): | ||||||
|  |         recorded.append((message, category)) | ||||||
|  | 
 | ||||||
|  |     flask.message_flashed.connect(record, app) | ||||||
|  |     try: | ||||||
|  |         client = app.test_client() | ||||||
|  |         with client.session_transaction(): | ||||||
|  |             client.get('/') | ||||||
|  |             assert len(recorded) == 1 | ||||||
|  |             message, category = recorded[0] | ||||||
|  |             assert message == 'This is a flash message' | ||||||
|  |             assert category == 'notice' | ||||||
|  |     finally: | ||||||
|  |         flask.message_flashed.disconnect(record, app) | ||||||
|  | @ -0,0 +1,38 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.subclassing | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Test that certain behavior of flask can be customized by | ||||||
|  |     subclasses. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | import flask | ||||||
|  | import unittest | ||||||
|  | from logging import StreamHandler | ||||||
|  | 
 | ||||||
|  | from flask._compat import StringIO | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_suppressed_exception_logging(): | ||||||
|  |     class SuppressedFlask(flask.Flask): | ||||||
|  |         def log_exception(self, exc_info): | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  |     out = StringIO() | ||||||
|  |     app = SuppressedFlask(__name__) | ||||||
|  |     app.logger_name = 'flask_tests/test_suppressed_exception_logging' | ||||||
|  |     app.logger.addHandler(StreamHandler(out)) | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         1 // 0 | ||||||
|  | 
 | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.status_code == 500 | ||||||
|  |     assert b'Internal Server Error' in rv.data | ||||||
|  | 
 | ||||||
|  |     err = out.getvalue() | ||||||
|  |     assert err == '' | ||||||
|  | @ -0,0 +1,342 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.templating | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Template functionality | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import flask | ||||||
|  | import unittest | ||||||
|  | import logging | ||||||
|  | from jinja2 import TemplateNotFound | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_context_processing(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.context_processor | ||||||
|  |     def context_processor(): | ||||||
|  |         return {'injected_value': 42} | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('context_template.html', value=23) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'<p>23|42' | ||||||
|  | 
 | ||||||
|  | def test_original_win(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template_string('{{ config }}', config=42) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'42' | ||||||
|  | 
 | ||||||
|  | def test_request_less_rendering(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['WORLD_NAME'] = 'Special World' | ||||||
|  |     @app.context_processor | ||||||
|  |     def context_processor(): | ||||||
|  |         return dict(foo=42) | ||||||
|  | 
 | ||||||
|  |     with app.app_context(): | ||||||
|  |         rv = flask.render_template_string('Hello {{ config.WORLD_NAME }} ' | ||||||
|  |                                           '{{ foo }}') | ||||||
|  |         assert rv == 'Hello Special World 42' | ||||||
|  | 
 | ||||||
|  | def test_standard_context(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.secret_key = 'development key' | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         flask.g.foo = 23 | ||||||
|  |         flask.session['test'] = 'aha' | ||||||
|  |         return flask.render_template_string(''' | ||||||
|  |             {{ request.args.foo }} | ||||||
|  |             {{ g.foo }} | ||||||
|  |             {{ config.DEBUG }} | ||||||
|  |             {{ session.test }} | ||||||
|  |         ''') | ||||||
|  |     rv = app.test_client().get('/?foo=42') | ||||||
|  |     assert rv.data.split() == [b'42', b'23', b'False', b'aha'] | ||||||
|  | 
 | ||||||
|  | def test_escaping(): | ||||||
|  |     text = '<p>Hello World!' | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('escaping_template.html', text=text, | ||||||
|  |                                      html=flask.Markup(text)) | ||||||
|  |     lines = app.test_client().get('/').data.splitlines() | ||||||
|  |     assert lines == [ | ||||||
|  |         b'<p>Hello World!', | ||||||
|  |         b'<p>Hello World!', | ||||||
|  |         b'<p>Hello World!', | ||||||
|  |         b'<p>Hello World!', | ||||||
|  |         b'<p>Hello World!', | ||||||
|  |         b'<p>Hello World!' | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  | def test_no_escaping(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         assert flask.render_template_string( | ||||||
|  |             '{{ foo }}', foo='<test>') == '<test>' | ||||||
|  |         assert flask.render_template('mail.txt', foo='<test>') == \ | ||||||
|  |             '<test> Mail' | ||||||
|  | 
 | ||||||
|  | def test_macros(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         macro = flask.get_template_attribute('_macro.html', 'hello') | ||||||
|  |         assert macro('World') == 'Hello World!' | ||||||
|  | 
 | ||||||
|  | def test_template_filter(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_filter() | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     assert 'my_reverse' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['my_reverse'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app.add_template_filter(my_reverse) | ||||||
|  |     assert 'my_reverse' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['my_reverse'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_filter_with_name(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_filter('strrev') | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     assert 'strrev' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['strrev'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['strrev']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter_with_name(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app.add_template_filter(my_reverse, 'strrev') | ||||||
|  |     assert 'strrev' in app.jinja_env.filters.keys() | ||||||
|  |     assert app.jinja_env.filters['strrev'] == my_reverse | ||||||
|  |     assert app.jinja_env.filters['strrev']('abcd') == 'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_filter_with_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_filter() | ||||||
|  |     def super_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter_with_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def super_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app.add_template_filter(super_reverse) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_filter_with_name_and_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_filter('super_reverse') | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_add_template_filter_with_name_and_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def my_reverse(s): | ||||||
|  |         return s[::-1] | ||||||
|  |     app.add_template_filter(my_reverse, 'super_reverse') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_filter.html', value='abcd') | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'dcba' | ||||||
|  | 
 | ||||||
|  | def test_template_test(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_test() | ||||||
|  |     def boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     assert 'boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['boolean'] == boolean | ||||||
|  |     assert app.jinja_env.tests['boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_add_template_test(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app.add_template_test(boolean) | ||||||
|  |     assert 'boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['boolean'] == boolean | ||||||
|  |     assert app.jinja_env.tests['boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_template_test_with_name(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_test('boolean') | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     assert 'boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['boolean'] == is_boolean | ||||||
|  |     assert app.jinja_env.tests['boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_add_template_test_with_name(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app.add_template_test(is_boolean, 'boolean') | ||||||
|  |     assert 'boolean' in app.jinja_env.tests.keys() | ||||||
|  |     assert app.jinja_env.tests['boolean'] == is_boolean | ||||||
|  |     assert app.jinja_env.tests['boolean'](False) | ||||||
|  | 
 | ||||||
|  | def test_template_test_with_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_test() | ||||||
|  |     def boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_add_template_test_with_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app.add_template_test(boolean) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_template_test_with_name_and_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_test('boolean') | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_add_template_test_with_name_and_template(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     def is_boolean(value): | ||||||
|  |         return isinstance(value, bool) | ||||||
|  |     app.add_template_test(is_boolean, 'boolean') | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('template_test.html', value=False) | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert b'Success!' in rv.data | ||||||
|  | 
 | ||||||
|  | def test_add_template_global(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.template_global() | ||||||
|  |     def get_stuff(): | ||||||
|  |         return 42 | ||||||
|  |     assert 'get_stuff' in app.jinja_env.globals.keys() | ||||||
|  |     assert app.jinja_env.globals['get_stuff'] == get_stuff | ||||||
|  |     assert app.jinja_env.globals['get_stuff'](), 42 | ||||||
|  |     with app.app_context(): | ||||||
|  |         rv = flask.render_template_string('{{ get_stuff() }}') | ||||||
|  |         assert rv == '42' | ||||||
|  | 
 | ||||||
|  | def test_custom_template_loader(): | ||||||
|  |     class MyFlask(flask.Flask): | ||||||
|  |         def create_global_jinja_loader(self): | ||||||
|  |             from jinja2 import DictLoader | ||||||
|  |             return DictLoader({'index.html': 'Hello Custom World!'}) | ||||||
|  |     app = MyFlask(__name__) | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template('index.html') | ||||||
|  |     c = app.test_client() | ||||||
|  |     rv = c.get('/') | ||||||
|  |     assert rv.data == b'Hello Custom World!' | ||||||
|  | 
 | ||||||
|  | def test_iterable_loader(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     @app.context_processor | ||||||
|  |     def context_processor(): | ||||||
|  |         return {'whiskey': 'Jameson'} | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.render_template( | ||||||
|  |             ['no_template.xml', # should skip this one | ||||||
|  |             'simple_template.html', # should render this | ||||||
|  |             'context_template.html'], | ||||||
|  |             value=23) | ||||||
|  | 
 | ||||||
|  |     rv = app.test_client().get('/') | ||||||
|  |     assert rv.data == b'<h1>Jameson</h1>' | ||||||
|  | 
 | ||||||
|  | def test_templates_auto_reload(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     assert app.config['TEMPLATES_AUTO_RELOAD'] | ||||||
|  |     assert app.jinja_env.auto_reload | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['TEMPLATES_AUTO_RELOAD'] = False | ||||||
|  |     assert not app.jinja_env.auto_reload | ||||||
|  | 
 | ||||||
|  | def test_template_loader_debugging(test_apps): | ||||||
|  |     from blueprintapp import app | ||||||
|  | 
 | ||||||
|  |     called = [] | ||||||
|  |     class _TestHandler(logging.Handler): | ||||||
|  |         def handle(x, record): | ||||||
|  |             called.append(True) | ||||||
|  |             text = str(record.msg) | ||||||
|  |             assert '1: trying loader of application "blueprintapp"' in text | ||||||
|  |             assert ('2: trying loader of blueprint "admin" ' | ||||||
|  |                     '(blueprintapp.apps.admin)') in text | ||||||
|  |             assert ('trying loader of blueprint "frontend" ' | ||||||
|  |                     '(blueprintapp.apps.frontend)') in text | ||||||
|  |             assert 'Error: the template could not be found' in text | ||||||
|  |             assert ('looked up from an endpoint that belongs to ' | ||||||
|  |                     'the blueprint "frontend"') in text | ||||||
|  |             assert 'See http://flask.pocoo.org/docs/blueprints/#templates' in text | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         try: | ||||||
|  |             old_load_setting = app.config['EXPLAIN_TEMPLATE_LOADING'] | ||||||
|  |             old_handlers = app.logger.handlers[:] | ||||||
|  |             app.logger.handlers = [_TestHandler()] | ||||||
|  |             app.config['EXPLAIN_TEMPLATE_LOADING'] = True | ||||||
|  | 
 | ||||||
|  |             with pytest.raises(TemplateNotFound) as excinfo: | ||||||
|  |                 c.get('/missing') | ||||||
|  | 
 | ||||||
|  |             assert 'missing_template.html' in str(excinfo.value) | ||||||
|  |         finally: | ||||||
|  |             app.logger.handlers[:] = old_handlers | ||||||
|  |             app.config['EXPLAIN_TEMPLATE_LOADING'] = old_load_setting | ||||||
|  | 
 | ||||||
|  |     assert len(called) == 1 | ||||||
|  | @ -0,0 +1,243 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.testing | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Test client and more. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import flask | ||||||
|  | import unittest | ||||||
|  | 
 | ||||||
|  | from flask._compat import text_type | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_environ_defaults_from_config(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  |     app.config['SERVER_NAME'] = 'example.com:1234' | ||||||
|  |     app.config['APPLICATION_ROOT'] = '/foo' | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.request.url | ||||||
|  | 
 | ||||||
|  |     ctx = app.test_request_context() | ||||||
|  |     assert ctx.request.url == 'http://example.com:1234/foo/' | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         rv = c.get('/') | ||||||
|  |         assert rv.data == b'http://example.com:1234/foo/' | ||||||
|  | 
 | ||||||
|  | def test_environ_defaults(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return flask.request.url | ||||||
|  | 
 | ||||||
|  |     ctx = app.test_request_context() | ||||||
|  |     assert ctx.request.url == 'http://localhost/' | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         rv = c.get('/') | ||||||
|  |         assert rv.data == b'http://localhost/' | ||||||
|  | 
 | ||||||
|  | def test_redirect_keep_session(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.secret_key = 'testing' | ||||||
|  | 
 | ||||||
|  |     @app.route('/', methods=['GET', 'POST']) | ||||||
|  |     def index(): | ||||||
|  |         if flask.request.method == 'POST': | ||||||
|  |             return flask.redirect('/getsession') | ||||||
|  |         flask.session['data'] = 'foo' | ||||||
|  |         return 'index' | ||||||
|  | 
 | ||||||
|  |     @app.route('/getsession') | ||||||
|  |     def get_session(): | ||||||
|  |         return flask.session.get('data', '<missing>') | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         rv = c.get('/getsession') | ||||||
|  |         assert rv.data == b'<missing>' | ||||||
|  | 
 | ||||||
|  |         rv = c.get('/') | ||||||
|  |         assert rv.data == b'index' | ||||||
|  |         assert flask.session.get('data') == 'foo' | ||||||
|  |         rv = c.post('/', data={}, follow_redirects=True) | ||||||
|  |         assert rv.data == b'foo' | ||||||
|  | 
 | ||||||
|  |         # This support requires a new Werkzeug version | ||||||
|  |         if not hasattr(c, 'redirect_client'): | ||||||
|  |             assert flask.session.get('data') == 'foo' | ||||||
|  | 
 | ||||||
|  |         rv = c.get('/getsession') | ||||||
|  |         assert rv.data == b'foo' | ||||||
|  | 
 | ||||||
|  | def test_session_transactions(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  |     app.secret_key = 'testing' | ||||||
|  | 
 | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         return text_type(flask.session['foo']) | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         with c.session_transaction() as sess: | ||||||
|  |             assert len(sess) == 0 | ||||||
|  |             sess['foo'] = [42] | ||||||
|  |             assert len(sess) == 1 | ||||||
|  |         rv = c.get('/') | ||||||
|  |         assert rv.data == b'[42]' | ||||||
|  |         with c.session_transaction() as sess: | ||||||
|  |             assert len(sess) == 1 | ||||||
|  |             assert sess['foo'] == [42] | ||||||
|  | 
 | ||||||
|  | def test_session_transactions_no_null_sessions(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         try: | ||||||
|  |             with c.session_transaction() as sess: | ||||||
|  |                 pass | ||||||
|  |         except RuntimeError as e: | ||||||
|  |             assert 'Session backend did not open a session' in str(e) | ||||||
|  |         else: | ||||||
|  |             assert False, 'Expected runtime error' | ||||||
|  | 
 | ||||||
|  | def test_session_transactions_keep_context(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  |     app.secret_key = 'testing' | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         rv = c.get('/') | ||||||
|  |         req = flask.request._get_current_object() | ||||||
|  |         assert req is not None | ||||||
|  |         with c.session_transaction(): | ||||||
|  |             assert req is flask.request._get_current_object() | ||||||
|  | 
 | ||||||
|  | def test_session_transaction_needs_cookies(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  |     c = app.test_client(use_cookies=False) | ||||||
|  |     try: | ||||||
|  |         with c.session_transaction() as s: | ||||||
|  |             pass | ||||||
|  |     except RuntimeError as e: | ||||||
|  |         assert 'cookies' in str(e) | ||||||
|  |     else: | ||||||
|  |         assert False, 'Expected runtime error' | ||||||
|  | 
 | ||||||
|  | def test_test_client_context_binding(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['LOGGER_HANDLER_POLICY'] = 'never' | ||||||
|  |     @app.route('/') | ||||||
|  |     def index(): | ||||||
|  |         flask.g.value = 42 | ||||||
|  |         return 'Hello World!' | ||||||
|  | 
 | ||||||
|  |     @app.route('/other') | ||||||
|  |     def other(): | ||||||
|  |         1 // 0 | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         resp = c.get('/') | ||||||
|  |         assert flask.g.value == 42 | ||||||
|  |         assert resp.data == b'Hello World!' | ||||||
|  |         assert resp.status_code == 200 | ||||||
|  | 
 | ||||||
|  |         resp = c.get('/other') | ||||||
|  |         assert not hasattr(flask.g, 'value') | ||||||
|  |         assert b'Internal Server Error' in resp.data | ||||||
|  |         assert resp.status_code == 500 | ||||||
|  |         flask.g.value = 23 | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         flask.g.value | ||||||
|  |     except (AttributeError, RuntimeError): | ||||||
|  |         pass | ||||||
|  |     else: | ||||||
|  |         raise AssertionError('some kind of exception expected') | ||||||
|  | 
 | ||||||
|  | def test_reuse_client(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     c = app.test_client() | ||||||
|  | 
 | ||||||
|  |     with c: | ||||||
|  |         assert c.get('/').status_code == 404 | ||||||
|  | 
 | ||||||
|  |     with c: | ||||||
|  |         assert c.get('/').status_code == 404 | ||||||
|  | 
 | ||||||
|  | def test_test_client_calls_teardown_handlers(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     called = [] | ||||||
|  |     @app.teardown_request | ||||||
|  |     def remember(error): | ||||||
|  |         called.append(error) | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         assert called == [] | ||||||
|  |         c.get('/') | ||||||
|  |         assert called == [] | ||||||
|  |     assert called == [None] | ||||||
|  | 
 | ||||||
|  |     del called[:] | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         assert called == [] | ||||||
|  |         c.get('/') | ||||||
|  |         assert called == [] | ||||||
|  |         c.get('/') | ||||||
|  |         assert called == [None] | ||||||
|  |     assert called == [None, None] | ||||||
|  | 
 | ||||||
|  | def test_full_url_request(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.testing = True | ||||||
|  | 
 | ||||||
|  |     @app.route('/action', methods=['POST']) | ||||||
|  |     def action(): | ||||||
|  |         return 'x' | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         rv = c.post('http://domain.com/action?vodka=42', data={'gin': 43}) | ||||||
|  |         assert rv.status_code == 200 | ||||||
|  |         assert 'gin' in flask.request.form | ||||||
|  |         assert 'vodka' in flask.request.args | ||||||
|  | 
 | ||||||
|  | def test_subdomain(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['SERVER_NAME'] = 'example.com' | ||||||
|  |     @app.route('/', subdomain='<company_id>') | ||||||
|  |     def view(company_id): | ||||||
|  |         return company_id | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         url = flask.url_for('view', company_id='xxx') | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         response = c.get(url) | ||||||
|  | 
 | ||||||
|  |     assert 200 == response.status_code | ||||||
|  |     assert b'xxx' == response.data | ||||||
|  | 
 | ||||||
|  | def test_nosubdomain(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.config['SERVER_NAME'] = 'example.com' | ||||||
|  |     @app.route('/<company_id>') | ||||||
|  |     def view(company_id): | ||||||
|  |         return company_id | ||||||
|  | 
 | ||||||
|  |     with app.test_request_context(): | ||||||
|  |         url = flask.url_for('view', company_id='xxx') | ||||||
|  | 
 | ||||||
|  |     with app.test_client() as c: | ||||||
|  |         response = c.get(url) | ||||||
|  | 
 | ||||||
|  |     assert 200 == response.status_code | ||||||
|  |     assert b'xxx' == response.data | ||||||
|  | @ -0,0 +1,163 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | """ | ||||||
|  |     tests.views | ||||||
|  |     ~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  |     Pluggable views. | ||||||
|  | 
 | ||||||
|  |     :copyright: (c) 2014 by Armin Ronacher. | ||||||
|  |     :license: BSD, see LICENSE for more details. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import flask | ||||||
|  | import flask.views | ||||||
|  | import unittest | ||||||
|  | 
 | ||||||
|  | from werkzeug.http import parse_set_header | ||||||
|  | 
 | ||||||
|  | def common_test(app): | ||||||
|  |     c = app.test_client() | ||||||
|  | 
 | ||||||
|  |     assert c.get('/').data == b'GET' | ||||||
|  |     assert c.post('/').data == b'POST' | ||||||
|  |     assert c.put('/').status_code == 405 | ||||||
|  |     meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow']) | ||||||
|  |     assert sorted(meths) == ['GET', 'HEAD', 'OPTIONS', 'POST'] | ||||||
|  | 
 | ||||||
|  | def test_basic_view(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.View): | ||||||
|  |         methods = ['GET', 'POST'] | ||||||
|  |         def dispatch_request(self): | ||||||
|  |             return flask.request.method | ||||||
|  | 
 | ||||||
|  |     app.add_url_rule('/', view_func=Index.as_view('index')) | ||||||
|  |     common_test(app) | ||||||
|  | 
 | ||||||
|  | def test_method_based_view(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.MethodView): | ||||||
|  |         def get(self): | ||||||
|  |             return 'GET' | ||||||
|  |         def post(self): | ||||||
|  |             return 'POST' | ||||||
|  | 
 | ||||||
|  |     app.add_url_rule('/', view_func=Index.as_view('index')) | ||||||
|  | 
 | ||||||
|  |     common_test(app) | ||||||
|  | 
 | ||||||
|  | def test_view_patching(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.MethodView): | ||||||
|  |         def get(self): | ||||||
|  |             1 // 0 | ||||||
|  |         def post(self): | ||||||
|  |             1 // 0 | ||||||
|  | 
 | ||||||
|  |     class Other(Index): | ||||||
|  |         def get(self): | ||||||
|  |             return 'GET' | ||||||
|  |         def post(self): | ||||||
|  |             return 'POST' | ||||||
|  | 
 | ||||||
|  |     view = Index.as_view('index') | ||||||
|  |     view.view_class = Other | ||||||
|  |     app.add_url_rule('/', view_func=view) | ||||||
|  |     common_test(app) | ||||||
|  | 
 | ||||||
|  | def test_view_inheritance(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.MethodView): | ||||||
|  |         def get(self): | ||||||
|  |             return 'GET' | ||||||
|  |         def post(self): | ||||||
|  |             return 'POST' | ||||||
|  | 
 | ||||||
|  |     class BetterIndex(Index): | ||||||
|  |         def delete(self): | ||||||
|  |             return 'DELETE' | ||||||
|  | 
 | ||||||
|  |     app.add_url_rule('/', view_func=BetterIndex.as_view('index')) | ||||||
|  |     c = app.test_client() | ||||||
|  | 
 | ||||||
|  |     meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow']) | ||||||
|  |     assert sorted(meths) == ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST'] | ||||||
|  | 
 | ||||||
|  | def test_view_decorators(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     def add_x_parachute(f): | ||||||
|  |         def new_function(*args, **kwargs): | ||||||
|  |             resp = flask.make_response(f(*args, **kwargs)) | ||||||
|  |             resp.headers['X-Parachute'] = 'awesome' | ||||||
|  |             return resp | ||||||
|  |         return new_function | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.View): | ||||||
|  |         decorators = [add_x_parachute] | ||||||
|  |         def dispatch_request(self): | ||||||
|  |             return 'Awesome' | ||||||
|  | 
 | ||||||
|  |     app.add_url_rule('/', view_func=Index.as_view('index')) | ||||||
|  |     c = app.test_client() | ||||||
|  |     rv = c.get('/') | ||||||
|  |     assert rv.headers['X-Parachute'] == 'awesome' | ||||||
|  |     assert rv.data == b'Awesome' | ||||||
|  | 
 | ||||||
|  | def test_implicit_head(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.MethodView): | ||||||
|  |         def get(self): | ||||||
|  |             return flask.Response('Blub', headers={ | ||||||
|  |                 'X-Method': flask.request.method | ||||||
|  |             }) | ||||||
|  | 
 | ||||||
|  |     app.add_url_rule('/', view_func=Index.as_view('index')) | ||||||
|  |     c = app.test_client() | ||||||
|  |     rv = c.get('/') | ||||||
|  |     assert rv.data == b'Blub' | ||||||
|  |     assert rv.headers['X-Method'] == 'GET' | ||||||
|  |     rv = c.head('/') | ||||||
|  |     assert rv.data == b'' | ||||||
|  |     assert rv.headers['X-Method'] == 'HEAD' | ||||||
|  | 
 | ||||||
|  | def test_explicit_head(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.MethodView): | ||||||
|  |         def get(self): | ||||||
|  |             return 'GET' | ||||||
|  |         def head(self): | ||||||
|  |             return flask.Response('', headers={'X-Method': 'HEAD'}) | ||||||
|  | 
 | ||||||
|  |     app.add_url_rule('/', view_func=Index.as_view('index')) | ||||||
|  |     c = app.test_client() | ||||||
|  |     rv = c.get('/') | ||||||
|  |     assert rv.data == b'GET' | ||||||
|  |     rv = c.head('/') | ||||||
|  |     assert rv.data == b'' | ||||||
|  |     assert rv.headers['X-Method'] == 'HEAD' | ||||||
|  | 
 | ||||||
|  | def test_endpoint_override(): | ||||||
|  |     app = flask.Flask(__name__) | ||||||
|  |     app.debug = True | ||||||
|  | 
 | ||||||
|  |     class Index(flask.views.View): | ||||||
|  |         methods = ['GET', 'POST'] | ||||||
|  |         def dispatch_request(self): | ||||||
|  |             return flask.request.method | ||||||
|  | 
 | ||||||
|  |     app.add_url_rule('/', view_func=Index.as_view('index')) | ||||||
|  | 
 | ||||||
|  |     with pytest.raises(AssertionError): | ||||||
|  |         app.add_url_rule('/', view_func=Index.as_view('index')) | ||||||
|  | 
 | ||||||
|  |     # But these tests should still pass. We just log a warning. | ||||||
|  |     common_test(app) | ||||||
							
								
								
									
										22
									
								
								tox.ini
								
								
								
								
							
							
						
						
									
										22
									
								
								tox.ini
								
								
								
								
							|  | @ -1,10 +1,26 @@ | ||||||
| [tox] | [tox] | ||||||
| envlist = docs, py26, py27, pypy, py33, py34 | envlist = {py26,py27,pypy}-{lowest,release,devel}, {py33,py34}-{release,devel} | ||||||
| 
 | 
 | ||||||
| [testenv] | [testenv] | ||||||
| deps = blinker | commands = | ||||||
| commands = python run-tests.py [] |     py.test [] | ||||||
| 
 | 
 | ||||||
|  | deps= | ||||||
|  |     pytest | ||||||
|  |     greenlet | ||||||
|  | 
 | ||||||
|  |     lowest: Werkzeug==0.7 | ||||||
|  |     lowest: Jinja2==2.4 | ||||||
|  |     lowest: itsdangerous==0.21 | ||||||
|  |     lowest: blinker==1.0 | ||||||
|  |     release: blinker | ||||||
|  |     devel: git+git://github.com/mitsuhiko/werkzeug.git | ||||||
|  |     devel: git+git://github.com/mitsuhiko/jinja2.git | ||||||
|  |     devel: git+git://github.com/mitsuhiko/itsdangerous.git | ||||||
|  |     devel: git+git://github.com/jek/blinker.git | ||||||
|  | 
 | ||||||
|  | # extra dependencies | ||||||
|  | git+git://github.com/jek/blinker.git#egg=blinker | ||||||
| 
 | 
 | ||||||
| [testenv:docs] | [testenv:docs] | ||||||
| deps = sphinx | deps = sphinx | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue