コード例 #1
0
ファイル: test_generators.py プロジェクト: yan12125/pelican
    def test_static_excludes(self):
        """Test that StaticGenerator respects STATIC_EXCLUDES.
        """
        settings = get_settings(STATIC_EXCLUDES=['subdir'],
                                PATH=self.content_path,
                                STATIC_PATHS=[''],
                                filenames={})
        context = settings.copy()

        StaticGenerator(context=context,
                        settings=settings,
                        path=settings['PATH'],
                        output_path=self.temp_output,
                        theme=settings['THEME']).generate_context()

        staticnames = [
            os.path.basename(c.source_path) for c in context['staticfiles']
        ]

        self.assertNotIn(
            'subdir_fake_image.jpg', staticnames,
            "StaticGenerator processed a file in a STATIC_EXCLUDES directory")
        self.assertIn(
            'fake_image.jpg', staticnames,
            "StaticGenerator skipped a file that it should have included")
コード例 #2
0
    def test_static_links(self):
        """Test that StaticGenerator uses files in static_links
        """
        settings = get_settings(
            STATIC_EXCLUDES=['subdir'],
            PATH=self.content_path,
            STATIC_PATHS=[],)
        context = get_context(settings)
        context['static_links'] |= {'short_page.md', 'subdir_fake_image.jpg'}

        StaticGenerator(
            context=context, settings=settings,
            path=settings['PATH'], output_path=self.temp_output,
            theme=settings['THEME']).generate_context()

        staticfiles_names = [
            os.path.basename(c.source_path) for c in context['staticfiles']]

        static_content_names = [
            os.path.basename(c) for c in context['static_content']]

        self.assertIn(
            'short_page.md', staticfiles_names,
            "StaticGenerator skipped a file that it should have included")
        self.assertIn(
            'short_page.md', static_content_names,
            "StaticGenerator skipped a file that it should have included")
        self.assertIn(
            'subdir_fake_image.jpg', staticfiles_names,
            "StaticGenerator skipped a file that it should have included")
        self.assertIn(
            'subdir_fake_image.jpg', static_content_names,
            "StaticGenerator skipped a file that it should have included")
コード例 #3
0
    def test_theme_static_paths_files(self):
        """Test that StaticGenerator properly copies also files mentioned in
           TEMPLATE_STATIC_PATHS, not just directories."""
        settings = get_settings(
            PATH=self.content_path,
            THEME_STATIC_PATHS=['static/css/fonts.css', 'static/fonts/'],)
        context = get_context(settings, staticfiles=[])

        StaticGenerator(
            context=context, settings=settings,
            path=settings['PATH'], output_path=self.temp_output,
            theme=settings['THEME']).generate_output(None)

        # Only the content of dirs and files listed in THEME_STATIC_PATHS are
        # put into the output, not everything from static/
        self.assertFalse(os.path.isdir(os.path.join(self.temp_output,
                                                    "theme/css/")))
        self.assertFalse(os.path.isdir(os.path.join(self.temp_output,
                                                    "theme/fonts/")))

        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.eot")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.svg")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.ttf")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.woff")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.woff2")))
        self.assertTrue(os.path.isfile(os.path.join(self.temp_output,
                                                    "theme/font.css")))
        self.assertTrue(os.path.isfile(os.path.join(self.temp_output,
                                                    "theme/fonts.css")))
コード例 #4
0
ファイル: test_generators.py プロジェクト: yan12125/pelican
 def setUp(self):
     self.content_path = os.path.join(CUR_DIR, 'mixed_content')
     self.temp_content = mkdtemp(prefix='testcontent.')
     self.temp_output = mkdtemp(prefix='testoutput.')
     self.settings = get_settings()
     self.settings['PATH'] = self.temp_content
     self.settings['STATIC_PATHS'] = ["static"]
     self.settings['OUTPUT_PATH'] = self.temp_output
     os.mkdir(os.path.join(self.temp_content, "static"))
     self.startfile = os.path.join(self.temp_content, "static",
                                   "staticfile")
     self.endfile = os.path.join(self.temp_output, "static", "staticfile")
     self.generator = StaticGenerator(
         context={'filenames': {}},
         settings=self.settings,
         path=self.temp_content,
         theme="",
         output_path=self.temp_output,
     )
