diff --git a/test/helper.rb b/test/helper.rb index 7b1a2b4b..3ec9d75c 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -262,3 +262,35 @@ module TestWEBrick ) end end + +class TagUnitTest < JekyllUnitTest + def render_content(content, override = {}) + base_config = { + "source" => source_dir, + "destination" => dest_dir, + } + site = fixture_site(base_config.merge(override)) + + if override["read_posts"] + site.posts.docs.concat(PostReader.new(site).read_posts("")) + elsif override["read_collections"] + CollectionReader.new(site).read + elsif override["read_all"] + site.read + end + + @result = render_with(site, content) + end + + private + + def render_with(site, content) + converter = site.converters.find { |c| c.instance_of?(Jekyll::Converters::Markdown) } + payload = { "highlighter_prefix" => converter.highlighter_prefix, + "highlighter_suffix" => converter.highlighter_suffix, } + info = { :registers => { :site => site } } + converter.convert( + Liquid::Template.parse(content).render!(payload, info) + ) + end +end diff --git a/test/test_tag_highlight.rb b/test/test_tag_highlight.rb new file mode 100644 index 00000000..14a3bdee --- /dev/null +++ b/test/test_tag_highlight.rb @@ -0,0 +1,302 @@ +# frozen_string_literal: true + +require "helper" + +class TestTagHighlight < TagUnitTest + def render_content_with_text_to_highlight(code) + content = <<~CONTENT + --- + title: This is a test + --- + + This document has some highlighted code in it. + + {% highlight text %} + #{code} + {% endhighlight %} + + {% highlight text linenos %} + #{code} + {% endhighlight %} + CONTENT + render_content(content) + end + + # Syntax sugar for low-level version of: + # ``` + # {% highlight markup%}test{% endhighlight %} + # ``` + def highlight_block_with_markup(markup) + Jekyll::Tags::HighlightBlock.parse( + "highlight", + markup, + Liquid::Tokenizer.new("test{% endhighlight %}\n"), + Liquid::ParseContext.new + ) + end + + context "language name" do + should "match only the required set of chars" do + r = Jekyll::Tags::HighlightBlock::SYNTAX + [ + "ruby", + "c#", + "xml+cheetah", + "x.y", + "coffee-script", + "shell_session", + "ruby key=val", + "ruby a=b c=d", + ].each { |sample| assert_match(r, sample) } + + refute_match r, "blah^" + end + end + + context "highlight tag in unsafe mode" do + should "set the no options with just a language name" do + tag = highlight_block_with_markup("ruby ") + assert_equal({}, tag.instance_variable_get(:@highlight_options)) + end + + should "set the linenos option as 'inline' if no linenos value" do + tag = highlight_block_with_markup("ruby linenos ") + assert_equal( + { :linenos => "inline" }, + tag.instance_variable_get(:@highlight_options) + ) + end + + should "set the linenos option to 'table' " \ + "if the linenos key is given the table value" do + tag = highlight_block_with_markup("ruby linenos=table ") + assert_equal( + { :linenos => "table" }, + tag.instance_variable_get(:@highlight_options) + ) + end + + should "recognize nowrap option with linenos set" do + tag = highlight_block_with_markup("ruby linenos=table nowrap ") + assert_equal( + { :linenos => "table", :nowrap => true }, + tag.instance_variable_get(:@highlight_options) + ) + end + + should "recognize the cssclass option" do + tag = highlight_block_with_markup("ruby linenos=table cssclass=hl ") + assert_equal( + { :cssclass => "hl", :linenos => "table" }, + tag.instance_variable_get(:@highlight_options) + ) + end + + should "recognize the hl_linenos option and its value" do + tag = highlight_block_with_markup("ruby linenos=table cssclass=hl hl_linenos=3 ") + assert_equal( + { :cssclass => "hl", :linenos => "table", :hl_linenos => "3" }, + tag.instance_variable_get(:@highlight_options) + ) + end + + should "recognize multiple values of hl_linenos" do + tag = highlight_block_with_markup 'ruby linenos=table cssclass=hl hl_linenos="3 5 6" ' + assert_equal( + { :cssclass => "hl", :linenos => "table", :hl_linenos => %w(3 5 6) }, + tag.instance_variable_get(:@highlight_options) + ) + end + + should "treat language name as case insensitive" do + tag = highlight_block_with_markup("Ruby ") + assert_equal "ruby", tag.instance_variable_get(:@lang), "lexers should be case insensitive" + end + end + + context "with the rouge highlighter" do + context "post content has highlight tag" do + setup do + render_content_with_text_to_highlight "test" + end + + should "render markdown with rouge" do + assert_match( + %(
test
),
+ @result
+ )
+ end
+
+ should "render markdown with rouge with line numbers" do
+ assert_match(
+ %() +
+ %(1\n | ) +
+ %(test\n |
' \
+ "./jekyll.gemspec
",
+ @result
+ )
+ end
+ end
+
+ context "post content has highlight tag with UTF character" do
+ setup do
+ render_content_with_text_to_highlight "Æ"
+ end
+
+ should "render markdown with pygments line handling" do
+ assert_match(
+ 'Æ
',
+ @result
+ )
+ end
+ end
+
+ context "post content has highlight tag with preceding spaces & lines" do
+ setup do
+ render_content_with_text_to_highlight <<~EOS
+
+
+ [,1] [,2]
+ [1,] FALSE TRUE
+ [2,] FALSE TRUE
+ EOS
+ end
+
+ should "only strip the preceding newlines" do
+ assert_match(
+ ' [,1] [,2]',
+ @result
+ )
+ end
+ end
+
+ context "post content has highlight tag with preceding spaces & lines in several places" do
+ setup do
+ render_content_with_text_to_highlight <<~EOS
+
+
+ [,1] [,2]
+
+
+ [1,] FALSE TRUE
+ [2,] FALSE TRUE
+
+
+ EOS
+ end
+
+ should "only strip the newlines which precede and succeed the entire block" do
+ assert_match(
+ " [,1] [,2]\n\n\n" \
+ "[1,] FALSE TRUE\n[2,] FALSE TRUE
",
+ @result
+ )
+ end
+ end
+
+ context "post content has highlight tag with linenumbers" do
+ setup do
+ render_content <<~EOS
+ ---
+ title: This is a test
+ ---
+
+ This is not yet highlighted
+ {% highlight php linenos %}
+ test
+ {% endhighlight %}
+
+ This should not be highlighted, right?
+ EOS
+ end
+
+ should "should stop highlighting at boundary with rouge" do
+ expected = <<~EOS
+ This is not yet highlighted
+
+ 1
+
test
+
+
+ This should not be highlighted, right?
+ EOS
+ assert_match(expected, @result)
+ end
+ end
+
+ context "post content has highlight tag with " \
+ "preceding spaces & Windows-style newlines" do
+ setup do
+ render_content_with_text_to_highlight "\r\n\r\n\r\n [,1] [,2]"
+ end
+
+ should "only strip the preceding newlines" do
+ assert_match(
+ ' [,1] [,2]',
+ @result
+ )
+ end
+ end
+
+ context "post content has highlight tag with only preceding spaces" do
+ setup do
+ render_content_with_text_to_highlight <<~EOS
+ [,1] [,2]
+ [1,] FALSE TRUE
+ [2,] FALSE TRUE
+ EOS
+ end
+
+ should "only strip the preceding newlines" do
+ assert_match(
+ ' [,1] [,2]',
+ @result
+ )
+ end
+ end
+ end
+
+ context "simple post with markdown and pre tags" do
+ setup do
+ @content = <<~CONTENT
+ ---
+ title: Kramdown post with pre
+ ---
+
+ _FIGHT!_
+
+ {% highlight ruby %}
+ puts "3..2..1.."
+ {% endhighlight %}
+
+ *FINISH HIM*
+ CONTENT
+ end
+
+ context "using Kramdown" do
+ setup do
+ render_content(@content, "markdown" => "kramdown")
+ end
+
+ should "parse correctly" do
+ assert_match %r{FIGHT!}, @result
+ assert_match %r!FINISH HIM!, @result
+ end
+ end
+ end
+end
diff --git a/test/test_tag_include.rb b/test/test_tag_include.rb
new file mode 100644
index 00000000..59fbb17f
--- /dev/null
+++ b/test/test_tag_include.rb
@@ -0,0 +1,310 @@
+# frozen_string_literal: true
+
+require "helper"
+
+class TestTagInclude < TagUnitTest
+ context "include tag with parameters" do
+ context "with symlink'd include" do
+ should "not allow symlink includes" do
+ FileUtils.mkdir_p("tmp")
+ File.write("tmp/pages-test", "SYMLINK TEST")
+ assert_raises IOError do
+ content = <<~CONTENT
+ ---
+ title: Include symlink
+ ---
+
+ {% include tmp/pages-test %}
+
+ CONTENT
+ render_content(content, "safe" => true)
+ end
+ @result ||= ""
+ refute_match(%r!SYMLINK TEST!, @result)
+ end
+
+ should "not expose the existence of symlinked files" do
+ ex = assert_raises IOError do
+ content = <<~CONTENT
+ ---
+ title: Include symlink
+ ---
+
+ {% include tmp/pages-test-does-not-exist %}
+
+ CONTENT
+ render_content(content, "safe" => true)
+ end
+ assert_match(
+ "Could not locate the included file 'tmp/pages-test-does-not-exist' in any of " \
+ "[\"#{source_dir}/_includes\"]. Ensure it exists in one of those directories and is " \
+ "not a symlink as those are not allowed in safe mode.",
+ ex.message
+ )
+ end
+ end
+
+ context "with one parameter" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: Include tag parameters
+ ---
+
+ {% include sig.markdown myparam="test" %}
+
+ {% include params.html param="value" %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "correctly output include variable" do
+ assert_match "value", @result.strip
+ end
+
+ should "ignore parameters if unused" do
+ assert_match "
\nTom Preston-Werner\ngithub.com/mojombo
\n", @result
+ end
+ end
+
+ context "with simple syntax but multiline markup" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: Include tag parameters
+ ---
+
+ {% include sig.markdown myparam="test" %}
+
+ {% include params.html
+ param="value" %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "correctly output include variable" do
+ assert_match "value", @result.strip
+ end
+
+ should "ignore parameters if unused" do
+ assert_match "
\nTom Preston-Werner\ngithub.com/mojombo
\n", @result
+ end
+ end
+
+ context "with variable syntax but multiline markup" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: Include tag parameters
+ ---
+
+ {% include sig.markdown myparam="test" %}
+ {% assign path = "params" | append: ".html" %}
+ {% include {{ path }}
+ param="value" %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "correctly output include variable" do
+ assert_match "value", @result.strip
+ end
+
+ should "ignore parameters if unused" do
+ assert_match "
\nTom Preston-Werner\ngithub.com/mojombo
\n", @result
+ end
+ end
+
+ context "with invalid parameter syntax" do
+ should "throw a ArgumentError" do
+ content = <<~CONTENT
+ ---
+ title: Invalid parameter syntax
+ ---
+
+ {% include params.html param s="value" %}
+ CONTENT
+ assert_raises ArgumentError, %(Did not raise exception on invalid "include" syntax) do
+ render_content(content)
+ end
+
+ content = <<~CONTENT
+ ---
+ title: Invalid parameter syntax
+ ---
+
+ {% include params.html params="value %}
+ CONTENT
+ assert_raises ArgumentError, %(Did not raise exception on invalid "include" syntax) do
+ render_content(content)
+ end
+ end
+ end
+
+ context "with several parameters" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: multiple include parameters
+ ---
+
+ {% include params.html param1="new_value" param2="another" %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "list all parameters" do
+ assert_match "param1 = new_value ", @result
+ assert_match "param2 = another ", @result
+ end
+
+ should "not include previously used parameters" do
+ assert_match "", @result
+ end
+ end
+
+ context "without parameters" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: without parameters
+ ---
+
+ {% include params.html %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "include file with empty parameters" do
+ assert_match "", @result
+ end
+ end
+
+ context "with include file with special characters without params" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: special characters
+ ---
+
+ {% include params@2.0.html %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "include file with empty parameters" do
+ assert_match "", @result
+ end
+ end
+
+ context "with include file with special characters with params" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: special characters
+ ---
+
+ {% include params@2.0.html param1="foobar" param2="bazbar" %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "include file with empty parameters" do
+ assert_match "param1 = foobar ", @result
+ assert_match "param2 = bazbar ", @result
+ end
+ end
+
+ context "with custom includes directory" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: custom includes directory
+ ---
+
+ {% include custom.html %}
+ CONTENT
+
+ render_content(content, "includes_dir" => "_includes_custom")
+ end
+
+ should "include file from custom directory" do
+ assert_match "custom_included", @result
+ end
+ end
+
+ context "without parameters within if statement" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: without parameters within if statement
+ ---
+
+ {% if true %}{% include params.html %}{% endif %}
+ CONTENT
+ render_content(content)
+ end
+
+ should "include file with empty parameters within if statement" do
+ assert_match "", @result
+ end
+ end
+
+ context "include missing file" do
+ setup do
+ @content = <<~CONTENT
+ ---
+ title: missing file
+ ---
+
+ {% include missing.html %}
+ CONTENT
+ end
+
+ should "raise error relative to source directory" do
+ exception = assert_raises IOError do
+ render_content(@content)
+ end
+ assert_match(
+ "Could not locate the included file 'missing.html' in any of " \
+ "[\"#{source_dir}/_includes\"].",
+ exception.message
+ )
+ end
+ end
+
+ context "include tag with variable and liquid filters" do
+ setup do
+ site = fixture_site.tap do |s|
+ s.read
+ s.render
+ end
+ post = site.posts.docs.find do |p|
+ p.basename.eql? "2013-12-17-include-variable-filters.markdown"
+ end
+ @content = post.output
+ end
+
+ should "include file as variable with liquid filters" do
+ assert_match(%r!1 included!, @content)
+ assert_match(%r!2 included!, @content)
+ assert_match(%r!3 included!, @content)
+ end
+
+ should "include file as variable and liquid filters with arbitrary whitespace" do
+ assert_match(%r!4 included!, @content)
+ assert_match(%r!5 included!, @content)
+ assert_match(%r!6 included!, @content)
+ end
+
+ should "include file as variable and filters with additional parameters" do
+ assert_match("var1 = foo ", @content)
+ assert_match("var2 = bar ", @content)
+ end
+
+ should "include file as partial variable" do
+ assert_match(%r!8 included!, @content)
+ end
+ end
+ end
+end
diff --git a/test/test_tag_include_relative.rb b/test/test_tag_include_relative.rb
new file mode 100644
index 00000000..a378c418
--- /dev/null
+++ b/test/test_tag_include_relative.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+
+require "helper"
+
+class TestTagIncludeRelative < TagUnitTest
+ context "include_relative tag with variable and liquid filters" do
+ setup do
+ site = fixture_site.tap do |s|
+ s.read
+ s.render
+ end
+
+ post = site.posts.docs.find do |p|
+ p.basename.eql? "2014-09-02-relative-includes.markdown"
+ end
+
+ @content = post.output
+ end
+
+ should "include file as variable with liquid filters" do
+ assert_match(%r!1 relative_include!, @content)
+ assert_match(%r!2 relative_include!, @content)
+ assert_match(%r!3 relative_include!, @content)
+ end
+
+ should "include file as variable and liquid filters with arbitrary whitespace" do
+ assert_match(%r!4 relative_include!, @content)
+ assert_match(%r!5 relative_include!, @content)
+ assert_match(%r!6 relative_include!, @content)
+ end
+
+ should "include file as variable and filters with additional parameters" do
+ assert_match("var1 = foo ", @content)
+ assert_match("var2 = bar ", @content)
+ end
+
+ should "include file as partial variable" do
+ assert_match(%r!8 relative_include!, @content)
+ end
+
+ should "include files relative to self" do
+ assert_match(%r!9 —\ntitle: Test Post Where YAML!, @content)
+ end
+
+ context "trying to do bad stuff" do
+ context "include missing file" do
+ setup do
+ @content = <<~CONTENT
+ ---
+ title: missing file
+ ---
+
+ {% include_relative missing.html %}
+ CONTENT
+ end
+
+ should "raise error relative to source directory" do
+ exception = assert_raises(IOError) { render_content(@content) }
+ assert_match "Could not locate the included file 'missing.html' in any of " \
+ "[\"#{source_dir}\"].", exception.message
+ end
+ end
+
+ context "include existing file above you" do
+ setup do
+ @content = <<~CONTENT
+ ---
+ title: higher file
+ ---
+
+ {% include_relative ../README.markdown %}
+ CONTENT
+ end
+
+ should "raise error relative to source directory" do
+ exception = assert_raises(ArgumentError) { render_content(@content) }
+ assert_equal(
+ "Invalid syntax for include tag. File contains invalid characters or " \
+ "sequences:\n\n ../README.markdown\n\nValid syntax:\n\n " \
+ "{% include_relative file.ext param='value' param2='value' %}\n\n",
+ exception.message
+ )
+ end
+ end
+ end
+
+ context "with symlink'd include" do
+ should "not allow symlink includes" do
+ FileUtils.mkdir_p("tmp")
+ File.write("tmp/pages-test", "SYMLINK TEST")
+ assert_raises IOError do
+ content = <<~CONTENT
+ ---
+ title: Include symlink
+ ---
+
+ {% include_relative tmp/pages-test %}
+
+ CONTENT
+ render_content(content, "safe" => true)
+ end
+ @result ||= ""
+ refute_match(%r!SYMLINK TEST!, @result)
+ end
+
+ should "not expose the existence of symlinked files" do
+ exception = assert_raises IOError do
+ content = <<~CONTENT
+ ---
+ title: Include symlink
+ ---
+
+ {% include_relative tmp/pages-test-does-not-exist %}
+
+ CONTENT
+ render_content(content, "safe" => true)
+ end
+ assert_match(
+ "Ensure it exists in one of those directories and is not a symlink " \
+ "as those are not allowed in safe mode.",
+ exception.message
+ )
+ end
+ end
+ end
+end
diff --git a/test/test_tag_link.rb b/test/test_tag_link.rb
new file mode 100644
index 00000000..e0d2a714
--- /dev/null
+++ b/test/test_tag_link.rb
@@ -0,0 +1,206 @@
+# frozen_string_literal: true
+
+require "helper"
+
+class TestTagLink < TagUnitTest
+ def render_content_with_collection(content, collection_label)
+ render_content(
+ content,
+ "collections" => { collection_label => { "output" => true } },
+ "read_collections" => true
+ )
+ end
+
+ context "post content has raw tag" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: This is a test
+ ---
+
+ ```liquid
+ {% raw %}
+ {% link _collection/name-of-document.md %}
+ {% endraw %}
+ ```
+ CONTENT
+ render_content(content)
+ end
+
+ should "render markdown with rouge" do
+ assert_match(
+ %() +
+ %(),
+ @result
+ )
+ end
+ end
+
+ context "simple page with linking to a page" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: linking
+ ---
+
+ {% link contacts.html %}
+ {% link info.md %}
+ {% link /css/screen.css %}
+ CONTENT
+ render_content(content, "read_all" => true)
+ end
+
+ should "not cause an error" do
+ refute_match(%r!markdown-html-error!, @result)
+ end
+
+ should "have the URL to the 'contacts' item" do
+ assert_match(%r!/contacts\.html!, @result)
+ end
+
+ should "have the URL to the 'info' item" do
+ assert_match(%r!/info\.html!, @result)
+ end
+
+ should "have the URL to the 'screen.css' item" do
+ assert_match(%r!/css/screen\.css!, @result)
+ end
+ end
+
+ context "simple page with dynamic linking to a page" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: linking
+ ---
+
+ {% assign contacts_filename = 'contacts' %}
+ {% assign contacts_ext = 'html' %}
+ {% link {{contacts_filename}}.{{contacts_ext}} %}
+ {% assign info_path = 'info.md' %}
+ {% link {{\ info_path\ }} %}
+ {% assign screen_css_path = '/css' %}
+ {% link {{ screen_css_path }}/screen.css %}
+ CONTENT
+ render_content(content, "read_all" => true)
+ end
+
+ should "not cause an error" do
+ refute_match(%r!markdown-html-error!, @result)
+ end
+
+ should "have the URL to the 'contacts' item" do
+ assert_match(%r!/contacts\.html!, @result)
+ end
+
+ should "have the URL to the 'info' item" do
+ assert_match(%r!/info\.html!, @result)
+ end
+
+ should "have the URL to the 'screen.css' item" do
+ assert_match(%r!/css/screen\.css!, @result)
+ end
+ end
+
+ context "simple page with linking" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: linking
+ ---
+
+ {% link _methods/yaml_with_dots.md %}
+ CONTENT
+ render_content_with_collection(content, "methods")
+ end
+
+ should "not cause an error" do
+ refute_match(%r!markdown-html-error!, @result)
+ end
+
+ should "have the URL to the 'yaml_with_dots' item" do
+ assert_match(%r!/methods/yaml_with_dots\.html!, @result)
+ end
+ end
+
+ context "simple page with dynamic linking" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: linking
+ ---
+
+ {% assign yaml_with_dots_path = '_methods/yaml_with_dots.md' %}
+ {% link {{yaml_with_dots_path}} %}
+ CONTENT
+ render_content_with_collection(content, "methods")
+ end
+
+ should "not cause an error" do
+ refute_match(%r!markdown-html-error!, @result)
+ end
+
+ should "have the URL to the 'yaml_with_dots' item" do
+ assert_match(%r!/methods/yaml_with_dots\.html!, @result)
+ end
+ end
+
+ context "simple page with nested linking" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: linking
+ ---
+
+ - 1 {% link _methods/sanitized_path.md %}
+ - 2 {% link _methods/site/generate.md %}
+ CONTENT
+ render_content_with_collection(content, "methods")
+ end
+
+ should "not cause an error" do
+ refute_match(%r!markdown-html-error!, @result)
+ end
+
+ should "have the URL to the 'sanitized_path' item" do
+ assert_match %r!1\s/methods/sanitized_path\.html!, @result
+ end
+
+ should "have the URL to the 'site/generate' item" do
+ assert_match %r!2\s/methods/site/generate\.html!, @result
+ end
+ end
+
+ context "simple page with invalid linking" do
+ should "cause an error" do
+ content = <<~CONTENT
+ ---
+ title: Invalid linking
+ ---
+
+ {% link non-existent-collection-item %}
+ CONTENT
+
+ assert_raises ArgumentError do
+ render_content_with_collection(content, "methods")
+ end
+ end
+ end
+
+ context "simple page with invalid dynamic linking" do
+ should "cause an error" do
+ content = <<~CONTENT
+ ---
+ title: Invalid linking
+ ---
+
+ {% assign non_existent_path = 'non-existent-collection-item' %}
+ {% link {{\ non_existent_path\ }} %}
+ CONTENT
+
+ assert_raises ArgumentError do
+ render_content_with_collection(content, "methods")
+ end
+ end
+ end
+end
diff --git a/test/test_tag_post_url.rb b/test/test_tag_post_url.rb
new file mode 100644
index 00000000..5a48857b
--- /dev/null
+++ b/test/test_tag_post_url.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require "helper"
+
+class TestTagPostUrl < TagUnitTest
+ context "simple page with post linking" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: Post linking
+ ---
+
+ {% post_url 2008-11-21-complex %}
+ CONTENT
+
+ render_content(content, "permalink" => "pretty", "read_posts" => true)
+ end
+
+ should "not cause an error" do
+ refute_match %r!markdown-html-error!, @result
+ end
+
+ should "have the URL to the 'complex' post from 2008-11-21" do
+ assert_match %r!/2008/11/21/complex/!, @result
+ end
+ end
+
+ context "simple page with post linking containing special characters" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: Post linking
+ ---
+
+ {% post_url 2016-11-26-special-chars-(+) %}
+ CONTENT
+
+ render_content(content, "permalink" => "pretty", "read_posts" => true)
+ end
+
+ should "not cause an error" do
+ refute_match %r!markdown-html-error!, @result
+ end
+
+ should "have the URL to the 'special-chars' post from 2016-11-26" do
+ assert_match %r!/2016/11/26/special-chars-\(\+\)/!, @result
+ end
+ end
+
+ context "simple page with nested post linking" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: Post linking
+ ---
+
+ - 1 {% post_url 2008-11-21-complex %}
+ - 2 {% post_url /2008-11-21-complex %}
+ - 3 {% post_url es/2008-11-21-nested %}
+ - 4 {% post_url /es/2008-11-21-nested %}
+ CONTENT
+
+ render_content(content, "permalink" => "pretty", "read_posts" => true)
+ end
+
+ should "not cause an error" do
+ refute_match %r!markdown-html-error!, @result
+ end
+
+ should "have the URL to the 'complex' post from 2008-11-21" do
+ assert_match %r!1\s/2008/11/21/complex/!, @result
+ assert_match %r!2\s/2008/11/21/complex/!, @result
+ end
+
+ should "have the URL to the 'nested' post from 2008-11-21" do
+ assert_match %r!3\s/2008/11/21/nested/!, @result
+ assert_match %r!4\s/2008/11/21/nested/!, @result
+ end
+ end
+
+ context "simple page with nested post linking and path not used in `post_url`" do
+ setup do
+ content = <<~CONTENT
+ ---
+ title: Deprecated Post linking
+ ---
+
+ - 1 {% post_url 2008-11-21-nested %}
+ CONTENT
+
+ render_content(content, "permalink" => "pretty", "read_posts" => true)
+ end
+
+ should "not cause an error" do
+ refute_match(%r!markdown-html-error!, @result)
+ end
+
+ should "have the url to the 'nested' post from 2008-11-21" do
+ assert_match %r!1\s/2008/11/21/nested/!, @result
+ end
+
+ should "throw a deprecation warning" do
+ deprecation_warning = " Deprecation: A call to '{% post_url 2008-11-21-nested %}' " \
+ "did not match a post using the new matching method of checking " \
+ "name (path-date-slug) equality. Please make sure that you change " \
+ "this tag to match the post's name exactly."
+ assert_includes Jekyll.logger.messages, deprecation_warning
+ end
+ end
+
+ context "simple page with invalid post name linking" do
+ should "cause an error" do
+ assert_raises Jekyll::Errors::PostURLError do
+ render_content(<<~CONTENT, "read_posts" => true)
+ ---
+ title: Invalid post name linking
+ ---
+
+ {% post_url abc2008-11-21-complex %}
+ CONTENT
+ end
+ end
+
+ should "cause an error with a bad date" do
+ assert_raises Jekyll::Errors::InvalidDateError do
+ render_content(<<~CONTENT, "read_posts" => true)
+ ---
+ title: Invalid post name linking
+ ---
+
+ {% post_url 2008-42-21-complex %}
+ CONTENT
+ end
+ end
+ end
+end
diff --git a/test/test_tags.rb b/test/test_tags.rb
deleted file mode 100644
index a82a6f2e..00000000
--- a/test/test_tags.rb
+++ /dev/null
@@ -1,1191 +0,0 @@
-# frozen_string_literal: true
-
-require "helper"
-
-class TestTags < JekyllUnitTest
- def setup
- FileUtils.mkdir_p("tmp")
- end
-
- def create_post(content, override = {}, converter_class = Jekyll::Converters::Markdown)
- site = fixture_site({ "highlighter" => "rouge" }.merge(override))
-
- site.posts.docs.concat(PostReader.new(site).read_posts("")) if override["read_posts"]
- CollectionReader.new(site).read if override["read_collections"]
- site.read if override["read_all"]
-
- info = { :filters => [Jekyll::Filters], :registers => { :site => site } }
- @converter = site.converters.find { |c| c.instance_of?(converter_class) }
- payload = { "highlighter_prefix" => @converter.highlighter_prefix,
- "highlighter_suffix" => @converter.highlighter_suffix, }
-
- @result = Liquid::Template.parse(content).render!(payload, info)
- @result = @converter.convert(@result)
- end
-
- def fill_post(code, override = {})
- content = <<~CONTENT
- ---
- title: This is a test
- ---
-
- This document has some highlighted code in it.
-
- {% highlight text %}
- #{code}
- {% endhighlight %}
- {% highlight text linenos %}
- #{code}
- {% endhighlight %}
- CONTENT
- create_post(content, override)
- end
-
- def highlight_block_with_opts(options_string)
- Jekyll::Tags::HighlightBlock.parse(
- "highlight",
- options_string,
- Liquid::Tokenizer.new("test{% endhighlight %}\n"),
- Liquid::ParseContext.new
- )
- end
-
- context "language name" do
- should "match only the required set of chars" do
- r = Jekyll::Tags::HighlightBlock::SYNTAX
- assert_match r, "ruby"
- assert_match r, "c#"
- assert_match r, "xml+cheetah"
- assert_match r, "x.y"
- assert_match r, "coffee-script"
- assert_match r, "shell_session"
-
- refute_match r, "blah^"
-
- assert_match r, "ruby key=val"
- assert_match r, "ruby a=b c=d"
- end
- end
-
- context "highlight tag in unsafe mode" do
- should "set the no options with just a language name" do
- tag = highlight_block_with_opts("ruby ")
- assert_equal({}, tag.instance_variable_get(:@highlight_options))
- end
-
- should "set the linenos option as 'inline' if no linenos value" do
- tag = highlight_block_with_opts("ruby linenos ")
- assert_equal(
- { :linenos => "inline" },
- tag.instance_variable_get(:@highlight_options)
- )
- end
-
- should "set the linenos option to 'table' " \
- "if the linenos key is given the table value" do
- tag = highlight_block_with_opts("ruby linenos=table ")
- assert_equal(
- { :linenos => "table" },
- tag.instance_variable_get(:@highlight_options)
- )
- end
-
- should "recognize nowrap option with linenos set" do
- tag = highlight_block_with_opts("ruby linenos=table nowrap ")
- assert_equal(
- { :linenos => "table", :nowrap => true },
- tag.instance_variable_get(:@highlight_options)
- )
- end
-
- should "recognize the cssclass option" do
- tag = highlight_block_with_opts("ruby linenos=table cssclass=hl ")
- assert_equal(
- { :cssclass => "hl", :linenos => "table" },
- tag.instance_variable_get(:@highlight_options)
- )
- end
-
- should "recognize the hl_linenos option and its value" do
- tag = highlight_block_with_opts("ruby linenos=table cssclass=hl hl_linenos=3 ")
- assert_equal(
- { :cssclass => "hl", :linenos => "table", :hl_linenos => "3" },
- tag.instance_variable_get(:@highlight_options)
- )
- end
-
- should "recognize multiple values of hl_linenos" do
- tag = highlight_block_with_opts 'ruby linenos=table cssclass=hl hl_linenos="3 5 6" '
- assert_equal(
- { :cssclass => "hl", :linenos => "table", :hl_linenos => %w(3 5 6) },
- tag.instance_variable_get(:@highlight_options)
- )
- end
-
- should "treat language name as case insensitive" do
- tag = highlight_block_with_opts("Ruby ")
- assert_equal(
- "ruby",
- tag.instance_variable_get(:@lang),
- "lexers should be case insensitive"
- )
- end
- end
-
- context "with the rouge highlighter" do
- context "post content has highlight tag" do
- setup do
- fill_post("test")
- end
-
- should "render markdown with rouge" do
- assert_match(
- %(test
),
- @result
- )
- end
-
- should "render markdown with rouge with line numbers" do
- assert_match(
- %() +
- %() +
- %(1\n
) +
- %(test\n
) +
- %(
),
- @result
- )
- end
- end
-
- context "post content has raw tag" do
- setup do
- content = <<~CONTENT
- ---
- title: This is a test
- ---
-
- ```liquid
- {% raw %}
- {{ site.baseurl }}{% link _collection/name-of-document.md %}
- {% endraw %}
- ```
- CONTENT
- create_post(content)
- end
-
- should "render markdown with rouge" do
- assert_match(
- %() +
- %(),
- @result
- )
- end
- end
-
- context "post content has highlight with file reference" do
- setup do
- fill_post("./jekyll.gemspec")
- end
-
- should "not embed the file" do
- assert_match(
- '' \
- "./jekyll.gemspec
",
- @result
- )
- end
- end
-
- context "post content has highlight tag with UTF character" do
- setup do
- fill_post("Æ")
- end
-
- should "render markdown with pygments line handling" do
- assert_match(
- 'Æ
',
- @result
- )
- end
- end
-
- context "post content has highlight tag with preceding spaces & lines" do
- setup do
- fill_post <<~EOS
-
-
- [,1] [,2]
- [1,] FALSE TRUE
- [2,] FALSE TRUE
- EOS
- end
-
- should "only strip the preceding newlines" do
- assert_match(
- ' [,1] [,2]',
- @result
- )
- end
- end
-
- context "post content has highlight tag with " \
- "preceding spaces & lines in several places" do
- setup do
- fill_post <<~EOS
-
-
- [,1] [,2]
-
-
- [1,] FALSE TRUE
- [2,] FALSE TRUE
-
-
- EOS
- end
-
- should "only strip the newlines which precede and succeed the entire block" do
- assert_match(
- " [,1] [,2]\n\n\n" \
- "[1,] FALSE TRUE\n[2,] FALSE TRUE
",
- @result
- )
- end
- end
-
- context "post content has highlight tag with linenumbers" do
- setup do
- create_post <<~EOS
- ---
- title: This is a test
- ---
-
- This is not yet highlighted
- {% highlight php linenos %}
- test
- {% endhighlight %}
-
- This should not be highlighted, right?
- EOS
- end
-
- should "should stop highlighting at boundary with rouge" do
- expected = <<~EOS
- This is not yet highlighted
\n
- 1
-
test\n
\n
- This should not be highlighted, right?
- EOS
- assert_match(expected, @result)
- end
- end
-
- context "post content has highlight tag with " \
- "preceding spaces & Windows-style newlines" do
- setup do
- fill_post "\r\n\r\n\r\n [,1] [,2]"
- end
-
- should "only strip the preceding newlines" do
- assert_match(
- ' [,1] [,2]',
- @result
- )
- end
- end
-
- context "post content has highlight tag with only preceding spaces" do
- setup do
- fill_post <<~EOS
- [,1] [,2]
- [1,] FALSE TRUE
- [2,] FALSE TRUE
- EOS
- end
-
- should "only strip the preceding newlines" do
- assert_match(
- ' [,1] [,2]',
- @result
- )
- end
- end
- end
-
- context "simple post with markdown and pre tags" do
- setup do
- @content = <<~CONTENT
- ---
- title: Kramdown post with pre
- ---
-
- _FIGHT!_
-
- {% highlight ruby %}
- puts "3..2..1.."
- {% endhighlight %}
-
- *FINISH HIM*
- CONTENT
- end
-
- context "using Kramdown" do
- setup do
- create_post(@content, "markdown" => "kramdown")
- end
-
- should "parse correctly" do
- assert_match %r{FIGHT!}, @result
- assert_match %r!FINISH HIM!, @result
- end
- end
- end
-
- context "simple page with post linking" do
- setup do
- content = <<~CONTENT
- ---
- title: Post linking
- ---
-
- {% post_url 2008-11-21-complex %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'complex' post from 2008-11-21" do
- assert_match %r!/2008/11/21/complex/!, @result
- end
- end
-
- context "simple page with post linking containing special characters" do
- setup do
- content = <<~CONTENT
- ---
- title: Post linking
- ---
-
- {% post_url 2016-11-26-special-chars-(+) %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'special-chars' post from 2016-11-26" do
- assert_match %r!/2016/11/26/special-chars-\(\+\)/!, @result
- end
- end
-
- context "simple page with nested post linking" do
- setup do
- content = <<~CONTENT
- ---
- title: Post linking
- ---
-
- - 1 {% post_url 2008-11-21-complex %}
- - 2 {% post_url /2008-11-21-complex %}
- - 3 {% post_url es/2008-11-21-nested %}
- - 4 {% post_url /es/2008-11-21-nested %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'complex' post from 2008-11-21" do
- assert_match %r!1\s/2008/11/21/complex/!, @result
- assert_match %r!2\s/2008/11/21/complex/!, @result
- end
-
- should "have the URL to the 'nested' post from 2008-11-21" do
- assert_match %r!3\s/2008/11/21/nested/!, @result
- assert_match %r!4\s/2008/11/21/nested/!, @result
- end
- end
-
- context "simple page with nested post linking and path not used in `post_url`" do
- setup do
- content = <<~CONTENT
- ---
- title: Deprecated Post linking
- ---
-
- - 1 {% post_url 2008-11-21-nested %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the url to the 'nested' post from 2008-11-21" do
- assert_match %r!1\s/2008/11/21/nested/!, @result
- end
-
- should "throw a deprecation warning" do
- deprecation_warning = " Deprecation: A call to '{% post_url 2008-11-21-nested %}' " \
- "did not match a post using the new matching method of checking " \
- "name (path-date-slug) equality. Please make sure that you change " \
- "this tag to match the post's name exactly."
- assert_includes Jekyll.logger.messages, deprecation_warning
- end
- end
-
- context "simple page with invalid post name linking" do
- should "cause an error" do
- content = <<~CONTENT
- ---
- title: Invalid post name linking
- ---
-
- {% post_url abc2008-11-21-complex %}
- CONTENT
-
- assert_raises Jekyll::Errors::PostURLError do
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
- end
-
- should "cause an error with a bad date" do
- content = <<~CONTENT
- ---
- title: Invalid post name linking
- ---
-
- {% post_url 2008-42-21-complex %}
- CONTENT
-
- assert_raises Jekyll::Errors::InvalidDateError do
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
- end
- end
-
- context "simple page with linking to a page" do
- setup do
- content = <<~CONTENT
- ---
- title: linking
- ---
-
- {% link contacts.html %}
- {% link info.md %}
- {% link /css/screen.css %}
- CONTENT
- create_post(content,
- "source" => source_dir,
- "destination" => dest_dir,
- "read_all" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'contacts' item" do
- assert_match(%r!/contacts\.html!, @result)
- end
-
- should "have the URL to the 'info' item" do
- assert_match(%r!/info\.html!, @result)
- end
-
- should "have the URL to the 'screen.css' item" do
- assert_match(%r!/css/screen\.css!, @result)
- end
- end
-
- context "simple page with dynamic linking to a page" do
- setup do
- content = <<~CONTENT
- ---
- title: linking
- ---
-
- {% assign contacts_filename = 'contacts' %}
- {% assign contacts_ext = 'html' %}
- {% link {{contacts_filename}}.{{contacts_ext}} %}
- {% assign info_path = 'info.md' %}
- {% link {{\ info_path\ }} %}
- {% assign screen_css_path = '/css' %}
- {% link {{ screen_css_path }}/screen.css %}
- CONTENT
- create_post(content,
- "source" => source_dir,
- "destination" => dest_dir,
- "read_all" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'contacts' item" do
- assert_match(%r!/contacts\.html!, @result)
- end
-
- should "have the URL to the 'info' item" do
- assert_match(%r!/info\.html!, @result)
- end
-
- should "have the URL to the 'screen.css' item" do
- assert_match(%r!/css/screen\.css!, @result)
- end
- end
-
- context "simple page with linking" do
- setup do
- content = <<~CONTENT
- ---
- title: linking
- ---
-
- {% link _methods/yaml_with_dots.md %}
- CONTENT
- create_post(content,
- "source" => source_dir,
- "destination" => dest_dir,
- "collections" => { "methods" => { "output" => true } },
- "read_collections" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'yaml_with_dots' item" do
- assert_match(%r!/methods/yaml_with_dots\.html!, @result)
- end
- end
-
- context "simple page with dynamic linking" do
- setup do
- content = <<~CONTENT
- ---
- title: linking
- ---
-
- {% assign yaml_with_dots_path = '_methods/yaml_with_dots.md' %}
- {% link {{yaml_with_dots_path}} %}
- CONTENT
- create_post(content,
- "source" => source_dir,
- "destination" => dest_dir,
- "collections" => { "methods" => { "output" => true } },
- "read_collections" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'yaml_with_dots' item" do
- assert_match(%r!/methods/yaml_with_dots\.html!, @result)
- end
- end
-
- context "simple page with nested linking" do
- setup do
- content = <<~CONTENT
- ---
- title: linking
- ---
-
- - 1 {% link _methods/sanitized_path.md %}
- - 2 {% link _methods/site/generate.md %}
- CONTENT
- create_post(content,
- "source" => source_dir,
- "destination" => dest_dir,
- "collections" => { "methods" => { "output" => true } },
- "read_collections" => true)
- end
-
- should "not cause an error" do
- refute_match(%r!markdown-html-error!, @result)
- end
-
- should "have the URL to the 'sanitized_path' item" do
- assert_match %r!1\s/methods/sanitized_path\.html!, @result
- end
-
- should "have the URL to the 'site/generate' item" do
- assert_match %r!2\s/methods/site/generate\.html!, @result
- end
- end
-
- context "simple page with invalid linking" do
- should "cause an error" do
- content = <<~CONTENT
- ---
- title: Invalid linking
- ---
-
- {% link non-existent-collection-item %}
- CONTENT
-
- assert_raises ArgumentError do
- create_post(content,
- "source" => source_dir,
- "destination" => dest_dir,
- "collections" => { "methods" => { "output" => true } },
- "read_collections" => true)
- end
- end
- end
-
- context "simple page with invalid dynamic linking" do
- should "cause an error" do
- content = <<~CONTENT
- ---
- title: Invalid linking
- ---
-
- {% assign non_existent_path = 'non-existent-collection-item' %}
- {% link {{\ non_existent_path\ }} %}
- CONTENT
-
- assert_raises ArgumentError do
- create_post(content,
- "source" => source_dir,
- "destination" => dest_dir,
- "collections" => { "methods" => { "output" => true } },
- "read_collections" => true)
- end
- end
- end
-
- context "include tag with parameters" do
- context "with symlink'd include" do
- should "not allow symlink includes" do
- File.write("tmp/pages-test", "SYMLINK TEST")
- assert_raises IOError do
- content = <<~CONTENT
- ---
- title: Include symlink
- ---
-
- {% include tmp/pages-test %}
-
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true,
- "safe" => true)
- end
- @result ||= ""
- refute_match(%r!SYMLINK TEST!, @result)
- end
-
- should "not expose the existence of symlinked files" do
- ex = assert_raises IOError do
- content = <<~CONTENT
- ---
- title: Include symlink
- ---
-
- {% include tmp/pages-test-does-not-exist %}
-
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true,
- "safe" => true)
- end
- assert_match(
- "Could not locate the included file 'tmp/pages-test-does-not-exist' " \
- "in any of [\"#{source_dir}/_includes\"]. Ensure it exists in one of " \
- "those directories and is not a symlink as those are not allowed in " \
- "safe mode.",
- ex.message
- )
- end
- end
-
- context "with one parameter" do
- setup do
- content = <<~CONTENT
- ---
- title: Include tag parameters
- ---
-
- {% include sig.markdown myparam="test" %}
-
- {% include params.html param="value" %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "correctly output include variable" do
- assert_match "value", @result.strip
- end
-
- should "ignore parameters if unused" do
- assert_match "
\nTom Preston-Werner\ngithub.com/mojombo
\n", @result
- end
- end
-
- context "with simple syntax but multiline markup" do
- setup do
- content = <<~CONTENT
- ---
- title: Include tag parameters
- ---
-
- {% include sig.markdown myparam="test" %}
-
- {% include params.html
- param="value" %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "correctly output include variable" do
- assert_match "value", @result.strip
- end
-
- should "ignore parameters if unused" do
- assert_match "
\nTom Preston-Werner\ngithub.com/mojombo
\n", @result
- end
- end
-
- context "with variable syntax but multiline markup" do
- setup do
- content = <<~CONTENT
- ---
- title: Include tag parameters
- ---
-
- {% include sig.markdown myparam="test" %}
- {% assign path = "params" | append: ".html" %}
- {% include {{ path }}
- param="value" %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "correctly output include variable" do
- assert_match "value", @result.strip
- end
-
- should "ignore parameters if unused" do
- assert_match "
\nTom Preston-Werner\ngithub.com/mojombo
\n", @result
- end
- end
-
- context "with invalid parameter syntax" do
- should "throw a ArgumentError" do
- content = <<~CONTENT
- ---
- title: Invalid parameter syntax
- ---
-
- {% include params.html param s="value" %}
- CONTENT
- assert_raises ArgumentError, "Did not raise exception on invalid " \
- '"include" syntax' do
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- content = <<~CONTENT
- ---
- title: Invalid parameter syntax
- ---
-
- {% include params.html params="value %}
- CONTENT
- assert_raises ArgumentError, "Did not raise exception on invalid " \
- '"include" syntax' do
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
- end
- end
-
- context "with several parameters" do
- setup do
- content = <<~CONTENT
- ---
- title: multiple include parameters
- ---
-
- {% include params.html param1="new_value" param2="another" %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "list all parameters" do
- assert_match "param1 = new_value ", @result
- assert_match "param2 = another ", @result
- end
-
- should "not include previously used parameters" do
- assert_match "", @result
- end
- end
-
- context "without parameters" do
- setup do
- content = <<~CONTENT
- ---
- title: without parameters
- ---
-
- {% include params.html %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "include file with empty parameters" do
- assert_match "", @result
- end
- end
-
- context "with include file with special characters without params" do
- setup do
- content = <<~CONTENT
- ---
- title: special characters
- ---
-
- {% include params@2.0.html %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "include file with empty parameters" do
- assert_match "", @result
- end
- end
-
- context "with include file with special characters with params" do
- setup do
- content = <<~CONTENT
- ---
- title: special characters
- ---
-
- {% include params@2.0.html param1="foobar" param2="bazbar" %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "include file with empty parameters" do
- assert_match "param1 = foobar ", @result
- assert_match "param2 = bazbar ", @result
- end
- end
-
- context "with custom includes directory" do
- setup do
- content = <<~CONTENT
- ---
- title: custom includes directory
- ---
-
- {% include custom.html %}
- CONTENT
- create_post(content,
- "includes_dir" => "_includes_custom",
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "include file from custom directory" do
- assert_match "custom_included", @result
- end
- end
-
- context "without parameters within if statement" do
- setup do
- content = <<~CONTENT
- ---
- title: without parameters within if statement
- ---
-
- {% if true %}{% include params.html %}{% endif %}
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
-
- should "include file with empty parameters within if statement" do
- assert_match "", @result
- end
- end
-
- context "include missing file" do
- setup do
- @content = <<~CONTENT
- ---
- title: missing file
- ---
-
- {% include missing.html %}
- CONTENT
- end
-
- should "raise error relative to source directory" do
- exception = assert_raises IOError do
- create_post(@content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
- assert_match(
- "Could not locate the included file 'missing.html' in any of " \
- "[\"#{source_dir}/_includes\"].",
- exception.message
- )
- end
- end
-
- context "include tag with variable and liquid filters" do
- setup do
- site = fixture_site("pygments" => true).tap(&:read).tap(&:render)
- post = site.posts.docs.find do |p|
- p.basename.eql? "2013-12-17-include-variable-filters.markdown"
- end
- @content = post.output
- end
-
- should "include file as variable with liquid filters" do
- assert_match(%r!1 included!, @content)
- assert_match(%r!2 included!, @content)
- assert_match(%r!3 included!, @content)
- end
-
- should "include file as variable and liquid filters with arbitrary whitespace" do
- assert_match(%r!4 included!, @content)
- assert_match(%r!5 included!, @content)
- assert_match(%r!6 included!, @content)
- end
-
- should "include file as variable and filters with additional parameters" do
- assert_match("var1 = foo ", @content)
- assert_match("var2 = bar ", @content)
- end
-
- should "include file as partial variable" do
- assert_match(%r!8 included!, @content)
- end
- end
- end
-
- context "relative include tag with variable and liquid filters" do
- setup do
- site = fixture_site("pygments" => true).tap(&:read).tap(&:render)
- post = site.posts.docs.find do |p|
- p.basename.eql? "2014-09-02-relative-includes.markdown"
- end
- @content = post.output
- end
-
- should "include file as variable with liquid filters" do
- assert_match(%r!1 relative_include!, @content)
- assert_match(%r!2 relative_include!, @content)
- assert_match(%r!3 relative_include!, @content)
- end
-
- should "include file as variable and liquid filters with arbitrary whitespace" do
- assert_match(%r!4 relative_include!, @content)
- assert_match(%r!5 relative_include!, @content)
- assert_match(%r!6 relative_include!, @content)
- end
-
- should "include file as variable and filters with additional parameters" do
- assert_match("var1 = foo ", @content)
- assert_match("var2 = bar ", @content)
- end
-
- should "include file as partial variable" do
- assert_match(%r!8 relative_include!, @content)
- end
-
- should "include files relative to self" do
- assert_match(%r!9 —\ntitle: Test Post Where YAML!, @content)
- end
-
- context "trying to do bad stuff" do
- context "include missing file" do
- setup do
- @content = <<~CONTENT
- ---
- title: missing file
- ---
-
- {% include_relative missing.html %}
- CONTENT
- end
-
- should "raise error relative to source directory" do
- exception = assert_raises IOError do
- create_post(@content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
- assert_match "Could not locate the included file 'missing.html' in any of " \
- "[\"#{source_dir}\"].", exception.message
- end
- end
-
- context "include existing file above you" do
- setup do
- @content = <<~CONTENT
- ---
- title: higher file
- ---
-
- {% include_relative ../README.markdown %}
- CONTENT
- end
-
- should "raise error relative to source directory" do
- exception = assert_raises ArgumentError do
- create_post(@content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true)
- end
- assert_equal(
- "Invalid syntax for include tag. File contains invalid characters or " \
- "sequences:\n\n ../README.markdown\n\nValid syntax:\n\n " \
- "{% include_relative file.ext param='value' param2='value' %}\n\n",
- exception.message
- )
- end
- end
- end
-
- context "with symlink'd include" do
- should "not allow symlink includes" do
- File.write("tmp/pages-test", "SYMLINK TEST")
- assert_raises IOError do
- content = <<~CONTENT
- ---
- title: Include symlink
- ---
-
- {% include_relative tmp/pages-test %}
-
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true,
- "safe" => true)
- end
- @result ||= ""
- refute_match(%r!SYMLINK TEST!, @result)
- end
-
- should "not expose the existence of symlinked files" do
- ex = assert_raises IOError do
- content = <<~CONTENT
- ---
- title: Include symlink
- ---
-
- {% include_relative tmp/pages-test-does-not-exist %}
-
- CONTENT
- create_post(content,
- "permalink" => "pretty",
- "source" => source_dir,
- "destination" => dest_dir,
- "read_posts" => true,
- "safe" => true)
- end
- assert_match(
- "Ensure it exists in one of those directories and is not a symlink " \
- "as those are not allowed in safe mode.",
- ex.message
- )
- end
- end
- end
-end