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" | ||||
|   - "pypy" | ||||
|   - "3.3" | ||||
|   - "3.4" | ||||
| 
 | ||||
| env: | ||||
|   - REQUIREMENTS=lowest | ||||
|  | @ -16,12 +17,16 @@ matrix: | |||
|     # Python 3 support currently does not work with lowest requirements | ||||
|     - python: "3.3" | ||||
|       env: REQUIREMENTS=lowest | ||||
|     - python: "3.4" | ||||
|       env: REQUIREMENTS=lowest | ||||
| 
 | ||||
| 
 | ||||
| install: | ||||
|   - pip install -r .travis-$REQUIREMENTS-requirements.txt | ||||
|   - pip install --editable . | ||||
|     - pip install hg+https://bitbucket.org/hpk42/tox | ||||
| 
 | ||||
| script: make test | ||||
| script: | ||||
|     - tox -e \ | ||||
|       $(echo py$TRAVIS_PYTHON_VERSION | tr -d . | sed -e 's/pypypy/pypy/')-$REQUIREMENTS | ||||
| 
 | ||||
| branches: | ||||
|   except: | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| include Makefile CHANGES LICENSE AUTHORS run-tests.py | ||||
| include Makefile CHANGES LICENSE AUTHORS | ||||
| recursive-include artwork * | ||||
| recursive-include tests * | ||||
| recursive-include examples * | ||||
|  | @ -9,8 +9,5 @@ recursive-exclude tests *.pyc | |||
| recursive-exclude tests *.pyo | ||||
| recursive-exclude examples *.pyc | ||||
| 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/_themes/.git | ||||
|  |  | |||
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							|  | @ -3,7 +3,7 @@ | |||
| all: clean-pyc test | ||||
| 
 | ||||
| test: | ||||
| 	python run-tests.py | ||||
| 	py.test | ||||
| 
 | ||||
| tox-test: | ||||
| 	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 | ||||
| 
 | ||||
| 
 | ||||
