Example #1
0
    def test_article_order_by(self):
        settings = get_settings(filenames={})
        settings['DEFAULT_CATEGORY'] = 'Default'
        settings['DEFAULT_DATE'] = (1970, 1, 1)
        settings['CACHE_CONTENT'] = False   # cache not needed for this logic tests
        settings['ARTICLE_ORDER_BY'] = 'title'

        generator = ArticlesGenerator(
            context=settings.copy(), settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()

        expected = [
            'An Article With Code Block To Test Typogrify Ignore',
            'Article title',
            'Article with Nonconformant HTML meta tags',
            'Article with markdown and summary metadata multi',
            'Article with markdown and summary metadata single',
            'Article with markdown containing footnotes',
            'Article with template',
            'Rst with filename metadata',
            'Test Markdown extensions',
            'Test markdown File',
            'Test md File',
            'Test mdown File',
            'Test mkd File',
            'This is a super article !',
            'This is a super article !',
            'This is a super article !',
            'This is a super article !',
            'This is a super article !',
            'This is a super article !',
            'This is an article with category !',
            'This is an article with multiple authors in lastname, firstname format!',
            'This is an article with multiple authors in list format!',
            'This is an article with multiple authors!',
            'This is an article with multiple authors!',
            'This is an article without category !',
            'This is an article without category !',
            'マックOS X 10.8でパイソンとVirtualenvをインストールと設定']

        articles = [article.title for article in generator.articles]
        self.assertEqual(articles, expected)

        # reversed title
        settings = get_settings(filenames={})
        settings['DEFAULT_CATEGORY'] = 'Default'
        settings['DEFAULT_DATE'] = (1970, 1, 1)
        settings['CACHE_CONTENT'] = False   # cache not needed for this logic tests
        settings['ARTICLE_ORDER_BY'] = 'reversed-title'

        generator = ArticlesGenerator(
            context=settings.copy(), settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()

        articles = [article.title for article in generator.articles]
        self.assertEqual(articles, list(reversed(expected)))
Example #2
0
    def test_article_order_by(self):
        settings = get_settings(filenames={})
        settings["DEFAULT_CATEGORY"] = "Default"
        settings["DEFAULT_DATE"] = (1970, 1, 1)
        settings["ARTICLE_ORDER_BY"] = "title"

        generator = ArticlesGenerator(
            context=settings.copy(), settings=settings, path=CONTENT_DIR, theme=settings["THEME"], output_path=None
        )
        generator.generate_context()

        expected = [
            "An Article With Code Block To Test Typogrify Ignore",
            "Article title",
            "Article with Nonconformant HTML meta tags",
            "Article with markdown and summary metadata multi",
            "Article with markdown and summary metadata single",
            "Article with markdown containing footnotes",
            "Article with template",
            "Rst with filename metadata",
            "Test Markdown extensions",
            "Test markdown File",
            "Test md File",
            "Test mdown File",
            "Test metadata duplicates",
            "Test mkd File",
            "This is a super article !",
            "This is a super article !",
            "This is a super article !",
            "This is a super article !",
            "This is a super article !",
            "This is a super article !",
            "This is an article with category !",
            ("This is an article with multiple authors in lastname, " "firstname format!"),
            "This is an article with multiple authors in list format!",
            "This is an article with multiple authors!",
            "This is an article with multiple authors!",
            "This is an article without category !",
            "This is an article without category !",
            "マックOS X 10.8でパイソンとVirtualenvをインストールと設定",
        ]

        articles = [article.title for article in generator.articles]
        self.assertEqual(articles, expected)

        # reversed title
        settings = get_settings(filenames={})
        settings["DEFAULT_CATEGORY"] = "Default"
        settings["DEFAULT_DATE"] = (1970, 1, 1)
        settings["ARTICLE_ORDER_BY"] = "reversed-title"

        generator = ArticlesGenerator(
            context=settings.copy(), settings=settings, path=CONTENT_DIR, theme=settings["THEME"], output_path=None
        )
        generator.generate_context()

        articles = [article.title for article in generator.articles]
        self.assertEqual(articles, list(reversed(expected)))
Example #3
0
    def test_generate_feeds(self):
        settings = get_settings()
        generator = ArticlesGenerator(settings, settings, None,
                settings['THEME'], None, settings['MARKUP'])
        writer = MagicMock()
        generator.generate_feeds(writer)
        writer.write_feed.assert_called_with([], settings,
                                             'feeds/all.atom.xml')

        generator = ArticlesGenerator(
            settings, get_settings(FEED_ALL_ATOM=None), None,
            settings['THEME'], None, None)
        writer = MagicMock()
        generator.generate_feeds(writer)
        self.assertFalse(writer.write_feed.called)
Example #4
0
 def test_nonexistent_template(self):
     """Attempt to load a non-existent template"""
     settings = get_settings(filenames={})
     generator = ArticlesGenerator(
         context=settings, settings=settings,
         path=None, theme=settings['THEME'], output_path=None)
     self.assertRaises(Exception, generator.get_template, "not_a_template")
Example #5
0
    def test_article_metadata_key_lowercase(self):
        # Keys of metadata should be lowercase.
        reader = readers.RstReader(settings=get_settings())
        content, metadata = reader.read(_path("article_with_uppercase_metadata.rst"))

        self.assertIn("category", metadata, "Key should be lowercase.")
        self.assertEqual("Yeah", metadata.get("category"), "Value keeps case.")
    def test_image_generation(self, process_image):
        settings = get_settings(IMAGE_PROCESS=self.valid_transforms,
                                IMAGE_PROCESS_DIR='derivs')

        test_data = [
            ('<img class="image-process-thumb" src="/tmp/test.jpg" />',
             '<img class="image-process-thumb" '
             'src="/tmp/derivs/thumb/test.jpg"/>',
             (
                 'tmp/test.jpg', 'thumb/test.jpg',
                 ["crop 0 0 50% 50%", "scale_out 150 150", "crop 0 0 150 150"]
             )),
            ('<img class="image-process-article-image" src="/tmp/test.jpg" />',
             '<img class="image-process-article-image" '
             'src="/tmp/derivs/article-image/test.jpg"/>',
             ('tmp/test.jpg', 'article-image/test.jpg', ["scale_in 300 300"]))
        ]

        for data in test_data:
            expected_source = os.path.join(settings['PATH'], data[2][0])
            expected_destination = os.path.join(
                settings['OUTPUT_PATH'], 'tmp', settings['IMAGE_PROCESS_DIR'],
                data[2][1]
            )
            html = harvest_images_in_fragment(data[0], settings)

            expected_image = (expected_source, expected_destination,
                              data[2][2])

            expected_calls = [mock.call(expected_image, settings)]
            self.assertEqual(html, data[1])
            self.assertEqual(expected_calls, process_image.call_args_list)
            process_image.reset_mock()
Example #7
0
 def test_valid_save_as_detects_breakout_to_root(self):
     settings = get_settings()
     article_kwargs = self._copy_page_kwargs()
     article_kwargs['metadata']['slug'] = '/foo'
     article_kwargs['settings'] = settings
     article = Article(**article_kwargs)
     self.assertFalse(article._has_valid_save_as())
Example #8
0
    def test_get_content(self):
        # Test that the content is updated with the relative links to
        # filenames, tags and categories.
        settings = get_settings()
        args = self.page_kwargs.copy()
        args['settings'] = settings

        # Tag
        args['content'] = ('A simple test, with a '
                           '<a href="|tag|tagname">link</a>')
        page = Page(**args)
        content = page.get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            ('A simple test, with a '
             '<a href="http://notmyidea.org/tag/tagname.html">link</a>'))

        # Category
        args['content'] = ('A simple test, with a '
                           '<a href="|category|category">link</a>')
        page = Page(**args)
        content = page.get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            ('A simple test, with a '
             '<a href="http://notmyidea.org/category/category.html">link</a>'))