コード例 #5
0
    def test_theme_static_paths_dirs(self):
        """Test that StaticGenerator properly copies also files mentioned in
           TEMPLATE_STATIC_PATHS, not just directories."""
        settings = get_settings(PATH=self.content_path)
        context = get_context(settings, staticfiles=[])

        StaticGenerator(
            context=context, settings=settings,
            path=settings['PATH'], output_path=self.temp_output,
            theme=settings['THEME']).generate_output(None)

        # The content of dirs listed in THEME_STATIC_PATHS (defaulting to
        # "static") is put into the output
        self.assertTrue(os.path.isdir(os.path.join(self.temp_output,
                                                   "theme/css/")))
        self.assertTrue(os.path.isdir(os.path.join(self.temp_output,
                                                   "theme/fonts/")))
コード例 #6
0
ファイル: test_generators.py プロジェクト: getpelican/pelican
 def setUp(self):
     self.content_path = os.path.join(CUR_DIR, 'mixed_content')
     self.temp_content = mkdtemp(prefix='testcontent.')
     self.temp_output = mkdtemp(prefix='testoutput.')
     self.settings = get_settings()
     self.settings['PATH'] = self.temp_content
     self.settings['STATIC_PATHS'] = ["static"]
     self.settings['OUTPUT_PATH'] = self.temp_output
     os.mkdir(os.path.join(self.temp_content, "static"))
     self.startfile = os.path.join(self.temp_content,
                                   "static", "staticfile")
     self.endfile = os.path.join(self.temp_output, "static", "staticfile")
     self.generator = StaticGenerator(
         context=get_context(),
         settings=self.settings,
         path=self.temp_content,
         theme="",
         output_path=self.temp_output,
         )
