github.com/gohugoio/hugo@v0.88.1/create/content_test.go (about) 1 // Copyright 2016 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 create_test 15 16 import ( 17 "fmt" 18 "os" 19 "path/filepath" 20 "strings" 21 "testing" 22 23 "github.com/gohugoio/hugo/config" 24 25 "github.com/gohugoio/hugo/deps" 26 27 "github.com/gohugoio/hugo/hugolib" 28 29 "github.com/gohugoio/hugo/hugofs" 30 31 qt "github.com/frankban/quicktest" 32 "github.com/gohugoio/hugo/create" 33 "github.com/gohugoio/hugo/helpers" 34 "github.com/spf13/afero" 35 ) 36 37 func TestNewContent(t *testing.T) { 38 cases := []struct { 39 kind string 40 path string 41 expected []string 42 }{ 43 {"post", "post/sample-1.md", []string{`title = "Post Arch title"`, `test = "test1"`, "date = \"2015-01-12T19:20:04-07:00\""}}, 44 {"post", "post/org-1.org", []string{`#+title: ORG-1`}}, 45 {"emptydate", "post/sample-ed.md", []string{`title = "Empty Date Arch title"`, `test = "test1"`}}, 46 {"stump", "stump/sample-2.md", []string{`title: "Sample 2"`}}, // no archetype file 47 {"", "sample-3.md", []string{`title: "Sample 3"`}}, // no archetype 48 {"product", "product/sample-4.md", []string{`title = "SAMPLE-4"`}}, // empty archetype front matter 49 {"lang", "post/lang-1.md", []string{`Site Lang: en|Name: Lang 1|i18n: Hugo Rocks!`}}, 50 {"lang", "post/lang-2.en.md", []string{`Site Lang: en|Name: Lang 2|i18n: Hugo Rocks!`}}, 51 {"lang", "content/post/lang-3.nn.md", []string{`Site Lang: nn|Name: Lang 3|i18n: Hugo Rokkar!`}}, 52 {"lang", "content_nn/post/lang-4.md", []string{`Site Lang: nn|Name: Lang 4|i18n: Hugo Rokkar!`}}, 53 {"lang", "content_nn/post/lang-5.en.md", []string{`Site Lang: en|Name: Lang 5|i18n: Hugo Rocks!`}}, 54 {"lang", "post/my-bundle/index.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}}, 55 {"lang", "post/my-bundle/index.en.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}}, 56 {"lang", "content/post/my-bundle/index.nn.md", []string{`Site Lang: nn|Name: My Bundle|i18n: Hugo Rokkar!`}}, 57 {"shortcodes", "shortcodes/go.md", []string{ 58 `title = "GO"`, 59 "{{< myshortcode >}}", 60 "{{% myshortcode %}}", 61 "{{</* comment */>}}\n{{%/* comment */%}}", 62 }}, // shortcodes 63 } 64 65 for i, cas := range cases { 66 cas := cas 67 t.Run(fmt.Sprintf("%s-%d", cas.kind, i), func(t *testing.T) { 68 t.Parallel() 69 c := qt.New(t) 70 mm := afero.NewMemMapFs() 71 c.Assert(initFs(mm), qt.IsNil) 72 cfg, fs := newTestCfg(c, mm) 73 h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) 74 c.Assert(err, qt.IsNil) 75 76 c.Assert(create.NewContent(h, cas.kind, cas.path), qt.IsNil) 77 78 fname := filepath.FromSlash(cas.path) 79 if !strings.HasPrefix(fname, "content") { 80 fname = filepath.Join("content", fname) 81 } 82 content := readFileFromFs(t, fs.Source, fname) 83 for _, v := range cas.expected { 84 found := strings.Contains(content, v) 85 if !found { 86 t.Fatalf("[%d] %q missing from output:\n%q", i, v, content) 87 } 88 } 89 }) 90 91 } 92 } 93 94 func TestNewContentFromDir(t *testing.T) { 95 mm := afero.NewMemMapFs() 96 c := qt.New(t) 97 98 archetypeDir := filepath.Join("archetypes", "my-bundle") 99 c.Assert(mm.MkdirAll(archetypeDir, 0755), qt.IsNil) 100 101 archetypeThemeDir := filepath.Join("themes", "mytheme", "archetypes", "my-theme-bundle") 102 c.Assert(mm.MkdirAll(archetypeThemeDir, 0755), qt.IsNil) 103 104 contentFile := ` 105 File: %s 106 Site Lang: {{ .Site.Language.Lang }} 107 Name: {{ replace .Name "-" " " | title }} 108 i18n: {{ T "hugo" }} 109 ` 110 111 c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755), qt.IsNil) 112 c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.nn.md"), []byte(fmt.Sprintf(contentFile, "index.nn.md")), 0755), qt.IsNil) 113 114 c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "pages", "bio.md"), []byte(fmt.Sprintf(contentFile, "bio.md")), 0755), qt.IsNil) 115 c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755), qt.IsNil) 116 c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo2.xml"), []byte(`hugo2: {{ printf "no template handling in here" }}`), 0755), qt.IsNil) 117 118 c.Assert(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755), qt.IsNil) 119 c.Assert(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755), qt.IsNil) 120 121 c.Assert(initFs(mm), qt.IsNil) 122 cfg, fs := newTestCfg(c, mm) 123 124 h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) 125 c.Assert(err, qt.IsNil) 126 c.Assert(len(h.Sites), qt.Equals, 2) 127 128 c.Assert(create.NewContent(h, "my-bundle", "post/my-post"), qt.IsNil) 129 130 cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`) 131 cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo2.xml")), `hugo2: {{ printf "no template handling in here" }}`) 132 133 // Content files should get the correct site context. 134 // TODO(bep) archetype check i18n 135 cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Post`, `i18n: Hugo Rocks!`) 136 cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.nn.md")), `File: index.nn.md`, `Site Lang: nn`, `Name: My Post`, `i18n: Hugo Rokkar!`) 137 138 cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/pages/bio.md")), `File: bio.md`, `Site Lang: en`, `Name: My Post`) 139 140 c.Assert(create.NewContent(h, "my-theme-bundle", "post/my-theme-post"), qt.IsNil) 141 cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Theme Post`, `i18n: Hugo Rocks!`) 142 cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`) 143 } 144 145 func initFs(fs afero.Fs) error { 146 perm := os.FileMode(0755) 147 var err error 148 149 // create directories 150 dirs := []string{ 151 "archetypes", 152 "content", 153 filepath.Join("themes", "sample", "archetypes"), 154 } 155 for _, dir := range dirs { 156 err = fs.Mkdir(dir, perm) 157 if err != nil && !os.IsExist(err) { 158 return err 159 } 160 } 161 162 // create files 163 for _, v := range []struct { 164 path string 165 content string 166 }{ 167 { 168 path: filepath.Join("archetypes", "post.md"), 169 content: "+++\ndate = \"2015-01-12T19:20:04-07:00\"\ntitle = \"Post Arch title\"\ntest = \"test1\"\n+++\n", 170 }, 171 { 172 path: filepath.Join("archetypes", "post.org"), 173 content: "#+title: {{ .BaseFileName | upper }}", 174 }, 175 { 176 path: filepath.Join("archetypes", "product.md"), 177 content: `+++ 178 title = "{{ .BaseFileName | upper }}" 179 +++`, 180 }, 181 { 182 path: filepath.Join("archetypes", "emptydate.md"), 183 content: "+++\ndate =\"\"\ntitle = \"Empty Date Arch title\"\ntest = \"test1\"\n+++\n", 184 }, 185 { 186 path: filepath.Join("archetypes", "lang.md"), 187 content: `Site Lang: {{ .Site.Language.Lang }}|Name: {{ replace .Name "-" " " | title }}|i18n: {{ T "hugo" }}`, 188 }, 189 // #3623x 190 { 191 path: filepath.Join("archetypes", "shortcodes.md"), 192 content: `+++ 193 title = "{{ .BaseFileName | upper }}" 194 +++ 195 196 {{< myshortcode >}} 197 198 Some text. 199 200 {{% myshortcode %}} 201 {{</* comment */>}} 202 {{%/* comment */%}} 203 204 205 `, 206 }, 207 } { 208 f, err := fs.Create(v.path) 209 if err != nil { 210 return err 211 } 212 defer f.Close() 213 214 _, err = f.Write([]byte(v.content)) 215 if err != nil { 216 return err 217 } 218 } 219 220 return nil 221 } 222 223 func cContains(c *qt.C, v interface{}, matches ...string) { 224 for _, m := range matches { 225 c.Assert(v, qt.Contains, m) 226 } 227 } 228 229 // TODO(bep) extract common testing package with this and some others 230 func readFileFromFs(t *testing.T, fs afero.Fs, filename string) string { 231 t.Helper() 232 filename = filepath.FromSlash(filename) 233 b, err := afero.ReadFile(fs, filename) 234 if err != nil { 235 // Print some debug info 236 root := strings.Split(filename, helpers.FilePathSeparator)[0] 237 afero.Walk(fs, root, func(path string, info os.FileInfo, err error) error { 238 if info != nil && !info.IsDir() { 239 fmt.Println(" ", path) 240 } 241 242 return nil 243 }) 244 t.Fatalf("Failed to read file: %s", err) 245 } 246 return string(b) 247 } 248 249 func newTestCfg(c *qt.C, mm afero.Fs) (config.Provider, *hugofs.Fs) { 250 cfg := ` 251 252 theme = "mytheme" 253 [languages] 254 [languages.en] 255 weight = 1 256 languageName = "English" 257 [languages.nn] 258 weight = 2 259 languageName = "Nynorsk" 260 contentDir = "content_nn" 261 262 ` 263 if mm == nil { 264 mm = afero.NewMemMapFs() 265 } 266 267 mm.MkdirAll(filepath.FromSlash("content_nn"), 0777) 268 269 mm.MkdirAll(filepath.FromSlash("themes/mytheme"), 0777) 270 271 c.Assert(afero.WriteFile(mm, filepath.Join("i18n", "en.toml"), []byte(`[hugo] 272 other = "Hugo Rocks!"`), 0755), qt.IsNil) 273 c.Assert(afero.WriteFile(mm, filepath.Join("i18n", "nn.toml"), []byte(`[hugo] 274 other = "Hugo Rokkar!"`), 0755), qt.IsNil) 275 276 c.Assert(afero.WriteFile(mm, "config.toml", []byte(cfg), 0755), qt.IsNil) 277 278 v, _, err := hugolib.LoadConfig(hugolib.ConfigSourceDescriptor{Fs: mm, Filename: "config.toml"}) 279 c.Assert(err, qt.IsNil) 280 281 return v, hugofs.NewFrom(mm, v) 282 }