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 }