testhelpers_test.go (5285B)
1 package resources
2
3 import (
4 "image"
5 "io"
6 "io/ioutil"
7 "os"
8 "path/filepath"
9 "runtime"
10 "strings"
11 "testing"
12
13 "github.com/gohugoio/hugo/config"
14 "github.com/gohugoio/hugo/langs"
15 "github.com/gohugoio/hugo/modules"
16
17 qt "github.com/frankban/quicktest"
18 "github.com/gohugoio/hugo/cache/filecache"
19 "github.com/gohugoio/hugo/helpers"
20 "github.com/gohugoio/hugo/hugofs"
21 "github.com/gohugoio/hugo/media"
22 "github.com/gohugoio/hugo/output"
23 "github.com/gohugoio/hugo/resources/images"
24 "github.com/gohugoio/hugo/resources/page"
25 "github.com/gohugoio/hugo/resources/resource"
26 "github.com/spf13/afero"
27 )
28
29 type specDescriptor struct {
30 baseURL string
31 c *qt.C
32 fs afero.Fs
33 }
34
35 func createTestCfg() config.Provider {
36 cfg := config.New()
37 cfg.Set("resourceDir", "resources")
38 cfg.Set("contentDir", "content")
39 cfg.Set("dataDir", "data")
40 cfg.Set("i18nDir", "i18n")
41 cfg.Set("layoutDir", "layouts")
42 cfg.Set("assetDir", "assets")
43 cfg.Set("archetypeDir", "archetypes")
44 cfg.Set("publishDir", "public")
45
46 langs.LoadLanguageSettings(cfg, nil)
47 mod, err := modules.CreateProjectModule(cfg)
48 if err != nil {
49 panic(err)
50 }
51 cfg.Set("allModules", modules.Modules{mod})
52
53 return cfg
54 }
55
56 func newTestResourceSpec(desc specDescriptor) *Spec {
57 baseURL := desc.baseURL
58 if baseURL == "" {
59 baseURL = "https://example.com/"
60 }
61
62 afs := desc.fs
63 if afs == nil {
64 afs = afero.NewMemMapFs()
65 }
66
67 afs = hugofs.NewBaseFileDecorator(afs)
68
69 c := desc.c
70
71 cfg := createTestCfg()
72 cfg.Set("baseURL", baseURL)
73
74 imagingCfg := map[string]any{
75 "resampleFilter": "linear",
76 "quality": 68,
77 "anchor": "left",
78 }
79
80 cfg.Set("imaging", imagingCfg)
81
82 fs := hugofs.NewFrom(afs, cfg)
83 fs.PublishDir = hugofs.NewCreateCountingFs(fs.PublishDir)
84
85 s, err := helpers.NewPathSpec(fs, cfg, nil)
86 c.Assert(err, qt.IsNil)
87
88 filecaches, err := filecache.NewCaches(s)
89 c.Assert(err, qt.IsNil)
90
91 spec, err := NewSpec(s, filecaches, nil, nil, nil, nil, output.DefaultFormats, media.DefaultTypes)
92 c.Assert(err, qt.IsNil)
93 return spec
94 }
95
96 func newTargetPaths(link string) func() page.TargetPaths {
97 return func() page.TargetPaths {
98 return page.TargetPaths{
99 SubResourceBaseTarget: filepath.FromSlash(link),
100 SubResourceBaseLink: link,
101 }
102 }
103 }
104
105 func newTestResourceOsFs(c *qt.C) (*Spec, string) {
106 cfg := createTestCfg()
107 cfg.Set("baseURL", "https://example.com")
108
109 workDir, err := ioutil.TempDir("", "hugores")
110 c.Assert(err, qt.IsNil)
111 c.Assert(workDir, qt.Not(qt.Equals), "")
112
113 if runtime.GOOS == "darwin" && !strings.HasPrefix(workDir, "/private") {
114 // To get the entry folder in line with the rest. This its a little bit
115 // mysterious, but so be it.
116 workDir = "/private" + workDir
117 }
118
119 cfg.Set("workingDir", workDir)
120
121 fs := hugofs.NewFrom(hugofs.NewBaseFileDecorator(hugofs.Os), cfg)
122
123 s, err := helpers.NewPathSpec(fs, cfg, nil)
124 c.Assert(err, qt.IsNil)
125
126 filecaches, err := filecache.NewCaches(s)
127 c.Assert(err, qt.IsNil)
128
129 spec, err := NewSpec(s, filecaches, nil, nil, nil, nil, output.DefaultFormats, media.DefaultTypes)
130 c.Assert(err, qt.IsNil)
131
132 return spec, workDir
133 }
134
135 func fetchSunset(c *qt.C) images.ImageResource {
136 return fetchImage(c, "sunset.jpg")
137 }
138
139 func fetchImage(c *qt.C, name string) images.ImageResource {
140 spec := newTestResourceSpec(specDescriptor{c: c})
141 return fetchImageForSpec(spec, c, name)
142 }
143
144 func fetchImageForSpec(spec *Spec, c *qt.C, name string) images.ImageResource {
145 r := fetchResourceForSpec(spec, c, name)
146
147 img := r.(images.ImageResource)
148
149 c.Assert(img, qt.Not(qt.IsNil))
150 c.Assert(img.(specProvider).getSpec(), qt.Not(qt.IsNil))
151
152 return img
153 }
154
155 func fetchResourceForSpec(spec *Spec, c *qt.C, name string, targetPathAddends ...string) resource.ContentResource {
156 src, err := os.Open(filepath.FromSlash("testdata/" + name))
157 c.Assert(err, qt.IsNil)
158 workDir := spec.WorkingDir
159 if len(targetPathAddends) > 0 {
160 addends := strings.Join(targetPathAddends, "_")
161 name = addends + "_" + name
162 }
163 targetFilename := filepath.Join(workDir, name)
164 out, err := helpers.OpenFileForWriting(spec.Fs.Source, targetFilename)
165 c.Assert(err, qt.IsNil)
166 _, err = io.Copy(out, src)
167 out.Close()
168 src.Close()
169 c.Assert(err, qt.IsNil)
170
171 factory := newTargetPaths("/a")
172
173 r, err := spec.New(ResourceSourceDescriptor{Fs: spec.Fs.Source, TargetPaths: factory, LazyPublish: true, RelTargetFilename: name, SourceFilename: targetFilename})
174 c.Assert(err, qt.IsNil)
175 c.Assert(r, qt.Not(qt.IsNil))
176
177 return r.(resource.ContentResource)
178 }
179
180 func assertImageFile(c *qt.C, fs afero.Fs, filename string, width, height int) {
181 filename = filepath.Clean(filename)
182 f, err := fs.Open(filename)
183 c.Assert(err, qt.IsNil)
184 defer f.Close()
185
186 config, _, err := image.DecodeConfig(f)
187 c.Assert(err, qt.IsNil)
188
189 c.Assert(config.Width, qt.Equals, width)
190 c.Assert(config.Height, qt.Equals, height)
191 }
192
193 func assertFileCache(c *qt.C, fs afero.Fs, filename string, width, height int) {
194 assertImageFile(c, fs, filepath.Clean(filename), width, height)
195 }
196
197 func writeSource(t testing.TB, fs *hugofs.Fs, filename, content string) {
198 writeToFs(t, fs.Source, filename, content)
199 }
200
201 func writeToFs(t testing.TB, fs afero.Fs, filename, content string) {
202 if err := afero.WriteFile(fs, filepath.FromSlash(filename), []byte(content), 0755); err != nil {
203 t.Fatalf("Failed to write file: %s", err)
204 }
205 }