| 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( | ||||
|     name='Flask', | ||||
|     version='0.11-dev', | ||||
|  | @ -92,7 +56,7 @@ setup( | |||
|     description='A microframework based on Werkzeug, Jinja2 ' | ||||
|                 'and good intentions', | ||||
|     long_description=__doc__, | ||||
|     packages=['flask', 'flask.ext', 'flask.testsuite'], | ||||
|     packages=['flask', 'flask.ext'], | ||||
|     include_package_data=True, | ||||
|     zip_safe=False, | ||||
|     platforms='any', | ||||
|  | @ -116,7 +80,5 @@ setup( | |||
|     entry_points=''' | ||||
|         [console_scripts] | ||||
|         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 -*- | ||||
| """ | ||||
|     flask.testsuite.helpers | ||||
|     tests.helpers | ||||
|     ~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
|     Various helpers. | ||||
|  | @ -9,11 +9,11 @@ | |||
|     :license: BSD, see LICENSE for more details. | ||||
| """ | ||||
| 
 | ||||
| import pytest | ||||
| 
 | ||||
| import os | ||||
| import flask | ||||
| import unittest | ||||
| 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 flask._compat import StringIO, text_type | ||||
| 
 | ||||
|  | @ -27,7 +27,7 @@ def has_encoding(name): | |||
|         return False | ||||
| 
 | ||||
| 
 | ||||
| class JSONTestCase(FlaskTestCase): | ||||
| class TestJSON(object): | ||||
| 
 | ||||
|     def test_json_bad_requests(self): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -36,7 +36,7 @@ class JSONTestCase(FlaskTestCase): | |||
|             return flask.jsonify(foo=text_type(flask.request.get_json())) | ||||
|         c = app.test_client() | ||||
|         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): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -45,7 +45,7 @@ class JSONTestCase(FlaskTestCase): | |||
|             return flask.request.get_json() | ||||
|         c = app.test_client() | ||||
|         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): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -57,7 +57,7 @@ class JSONTestCase(FlaskTestCase): | |||
|         c = app.test_client() | ||||
|         resp = c.get('/', data=u'"Hällo Wörld"'.encode('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): | ||||
|         d = dict(a=23, b=42, c=[1, 2, 3]) | ||||
|  | @ -71,8 +71,8 @@ class JSONTestCase(FlaskTestCase): | |||
|         c = app.test_client() | ||||
|         for url in '/kw', '/dict': | ||||
|             rv = c.get(url) | ||||
|             self.assert_equal(rv.mimetype, 'application/json') | ||||
|             self.assert_equal(flask.json.loads(rv.data), d) | ||||
|             assert rv.mimetype == 'application/json' | ||||
|             assert flask.json.loads(rv.data) == d | ||||
| 
 | ||||
|     def test_json_as_unicode(self): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -80,12 +80,12 @@ class JSONTestCase(FlaskTestCase): | |||
|         app.config['JSON_AS_ASCII'] = True | ||||
|         with app.app_context(): | ||||
|             rv = flask.json.dumps(u'\N{SNOWMAN}') | ||||
|             self.assert_equal(rv, '"\\u2603"') | ||||
|             assert rv == '"\\u2603"' | ||||
| 
 | ||||
|         app.config['JSON_AS_ASCII'] = False | ||||
|         with app.app_context(): | ||||
|             rv = flask.json.dumps(u'\N{SNOWMAN}') | ||||
|             self.assert_equal(rv, u'"\u2603"') | ||||
|             assert rv == u'"\u2603"' | ||||
| 
 | ||||
|     def test_json_attr(self): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -96,29 +96,28 @@ class JSONTestCase(FlaskTestCase): | |||
|         c = app.test_client() | ||||
|         rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}), | ||||
|                             content_type='application/json') | ||||
|         self.assert_equal(rv.data, b'3') | ||||
|         assert rv.data == b'3' | ||||
| 
 | ||||
|     def test_template_escaping(self): | ||||
|         app = flask.Flask(__name__) | ||||
|         render = flask.render_template_string | ||||
|         with app.test_request_context(): | ||||
|             rv = flask.json.htmlsafe_dumps('</script>') | ||||
|             self.assert_equal(rv, u'"\\u003c/script\\u003e"') | ||||
|             self.assert_equal(type(rv), text_type) | ||||
|             assert rv == u'"\\u003c/script\\u003e"' | ||||
|             assert type(rv) == text_type | ||||
|             rv = render('{{ "</script>"|tojson }}') | ||||
|             self.assert_equal(rv, '"\\u003c/script\\u003e"') | ||||
|             assert rv == '"\\u003c/script\\u003e"' | ||||
|             rv = render('{{ "<\0/script>"|tojson }}') | ||||
|             self.assert_equal(rv, '"\\u003c\\u0000/script\\u003e"') | ||||
|             assert rv == '"\\u003c\\u0000/script\\u003e"' | ||||
|             rv = render('{{ "<!--<script>"|tojson }}') | ||||
|             self.assert_equal(rv, '"\\u003c!--\\u003cscript\\u003e"') | ||||
|             assert rv == '"\\u003c!--\\u003cscript\\u003e"' | ||||
|             rv = render('{{ "&"|tojson }}') | ||||
|             self.assert_equal(rv, '"\\u0026"') | ||||
|             assert rv == '"\\u0026"' | ||||
|             rv = render('{{ "\'"|tojson }}') | ||||
|             self.assert_equal(rv, '"\\u0027"') | ||||
|             assert rv == '"\\u0027"' | ||||
|             rv = render("<a ng-data='{{ data|tojson }}'></a>", | ||||
|                 data={'x': ["foo", "bar", "baz'"]}) | ||||
|             self.assert_equal(rv, | ||||
|                 '<a ng-data=\'{"x": ["foo", "bar", "baz\\u0027"]}\'></a>') | ||||
|             assert rv == '<a ng-data=\'{"x": ["foo", "bar", "baz\\u0027"]}\'></a>' | ||||
| 
 | ||||
|     def test_json_customization(self): | ||||
|         class X(object): | ||||
|  | @ -148,7 +147,7 @@ class JSONTestCase(FlaskTestCase): | |||
|         rv = c.post('/', data=flask.json.dumps({ | ||||
|             'x': {'_foo': 42} | ||||
|         }), content_type='application/json') | ||||
|         self.assertEqual(rv.data, b'"<42>"') | ||||
|         assert rv.data == b'"<42>"' | ||||
| 
 | ||||
|     def test_modified_url_encoding(self): | ||||
|         class ModifiedRequest(flask.Request): | ||||
|  | @ -163,8 +162,8 @@ class JSONTestCase(FlaskTestCase): | |||
|             return flask.request.args['foo'] | ||||
| 
 | ||||
|         rv = app.test_client().get(u'/?foo=정상처리'.encode('euc-kr')) | ||||
|         self.assert_equal(rv.status_code, 200) | ||||
|         self.assert_equal(rv.data, u'정상처리'.encode('utf-8')) | ||||
|         assert rv.status_code == 200 | ||||
|         assert rv.data == u'정상처리'.encode('utf-8') | ||||
| 
 | ||||
|     if not has_encoding('euc-kr'): | ||||
|         test_modified_url_encoding = None | ||||
|  | @ -172,7 +171,7 @@ class JSONTestCase(FlaskTestCase): | |||
|     def test_json_key_sorting(self): | ||||
|         app = flask.Flask(__name__) | ||||
|         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') | ||||
| 
 | ||||
|         @app.route('/') | ||||
|  | @ -236,21 +235,21 @@ class JSONTestCase(FlaskTestCase): | |||
|         ] | ||||
| 
 | ||||
|         try: | ||||
|             self.assert_equal(lines, sorted_by_int) | ||||
|             assert lines == sorted_by_int | ||||
|         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): | ||||
|         app = flask.Flask(__name__) | ||||
|         with app.test_request_context(): | ||||
|             rv = flask.send_file('static/index.html') | ||||
|             self.assert_true(rv.direct_passthrough) | ||||
|             self.assert_equal(rv.mimetype, 'text/html') | ||||
|             assert rv.direct_passthrough | ||||
|             assert rv.mimetype == 'text/html' | ||||
|             with app.open_resource('static/index.html') as f: | ||||
|                 rv.direct_passthrough = False | ||||
|                 self.assert_equal(rv.data, f.read()) | ||||
|                 assert rv.data == f.read() | ||||
|             rv.close() | ||||
| 
 | ||||
|     def test_send_file_xsendfile(self): | ||||
|  | @ -258,52 +257,52 @@ class SendfileTestCase(FlaskTestCase): | |||
|         app.use_x_sendfile = True | ||||
|         with app.test_request_context(): | ||||
|             rv = flask.send_file('static/index.html') | ||||
|             self.assert_true(rv.direct_passthrough) | ||||
|             self.assert_in('x-sendfile', rv.headers) | ||||
|             self.assert_equal(rv.headers['x-sendfile'], | ||||
|                 os.path.join(app.root_path, 'static/index.html')) | ||||
|             self.assert_equal(rv.mimetype, 'text/html') | ||||
|             assert rv.direct_passthrough | ||||
|             assert 'x-sendfile' in rv.headers | ||||
|             assert rv.headers['x-sendfile'] == \ | ||||
|                 os.path.join(app.root_path, 'static/index.html') | ||||
|             assert rv.mimetype == 'text/html' | ||||
|             rv.close() | ||||
| 
 | ||||
|     def test_send_file_object(self): | ||||
|     def test_send_file_object(self, catch_deprecation_warnings): | ||||
|         app = flask.Flask(__name__) | ||||
|         with catch_warnings() as captured: | ||||
|         with catch_deprecation_warnings() as captured: | ||||
|             with app.test_request_context(): | ||||
|                 f = open(os.path.join(app.root_path, 'static/index.html'), mode='rb') | ||||
|                 rv = flask.send_file(f) | ||||
|                 rv.direct_passthrough = False | ||||
|                 with app.open_resource('static/index.html') as f: | ||||
|                     self.assert_equal(rv.data, f.read()) | ||||
|                 self.assert_equal(rv.mimetype, 'text/html') | ||||
|                     assert rv.data == f.read() | ||||
|                 assert rv.mimetype == 'text/html' | ||||
|                 rv.close() | ||||
|             # mimetypes + etag | ||||
|             self.assert_equal(len(captured), 2) | ||||
|             assert len(captured) == 2 | ||||
| 
 | ||||
|         app.use_x_sendfile = True | ||||
|         with catch_warnings() as captured: | ||||
|         with catch_deprecation_warnings() as captured: | ||||
|             with app.test_request_context(): | ||||
|                 f = open(os.path.join(app.root_path, 'static/index.html')) | ||||
|                 rv = flask.send_file(f) | ||||
|                 self.assert_equal(rv.mimetype, 'text/html') | ||||
|                 self.assert_in('x-sendfile', rv.headers) | ||||
|                 self.assert_equal(rv.headers['x-sendfile'], | ||||
|                     os.path.join(app.root_path, 'static/index.html')) | ||||
|                 assert rv.mimetype == 'text/html' | ||||
|                 assert 'x-sendfile' in rv.headers | ||||
|                 assert rv.headers['x-sendfile'] == \ | ||||
|                     os.path.join(app.root_path, 'static/index.html') | ||||
|                 rv.close() | ||||
|             # mimetypes + etag | ||||
|             self.assert_equal(len(captured), 2) | ||||
|             assert len(captured) == 2 | ||||
| 
 | ||||
|         app.use_x_sendfile = False | ||||
|         with app.test_request_context(): | ||||
|             with catch_warnings() as captured: | ||||
|             with catch_deprecation_warnings() as captured: | ||||
|                 f = StringIO('Test') | ||||
|                 rv = flask.send_file(f) | ||||
|                 rv.direct_passthrough = False | ||||
|                 self.assert_equal(rv.data, b'Test') | ||||
|                 self.assert_equal(rv.mimetype, 'application/octet-stream') | ||||
|                 assert rv.data == b'Test' | ||||
|                 assert rv.mimetype == 'application/octet-stream' | ||||
|                 rv.close() | ||||
|             # etags | ||||
|             self.assert_equal(len(captured), 1) | ||||
|             with catch_warnings() as captured: | ||||
|             assert len(captured) == 1 | ||||
|             with catch_deprecation_warnings() as captured: | ||||
|                 class PyStringIO(object): | ||||
|                     def __init__(self, *args, **kwargs): | ||||
|                         self._io = StringIO(*args, **kwargs) | ||||
|  | @ -313,59 +312,59 @@ class SendfileTestCase(FlaskTestCase): | |||
|                 f.name = 'test.txt' | ||||
|                 rv = flask.send_file(f) | ||||
|                 rv.direct_passthrough = False | ||||
|                 self.assert_equal(rv.data, b'Test') | ||||
|                 self.assert_equal(rv.mimetype, 'text/plain') | ||||
|                 assert rv.data == b'Test' | ||||
|                 assert rv.mimetype == 'text/plain' | ||||
|                 rv.close() | ||||
|             # attachment_filename and etags | ||||
|             self.assert_equal(len(captured), 3) | ||||
|             with catch_warnings() as captured: | ||||
|             assert len(captured) == 3 | ||||
|             with catch_deprecation_warnings() as captured: | ||||
|                 f = StringIO('Test') | ||||
|                 rv = flask.send_file(f, mimetype='text/plain') | ||||
|                 rv.direct_passthrough = False | ||||
|                 self.assert_equal(rv.data, b'Test') | ||||
|                 self.assert_equal(rv.mimetype, 'text/plain') | ||||
|                 assert rv.data == b'Test' | ||||
|                 assert rv.mimetype == 'text/plain' | ||||
|                 rv.close() | ||||
|             # etags | ||||
|             self.assert_equal(len(captured), 1) | ||||
|             assert len(captured) == 1 | ||||
| 
 | ||||
|         app.use_x_sendfile = True | ||||
|         with catch_warnings() as captured: | ||||
|         with catch_deprecation_warnings() as captured: | ||||
|             with app.test_request_context(): | ||||
|                 f = StringIO('Test') | ||||
|                 rv = flask.send_file(f) | ||||
|                 self.assert_not_in('x-sendfile', rv.headers) | ||||
|                 assert 'x-sendfile' not in rv.headers | ||||
|                 rv.close() | ||||
|             # 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__) | ||||
|         with catch_warnings() as captured: | ||||
|         with catch_deprecation_warnings() as captured: | ||||
|             with app.test_request_context(): | ||||
|                 f = open(os.path.join(app.root_path, 'static/index.html')) | ||||
|                 rv = flask.send_file(f, as_attachment=True) | ||||
|                 value, options = parse_options_header(rv.headers['Content-Disposition']) | ||||
|                 self.assert_equal(value, 'attachment') | ||||
|                 assert value == 'attachment' | ||||
|                 rv.close() | ||||
|             # mimetypes + etag | ||||
|             self.assert_equal(len(captured), 2) | ||||
|             assert len(captured) == 2 | ||||
| 
 | ||||
|         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) | ||||
|             value, options = parse_options_header(rv.headers['Content-Disposition']) | ||||
|             self.assert_equal(value, 'attachment') | ||||
|             self.assert_equal(options['filename'], 'index.html') | ||||
|             assert value == 'attachment' | ||||
|             assert options['filename'] == 'index.html' | ||||
|             rv.close() | ||||
| 
 | ||||
|         with app.test_request_context(): | ||||
|             rv = flask.send_file(StringIO('Test'), as_attachment=True, | ||||
|                                  attachment_filename='index.txt', | ||||
|                                  add_etags=False) | ||||
|             self.assert_equal(rv.mimetype, 'text/plain') | ||||
|             assert rv.mimetype == 'text/plain' | ||||
|             value, options = parse_options_header(rv.headers['Content-Disposition']) | ||||
|             self.assert_equal(value, 'attachment') | ||||
|             self.assert_equal(options['filename'], 'index.txt') | ||||
|             assert value == 'attachment' | ||||
|             assert options['filename'] == 'index.txt' | ||||
|             rv.close() | ||||
| 
 | ||||
|     def test_static_file(self): | ||||
|  | @ -375,24 +374,24 @@ class SendfileTestCase(FlaskTestCase): | |||
|             # Test with static file handler. | ||||
|             rv = app.send_static_file('index.html') | ||||
|             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() | ||||
|             # Test again with direct use of send_file utility. | ||||
|             rv = flask.send_file('static/index.html') | ||||
|             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() | ||||
|         app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3600 | ||||
|         with app.test_request_context(): | ||||
|             # Test with static file handler. | ||||
|             rv = app.send_static_file('index.html') | ||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||
|             self.assert_equal(cc.max_age, 3600) | ||||
|             assert cc.max_age == 3600 | ||||
|             rv.close() | ||||
|             # Test again with direct use of send_file utility. | ||||
|             rv = flask.send_file('static/index.html') | ||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||
|             self.assert_equal(cc.max_age, 3600) | ||||
|             assert cc.max_age == 3600 | ||||
|             rv.close() | ||||
|         class StaticFileApp(flask.Flask): | ||||
|             def get_send_file_max_age(self, filename): | ||||
|  | @ -402,12 +401,12 @@ class SendfileTestCase(FlaskTestCase): | |||
|             # Test with static file handler. | ||||
|             rv = app.send_static_file('index.html') | ||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||
|             self.assert_equal(cc.max_age, 10) | ||||
|             assert cc.max_age == 10 | ||||
|             rv.close() | ||||
|             # Test again with direct use of send_file utility. | ||||
|             rv = flask.send_file('static/index.html') | ||||
|             cc = parse_cache_control_header(rv.headers['Cache-Control']) | ||||
|             self.assert_equal(cc.max_age, 10) | ||||
|             assert cc.max_age == 10 | ||||
|             rv.close() | ||||
| 
 | ||||
|     def test_send_from_directory(self): | ||||
|  | @ -418,21 +417,21 @@ class SendfileTestCase(FlaskTestCase): | |||
|         with app.test_request_context(): | ||||
|             rv = flask.send_from_directory('static', 'hello.txt') | ||||
|             rv.direct_passthrough = False | ||||
|             self.assert_equal(rv.data.strip(), b'Hello Subdomain') | ||||
|             assert rv.data.strip() == b'Hello Subdomain' | ||||
|             rv.close() | ||||
| 
 | ||||
| 
 | ||||
| class LoggingTestCase(FlaskTestCase): | ||||
| class TestLogging(object): | ||||
| 
 | ||||
|     def test_logger_cache(self): | ||||
|         app = flask.Flask(__name__) | ||||
|         logger1 = app.logger | ||||
|         self.assert_true(app.logger is logger1) | ||||
|         self.assert_equal(logger1.name, __name__) | ||||
|         assert app.logger is logger1 | ||||
|         assert logger1.name == __name__ | ||||
|         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.debug = True | ||||
| 
 | ||||
|  | @ -447,28 +446,22 @@ class LoggingTestCase(FlaskTestCase): | |||
|             1 // 0 | ||||
| 
 | ||||
|         with app.test_client() as c: | ||||
|             with catch_stderr() as err: | ||||
|                 c.get('/') | ||||
|                 out = err.getvalue() | ||||
|                 self.assert_in('WARNING in helpers [', out) | ||||
|                 self.assert_in(os.path.basename(__file__.rsplit('.', 1)[0] + '.py'), out) | ||||
|                 self.assert_in('the standard library is dead', out) | ||||
|                 self.assert_in('this is a debug statement', out) | ||||
|             c.get('/') | ||||
|             out, err = capsys.readouterr() | ||||
|             assert 'WARNING in test_helpers [' in err | ||||
|             assert os.path.basename(__file__.rsplit('.', 1)[0] + '.py') in err | ||||
|             assert 'the standard library is dead' in err | ||||
|             assert 'this is a debug statement' in err | ||||
| 
 | ||||
|             with catch_stderr() as err: | ||||
|                 try: | ||||
|                     c.get('/exc') | ||||
|                 except ZeroDivisionError: | ||||
|                     pass | ||||
|                 else: | ||||
|                     self.assert_true(False, 'debug log ate the exception') | ||||
|             with pytest.raises(ZeroDivisionError): | ||||
|                 c.get('/exc') | ||||
| 
 | ||||
|     def test_debug_log_override(self): | ||||
|         app = flask.Flask(__name__) | ||||
|         app.debug = True | ||||
|         app.logger_name = 'flask_tests/test_debug_log_override' | ||||
|         app.logger.level = 10 | ||||
|         self.assert_equal(app.logger.level, 10) | ||||
|         assert app.logger.level == 10 | ||||
| 
 | ||||
|     def test_exception_logging(self): | ||||
|         out = StringIO() | ||||
|  | @ -482,14 +475,14 @@ class LoggingTestCase(FlaskTestCase): | |||
|             1 // 0 | ||||
| 
 | ||||
|         rv = app.test_client().get('/') | ||||
|         self.assert_equal(rv.status_code, 500) | ||||
|         self.assert_in(b'Internal Server Error', rv.data) | ||||
|         assert rv.status_code == 500 | ||||
|         assert b'Internal Server Error' in rv.data | ||||
| 
 | ||||
|         err = out.getvalue() | ||||
|         self.assert_in('Exception on / [GET]', err) | ||||
|         self.assert_in('Traceback (most recent call last):', err) | ||||
|         self.assert_in('1 // 0', err) | ||||
|         self.assert_in('ZeroDivisionError:', err) | ||||
|         assert 'Exception on / [GET]' in err | ||||
|         assert 'Traceback (most recent call last):' in err | ||||
|         assert '1 // 0' in err | ||||
|         assert 'ZeroDivisionError:' in err | ||||
| 
 | ||||
|     def test_processor_exceptions(self): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -511,8 +504,8 @@ class LoggingTestCase(FlaskTestCase): | |||
|             return 'Hello Server Error', 500 | ||||
|         for trigger in 'before', 'after': | ||||
|             rv = app.test_client().get('/') | ||||
|             self.assert_equal(rv.status_code, 500) | ||||
|             self.assert_equal(rv.data, b'Hello Server Error') | ||||
|             assert rv.status_code == 500 | ||||
|             assert rv.data == b'Hello Server Error' | ||||
| 
 | ||||
|     def test_url_for_with_anchor(self): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -520,8 +513,7 @@ class LoggingTestCase(FlaskTestCase): | |||
|         def index(): | ||||
|             return '42' | ||||
|         with app.test_request_context(): | ||||
|             self.assert_equal(flask.url_for('index', _anchor='x y'), | ||||
|                               '/#x%20y') | ||||
|             assert flask.url_for('index', _anchor='x y') == '/#x%20y' | ||||
| 
 | ||||
|     def test_url_for_with_scheme(self): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -529,10 +521,7 @@ class LoggingTestCase(FlaskTestCase): | |||
|         def index(): | ||||
|             return '42' | ||||
|         with app.test_request_context(): | ||||
|             self.assert_equal(flask.url_for('index', | ||||
|                                             _external=True, | ||||
|                                             _scheme='https'), | ||||
|                               'https://localhost/') | ||||
|             assert flask.url_for('index', _external=True, _scheme='https') == 'https://localhost/' | ||||
| 
 | ||||
|     def test_url_for_with_scheme_not_external(self): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -540,7 +529,7 @@ class LoggingTestCase(FlaskTestCase): | |||
|         def index(): | ||||
|             return '42' | ||||
|         with app.test_request_context(): | ||||
|             self.assert_raises(ValueError, | ||||
|             pytest.raises(ValueError, | ||||
|                                flask.url_for, | ||||
|                                'index', | ||||
|                                _scheme='https') | ||||
|  | @ -564,15 +553,12 @@ class LoggingTestCase(FlaskTestCase): | |||
|                          view_func=myview) | ||||
| 
 | ||||
|         with app.test_request_context(): | ||||
|             self.assert_equal(flask.url_for('myview', _method='GET'), | ||||
|                               '/myview/') | ||||
|             self.assert_equal(flask.url_for('myview', id=42, _method='GET'), | ||||
|                               '/myview/42') | ||||
|             self.assert_equal(flask.url_for('myview', _method='POST'), | ||||
|                               '/myview/create') | ||||
|             assert flask.url_for('myview', _method='GET') == '/myview/' | ||||
|             assert flask.url_for('myview', id=42, _method='GET') == '/myview/42' | ||||
|             assert flask.url_for('myview', _method='POST') == '/myview/create' | ||||
| 
 | ||||
| 
 | ||||
| class NoImportsTestCase(FlaskTestCase): | ||||
| class TestNoImports(object): | ||||
|     """Test Flasks are created without import. | ||||
| 
 | ||||
|     Avoiding ``__import__`` helps create Flask instances where there are errors | ||||
|  | @ -583,14 +569,15 @@ class NoImportsTestCase(FlaskTestCase): | |||
|     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: | ||||
|             flask.Flask('importerror') | ||||
|         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): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -604,7 +591,7 @@ class StreamingTestCase(FlaskTestCase): | |||
|             return flask.Response(flask.stream_with_context(generate())) | ||||
|         c = app.test_client() | ||||
|         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): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -619,7 +606,7 @@ class StreamingTestCase(FlaskTestCase): | |||
|             return flask.Response(generate()) | ||||
|         c = app.test_client() | ||||
|         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): | ||||
|         app = flask.Flask(__name__) | ||||
|  | @ -645,16 +632,5 @@ class StreamingTestCase(FlaskTestCase): | |||
|                 Wrapper(generate()))) | ||||
|         c = app.test_client() | ||||
|         rv = c.get('/?name=World') | ||||
|         self.assertEqual(rv.data, b'Hello World!') | ||||
|         self.assertEqual(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 | ||||
|         assert rv.data == b'Hello World!' | ||||
|         assert called == [42] | ||||
|  | @ -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] | ||||
| envlist = docs, py26, py27, pypy, py33, py34 | ||||
| envlist = {py26,py27,pypy}-{lowest,release,devel}, {py33,py34}-{release,devel} | ||||
| 
 | ||||
| [testenv] | ||||
| deps = blinker | ||||
| commands = python run-tests.py [] | ||||
| commands = | ||||
|     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] | ||||
| deps = sphinx | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue