transform_test.go (6243B)
1 // Copyright 2017 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 14 package transform_test 15 16 import ( 17 "html/template" 18 "strings" 19 "testing" 20 21 "github.com/gohugoio/hugo/common/loggers" 22 "github.com/gohugoio/hugo/hugolib" 23 "github.com/gohugoio/hugo/tpl/transform" 24 "github.com/spf13/afero" 25 26 qt "github.com/frankban/quicktest" 27 "github.com/gohugoio/hugo/config" 28 "github.com/gohugoio/hugo/deps" 29 "github.com/gohugoio/hugo/helpers" 30 "github.com/gohugoio/hugo/hugofs" 31 "github.com/gohugoio/hugo/langs" 32 ) 33 34 type tstNoStringer struct{} 35 36 func TestEmojify(t *testing.T) { 37 t.Parallel() 38 b := hugolib.NewIntegrationTestBuilder( 39 hugolib.IntegrationTestConfig{T: t}, 40 ).Build() 41 42 ns := transform.New(b.H.Deps) 43 44 for _, test := range []struct { 45 s any 46 expect any 47 }{ 48 {":notamoji:", template.HTML(":notamoji:")}, 49 {"I :heart: Hugo", template.HTML("I ❤️ Hugo")}, 50 // errors 51 {tstNoStringer{}, false}, 52 } { 53 54 result, err := ns.Emojify(test.s) 55 56 if bb, ok := test.expect.(bool); ok && !bb { 57 b.Assert(err, qt.Not(qt.IsNil)) 58 continue 59 } 60 61 b.Assert(err, qt.IsNil) 62 b.Assert(result, qt.Equals, test.expect) 63 } 64 } 65 66 func TestHighlight(t *testing.T) { 67 t.Parallel() 68 b := hugolib.NewIntegrationTestBuilder( 69 hugolib.IntegrationTestConfig{T: t}, 70 ).Build() 71 72 ns := transform.New(b.H.Deps) 73 74 for _, test := range []struct { 75 s any 76 lang string 77 opts any 78 expect any 79 }{ 80 {"func boo() {}", "go", "", "boo"}, 81 {"func boo() {}", "go", nil, "boo"}, 82 // Issue #4179 83 {`<Foo attr=" < "></Foo>`, "xml", "", `&lt;`}, 84 {tstNoStringer{}, "go", "", false}, 85 // Issue #9591 86 {strings.Repeat("AAA \n", 10), "bash", template.HTML("linenos=true,noClasses=false"), "line"}, 87 } { 88 89 result, err := ns.Highlight(test.s, test.lang, test.opts) 90 91 if bb, ok := test.expect.(bool); ok && !bb { 92 b.Assert(err, qt.Not(qt.IsNil)) 93 continue 94 } 95 96 b.Assert(err, qt.IsNil) 97 b.Assert(string(result), qt.Contains, test.expect.(string)) 98 } 99 } 100 101 func TestCanHighlight(t *testing.T) { 102 t.Parallel() 103 104 c := qt.New(t) 105 ns := &transform.Namespace{} 106 107 c.Assert(ns.CanHighlight("go"), qt.Equals, true) 108 c.Assert(ns.CanHighlight("foo"), qt.Equals, false) 109 } 110 111 func TestHTMLEscape(t *testing.T) { 112 t.Parallel() 113 b := hugolib.NewIntegrationTestBuilder( 114 hugolib.IntegrationTestConfig{T: t}, 115 ).Build() 116 117 ns := transform.New(b.H.Deps) 118 119 for _, test := range []struct { 120 s any 121 expect any 122 }{ 123 {`"Foo & Bar's Diner" <y@z>`, `"Foo & Bar's Diner" <y@z>`}, 124 {"Hugo & Caddy > Wordpress & Apache", "Hugo & Caddy > Wordpress & Apache"}, 125 // errors 126 {tstNoStringer{}, false}, 127 } { 128 129 result, err := ns.HTMLEscape(test.s) 130 131 if bb, ok := test.expect.(bool); ok && !bb { 132 b.Assert(err, qt.Not(qt.IsNil)) 133 continue 134 } 135 136 b.Assert(err, qt.IsNil) 137 b.Assert(result, qt.Equals, test.expect) 138 } 139 } 140 141 func TestHTMLUnescape(t *testing.T) { 142 t.Parallel() 143 b := hugolib.NewIntegrationTestBuilder( 144 hugolib.IntegrationTestConfig{T: t}, 145 ).Build() 146 147 ns := transform.New(b.H.Deps) 148 149 for _, test := range []struct { 150 s any 151 expect any 152 }{ 153 {`"Foo & Bar's Diner" <y@z>`, `"Foo & Bar's Diner" <y@z>`}, 154 {"Hugo & Caddy > Wordpress & Apache", "Hugo & Caddy > Wordpress & Apache"}, 155 // errors 156 {tstNoStringer{}, false}, 157 } { 158 159 result, err := ns.HTMLUnescape(test.s) 160 161 if bb, ok := test.expect.(bool); ok && !bb { 162 b.Assert(err, qt.Not(qt.IsNil)) 163 continue 164 } 165 166 b.Assert(err, qt.IsNil) 167 b.Assert(result, qt.Equals, test.expect) 168 } 169 } 170 171 func TestMarkdownify(t *testing.T) { 172 t.Parallel() 173 b := hugolib.NewIntegrationTestBuilder( 174 hugolib.IntegrationTestConfig{T: t}, 175 ).Build() 176 177 ns := transform.New(b.H.Deps) 178 179 for _, test := range []struct { 180 s any 181 expect any 182 }{ 183 {"Hello **World!**", template.HTML("Hello <strong>World!</strong>")}, 184 {[]byte("Hello Bytes **World!**"), template.HTML("Hello Bytes <strong>World!</strong>")}, 185 {tstNoStringer{}, false}, 186 } { 187 188 result, err := ns.Markdownify(test.s) 189 190 if bb, ok := test.expect.(bool); ok && !bb { 191 b.Assert(err, qt.Not(qt.IsNil)) 192 continue 193 } 194 195 b.Assert(err, qt.IsNil) 196 b.Assert(result, qt.Equals, test.expect) 197 } 198 } 199 200 // Issue #3040 201 func TestMarkdownifyBlocksOfText(t *testing.T) { 202 t.Parallel() 203 b := hugolib.NewIntegrationTestBuilder( 204 hugolib.IntegrationTestConfig{T: t}, 205 ).Build() 206 207 ns := transform.New(b.H.Deps) 208 209 text := ` 210 #First 211 212 This is some *bold* text. 213 214 ## Second 215 216 This is some more text. 217 218 And then some. 219 ` 220 221 result, err := ns.Markdownify(text) 222 b.Assert(err, qt.IsNil) 223 b.Assert(result, qt.Equals, template.HTML( 224 "<p>#First</p>\n<p>This is some <em>bold</em> text.</p>\n<h2 id=\"second\">Second</h2>\n<p>This is some more text.</p>\n<p>And then some.</p>\n")) 225 } 226 227 func TestPlainify(t *testing.T) { 228 t.Parallel() 229 b := hugolib.NewIntegrationTestBuilder( 230 hugolib.IntegrationTestConfig{T: t}, 231 ).Build() 232 233 ns := transform.New(b.H.Deps) 234 235 for _, test := range []struct { 236 s any 237 expect any 238 }{ 239 {"<em>Note:</em> blah <b>blah</b>", "Note: blah blah"}, 240 {"<div data-action='click->my-controller#doThing'>qwe</div>", "qwe"}, 241 // errors 242 {tstNoStringer{}, false}, 243 } { 244 245 result, err := ns.Plainify(test.s) 246 247 if bb, ok := test.expect.(bool); ok && !bb { 248 b.Assert(err, qt.Not(qt.IsNil)) 249 continue 250 } 251 252 b.Assert(err, qt.IsNil) 253 b.Assert(result, qt.Equals, test.expect) 254 } 255 } 256 257 func newDeps(cfg config.Provider) *deps.Deps { 258 cfg.Set("contentDir", "content") 259 cfg.Set("i18nDir", "i18n") 260 261 l := langs.NewLanguage("en", cfg) 262 263 cs, err := helpers.NewContentSpec(l, loggers.NewErrorLogger(), afero.NewMemMapFs(), nil) 264 if err != nil { 265 panic(err) 266 } 267 268 return &deps.Deps{ 269 Cfg: cfg, 270 Fs: hugofs.NewMem(l), 271 ContentSpec: cs, 272 } 273 }