Example #9
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")))
Example #10
0
 def test_metadata_url_format(self):
     # Arbitrary metadata should be passed through url_format()
     page = Page(**self.page_kwargs)
     self.assertIn('summary', page.url_format.keys())
     page.metadata['directory'] = 'test-dir'
     page.settings = get_settings(PAGE_SAVE_AS='{directory}/{slug}')
     self.assertEqual(page.save_as, 'test-dir/foo-bar')
Example #11
0
    def test_do_not_use_folder_as_category(self):

        settings = get_settings(filenames={})
        settings['DEFAULT_CATEGORY'] = 'Default'
        settings['DEFAULT_DATE'] = (1970, 1, 1)
        settings['USE_FOLDER_AS_CATEGORY'] = False
        settings['READERS'] = {'asc': None}
        settings['filenames'] = {}
        generator = ArticlesGenerator(
            context=settings.copy(), settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        # test for name
        # categories are grouped by slug; if two categories have the same slug
        # but different names they will be grouped together, the first one in
        # terms of process order will define the name for that category
        categories = [cat.name for cat, _ in generator.categories]
        categories_alternatives = (
            sorted(['Default', 'Yeah', 'test', '指導書']),
            sorted(['Default', 'yeah', 'test', '指導書']),
        )
        self.assertIn(sorted(categories), categories_alternatives)
        # test for slug
        categories = [cat.slug for cat, _ in generator.categories]
        categories_expected = ['default', 'yeah', 'test', 'zhi-dao-shu']
        self.assertEqual(sorted(categories), sorted(categories_expected))
Example #12
0
    def test_default_pagination_value(self):

        settings = get_settings()
        settings['DEFAULT_PAGINATION'] = 5
        paginator = Paginator('articles', 'articles', self.articles, settings)

        self.assertTrue(paginator._get_num_pages() > 1)
Example #13
0
    def test_standard_metadata_in_default_metadata(self):
        settings = get_settings()
        settings['CACHE_CONTENT'] = False
        settings['DEFAULT_CATEGORY'] = 'Default'
        settings['DEFAULT_DATE'] = (1970, 1, 1)
        settings['DEFAULT_METADATA'] = (('author', 'Blogger'),
                                        # category will be ignored in favor of
                                        # DEFAULT_CATEGORY
                                        ('category', 'Random'),
                                        ('tags', 'general, untagged'))
        context = get_context(settings)
        generator = ArticlesGenerator(
            context=context, settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()

        authors = sorted([author.name for author, _ in generator.authors])
        authors_expected = sorted(['Alexis Métaireau', 'Blogger',
                                   'Author, First', 'Author, Second',
                                   'First Author', 'Second Author'])
        self.assertEqual(authors, authors_expected)

        categories = sorted([category.name
                             for category, _ in generator.categories])
        categories_expected = [
            sorted(['Default', 'TestCategory', 'yeah', 'test', '指導書']),
            sorted(['Default', 'TestCategory', 'Yeah', 'test', '指導書'])]
        self.assertIn(categories, categories_expected)

        tags = sorted([tag.name for tag in generator.tags])
        tags_expected = sorted(['bar', 'foo', 'foobar', 'general', 'untagged',
                                'パイソン', 'マック'])
        self.assertEqual(tags, tags_expected)
Example #14
0
 def test_article_with_footnote(self):
     reader = readers.MarkdownReader(settings=get_settings())
     content, metadata = reader.read(_path("article_with_markdown_and_footnote.md"))
     expected_content = (
         "<p>This is some content"
         '<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" '
         'rel="footnote">1</a></sup>'
         " with some footnotes"
         '<sup id="fnref:footnote"><a class="footnote-ref" '
         'href="#fn:footnote" rel="footnote">2</a></sup></p>\n'
         '<div class="footnote">\n'
         '<hr />\n<ol>\n<li id="fn:1">\n'
         "<p>Numbered footnote&#160;"
         '<a class="footnote-backref" href="#fnref:1" rev="footnote" '
         'title="Jump back to footnote 1 in the text">&#8617;</a></p>\n'
         '</li>\n<li id="fn:footnote">\n'
         "<p>Named footnote&#160;"
         '<a class="footnote-backref" href="#fnref:footnote" rev="footnote" '
         'title="Jump back to footnote 2 in the text">&#8617;</a></p>\n'
         "</li>\n</ol>\n</div>"
     )
     expected_metadata = {
         "title": "Article with markdown containing footnotes",
         "summary": ("<p>Summary with <strong>inline</strong> markup " "<em>should</em> be supported.</p>"),
         "date": datetime.datetime(2012, 10, 31),
         "slug": "article-with-markdown-containing-footnotes",
     }
     self.assertEqual(content, expected_content)
     for key, value in metadata.items():
         self.assertEqual(value, expected_metadata[key], key)
Example #15
0
    def test_per_template_pagination_unaffected(self):

        settings = get_settings()
        settings['TEMPLATE_PAGINATION'] = { 'articles' : 5 }
        paginator = Paginator('index', 'index', self.articles, settings)

        self.assertEqual(paginator._get_num_pages(), 1)
Example #16
0
    def test_per_template_pagination_affected(self):

        settings = get_settings()
        settings['TEMPLATE_PAGINATION'] = { 'articles' : 5 }
        paginator = Paginator('articles', 'articles', self.articles, settings)

        self.assertTrue(paginator._get_num_pages() > 1)
Example #17
0
    def test_generate_feeds(self):
        settings = get_settings()
        generator = ArticlesGenerator(
            context=settings, settings=settings,
            path=None, theme=settings['THEME'], output_path=None)
        writer = MagicMock()
        generator.generate_feeds(writer)
        writer.write_feed.assert_called_with([], settings,
                                             'feeds/all.atom.xml')

        generator = ArticlesGenerator(
            context=settings, settings=get_settings(FEED_ALL_ATOM=None),
            path=None, theme=settings['THEME'], output_path=None)
        writer = MagicMock()
        generator.generate_feeds(writer)
        self.assertFalse(writer.write_feed.called)
Example #18
0
    def test_generate_output(self):

        settings = get_settings()
        settings["STATIC_PATHS"] = ["static"]
        settings["TEMPLATE_PAGES"] = {"template/source.html": "generated/file.html"}

        generator = TemplatePagesGenerator(
            context={"foo": "bar"}, settings=settings, path=self.temp_content, theme="", output_path=self.temp_output
        )

        # create a dummy template file
        template_dir = os.path.join(self.temp_content, "template")
        template_path = os.path.join(template_dir, "source.html")
        os.makedirs(template_dir)
        with open(template_path, "w") as template_file:
            template_file.write(self.TEMPLATE_CONTENT)

        writer = Writer(self.temp_output, settings=settings)
        generator.generate_output(writer)

        output_path = os.path.join(self.temp_output, "generated", "file.html")

        # output file has been generated
        self.assertTrue(os.path.exists(output_path))

        # output content is correct
        with open(output_path, "r") as output_file:
            self.assertEqual(output_file.read(), "foo: bar")
Example #19
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")
Example #20
0
    def test_period_in_timeperiod_archive(self):
        """
        Test that the context of a generated period_archive is passed
        'period' : a tuple of year, month, day according to the time period
        """
        settings = get_settings(filenames={})

        settings['YEAR_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/index.html'
        settings['CACHE_PATH'] = self.temp_cache
        generator = ArticlesGenerator(
            context=settings, settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        write = MagicMock()
        generator.generate_period_archives(write)
        dates = [d for d in generator.dates if d.date.year == 1970]
        self.assertEqual(len(dates), 1)
        #among other things it must have at least been called with this
        settings["period"] = (1970,)
        write.assert_called_with("posts/1970/index.html",
                                 generator.get_template("period_archives"),
                                 settings,
                                 blog=True, dates=dates)

        del settings["period"]
        settings['MONTH_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/{date:%b}/index.html'
        generator = ArticlesGenerator(
            context=settings, settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        write = MagicMock()
        generator.generate_period_archives(write)
        dates = [d for d in generator.dates if d.date.year == 1970
                                            and d.date.month == 1]
        self.assertEqual(len(dates), 1)
        settings["period"] = (1970, "January")
        #among other things it must have at least been called with this
        write.assert_called_with("posts/1970/Jan/index.html",
                                 generator.get_template("period_archives"),
                                 settings,
                                 blog=True, dates=dates)

        del settings["period"]
        settings['DAY_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/{date:%b}/{date:%d}/index.html'
        generator = ArticlesGenerator(
            context=settings, settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        write = MagicMock()
        generator.generate_period_archives(write)
        dates = [d for d in generator.dates if d.date.year == 1970
                                            and d.date.month == 1
                                            and d.date.day == 1]
        self.assertEqual(len(dates), 1)
        settings["period"] = (1970, "January", 1)
        #among other things it must have at least been called with this
        write.assert_called_with("posts/1970/Jan/01/index.html",
                                 generator.get_template("period_archives"),
                                 settings,
                                 blog=True, dates=dates)
Example #21
0
    def test_empty_file_with_bom(self):
        reader = readers.MarkdownReader(settings=get_settings())
        content, metadata = reader.read(
            _path('empty_with_bom.md'))

        self.assertEqual(metadata, {})
        self.assertEqual(content, '')
Example #22
0
    def test_article_with_metadata(self):
        reader = readers.MarkdownReader(settings=get_settings())
        content, metadata = reader.read(
            _path('article_with_md_extension.md'))
        expected = {
            'category': 'test',
            'title': 'Test md File',
            'summary': '<p>I have a lot to test</p>',
            'date': SafeDatetime(2010, 12, 2, 10, 14),
            'modified': SafeDatetime(2010, 12, 2, 10, 20),
            'tags': ['foo', 'bar', 'foobar'],
        }
        for key, value in metadata.items():
            self.assertEqual(value, expected[key], key)

        content, metadata = reader.read(
            _path('article_with_markdown_and_nonascii_summary.md'))
        expected = {
            'title': 'マックOS X 10.8でパイソンとVirtualenvをインストールと設定',
            'summary': '<p>パイソンとVirtualenvをまっくでインストールする方法について明確に説明します。</p>',
            'category': '指導書',
            'date': SafeDatetime(2012, 12, 20),
            'modified': SafeDatetime(2012, 12, 22),
            'tags': ['パイソン', 'マック'],
            'slug': 'python-virtualenv-on-mac-osx-mountain-lion-10.8',
        }
        for key, value in metadata.items():
            self.assertEqual(value, expected[key], key)
Example #23
0
    def test_intrasite_link_source_and_generated(self):
        """Test linking both to the source and the generated article
        """
        cls_name = '_DummyAsset' if six.PY3 else b'_DummyAsset'

        args = self.page_kwargs.copy()
        args['settings'] = get_settings()
        args['source_path'] = 'content'
        args['context']['generated_content'] = {
            'article.rst': type(cls_name, (object,), {'url': 'article.html'})}
        args['context']['static_content'] = {
            'article.rst': type(cls_name, (object,), {'url': 'article.rst'})}

        args['content'] = (
            'A simple test, with a link to an'
            '<a href="{filename}article.rst">article</a> and its'
            '<a href="{static}article.rst">source</a>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'A simple test, with a link to an'
            '<a href="http://notmyidea.org/article.html">article</a> and its'
            '<a href="http://notmyidea.org/article.rst">source</a>'
        )
Example #24
0
    def test_relative_source_path(self):
        # 'relative_source_path' should be the relative path
        # from 'PATH' to 'source_path'
        page_kwargs = self._copy_page_kwargs()

        # If 'source_path' is None, 'relative_source_path' should
        # also return None
        page_kwargs['source_path'] = None
        page = Page(**page_kwargs)
        self.assertIsNone(page.relative_source_path)

        page_kwargs = self._copy_page_kwargs()
        settings = get_settings()
        full_path = page_kwargs['source_path']

        settings['PATH'] = os.path.dirname(full_path)
        page_kwargs['settings'] = settings
        page = Page(**page_kwargs)

        # if 'source_path' is set, 'relative_source_path' should
        # return the relative path from 'PATH' to 'source_path'
        self.assertEqual(
            page.relative_source_path,
            os.path.relpath(
                full_path,
                os.path.dirname(full_path)
            ))
Example #25
0
 def test_article_with_file_extensions(self):
     reader = readers.MarkdownReader(settings=get_settings())
     # test to ensure the md file extension is being processed by the
     # correct reader
     content, metadata = reader.read(
         _path('article_with_md_extension.md'))
     expected = (
         "<h1>Test Markdown File Header</h1>\n"
         "<h2>Used for pelican test</h2>\n"
         "<p>The quick brown fox jumped over the lazy dog's back.</p>")
     self.assertEqual(content, expected)
     # test to ensure the mkd file extension is being processed by the
     # correct reader
     content, metadata = reader.read(
         _path('article_with_mkd_extension.mkd'))
     expected = ("<h1>Test Markdown File Header</h1>\n<h2>Used for pelican"
                 " test</h2>\n<p>This is another markdown test file.  Uses"
                 " the mkd extension.</p>")
     self.assertEqual(content, expected)
     # test to ensure the markdown file extension is being processed by the
     # correct reader
     content, metadata = reader.read(
         _path('article_with_markdown_extension.markdown'))
     expected = ("<h1>Test Markdown File Header</h1>\n<h2>Used for pelican"
                 " test</h2>\n<p>This is another markdown test file.  Uses"
                 " the markdown extension.</p>")
     self.assertEqual(content, expected)
     # test to ensure the mdown file extension is being processed by the
     # correct reader
     content, metadata = reader.read(
         _path('article_with_mdown_extension.mdown'))
     expected = ("<h1>Test Markdown File Header</h1>\n<h2>Used for pelican"
                 " test</h2>\n<p>This is another markdown test file.  Uses"
                 " the mdown extension.</p>")
     self.assertEqual(content, expected)
Example #26
0
    def test_generate_context(self):
        settings = get_settings()
        settings['PAGE_DIR'] = 'TestPages'
        settings['DEFAULT_DATE'] = (1970, 1, 1)

        generator = PagesGenerator(settings.copy(), settings, CUR_DIR,
                                      settings['THEME'], None,
                                      settings['MARKUP'])
        generator.generate_context()
        pages = self.distill_pages(generator.pages)
        hidden_pages = self.distill_pages(generator.hidden_pages)

        pages_expected = [
            ['This is a test page', 'published', 'page'],
            ['This is a markdown test page', 'published', 'page'],
            ['This is a test page with a preset template', 'published',
             'custom']
        ]
        hidden_pages_expected = [
            ['This is a test hidden page', 'hidden', 'page'],
            ['This is a markdown test hidden page', 'hidden', 'page'],
            ['This is a test hidden page with a custom template', 'hidden',
             'custom']
        ]

        self.assertEqual(sorted(pages_expected), sorted(pages))
        self.assertEqual(sorted(hidden_pages_expected), sorted(hidden_pages))
Example #27
0
 def test_valid_save_as_passes_valid(self):
     settings = get_settings()
     article_kwargs = self._copy_page_kwargs()
     article_kwargs['metadata']['slug'] = 'foo'
     article_kwargs['settings'] = settings
     article = Article(**article_kwargs)
     self.assertTrue(article._has_valid_save_as())
Example #28
0
 def setUp(self):
     self.old_locale = locale.setlocale(locale.LC_ALL)
     locale.setlocale(locale.LC_ALL, str('C'))
     self.settings = get_settings()
     self.settings['READERS'] = {'asc': None}
     self.generator = Generator(self.settings.copy(), self.settings,
                                CUR_DIR, self.settings['THEME'], None)
Example #29
0
    def test_generate_context(self):
        settings = get_settings(filenames={})
        settings['PAGE_DIR'] = 'TestPages'  # relative to CUR_DIR
        settings['DEFAULT_DATE'] = (1970, 1, 1)

        generator = PagesGenerator(
            context=settings.copy(), settings=settings,
            path=CUR_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        pages = self.distill_pages(generator.pages)
        hidden_pages = self.distill_pages(generator.hidden_pages)

        pages_expected = [
            ['This is a test page', 'published', 'page'],
            ['This is a markdown test page', 'published', 'page'],
            ['This is a test page with a preset template', 'published',
             'custom']
        ]
        hidden_pages_expected = [
            ['This is a test hidden page', 'hidden', 'page'],
            ['This is a markdown test hidden page', 'hidden', 'page'],
            ['This is a test hidden page with a custom template', 'hidden',
             'custom']
        ]

        self.assertEqual(sorted(pages_expected), sorted(pages))
        self.assertEqual(sorted(hidden_pages_expected), sorted(hidden_pages))
Example #30
0
    def test_generate_output(self):

        settings = get_settings()
        settings['STATIC_PATHS'] = ['static']
        settings['TEMPLATE_PAGES'] = {
                'template/source.html': 'generated/file.html'
                }

        generator = TemplatePagesGenerator({'foo': 'bar'}, settings,
                self.temp_content, '', self.temp_output, None)

        # create a dummy template file
        template_dir = os.path.join(self.temp_content, 'template')
        template_path = os.path.join(template_dir, 'source.html')
        os.makedirs(template_dir)
        with open(template_path, 'w') as template_file:
            template_file.write(self.TEMPLATE_CONTENT)

        writer = Writer(self.temp_output, settings=settings)
        generator.generate_output(writer)

        output_path = os.path.join(
                self.temp_output, 'generated', 'file.html')

        # output file has been generated
        self.assertTrue(os.path.exists(output_path))

        # output content is correct
        with open(output_path, 'r') as output_file:
            self.assertEqual(output_file.read(), 'foo: bar')
Example #31
0
 def setUpClass(cls):
     cls.temp_path = mkdtemp(prefix='pelicantests.')
     cls.settings = get_settings(filenames={})
     cls.settings['PATH'] = os.path.join(CUR_DIR, 'test_data')
     cls.settings['PHOTO_LIBRARY'] = os.path.join(CUR_DIR, 'test_data')
     cls.settings['DEFAULT_DATE'] = (1970, 1, 1)
     cls.settings['FILENAME_METADATA'] = '(?P<slug>[^.]+)'
     cls.settings['PLUGINS'] = [photos]
     cls.settings['CACHE_CONTENT'] = False
     cls.settings['OUTPUT_PATH'] = cls.temp_path
     cls.settings['SITEURL'] = 'http://getpelican.com/sub'
     photos.initialized(cls)
     cls.generator = ArticlesGenerator(
         context=cls.settings.copy(),
         settings=cls.settings,
         path=cls.settings['PATH'],
         theme=cls.settings['THEME'],
         output_path=cls.settings['OUTPUT_PATH'])
     photos.register()
     cls.generator.generate_context()
     photos.detect_gallery(cls.generator)
     photos.detect_image(cls.generator)
    def test_extraction(self, process_image):

        settings = get_settings(IMAGE_PROCESS_DIR='derivatives',
                                IMAGE_PROCESS=self.transforms)
        html = ('<img class="test image-process image-process-crop test2"'
                ' src="/tmp/test.jpg" />')

        html = harvest_images_in_fragment(html, settings)

        expected_content = ('<img class="test image-process image-process-crop'
                            ' test2" src="/tmp/derivatives/crop/test.jpg"/>')

        expected_source = os.path.join(settings['PATH'], 'tmp/test.jpg')
        expected_destination = os.path.join(settings['OUTPUT_PATH'], 'tmp',
                                            settings['IMAGE_PROCESS_DIR'],
                                            'crop', 'test.jpg')
        expected_image = (expected_source, expected_destination,
                          ['crop 10 20 100 200'])
        expected_calls = [mock.call(expected_image, settings)]

        self.assertEqual(html, expected_content)
        self.assertEqual(expected_calls, process_image.call_args_list)
Example #33
0
    def test_save_as_preservation(self):
        settings = get_settings()
        # fix up pagination rules
        from pelican.paginator import PaginationRule
        pagination_rules = [
            PaginationRule(*r) for r in settings.get(
                'PAGINATION_PATTERNS',
                DEFAULT_CONFIG['PAGINATION_PATTERNS'],
            )
        ]
        settings['PAGINATION_PATTERNS'] = sorted(
            pagination_rules,
            key=lambda r: r[0],
        )

        object_list = [
            Article(**self.page_kwargs),
            Article(**self.page_kwargs)
        ]
        paginator = Paginator('foobar.foo', object_list, settings)
        page = paginator.page(1)
        self.assertEqual(page.save_as, 'foobar.foo')
    def test_intrasite_link_markdown_spaces(self):
        # Markdown introduces %20 instead of spaces, this tests that
        # we support markdown doing this.
        cls_name = '_DummyArticle' if six.PY3 else b'_DummyArticle'
        article = type(cls_name, (object,), {'url': 'article-spaces.html'})

        args = self.page_kwargs.copy()
        args['settings'] = get_settings()
        args['source_path'] = 'content'
        args['context']['filenames'] = {'article spaces.rst': article}

        # An intrasite link via filename with %20 as a space
        args['content'] = (
            'A simple test, with a '
            '<a href="|filename|article%20spaces.rst">link</a>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'A simple test, with a '
            '<a href="http://notmyidea.org/article-spaces.html">link</a>'
        )
Example #35
0
    def test_datetime(self):
        # If DATETIME is set to a tuple, it should be used to override LOCALE
        dt = datetime.datetime(2015, 9, 13)

        page_kwargs = self._copy_page_kwargs()

        # set its date to dt
        page_kwargs['metadata']['date'] = dt
        page = Page(**page_kwargs)

        # page.locale_date is a unicode string in both python2 and python3
        dt_date = dt.strftime(DEFAULT_CONFIG['DEFAULT_DATE_FORMAT'])

        self.assertEqual(page.locale_date, dt_date)
        page_kwargs['settings'] = get_settings()

        # I doubt this can work on all platforms ...
        if platform == "win32":
            locale = 'jpn'
        else:
            locale = 'ja_JP.utf8'
        page_kwargs['settings']['DATE_FORMATS'] = {
            'jp': (locale, '%Y-%m-%d(%a)')
        }
        page_kwargs['metadata']['lang'] = 'jp'

        import locale as locale_module
        try:
            page = Page(**page_kwargs)
            self.assertEqual(page.locale_date, '2015-09-13(\u65e5)')
        except locale_module.Error:
            # The constructor of ``Page`` will try to set the locale to
            # ``ja_JP.utf8``. But this attempt will failed when there is no
            # such locale in the system. You can see which locales there are
            # in your system with ``locale -a`` command.
            #
            # Until we find some other method to test this functionality, we
            # will simply skip this test.
            unittest.skip("There is no locale %s in this system." % locale)
Example #36
0
    def test_generate_ctags(self):
        settings = get_settings(filenames={})
        settings['GENERATE_CTAGS'] = True

        generator = ArticlesGenerator(
            context=settings.copy(), settings=settings,
            path=TEST_CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()

        writer = Writer(None, settings=settings)
        generate_ctags(generator, writer)

        output_path = os.path.join(TEST_CONTENT_DIR, 'tags')
        self.assertTrue(os.path.exists(output_path))

        try:
            # output content is correct
            with open(output_path, 'r') as output_file:
                ctags = [l.split('\t')[0] for l in output_file.readlines()]
                self.assertEqual(['bar', 'bar', 'foo', 'foo', 'foobar', 'foobar', 'マック', 'パイソン'], ctags)
        finally:
            os.remove(output_path)
Example #37
0
    def test_static_exclude_sources(self):
        """Test that StaticGenerator respects STATIC_EXCLUDE_SOURCES.
        """
        # Test STATIC_EXCLUDE_SOURCES=True

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

        for generator_class in (PagesGenerator, StaticGenerator):
            generator_class(context=context, settings=settings,
                path=settings['PATH'], output_path=None,
                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")

        # Test STATIC_EXCLUDE_SOURCES=False

        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=None,
                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")
Example #38
0
    def test_generate_sorted(self):
        settings = get_settings(filenames={})
        settings['PAGE_PATHS'] = ['TestPages']  # relative to CUR_DIR
        settings['CACHE_PATH'] = self.temp_cache
        settings['DEFAULT_DATE'] = (1970, 1, 1)

        # default sort (filename)
        pages_expected_sorted_by_filename = [
            ['This is a test page', 'published', 'page'],
            ['This is a markdown test page', 'published', 'page'],
            ['A Page (Test) for sorting', 'published', 'page'],
            ['Page with a bunch of links', 'published', 'page'],
            ['This is a test page with a preset template', 'published',
             'custom'],
        ]
        generator = PagesGenerator(
            context=settings.copy(), settings=settings,
            path=CUR_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        pages = self.distill_pages(generator.pages)
        self.assertEqual(pages_expected_sorted_by_filename, pages)

        # sort by title
        pages_expected_sorted_by_title = [
            ['A Page (Test) for sorting', 'published', 'page'],
            ['Page with a bunch of links', 'published', 'page'],
            ['This is a markdown test page', 'published', 'page'],
            ['This is a test page', 'published', 'page'],
            ['This is a test page with a preset template', 'published',
             'custom'],
        ]
        settings['PAGE_ORDER_BY'] = 'title'
        generator = PagesGenerator(
            context=settings.copy(), settings=settings,
            path=CUR_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        pages = self.distill_pages(generator.pages)
        self.assertEqual(pages_expected_sorted_by_title, pages)
    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_transforms(self):
        settings = get_settings(IMAGE_PROCESS=self.transforms)

        def test_transform(d, i, tmpdir):
            path, name = os.path.split(i)
            destination = os.path.join(tmpdir, d, name)
            image = (i, destination, settings['IMAGE_PROCESS'][d])

            process_image(image, settings)

            transformed = Image.open(destination)

            expected_path = os.path.join(path, 'results', d, name)
            expected = Image.open(expected_path)

            img_diff = ImageChops.difference(transformed, expected).getbbox()
            self.assertEqual(img_diff, None)

        with temporary_folder() as tmpdir:
            [
                test_transform(d, i, tmpdir) for d in self.transforms
                for i in TEST_IMAGES
            ]
Example #41
0
 def setUpClass(cls):
     cls.temp_path = mkdtemp(prefix="pelicantests.")
     settings = get_settings(filenames={})
     settings["PATH"] = os.path.join(CUR_DIR, "test_data")
     settings["AUTHOR"] = "Me"
     settings["DEFAULT_DATE"] = (1970, 1, 1)
     settings["DEFAULT_CATEGORY"] = "Default"
     settings["FILENAME_METADATA"] = "(?P<slug>[^.]+)"
     settings["PLUGINS"] = [sub_parts]
     settings["CACHE_CONTENT"] = False
     context = settings.copy()
     context["generated_content"] = dict()
     context["static_links"] = set()
     cls.generator = ArticlesGenerator(
         context=context,
         settings=settings,
         path=settings["PATH"],
         theme=settings["THEME"],
         output_path=cls.temp_path,
     )
     cls.generator.generate_context()
     cls.all_articles = list(cls.generator.articles)
     sub_parts.patch_subparts(cls.generator)
Example #42
0
    def test_transforms(self):
        settings = get_settings(IMAGE_PROCESS=self.transforms)
        p = Pelican(settings)
        del images[:]
        with temporary_folder() as tmpdir:
            for d in self.transforms:
                for i in TEST_IMAGES:
                    _, name = os.path.split(i)
                    destination = os.path.join(tmpdir, d, name)
                    images.append(
                        (i, destination, settings['IMAGE_PROCESS'][d]))
            process_images(p)

            for i in images:
                transformed = Image.open(i[1])

                path, name = os.path.split(i[0])
                expected_path = os.path.join(path, 'results', i[2], name)
                expected = Image.open(expected_path)

                self.assertEqual(
                    ImageChops.difference(transformed, expected).getbbox(),
                    None)
Example #43
0
    def test_custom_pagination_pattern(self):
        from pelican.paginator import PaginationRule
        settings = get_settings()
        settings['PAGINATION_PATTERNS'] = [
            PaginationRule(*r)
            for r in [(1, '/{url}', '{base_name}/index.html'),
                      (2, '/{url}{number}/',
                       '{base_name}/{number}/index.html')]
        ]

        self.page_kwargs['metadata']['author'] = Author('Blogger', settings)
        object_list = [
            Article(**self.page_kwargs),
            Article(**self.page_kwargs)
        ]
        paginator = Paginator('blog/index.html', '//blog.my.site/',
                              object_list, settings, 1)
        page1 = paginator.page(1)
        self.assertEqual(page1.save_as, 'blog/index.html')
        self.assertEqual(page1.url, '//blog.my.site/')
        page2 = paginator.page(2)
        self.assertEqual(page2.save_as, 'blog/2/index.html')
        self.assertEqual(page2.url, '//blog.my.site/2/')
    def test_img_handling(self):
        """Check if raw paths are left untouched in output returned."""
        settings = get_settings()

        myst_reader = MySTReader(settings)
        source_path = os.path.join(TEST_CONTENT_PATH, "valid_content_with_image.md")
        output, metadata = myst_reader.read(source_path)

        # Setting this so that assert is able to execute the difference
        self.maxDiff = None  # pylint: disable=invalid-name

        self.assertEqual(
            """
<p>This is file contains a image.</p>
<p><img src="/path/to/title.png" alt="Image alt title" /></p>
<p><a href="https://example.com/link.png"><img src="/path/to/link.png" alt="Image with link" /></a></p>
""",
            output,
        )

        self.assertEqual("Valid Content with Image", str(metadata["title"]))
        self.assertEqual("My Author", str(metadata["author"]))
        self.assertEqual("2020-10-16 00:00:00", str(metadata["date"]))
Example #45
0
    def test_ignore_cache(self):
        """Test that all the pages are read again when not loading cache

        used in --ignore_cache or autoreload mode"""
        settings = get_settings(filenames={})
        settings['CACHE_DIRECTORY'] = self.temp_cache
        settings['READERS'] = {'asc': None}

        generator = PagesGenerator(
            context=settings.copy(), settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.readers.read_file = MagicMock()
        generator.generate_context()
        self.assertTrue(hasattr(generator, '_cache_open'))
        orig_call_count = generator.readers.read_file.call_count

        settings['LOAD_CONTENT_CACHE'] = False
        generator = PagesGenerator(
            context=settings.copy(), settings=settings,
            path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
        generator.readers.read_file = MagicMock()
        generator.generate_context()
        generator.readers.read_file.assert_called_count == orig_call_count
Example #46
0
    def test_page_object_caching(self):
        """Test Page objects caching at the generator level"""
        settings = get_settings(filenames={})
        settings['CACHE_PATH'] = self.temp_cache
        settings['CONTENT_CACHING_LAYER'] = 'generator'
        settings['READERS'] = {'asc': None}

        generator = PagesGenerator(context=settings.copy(),
                                   settings=settings,
                                   path=CONTENT_DIR,
                                   theme=settings['THEME'],
                                   output_path=None)
        generator.generate_context()
        self.assertTrue(hasattr(generator, '_cache'))

        generator = PagesGenerator(context=settings.copy(),
                                   settings=settings,
                                   path=CONTENT_DIR,
                                   theme=settings['THEME'],
                                   output_path=None)
        generator.readers.read_file = MagicMock()
        generator.generate_context()
        generator.readers.read_file.assert_called_count == 0
Example #47
0
    def test_get_content(self):
        # Test that the content is updated with the relative links to
        # filenames, tags and categories.
        settings = get_settings()
        args = self.page_kwargs.copy()
        args['settings'] = settings

        # Tag
        args['content'] = ('A simple test, with a '
                           '<a href="|tag|tagname">link</a>')
        page = Page(**args)
        content = page.get_content('http://notmyidea.org')
        self.assertEqual(content, ('A simple test, with a '
                                   '<a href="tag/tagname.html">link</a>'))

        # Category
        args['content'] = ('A simple test, with a '
                           '<a href="|category|category">link</a>')
        page = Page(**args)
        content = page.get_content('http://notmyidea.org')
        self.assertEqual(content,
                         ('A simple test, with a '
                          '<a href="category/category.html">link</a>'))
Example #48
0
 def setUpClass(cls):
     cls.temp_path = mkdtemp(prefix='pelicantests.')
     settings = get_settings(filenames={})
     settings['PATH'] = os.path.join(CUR_DIR, 'test_data')
     settings['AUTHOR'] = 'Me'
     settings['DEFAULT_DATE'] = (1970, 1, 1)
     settings['DEFAULT_CATEGORY'] = 'Default'
     settings['FILENAME_METADATA'] = '(?P<slug>[^.]+)'
     settings['PLUGINS'] = [sub_parts]
     settings['CACHE_CONTENT'] = False
     context = settings.copy()
     context['generated_content'] = dict()
     context['static_links'] = set()
     cls.generator = ArticlesGenerator(context=context,
                                       settings=settings,
                                       path=settings['PATH'],
                                       theme=settings['THEME'],
                                       output_path=cls.temp_path)
     cls.generator.generate_context()
     cls.all_articles = list(cls.generator.articles)
     for a in cls.all_articles:
         a.photo_gallery = [('i.jpg', 'i.jpg', 'it.jpg', '', '')]
     sub_parts.patch_subparts(cls.generator)
Example #49
0
    def test_standard_metadata_in_default_metadata(self):
        settings = get_settings(filenames={})
        settings['CACHE_CONTENT'] = False
        settings['DEFAULT_CATEGORY'] = 'Default'
        settings['DEFAULT_DATE'] = (1970, 1, 1)
        settings['DEFAULT_METADATA'] = (
            ('author', 'Blogger'),
            # category will be ignored in favor of
            # DEFAULT_CATEGORY
            ('category', 'Random'),
            ('tags', 'general, untagged'))
        generator = ArticlesGenerator(context=settings.copy(),
                                      settings=settings,
                                      path=CONTENT_DIR,
                                      theme=settings['THEME'],
                                      output_path=None)
        generator.generate_context()

        authors = sorted([author.name for author, _ in generator.authors])
        authors_expected = sorted([
            'Alexis Métaireau', 'Blogger', 'Author, First', 'Author, Second',
            'First Author', 'Second Author'
        ])
        self.assertEqual(authors, authors_expected)

        categories = sorted(
            [category.name for category, _ in generator.categories])
        categories_expected = [
            sorted(['Default', 'TestCategory', 'yeah', 'test', '指導書']),
            sorted(['Default', 'TestCategory', 'Yeah', 'test', '指導書'])
        ]
        self.assertIn(categories, categories_expected)

        tags = sorted([tag.name for tag in generator.tags])
        tags_expected = sorted(
            ['bar', 'foo', 'foobar', 'general', 'untagged', 'パイソン', 'マック'])
        self.assertEqual(tags, tags_expected)
Example #50
0
 def test_article_with_footnote(self):
     reader = readers.MarkdownReader(settings=get_settings())
     content, metadata = reader.read(
         _path('article_with_markdown_and_footnote.md'))
     expected_content = (
         '<p>This is some content'
         '<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" '
         'rel="footnote">1</a></sup>'
         ' with some footnotes'
         '<sup id="fnref:footnote"><a class="footnote-ref" '
         'href="#fn:footnote" rel="footnote">2</a></sup></p>\n'
         '<div class="footnote">\n'
         '<hr />\n<ol>\n<li id="fn:1">\n'
         '<p>Numbered footnote&#160;'
         '<a class="footnote-backref" href="#fnref:1" rev="footnote" '
         'title="Jump back to footnote 1 in the text">&#8617;</a></p>\n'
         '</li>\n<li id="fn:footnote">\n'
         '<p>Named footnote&#160;'
         '<a class="footnote-backref" href="#fnref:footnote" rev="footnote"'
         ' title="Jump back to footnote 2 in the text">&#8617;</a></p>\n'
         '</li>\n</ol>\n</div>')
     expected_metadata = {
         'title':
         'Article with markdown containing footnotes',
         'summary': ('<p>Summary with <strong>inline</strong> markup '
                     '<em>should</em> be supported.</p>'),
         'date':
         datetime.datetime(2012, 10, 31),
         'modified':
         datetime.datetime(2012, 11, 1),
         'slug':
         'article-with-markdown-containing-footnotes',
     }
     self.assertEqual(content, expected_content)
     for key, value in metadata.items():
         self.assertEqual(value, expected_metadata[key], key)
    def test_valid_file_with_valid_defaults(self):
        """Check if we get the appropriate output specifying defaults."""
        pandoc_default_files = [
            os.path.join(TEST_DEFAULT_FILES_PATH, "valid_defaults.yaml")
        ]

        settings = get_settings(PANDOC_DEFAULT_FILES=pandoc_default_files)

        pandoc_reader = PandocReader(settings)

        source_path = os.path.join(TEST_CONTENT_PATH, "valid_content.md")
        output, metadata = pandoc_reader.read(source_path)

        self.assertEqual(
            (
                "<p>This is some valid content that should pass."
                " If it does not pass we will know something is wrong.</p>"
            ),
            output,
        )

        self.assertEqual("Valid Content", str(metadata["title"]))
        self.assertEqual("My Author", str(metadata["author"]))
        self.assertEqual("2020-10-16 00:00:00", str(metadata["date"]))
Example #52
0
    def test_generate_context(self):
        settings = get_settings(filenames={})
        settings['CACHE_PATH'] = self.temp_cache
        settings['PAGE_PATHS'] = ['TestPages']  # relative to CUR_DIR
        settings['DEFAULT_DATE'] = (1970, 1, 1)

        generator = PagesGenerator(
            context=settings.copy(), settings=settings,
            path=CUR_DIR, theme=settings['THEME'], output_path=None)
        generator.generate_context()
        pages = self.distill_pages(generator.pages)
        hidden_pages = self.distill_pages(generator.hidden_pages)

        pages_expected = [
            ['This is a test page', 'published', 'page'],
            ['This is a markdown test page', 'published', 'page'],
            ['This is a test page with a preset template', 'published',
             'custom'],
            ['Page with a bunch of links', 'published', 'page'],
            ['A Page (Test) for sorting', 'published', 'page'],
        ]
        hidden_pages_expected = [
            ['This is a test hidden page', 'hidden', 'page'],
            ['This is a markdown test hidden page', 'hidden', 'page'],
            ['This is a test hidden page with a custom template', 'hidden',
             'custom']
        ]

        self.assertEqual(sorted(pages_expected), sorted(pages))
        self.assertEqual(
            sorted(pages_expected),
            sorted(self.distill_pages(generator.context['pages'])))
        self.assertEqual(sorted(hidden_pages_expected), sorted(hidden_pages))
        self.assertEqual(
            sorted(hidden_pages_expected),
            sorted(self.distill_pages(generator.context['hidden_pages'])))
Example #53
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/'],
            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")))
Example #54
0
    def test_relative_source_path(self):
        # 'relative_source_path' should be the relative path
        # from 'PATH' to 'source_path'
        page_kwargs = self._copy_page_kwargs()

        # If 'source_path' is None, 'relative_source_path' should
        # also return None
        page_kwargs['source_path'] = None
        page = Page(**page_kwargs)
        self.assertIsNone(page.relative_source_path)

        page_kwargs = self._copy_page_kwargs()
        settings = get_settings()
        full_path = page_kwargs['source_path']

        settings['PATH'] = os.path.dirname(full_path)
        page_kwargs['settings'] = settings
        page = Page(**page_kwargs)

        # if 'source_path' is set, 'relative_source_path' should
        # return the relative path from 'PATH' to 'source_path'
        self.assertEqual(
            page.relative_source_path,
            os.path.relpath(full_path, os.path.dirname(full_path)))
Example #55
0
    def test_intrasite_link_source_and_generated(self):
        """Test linking both to the source and the generated article
        """
        cls_name = '_DummyAsset'

        args = self.page_kwargs.copy()
        args['settings'] = get_settings()
        args['source_path'] = 'content'
        args['context']['generated_content'] = {
            'article.rst': type(cls_name, (object, ), {'url': 'article.html'})
        }
        args['context']['static_content'] = {
            'article.rst': type(cls_name, (object, ), {'url': 'article.rst'})
        }

        args['content'] = (
            'A simple test, with a link to an'
            '<a href="{filename}article.rst">article</a> and its'
            '<a href="{static}article.rst">source</a>')
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content, 'A simple test, with a link to an'
            '<a href="http://notmyidea.org/article.html">article</a> and its'
            '<a href="http://notmyidea.org/article.rst">source</a>')
Example #56
0
    def test_empty_file_with_bom(self):
        reader = readers.MarkdownReader(settings=get_settings())
        content, metadata = reader.read(_path('empty_with_bom.md'))

        self.assertEqual(metadata, {})
        self.assertEqual(content, '')
Example #57
0
    def read_file(self, path, **kwargs):
        # Isolate from future API changes to readers.read_file

        r = readers.Readers(settings=get_settings(**kwargs))
        return r.read_file(base_path=CONTENT_PATH, path=path)
Example #58
0
    def test_intrasite_link_more(self):
        # type does not take unicode in PY2 and bytes in PY3, which in
        # combination with unicode literals leads to following insane line:
        cls_name = '_DummyAsset' if six.PY3 else b'_DummyAsset'

        args = self.page_kwargs.copy()
        args['settings'] = get_settings()
        args['source_path'] = 'content'
        args['context']['filenames'] = {
            'images/poster.jpg': type(
                cls_name, (object,), {'url': 'images/poster.jpg'}),
            'assets/video.mp4': type(
                cls_name, (object,), {'url': 'assets/video.mp4'}),
            'images/graph.svg': type(
                cls_name, (object,), {'url': 'images/graph.svg'}),
            'reference.rst': type(
                cls_name, (object,), {'url': 'reference.html'}),
        }

        # video.poster
        args['content'] = (
            'There is a video with poster '
            '<video controls poster="{filename}/images/poster.jpg">'
            '<source src="|filename|/assets/video.mp4" type="video/mp4">'
            '</video>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'There is a video with poster '
            '<video controls poster="http://notmyidea.org/images/poster.jpg">'
            '<source src="http://notmyidea.org/assets/video.mp4"'
            ' type="video/mp4">'
            '</video>'
        )

        # object.data
        args['content'] = (
            'There is a svg object '
            '<object data="{filename}/images/graph.svg"'
            ' type="image/svg+xml">'
            '</object>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'There is a svg object '
            '<object data="http://notmyidea.org/images/graph.svg"'
            ' type="image/svg+xml">'
            '</object>'
        )

        # blockquote.cite
        args['content'] = (
            'There is a blockquote with cite attribute '
            '<blockquote cite="{filename}reference.rst">blah blah</blockquote>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'There is a blockquote with cite attribute '
            '<blockquote cite="http://notmyidea.org/reference.html">'
            'blah blah'
            '</blockquote>'
        )
Example #59
0
    def test_intrasite_link(self):
        # type does not take unicode in PY2 and bytes in PY3, which in
        # combination with unicode literals leads to following insane line:
        cls_name = '_DummyArticle' if six.PY3 else b'_DummyArticle'
        article = type(cls_name, (object,), {'url': 'article.html'})

        args = self.page_kwargs.copy()
        args['settings'] = get_settings()
        args['source_path'] = 'content'
        args['context']['filenames'] = {'article.rst': article}

        # Classic intrasite link via filename
        args['content'] = (
            'A simple test, with a '
            '<a href="|filename|article.rst">link</a>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'A simple test, with a '
            '<a href="http://notmyidea.org/article.html">link</a>'
        )

        # fragment
        args['content'] = (
            'A simple test, with a '
            '<a href="|filename|article.rst#section-2">link</a>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'A simple test, with a '
            '<a href="http://notmyidea.org/article.html#section-2">link</a>'
        )

        # query
        args['content'] = (
            'A simple test, with a '
            '<a href="|filename|article.rst'
            '?utm_whatever=234&highlight=word">link</a>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'A simple test, with a '
            '<a href="http://notmyidea.org/article.html'
            '?utm_whatever=234&highlight=word">link</a>'
        )

        # combination
        args['content'] = (
            'A simple test, with a '
            '<a href="|filename|article.rst'
            '?utm_whatever=234&highlight=word#section-2">link</a>'
        )
        content = Page(**args).get_content('http://notmyidea.org')
        self.assertEqual(
            content,
            'A simple test, with a '
            '<a href="http://notmyidea.org/article.html'
            '?utm_whatever=234&highlight=word#section-2">link</a>'
        )

        # also test for summary in metadata
        args['metadata']['summary'] = (
            'A simple summary test, with a '
            '<a href="|filename|article.rst">link</a>'
        )
        args['context']['localsiteurl'] = 'http://notmyidea.org'
        p = Page(**args)
        self.assertEqual(
            p.summary,
            'A simple summary test, with a '
            '<a href="http://notmyidea.org/article.html">link</a>'
        )
Example #60
0
    def test_period_in_timeperiod_archive(self):
        """
        Test that the context of a generated period_archive is passed
        'period' : a tuple of year, month, day according to the time period
        """
        old_locale = locale.setlocale(locale.LC_ALL)
        locale.setlocale(locale.LC_ALL, str('C'))
        settings = get_settings(filenames={})

        settings['YEAR_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/index.html'
        settings['YEAR_ARCHIVE_URL'] = 'posts/{date:%Y}/'
        settings['CACHE_PATH'] = self.temp_cache
        generator = ArticlesGenerator(context=settings,
                                      settings=settings,
                                      path=CONTENT_DIR,
                                      theme=settings['THEME'],
                                      output_path=None)
        generator.generate_context()
        write = MagicMock()
        generator.generate_period_archives(write)
        dates = [d for d in generator.dates if d.date.year == 1970]
        self.assertEqual(len(dates), 1)
        # among other things it must have at least been called with this
        settings["period"] = (1970, )
        write.assert_called_with("posts/1970/index.html",
                                 generator.get_template("period_archives"),
                                 settings,
                                 blog=True,
                                 dates=dates,
                                 url="posts/1970/")

        del settings["period"]
        settings['MONTH_ARCHIVE_SAVE_AS'] = \
            'posts/{date:%Y}/{date:%b}/index.html'
        settings['MONTH_ARCHIVE_URL'] = \
            'posts/{date:%Y}/{date:%b}/'
        generator = ArticlesGenerator(context=settings,
                                      settings=settings,
                                      path=CONTENT_DIR,
                                      theme=settings['THEME'],
                                      output_path=None)
        generator.generate_context()
        write = MagicMock()
        generator.generate_period_archives(write)
        dates = [
            d for d in generator.dates
            if d.date.year == 1970 and d.date.month == 1
        ]
        self.assertEqual(len(dates), 1)
        settings["period"] = (1970, "January")
        # among other things it must have at least been called with this
        write.assert_called_with("posts/1970/Jan/index.html",
                                 generator.get_template("period_archives"),
                                 settings,
                                 blog=True,
                                 dates=dates,
                                 url="posts/1970/Jan/")

        del settings["period"]
        settings['DAY_ARCHIVE_SAVE_AS'] = \
            'posts/{date:%Y}/{date:%b}/{date:%d}/index.html'
        settings['DAY_ARCHIVE_URL'] = \
            'posts/{date:%Y}/{date:%b}/{date:%d}/'
        generator = ArticlesGenerator(context=settings,
                                      settings=settings,
                                      path=CONTENT_DIR,
                                      theme=settings['THEME'],
                                      output_path=None)
        generator.generate_context()
        write = MagicMock()
        generator.generate_period_archives(write)
        dates = [
            d for d in generator.dates
            if d.date.year == 1970 and d.date.month == 1 and d.date.day == 1
        ]
        self.assertEqual(len(dates), 1)
        settings["period"] = (1970, "January", 1)
        # among other things it must have at least been called with this
        write.assert_called_with("posts/1970/Jan/01/index.html",
                                 generator.get_template("period_archives"),
                                 settings,
                                 blog=True,
                                 dates=dates,
                                 url="posts/1970/Jan/01/")
        locale.setlocale(locale.LC_ALL, old_locale)