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 }