Commit dfa712ef authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Refactored autoreload tests.

* Added helpers to test uncached and cached access.
* Fixed test_project_root_locale: it duplicated test_locale_paths_setting.
* Rewrote test_only_new_files: test more cases.
parent 23620cb8
Loading
Loading
Loading
Loading
+70 −43
Original line number Diff line number Diff line
@@ -8,36 +8,53 @@ from django.contrib import admin
from django.test import SimpleTestCase, override_settings
from django.test.utils import extend_sys_path
from django.utils import autoreload
from django.utils._os import npath, upath
from django.utils.autoreload import gen_filenames
from django.utils._os import npath

LOCALE_PATH = os.path.join(os.path.dirname(__file__), 'locale')


class TestFilenameGenerator(SimpleTestCase):
    def setUp(self):
        # Empty cached variables
        from django.utils import autoreload

    def clear_autoreload_caches(self):
        autoreload._cached_modules = set()
        autoreload._cached_filenames = []

    def assertFileFound(self, filename):
        self.clear_autoreload_caches()
        # Test uncached access
        self.assertIn(npath(filename), autoreload.gen_filenames())
        # Test cached access
        self.assertIn(npath(filename), autoreload.gen_filenames())

    def assertFileNotFound(self, filename):
        self.clear_autoreload_caches()
        # Test uncached access
        self.assertNotIn(npath(filename), autoreload.gen_filenames())
        # Test cached access
        self.assertNotIn(npath(filename), autoreload.gen_filenames())

    def assertFileFoundOnlyNew(self, filename):
        self.clear_autoreload_caches()
        # Test uncached access
        self.assertIn(npath(filename), autoreload.gen_filenames(only_new=True))
        # Test cached access
        self.assertNotIn(npath(filename), autoreload.gen_filenames(only_new=True))

    def test_django_locales(self):
        """
        Test that gen_filenames() also yields the built-in django locale files.
        Test that gen_filenames() yields the built-in Django locale files.
        """
        filenames = list(gen_filenames())
        self.assertIn(os.path.join(os.path.dirname(conf.__file__), 'locale',
                                   'nl', 'LC_MESSAGES', 'django.mo'),
                      filenames)
        django_dir = os.path.join(os.path.dirname(conf.__file__), 'locale')
        django_mo = os.path.join(django_dir, 'nl', 'LC_MESSAGES', 'django.mo')
        self.assertFileFound(django_mo)

    @override_settings(LOCALE_PATHS=[LOCALE_PATH])
    def test_locale_paths_setting(self):
        """
        Test that gen_filenames also yields from LOCALE_PATHS locales.
        """
        filenames = list(gen_filenames())
        self.assertIn(os.path.join(LOCALE_PATH, 'nl', 'LC_MESSAGES', 'django.mo'),
                      filenames)
        locale_paths_mo = os.path.join(LOCALE_PATH, 'nl', 'LC_MESSAGES', 'django.mo')
        self.assertFileFound(locale_paths_mo)

    @override_settings(INSTALLED_APPS=[])
    def test_project_root_locale(self):
