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