コード例 #7
0
ファイル: test_generators.py プロジェクト: yan12125/pelican
class TestStaticGenerator(unittest.TestCase):
    def setUp(self):
        self.content_path = os.path.join(CUR_DIR, 'mixed_content')
        self.temp_content = mkdtemp(prefix='testcontent.')
        self.temp_output = mkdtemp(prefix='testoutput.')
        self.settings = get_settings()
        self.settings['PATH'] = self.temp_content
        self.settings['STATIC_PATHS'] = ["static"]
        self.settings['OUTPUT_PATH'] = self.temp_output
        os.mkdir(os.path.join(self.temp_content, "static"))
        self.startfile = os.path.join(self.temp_content, "static",
                                      "staticfile")
        self.endfile = os.path.join(self.temp_output, "static", "staticfile")
        self.generator = StaticGenerator(
            context={'filenames': {}},
            settings=self.settings,
            path=self.temp_content,
            theme="",
            output_path=self.temp_output,
        )

    def tearDown(self):
        rmtree(self.temp_content)
        rmtree(self.temp_output)

    def set_ancient_mtime(self, path, timestamp=1):
        os.utime(path, (timestamp, timestamp))

    def test_theme_static_paths_dirs(self):
        """Test that StaticGenerator properly copies also files mentioned in
           TEMPLATE_STATIC_PATHS, not just directories."""
        settings = get_settings(PATH=self.content_path, filenames={})
        context = settings.copy()
        context['staticfiles'] = []

        StaticGenerator(context=context,
                        settings=settings,
                        path=settings['PATH'],
                        output_path=self.temp_output,
                        theme=settings['THEME']).generate_output(None)

        # The content of dirs listed in THEME_STATIC_PATHS (defaulting to
        # "static") is put into the output
        self.assertTrue(
            os.path.isdir(os.path.join(self.temp_output, "theme/css/")))
        self.assertTrue(
            os.path.isdir(os.path.join(self.temp_output, "theme/fonts/")))

    def test_theme_static_paths_files(self):
        """Test that StaticGenerator properly copies also files mentioned in
           TEMPLATE_STATIC_PATHS, not just directories."""
        settings = get_settings(
            PATH=self.content_path,
            THEME_STATIC_PATHS=['static/css/fonts.css', 'static/fonts/'],
            filenames={})
        context = settings.copy()
        context['staticfiles'] = []

        StaticGenerator(context=context,
                        settings=settings,
                        path=settings['PATH'],
                        output_path=self.temp_output,
                        theme=settings['THEME']).generate_output(None)

        # Only the content of dirs and files listed in THEME_STATIC_PATHS are
        # put into the output, not everything from static/
        self.assertFalse(
            os.path.isdir(os.path.join(self.temp_output, "theme/css/")))
        self.assertFalse(
            os.path.isdir(os.path.join(self.temp_output, "theme/fonts/")))

        self.assertTrue(
            os.path.isfile(
                os.path.join(self.temp_output,
                             "theme/Yanone_Kaffeesatz_400.eot")))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.temp_output,
                             "theme/Yanone_Kaffeesatz_400.svg")))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.temp_output,
                             "theme/Yanone_Kaffeesatz_400.ttf")))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.temp_output,
                             "theme/Yanone_Kaffeesatz_400.woff")))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.temp_output,
                             "theme/Yanone_Kaffeesatz_400.woff2")))
        self.assertTrue(
            os.path.isfile(os.path.join(self.temp_output, "theme/font.css")))
        self.assertTrue(
            os.path.isfile(os.path.join(self.temp_output, "theme/fonts.css")))

    def test_static_excludes(self):
        """Test that StaticGenerator respects STATIC_EXCLUDES.
        """
        settings = get_settings(STATIC_EXCLUDES=['subdir'],
                                PATH=self.content_path,
                                STATIC_PATHS=[''],
                                filenames={})
        context = settings.copy()

        StaticGenerator(context=context,
                        settings=settings,
                        path=settings['PATH'],
                        output_path=self.temp_output,
                        theme=settings['THEME']).generate_context()

        staticnames = [
            os.path.basename(c.source_path) for c in context['staticfiles']
        ]

        self.assertNotIn(
            'subdir_fake_image.jpg', staticnames,
            "StaticGenerator processed a file in a STATIC_EXCLUDES directory")
        self.assertIn(
            'fake_image.jpg', staticnames,
            "StaticGenerator skipped a file that it should have included")

    def test_static_exclude_sources(self):
        """Test that StaticGenerator respects STATIC_EXCLUDE_SOURCES.
        """

        settings = get_settings(STATIC_EXCLUDE_SOURCES=True,
                                PATH=self.content_path,
                                PAGE_PATHS=[''],
                                STATIC_PATHS=[''],
                                CACHE_CONTENT=False,
                                filenames={})
        context = settings.copy()

        for generator_class in (PagesGenerator, StaticGenerator):
            generator_class(context=context,
                            settings=settings,
                            path=settings['PATH'],
                            output_path=self.temp_output,
                            theme=settings['THEME']).generate_context()

        staticnames = [
            os.path.basename(c.source_path) for c in context['staticfiles']
        ]

        self.assertFalse(
            any(name.endswith(".md") for name in staticnames),
            "STATIC_EXCLUDE_SOURCES=True failed to exclude a markdown file")

        settings.update(STATIC_EXCLUDE_SOURCES=False)
        context = settings.copy()
        context['filenames'] = {}

        for generator_class in (PagesGenerator, StaticGenerator):
            generator_class(context=context,
                            settings=settings,
                            path=settings['PATH'],
                            output_path=self.temp_output,
                            theme=settings['THEME']).generate_context()

        staticnames = [
            os.path.basename(c.source_path) for c in context['staticfiles']
        ]

        self.assertTrue(
            any(name.endswith(".md") for name in staticnames),
            "STATIC_EXCLUDE_SOURCES=False failed to include a markdown file")

    def test_copy_one_file(self):
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        with open(self.endfile, "r") as f:
            self.assertEqual(f.read(), "staticcontent")

    @unittest.skipUnless(MagicMock, 'Needs Mock module')
    def test_file_update_required_when_dest_does_not_exist(self):
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        with open(staticfile.source_path, "w") as f:
            f.write("a")
        update_required = self.generator._file_update_required(staticfile)
        self.assertTrue(update_required)

    @unittest.skipUnless(MagicMock, 'Needs Mock module')
    def test_dest_and_source_mtimes_are_equal(self):
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        self.settings['STATIC_CHECK_IF_MODIFIED'] = True
        with open(staticfile.source_path, "w") as f:
            f.write("a")
        os.mkdir(os.path.join(self.temp_output, "static"))
        copy(staticfile.source_path, staticfile.save_as)
        isnewer = self.generator._source_is_newer(staticfile)
        self.assertFalse(isnewer)

    @unittest.skipUnless(MagicMock, 'Needs Mock module')
    def test_source_is_newer(self):
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        with open(staticfile.source_path, "w") as f:
            f.write("a")
        os.mkdir(os.path.join(self.temp_output, "static"))
        copy(staticfile.source_path, staticfile.save_as)
        self.set_ancient_mtime(staticfile.save_as)
        isnewer = self.generator._source_is_newer(staticfile)
        self.assertTrue(isnewer)

    def test_skip_file_when_source_is_not_newer(self):
        self.settings['STATIC_CHECK_IF_MODIFIED'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        with open(self.endfile, "w") as f:
            f.write("staticcontent")
        expected = os.path.getmtime(self.endfile)
        self.set_ancient_mtime(self.startfile)
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertEqual(os.path.getmtime(self.endfile), expected)

    def test_dont_link_by_default(self):
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertFalse(os.path.samefile(self.startfile, self.endfile))

    def test_output_file_is_linked_to_source(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.samefile(self.startfile, self.endfile))

    def test_output_file_exists_and_is_newer(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        with open(self.endfile, "w") as f:
            f.write("othercontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.samefile(self.startfile, self.endfile))

    def test_can_symlink_when_hardlink_not_possible(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        self.generator.fallback_to_symlinks = True
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.islink(self.endfile))

    def test_existing_symlink_is_considered_up_to_date(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        os.symlink(self.startfile, self.endfile)
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        requires_update = self.generator._file_update_required(staticfile)
        self.assertFalse(requires_update)

    def test_invalid_symlink_is_overwritten(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        os.symlink("invalid", self.endfile)
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        requires_update = self.generator._file_update_required(staticfile)
        self.assertTrue(requires_update)
        self.generator.fallback_to_symlinks = True
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertEqual(os.path.realpath(self.endfile), self.startfile)

    def test_delete_existing_file_before_mkdir(self):
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        with open(os.path.join(self.temp_output, "static"), "w") as f:
            f.write("This file should be a directory")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.isdir(os.path.join(self.temp_output,
                                                   "static")))
        self.assertTrue(os.path.isfile(self.endfile))
コード例 #8
0
ファイル: test_generators.py プロジェクト: getpelican/pelican
class TestStaticGenerator(unittest.TestCase):

    def setUp(self):
        self.content_path = os.path.join(CUR_DIR, 'mixed_content')
        self.temp_content = mkdtemp(prefix='testcontent.')
        self.temp_output = mkdtemp(prefix='testoutput.')
        self.settings = get_settings()
        self.settings['PATH'] = self.temp_content
        self.settings['STATIC_PATHS'] = ["static"]
        self.settings['OUTPUT_PATH'] = self.temp_output
        os.mkdir(os.path.join(self.temp_content, "static"))
        self.startfile = os.path.join(self.temp_content,
                                      "static", "staticfile")
        self.endfile = os.path.join(self.temp_output, "static", "staticfile")
        self.generator = StaticGenerator(
            context=get_context(),
            settings=self.settings,
            path=self.temp_content,
            theme="",
            output_path=self.temp_output,
            )

    def tearDown(self):
        rmtree(self.temp_content)
        rmtree(self.temp_output)

    def set_ancient_mtime(self, path, timestamp=1):
        os.utime(path, (timestamp, timestamp))

    def test_theme_static_paths_dirs(self):
        """Test that StaticGenerator properly copies also files mentioned in
           TEMPLATE_STATIC_PATHS, not just directories."""
        settings = get_settings(PATH=self.content_path)
        context = get_context(settings, staticfiles=[])

        StaticGenerator(
            context=context, settings=settings,
            path=settings['PATH'], output_path=self.temp_output,
            theme=settings['THEME']).generate_output(None)

        # The content of dirs listed in THEME_STATIC_PATHS (defaulting to
        # "static") is put into the output
        self.assertTrue(os.path.isdir(os.path.join(self.temp_output,
                                                   "theme/css/")))
        self.assertTrue(os.path.isdir(os.path.join(self.temp_output,
                                                   "theme/fonts/")))

    def test_theme_static_paths_files(self):
        """Test that StaticGenerator properly copies also files mentioned in
           TEMPLATE_STATIC_PATHS, not just directories."""
        settings = get_settings(
            PATH=self.content_path,
            THEME_STATIC_PATHS=['static/css/fonts.css', 'static/fonts/'],)
        context = get_context(settings, staticfiles=[])

        StaticGenerator(
            context=context, settings=settings,
            path=settings['PATH'], output_path=self.temp_output,
            theme=settings['THEME']).generate_output(None)

        # Only the content of dirs and files listed in THEME_STATIC_PATHS are
        # put into the output, not everything from static/
        self.assertFalse(os.path.isdir(os.path.join(self.temp_output,
                                                    "theme/css/")))
        self.assertFalse(os.path.isdir(os.path.join(self.temp_output,
                                                    "theme/fonts/")))

        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.eot")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.svg")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.ttf")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.woff")))
        self.assertTrue(os.path.isfile(os.path.join(
            self.temp_output, "theme/Yanone_Kaffeesatz_400.woff2")))
        self.assertTrue(os.path.isfile(os.path.join(self.temp_output,
                                                    "theme/font.css")))
        self.assertTrue(os.path.isfile(os.path.join(self.temp_output,
                                                    "theme/fonts.css")))

    def test_static_excludes(self):
        """Test that StaticGenerator respects STATIC_EXCLUDES.
        """
        settings = get_settings(
            STATIC_EXCLUDES=['subdir'],
            PATH=self.content_path,
            STATIC_PATHS=[''],)
        context = get_context(settings)

        StaticGenerator(
            context=context, settings=settings,
            path=settings['PATH'], output_path=self.temp_output,
            theme=settings['THEME']).generate_context()

        staticnames = [os.path.basename(c.source_path)
                       for c in context['staticfiles']]

        self.assertNotIn(
            'subdir_fake_image.jpg', staticnames,
            "StaticGenerator processed a file in a STATIC_EXCLUDES directory")
        self.assertIn(
            'fake_image.jpg', staticnames,
            "StaticGenerator skipped a file that it should have included")

    def test_static_exclude_sources(self):
        """Test that StaticGenerator respects STATIC_EXCLUDE_SOURCES.
        """

        settings = get_settings(
            STATIC_EXCLUDE_SOURCES=True,
            PATH=self.content_path,
            PAGE_PATHS=[''],
            STATIC_PATHS=[''],
            CACHE_CONTENT=False,)
        context = get_context(settings)

        for generator_class in (PagesGenerator, StaticGenerator):
            generator_class(
                context=context, settings=settings,
                path=settings['PATH'], output_path=self.temp_output,
                theme=settings['THEME']).generate_context()

        staticnames = [os.path.basename(c.source_path)
                       for c in context['staticfiles']]

        self.assertFalse(
            any(name.endswith(".md") for name in staticnames),
            "STATIC_EXCLUDE_SOURCES=True failed to exclude a markdown file")

        settings.update(STATIC_EXCLUDE_SOURCES=False)
        context = get_context(settings)

        for generator_class in (PagesGenerator, StaticGenerator):
            generator_class(
                context=context, settings=settings,
                path=settings['PATH'], output_path=self.temp_output,
                theme=settings['THEME']).generate_context()

        staticnames = [os.path.basename(c.source_path)
                       for c in context['staticfiles']]

        self.assertTrue(
            any(name.endswith(".md") for name in staticnames),
            "STATIC_EXCLUDE_SOURCES=False failed to include a markdown file")

    def test_static_links(self):
        """Test that StaticGenerator uses files in static_links
        """
        settings = get_settings(
            STATIC_EXCLUDES=['subdir'],
            PATH=self.content_path,
            STATIC_PATHS=[],)
        context = get_context(settings)
        context['static_links'] |= {'short_page.md', 'subdir_fake_image.jpg'}

        StaticGenerator(
            context=context, settings=settings,
            path=settings['PATH'], output_path=self.temp_output,
            theme=settings['THEME']).generate_context()

        staticfiles_names = [
            os.path.basename(c.source_path) for c in context['staticfiles']]

        static_content_names = [
            os.path.basename(c) for c in context['static_content']]

        self.assertIn(
            'short_page.md', staticfiles_names,
            "StaticGenerator skipped a file that it should have included")
        self.assertIn(
            'short_page.md', static_content_names,
            "StaticGenerator skipped a file that it should have included")
        self.assertIn(
            'subdir_fake_image.jpg', staticfiles_names,
            "StaticGenerator skipped a file that it should have included")
        self.assertIn(
            'subdir_fake_image.jpg', static_content_names,
            "StaticGenerator skipped a file that it should have included")

    def test_copy_one_file(self):
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        with open(self.endfile, "r") as f:
            self.assertEqual(f.read(), "staticcontent")

    @unittest.skipUnless(MagicMock, 'Needs Mock module')
    def test_file_update_required_when_dest_does_not_exist(self):
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        with open(staticfile.source_path, "w") as f:
            f.write("a")
        update_required = self.generator._file_update_required(staticfile)
        self.assertTrue(update_required)

    @unittest.skipUnless(MagicMock, 'Needs Mock module')
    def test_dest_and_source_mtimes_are_equal(self):
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        self.settings['STATIC_CHECK_IF_MODIFIED'] = True
        with open(staticfile.source_path, "w") as f:
            f.write("a")
        os.mkdir(os.path.join(self.temp_output, "static"))
        copy(staticfile.source_path, staticfile.save_as)
        isnewer = self.generator._source_is_newer(staticfile)
        self.assertFalse(isnewer)

    @unittest.skipUnless(MagicMock, 'Needs Mock module')
    def test_source_is_newer(self):
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        with open(staticfile.source_path, "w") as f:
            f.write("a")
        os.mkdir(os.path.join(self.temp_output, "static"))
        copy(staticfile.source_path, staticfile.save_as)
        self.set_ancient_mtime(staticfile.save_as)
        isnewer = self.generator._source_is_newer(staticfile)
        self.assertTrue(isnewer)

    def test_skip_file_when_source_is_not_newer(self):
        self.settings['STATIC_CHECK_IF_MODIFIED'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        with open(self.endfile, "w") as f:
            f.write("staticcontent")
        expected = os.path.getmtime(self.endfile)
        self.set_ancient_mtime(self.startfile)
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertEqual(os.path.getmtime(self.endfile), expected)

    def test_dont_link_by_default(self):
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertFalse(os.path.samefile(self.startfile, self.endfile))

    def test_output_file_is_linked_to_source(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.samefile(self.startfile, self.endfile))

    def test_output_file_exists_and_is_newer(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        with open(self.endfile, "w") as f:
            f.write("othercontent")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.samefile(self.startfile, self.endfile))

    def test_can_symlink_when_hardlink_not_possible(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        self.generator.fallback_to_symlinks = True
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.islink(self.endfile))

    def test_existing_symlink_is_considered_up_to_date(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        os.symlink(self.startfile, self.endfile)
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        requires_update = self.generator._file_update_required(staticfile)
        self.assertFalse(requires_update)

    def test_invalid_symlink_is_overwritten(self):
        self.settings['STATIC_CREATE_LINKS'] = True
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        os.mkdir(os.path.join(self.temp_output, "static"))
        os.symlink("invalid", self.endfile)
        staticfile = MagicMock()
        staticfile.source_path = self.startfile
        staticfile.save_as = self.endfile
        requires_update = self.generator._file_update_required(staticfile)
        self.assertTrue(requires_update)
        self.generator.fallback_to_symlinks = True
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(os.path.islink(self.endfile))
        self.assertEqual(os.path.realpath(self.endfile),
                         os.path.realpath(self.startfile))

    def test_delete_existing_file_before_mkdir(self):
        with open(self.startfile, "w") as f:
            f.write("staticcontent")
        with open(os.path.join(self.temp_output, "static"), "w") as f:
            f.write("This file should be a directory")
        self.generator.generate_context()
        self.generator.generate_output(None)
        self.assertTrue(
            os.path.isdir(os.path.join(self.temp_output, "static")))
        self.assertTrue(os.path.isfile(self.endfile))