diff --git a/flask/testsuite/config.py b/flask/testsuite/config.py index e0f7005f..00f77cea 100644 --- a/flask/testsuite/config.py +++ b/flask/testsuite/config.py @@ -8,10 +8,14 @@ :copyright: (c) 2011 by Armin Ronacher. :license: BSD, see LICENSE for more details. """ +from __future__ import with_statement + import os import sys import flask +import pkgutil import unittest +from contextlib import contextmanager from flask.testsuite import FlaskTestCase @@ -84,6 +88,35 @@ class ConfigTestCase(FlaskTestCase): self.assert_equal(app.permanent_session_lifetime.seconds, 42) +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): @@ -133,6 +166,24 @@ class InstanceTestCase(FlaskTestCase): 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') @@ -150,6 +201,24 @@ class InstanceTestCase(FlaskTestCase): 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') @@ -167,6 +236,24 @@ class InstanceTestCase(FlaskTestCase): 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')