@@ -47,11 +64,10 @@ class TestFilenameGenerator(SimpleTestCase):
        """
        old_cwd = os.getcwd()
        os.chdir(os.path.dirname(__file__))
        current_dir = os.path.join(os.path.dirname(__file__), 'locale')
        current_dir_mo = os.path.join(current_dir, 'nl', 'LC_MESSAGES', 'django.mo')
        try:
            filenames = list(gen_filenames())
            self.assertIn(
                os.path.join(LOCALE_PATH, 'nl', 'LC_MESSAGES', 'django.mo'),
                filenames)
            self.assertFileFound(current_dir_mo)
        finally:
            os.chdir(old_cwd)

@@ -60,11 +76,9 @@ class TestFilenameGenerator(SimpleTestCase):
        """
        Test that gen_filenames also yields from locale dirs in installed apps.
        """
        filenames = list(gen_filenames())
        self.assertIn(
            os.path.join(os.path.dirname(upath(admin.__file__)), 'locale', 'nl', 'LC_MESSAGES', 'django.mo'),
            filenames
        )
        admin_dir = os.path.join(os.path.dirname(admin.__file__), 'locale')
        admin_mo = os.path.join(admin_dir, 'nl', 'LC_MESSAGES', 'django.mo')
        self.assertFileFound(admin_mo)

    @override_settings(USE_I18N=False)
    def test_no_i18n(self):
@@ -72,41 +86,58 @@ class TestFilenameGenerator(SimpleTestCase):
        If i18n machinery is disabled, there is no need for watching the
        locale files.
        """
        filenames = list(gen_filenames())
        self.assertNotIn(
            os.path.join(os.path.dirname(upath(conf.__file__)), 'locale', 'nl', 'LC_MESSAGES', 'django.mo'),
            filenames
        )
        django_dir = os.path.join(os.path.dirname(conf.__file__), 'locale')
        django_mo = os.path.join(django_dir, 'nl', 'LC_MESSAGES', 'django.mo')
        self.assertFileNotFound(django_mo)

    def test_only_new_files(self):
        """
        When calling a second time gen_filenames with only_new = True, only
        files from newly loaded modules should be given.
        """
        list(gen_filenames())
        from fractions import Fraction  # NOQA
        filenames2 = list(gen_filenames(only_new=True))
        self.assertEqual(len(filenames2), 1)
        self.assertTrue(filenames2[0].endswith('fractions.py'))
        self.assertFalse(any(f.endswith('.pyc') for f in gen_filenames()))
        dirname = tempfile.mkdtemp()
        filename = os.path.join(dirname, 'test_only_new_module.py')
        self.addCleanup(shutil.rmtree, dirname)
        with open(filename, 'w'):
            pass

        # Test uncached access
        self.clear_autoreload_caches()
        filenames = set(autoreload.gen_filenames(only_new=True))
        filenames_reference = set(autoreload.gen_filenames())
        self.assertEqual(filenames, filenames_reference)

        # Test cached access: no changes
        filenames = set(autoreload.gen_filenames(only_new=True))
        self.assertEqual(filenames, set())

        # Test cached access: add a module
        with extend_sys_path(dirname):
            import_module('test_only_new_module')
        filenames = set(autoreload.gen_filenames(only_new=True))
        self.assertEqual(filenames, {npath(filename)})

    def test_deleted_removed(self):
        """
        When a file is deleted, gen_filenames() no longer returns it.
        """
        dirname = tempfile.mkdtemp()
        filename = os.path.join(dirname, 'test_deleted_removed_module.py')
        self.addCleanup(shutil.rmtree, dirname)
        with open(filename, 'w'):
            pass

        with extend_sys_path(dirname):
            import_module('test_deleted_removed_module')
        self.assertIn(npath(filename), gen_filenames())
        self.assertFileFound(filename)

        os.unlink(filename)
        self.assertNotIn(filename, gen_filenames())
        self.assertFileNotFound(filename)

    def test_check_errors(self):
        """
        When a file containing an error is imported in a function wrapped by
        check_errors(), gen_filenames() returns it.

        Run assertions twice to test uncached and cached access.
        """
        dirname = tempfile.mkdtemp()
        filename = os.path.join(dirname, 'test_syntax_error.py')
@@ -117,15 +148,12 @@ class TestFilenameGenerator(SimpleTestCase):
        with extend_sys_path(dirname):
            with self.assertRaises(SyntaxError):
                autoreload.check_errors(import_module)('test_syntax_error')
        self.assertIn(npath(filename), gen_filenames())
        self.assertIn(npath(filename), gen_filenames())
        self.assertFileFound(filename)

    def test_check_errors_only_new(self):
        """
        When a file containing an error is imported in a function wrapped by
        check_errors(), gen_filenames(only_new=True) returns it.

        Run assertions twice to test uncached and cached access.
        """
        dirname = tempfile.mkdtemp()
        filename = os.path.join(dirname, 'test_syntax_error.py')
@@ -136,5 +164,4 @@ class TestFilenameGenerator(SimpleTestCase):
        with extend_sys_path(dirname):
            with self.assertRaises(SyntaxError):
                autoreload.check_errors(import_module)('test_syntax_error')
        self.assertIn(npath(filename), gen_filenames(only_new=True))
        self.assertNotIn(npath(filename), gen_filenames(only_new=True))
        self.assertFileFoundOnlyNew(filename)