1// Copyright 2019 The Hugo Authors. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package blackfriday 15 16import ( 17 "testing" 18 19 "github.com/gohugoio/hugo/config" 20 21 "github.com/gohugoio/hugo/markup/converter" 22 23 qt "github.com/frankban/quicktest" 24 "github.com/gohugoio/hugo/markup/blackfriday/blackfriday_config" 25 "github.com/russross/blackfriday" 26) 27 28func TestGetMarkdownExtensionsMasksAreRemovedFromExtensions(t *testing.T) { 29 b := blackfriday_config.Default 30 b.Extensions = []string{"headerId"} 31 b.ExtensionsMask = []string{"noIntraEmphasis"} 32 33 actualFlags := getMarkdownExtensions(b) 34 if actualFlags&blackfriday.EXTENSION_NO_INTRA_EMPHASIS == blackfriday.EXTENSION_NO_INTRA_EMPHASIS { 35 t.Errorf("Masked out flag {%v} found amongst returned extensions.", blackfriday.EXTENSION_NO_INTRA_EMPHASIS) 36 } 37} 38 39func TestGetMarkdownExtensionsByDefaultAllExtensionsAreEnabled(t *testing.T) { 40 type data struct { 41 testFlag int 42 } 43 44 b := blackfriday_config.Default 45 46 b.Extensions = []string{""} 47 b.ExtensionsMask = []string{""} 48 allExtensions := []data{ 49 {blackfriday.EXTENSION_NO_INTRA_EMPHASIS}, 50 {blackfriday.EXTENSION_TABLES}, 51 {blackfriday.EXTENSION_FENCED_CODE}, 52 {blackfriday.EXTENSION_AUTOLINK}, 53 {blackfriday.EXTENSION_STRIKETHROUGH}, 54 // {blackfriday.EXTENSION_LAX_HTML_BLOCKS}, 55 {blackfriday.EXTENSION_SPACE_HEADERS}, 56 // {blackfriday.EXTENSION_HARD_LINE_BREAK}, 57 // {blackfriday.EXTENSION_TAB_SIZE_EIGHT}, 58 {blackfriday.EXTENSION_FOOTNOTES}, 59 // {blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK}, 60 {blackfriday.EXTENSION_HEADER_IDS}, 61 // {blackfriday.EXTENSION_TITLEBLOCK}, 62 {blackfriday.EXTENSION_AUTO_HEADER_IDS}, 63 {blackfriday.EXTENSION_BACKSLASH_LINE_BREAK}, 64 {blackfriday.EXTENSION_DEFINITION_LISTS}, 65 } 66 67 actualFlags := getMarkdownExtensions(b) 68 for _, e := range allExtensions { 69 if actualFlags&e.testFlag != e.testFlag { 70 t.Errorf("Flag %v was not found in the list of extensions.", e) 71 } 72 } 73} 74 75func TestGetMarkdownExtensionsAddingFlagsThroughRenderingContext(t *testing.T) { 76 b := blackfriday_config.Default 77 78 b.Extensions = []string{"definitionLists"} 79 b.ExtensionsMask = []string{""} 80 81 actualFlags := getMarkdownExtensions(b) 82 if actualFlags&blackfriday.EXTENSION_DEFINITION_LISTS != blackfriday.EXTENSION_DEFINITION_LISTS { 83 t.Errorf("Masked out flag {%v} found amongst returned extensions.", blackfriday.EXTENSION_DEFINITION_LISTS) 84 } 85} 86 87func TestGetFlags(t *testing.T) { 88 b := blackfriday_config.Default 89 flags := getFlags(false, b) 90 if flags&blackfriday.HTML_USE_XHTML != blackfriday.HTML_USE_XHTML { 91 t.Errorf("Test flag: %d was not found amongs set flags:%d; Result: %d", blackfriday.HTML_USE_XHTML, flags, flags&blackfriday.HTML_USE_XHTML) 92 } 93} 94 95func TestGetAllFlags(t *testing.T) { 96 c := qt.New(t) 97 98 b := blackfriday_config.Default 99 100 type data struct { 101 testFlag int 102 } 103 104 allFlags := []data{ 105 {blackfriday.HTML_USE_XHTML}, 106 {blackfriday.HTML_FOOTNOTE_RETURN_LINKS}, 107 {blackfriday.HTML_USE_SMARTYPANTS}, 108 {blackfriday.HTML_SMARTYPANTS_QUOTES_NBSP}, 109 {blackfriday.HTML_SMARTYPANTS_ANGLED_QUOTES}, 110 {blackfriday.HTML_SMARTYPANTS_FRACTIONS}, 111 {blackfriday.HTML_HREF_TARGET_BLANK}, 112 {blackfriday.HTML_NOFOLLOW_LINKS}, 113 {blackfriday.HTML_NOREFERRER_LINKS}, 114 {blackfriday.HTML_SMARTYPANTS_DASHES}, 115 {blackfriday.HTML_SMARTYPANTS_LATEX_DASHES}, 116 } 117 118 b.AngledQuotes = true 119 b.Fractions = true 120 b.HrefTargetBlank = true 121 b.NofollowLinks = true 122 b.NoreferrerLinks = true 123 b.LatexDashes = true 124 b.PlainIDAnchors = true 125 b.SmartDashes = true 126 b.Smartypants = true 127 b.SmartypantsQuotesNBSP = true 128 129 actualFlags := getFlags(false, b) 130 131 var expectedFlags int 132 // OR-ing flags together... 133 for _, d := range allFlags { 134 expectedFlags |= d.testFlag 135 } 136 137 c.Assert(actualFlags, qt.Equals, expectedFlags) 138} 139 140func TestConvert(t *testing.T) { 141 c := qt.New(t) 142 p, err := Provider.New(converter.ProviderConfig{ 143 Cfg: config.New(), 144 }) 145 c.Assert(err, qt.IsNil) 146 conv, err := p.New(converter.DocumentContext{}) 147 c.Assert(err, qt.IsNil) 148 b, err := conv.Convert(converter.RenderContext{Src: []byte("testContent")}) 149 c.Assert(err, qt.IsNil) 150 c.Assert(string(b.Bytes()), qt.Equals, "<p>testContent</p>\n") 151} 152 153func TestGetHTMLRendererAnchors(t *testing.T) { 154 c := qt.New(t) 155 p, err := Provider.New(converter.ProviderConfig{ 156 Cfg: config.New(), 157 }) 158 c.Assert(err, qt.IsNil) 159 conv, err := p.New(converter.DocumentContext{ 160 DocumentID: "testid", 161 ConfigOverrides: map[string]interface{}{ 162 "plainIDAnchors": false, 163 "footnotes": true, 164 }, 165 }) 166 c.Assert(err, qt.IsNil) 167 b, err := conv.Convert(converter.RenderContext{Src: []byte(`# Header 168 169This is a footnote.[^1] And then some. 170 171 172[^1]: Footnote text. 173 174`)}) 175 176 c.Assert(err, qt.IsNil) 177 s := string(b.Bytes()) 178 c.Assert(s, qt.Contains, "<h1 id=\"header:testid\">Header</h1>") 179 c.Assert(s, qt.Contains, "This is a footnote.<sup class=\"footnote-ref\" id=\"fnref:testid:1\"><a href=\"#fn:testid:1\">1</a></sup>") 180 c.Assert(s, qt.Contains, "<a class=\"footnote-return\" href=\"#fnref:testid:1\"><sup>[return]</sup></a>") 181} 182 183// Tests borrowed from https://github.com/russross/blackfriday/blob/a925a152c144ea7de0f451eaf2f7db9e52fa005a/block_test.go#L1817 184func TestSanitizedAnchorName(t *testing.T) { 185 tests := []struct { 186 text string 187 want string 188 }{ 189 { 190 text: "This is a header", 191 want: "this-is-a-header", 192 }, 193 { 194 text: "This is also a header", 195 want: "this-is-also-a-header", 196 }, 197 { 198 text: "main.go", 199 want: "main-go", 200 }, 201 { 202 text: "Article 123", 203 want: "article-123", 204 }, 205 { 206 text: "<- Let's try this, shall we?", 207 want: "let-s-try-this-shall-we", 208 }, 209 { 210 text: " ", 211 want: "", 212 }, 213 { 214 text: "Hello, 世界", 215 want: "hello-世界", 216 }, 217 } 218 for _, test := range tests { 219 if got := SanitizedAnchorName(test.text); got != test.want { 220 t.Errorf("SanitizedAnchorName(%q):\ngot %q\nwant %q", test.text, got, test.want) 221 } 222 } 223} 224