2019-07-27 12:16:13 -04:00
|
|
|
// Copyright 2019 The Hugo Authors. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package hugolib
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2019-11-26 16:23:45 -05:00
|
|
|
"runtime"
|
2020-01-22 05:44:29 -05:00
|
|
|
"strings"
|
2019-07-27 12:16:13 -04:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/gohugoio/hugo/htesting"
|
|
|
|
|
2019-08-10 15:05:17 -04:00
|
|
|
qt "github.com/frankban/quicktest"
|
2019-07-27 12:16:13 -04:00
|
|
|
"github.com/gohugoio/hugo/hugofs"
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
)
|
|
|
|
|
|
|
|
// We have many tests for the different resize operations etc. in the resource package,
|
|
|
|
// this is an integration test.
|
2019-09-04 08:07:10 -04:00
|
|
|
func TestImageOps(t *testing.T) {
|
2019-08-10 15:05:17 -04:00
|
|
|
c := qt.New(t)
|
2019-07-27 12:16:13 -04:00
|
|
|
// Make this a real as possible.
|
|
|
|
workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "image-resize")
|
2019-08-10 15:05:17 -04:00
|
|
|
c.Assert(err, qt.IsNil)
|
2019-07-27 12:16:13 -04:00
|
|
|
defer clean()
|
|
|
|
|
2019-11-29 04:50:36 -05:00
|
|
|
newBuilder := func(timeout interface{}) *sitesBuilder {
|
2019-07-27 12:16:13 -04:00
|
|
|
v := viper.New()
|
|
|
|
v.Set("workingDir", workDir)
|
|
|
|
v.Set("baseURL", "https://example.org")
|
2019-11-25 06:49:04 -05:00
|
|
|
v.Set("timeout", timeout)
|
2019-07-27 12:16:13 -04:00
|
|
|
|
|
|
|
b := newTestSitesBuilder(t).WithWorkingDir(workDir)
|
|
|
|
b.Fs = hugofs.NewDefault(v)
|
|
|
|
b.WithViper(v)
|
|
|
|
b.WithContent("mybundle/index.md", `
|
|
|
|
---
|
|
|
|
title: "My bundle"
|
|
|
|
---
|
|
|
|
|
2019-11-25 06:49:04 -05:00
|
|
|
{{< imgproc >}}
|
|
|
|
|
2019-07-27 12:16:13 -04:00
|
|
|
`)
|
|
|
|
|
2019-11-25 06:49:04 -05:00
|
|
|
b.WithTemplatesAdded(
|
|
|
|
"shortcodes/imgproc.html", `
|
|
|
|
{{ $img := resources.Get "images/sunset.jpg" }}
|
|
|
|
{{ $r := $img.Resize "129x239" }}
|
|
|
|
IMG SHORTCODE: {{ $r.RelPermalink }}/{{ $r.Width }}
|
|
|
|
`,
|
|
|
|
"index.html", `
|
2019-07-27 12:16:13 -04:00
|
|
|
{{ $p := .Site.GetPage "mybundle" }}
|
|
|
|
{{ $img1 := resources.Get "images/sunset.jpg" }}
|
|
|
|
{{ $img2 := $p.Resources.GetMatch "sunset.jpg" }}
|
2019-08-13 12:45:08 -04:00
|
|
|
{{ $img3 := resources.GetMatch "images/*.jpg" }}
|
2019-07-27 12:16:13 -04:00
|
|
|
{{ $r := $img1.Resize "123x234" }}
|
|
|
|
{{ $r2 := $r.Resize "12x23" }}
|
|
|
|
{{ $b := $img2.Resize "345x678" }}
|
|
|
|
{{ $b2 := $b.Resize "34x67" }}
|
2019-08-13 12:45:08 -04:00
|
|
|
{{ $c := $img3.Resize "456x789" }}
|
2019-09-02 11:09:56 -04:00
|
|
|
{{ $fingerprinted := $img1.Resize "350x" | fingerprint }}
|
2019-07-27 12:16:13 -04:00
|
|
|
|
2019-09-02 11:09:56 -04:00
|
|
|
{{ $images := slice $r $r2 $b $b2 $c $fingerprinted }}
|
2019-07-27 12:16:13 -04:00
|
|
|
|
|
|
|
{{ range $i, $r := $images }}
|
|
|
|
{{ printf "Resized%d:" (add $i 1) }} {{ $r.Name }}|{{ $r.Width }}|{{ $r.Height }}|{{ $r.MediaType }}|{{ $r.RelPermalink }}|
|
|
|
|
{{ end }}
|
|
|
|
|
2019-09-04 08:07:10 -04:00
|
|
|
{{ $blurryGrayscale1 := $r | images.Filter images.Grayscale (images.GaussianBlur 8) }}
|
|
|
|
BG1: {{ $blurryGrayscale1.RelPermalink }}/{{ $blurryGrayscale1.Width }}
|
|
|
|
{{ $blurryGrayscale2 := $r.Filter images.Grayscale (images.GaussianBlur 8) }}
|
|
|
|
BG2: {{ $blurryGrayscale2.RelPermalink }}/{{ $blurryGrayscale2.Width }}
|
|
|
|
{{ $blurryGrayscale2_2 := $r.Filter images.Grayscale (images.GaussianBlur 8) }}
|
|
|
|
BG2_2: {{ $blurryGrayscale2_2.RelPermalink }}/{{ $blurryGrayscale2_2.Width }}
|
|
|
|
|
|
|
|
{{ $filters := slice images.Grayscale (images.GaussianBlur 9) }}
|
|
|
|
{{ $blurryGrayscale3 := $r | images.Filter $filters }}
|
|
|
|
BG3: {{ $blurryGrayscale3.RelPermalink }}/{{ $blurryGrayscale3.Width }}
|
|
|
|
|
|
|
|
{{ $blurryGrayscale4 := $r.Filter $filters }}
|
|
|
|
BG4: {{ $blurryGrayscale4.RelPermalink }}/{{ $blurryGrayscale4.Width }}
|
|
|
|
|
2019-11-25 06:49:04 -05:00
|
|
|
{{ $p.Content }}
|
2019-09-04 08:07:10 -04:00
|
|
|
|
2019-07-27 12:16:13 -04:00
|
|
|
`)
|
|
|
|
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
imageDir := filepath.Join(workDir, "assets", "images")
|
|
|
|
bundleDir := filepath.Join(workDir, "content", "mybundle")
|
|
|
|
|
2019-08-10 15:05:17 -04:00
|
|
|
c.Assert(os.MkdirAll(imageDir, 0777), qt.IsNil)
|
|
|
|
c.Assert(os.MkdirAll(bundleDir, 0777), qt.IsNil)
|
2019-07-27 12:16:13 -04:00
|
|
|
src, err := os.Open("testdata/sunset.jpg")
|
2019-08-10 15:05:17 -04:00
|
|
|
c.Assert(err, qt.IsNil)
|
2019-07-27 12:16:13 -04:00
|
|
|
out, err := os.Create(filepath.Join(imageDir, "sunset.jpg"))
|
2019-08-10 15:05:17 -04:00
|
|
|
c.Assert(err, qt.IsNil)
|
2019-07-27 12:16:13 -04:00
|
|
|
_, err = io.Copy(out, src)
|
2019-08-10 15:05:17 -04:00
|
|
|
c.Assert(err, qt.IsNil)
|
2019-07-27 12:16:13 -04:00
|
|
|
out.Close()
|
|
|
|
|
|
|
|
src.Seek(0, 0)
|
|
|
|
|
|
|
|
out, err = os.Create(filepath.Join(bundleDir, "sunset.jpg"))
|
2019-08-10 15:05:17 -04:00
|
|
|
c.Assert(err, qt.IsNil)
|
2019-07-27 12:16:13 -04:00
|
|
|
_, err = io.Copy(out, src)
|
2019-08-10 15:05:17 -04:00
|
|
|
c.Assert(err, qt.IsNil)
|
2019-07-27 12:16:13 -04:00
|
|
|
out.Close()
|
|
|
|
src.Close()
|
|
|
|
|
2019-11-25 06:49:04 -05:00
|
|
|
// First build it with a very short timeout to trigger errors.
|
|
|
|
b := newBuilder("10ns")
|
2019-07-27 12:16:13 -04:00
|
|
|
|
2019-09-02 11:09:56 -04:00
|
|
|
imgExpect := `
|
2019-12-19 09:04:18 -05:00
|
|
|
Resized1: images/sunset.jpg|123|234|image/jpeg|/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg|
|
|
|
|
Resized2: images/sunset.jpg|12|23|image/jpeg|/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_ada4bb1a57f77a63306e3bd67286248e.jpg|
|
|
|
|
Resized3: sunset.jpg|345|678|image/jpeg|/mybundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_345x678_resize_q75_box.jpg|
|
|
|
|
Resized4: sunset.jpg|34|67|image/jpeg|/mybundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_44d8c928664d7c5a67377c6ec58425ce.jpg|
|
|
|
|
Resized5: images/sunset.jpg|456|789|image/jpeg|/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_456x789_resize_q75_box.jpg|
|
|
|
|
Resized6: images/sunset.jpg|350|219|image/jpeg|/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_350x0_resize_q75_box.a86fe88d894e5db613f6aa8a80538fefc25b20fa24ba0d782c057adcef616f56.jpg|
|
2019-09-04 08:07:10 -04:00
|
|
|
BG1: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_2ae8bb993431ec1aec40fe59927b46b4.jpg/123
|
|
|
|
BG2: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_2ae8bb993431ec1aec40fe59927b46b4.jpg/123
|
|
|
|
BG3: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_ed7740a90b82802261c2fbdb98bc8082.jpg/123
|
|
|
|
BG4: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_ed7740a90b82802261c2fbdb98bc8082.jpg/123
|
2019-11-25 06:49:04 -05:00
|
|
|
IMG SHORTCODE: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_129x239_resize_q75_box.jpg/129
|
2019-09-02 11:09:56 -04:00
|
|
|
`
|
|
|
|
|
2019-11-25 06:49:04 -05:00
|
|
|
assertImages := func() {
|
|
|
|
b.Helper()
|
|
|
|
b.AssertFileContent(filepath.Join(workDir, "public/index.html"), imgExpect)
|
|
|
|
b.AssertImage(350, 219, "public/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_350x0_resize_q75_box.a86fe88d894e5db613f6aa8a80538fefc25b20fa24ba0d782c057adcef616f56.jpg")
|
|
|
|
b.AssertImage(129, 239, "public/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_129x239_resize_q75_box.jpg")
|
|
|
|
}
|
|
|
|
|
|
|
|
err = b.BuildE(BuildCfg{})
|
2020-12-23 03:26:23 -05:00
|
|
|
if runtime.GOOS != "windows" && !strings.Contains(runtime.GOARCH, "arm") && !htesting.IsGitHubAction() {
|
2019-11-26 16:23:45 -05:00
|
|
|
// TODO(bep)
|
|
|
|
c.Assert(err, qt.Not(qt.IsNil))
|
|
|
|
}
|
2019-11-25 06:49:04 -05:00
|
|
|
|
2019-11-29 04:50:36 -05:00
|
|
|
b = newBuilder(29000)
|
2019-11-25 06:49:04 -05:00
|
|
|
b.Build(BuildCfg{})
|
|
|
|
|
|
|
|
assertImages()
|
|
|
|
|
|
|
|
// Truncate one image.
|
|
|
|
imgInCache := filepath.Join(workDir, "resources/_gen/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_ed7740a90b82802261c2fbdb98bc8082.jpg")
|
|
|
|
f, err := os.Create(imgInCache)
|
|
|
|
c.Assert(err, qt.IsNil)
|
|
|
|
f.Close()
|
2019-07-27 12:16:13 -04:00
|
|
|
|
|
|
|
// Build it again to make sure we read images from file cache.
|
2019-11-25 06:49:04 -05:00
|
|
|
b = newBuilder("30s")
|
2019-07-27 12:16:13 -04:00
|
|
|
b.Build(BuildCfg{})
|
|
|
|
|
2019-11-25 06:49:04 -05:00
|
|
|
assertImages()
|
2019-07-27 12:16:13 -04:00
|
|
|
}
|
2019-09-03 04:36:09 -04:00
|
|
|
|
|
|
|
func TestImageResizeMultilingual(t *testing.T) {
|
|
|
|
b := newTestSitesBuilder(t).WithConfigFile("toml", `
|
|
|
|
baseURL="https://example.org"
|
|
|
|
defaultContentLanguage = "en"
|
|
|
|
|
|
|
|
[languages]
|
|
|
|
[languages.en]
|
|
|
|
title = "Title in English"
|
|
|
|
languageName = "English"
|
|
|
|
weight = 1
|
|
|
|
[languages.nn]
|
|
|
|
languageName = "Nynorsk"
|
|
|
|
weight = 2
|
|
|
|
title = "Tittel på nynorsk"
|
|
|
|
[languages.nb]
|
|
|
|
languageName = "Bokmål"
|
|
|
|
weight = 3
|
|
|
|
title = "Tittel på bokmål"
|
|
|
|
[languages.fr]
|
|
|
|
languageName = "French"
|
|
|
|
weight = 4
|
|
|
|
title = "French Title"
|
|
|
|
|
|
|
|
`)
|
|
|
|
|
|
|
|
pageContent := `---
|
|
|
|
title: "Page"
|
|
|
|
---
|
|
|
|
`
|
|
|
|
|
|
|
|
b.WithContent("bundle/index.md", pageContent)
|
|
|
|
b.WithContent("bundle/index.nn.md", pageContent)
|
|
|
|
b.WithContent("bundle/index.fr.md", pageContent)
|
|
|
|
b.WithSunset("content/bundle/sunset.jpg")
|
|
|
|
b.WithSunset("assets/images/sunset.jpg")
|
|
|
|
b.WithTemplates("index.html", `
|
|
|
|
{{ with (.Site.GetPage "bundle" ) }}
|
|
|
|
{{ $sunset := .Resources.GetMatch "sunset*" }}
|
|
|
|
{{ if $sunset }}
|
|
|
|
{{ $resized := $sunset.Resize "200x200" }}
|
|
|
|
SUNSET FOR: {{ $.Site.Language.Lang }}: {{ $resized.RelPermalink }}/{{ $resized.Width }}/Lat: {{ $resized.Exif.Lat }}
|
|
|
|
{{ end }}
|
|
|
|
{{ else }}
|
|
|
|
No bundle for {{ $.Site.Language.Lang }}
|
|
|
|
{{ end }}
|
|
|
|
|
|
|
|
{{ $sunset2 := resources.Get "images/sunset.jpg" }}
|
|
|
|
{{ $resized2 := $sunset2.Resize "123x234" }}
|
|
|
|
SUNSET2: {{ $resized2.RelPermalink }}/{{ $resized2.Width }}/Lat: {{ $resized2.Exif.Lat }}
|
|
|
|
|
2019-09-04 08:07:10 -04:00
|
|
|
|
2019-09-03 04:36:09 -04:00
|
|
|
`)
|
|
|
|
|
|
|
|
b.Build(BuildCfg{})
|
|
|
|
|
|
|
|
b.AssertFileContent("public/index.html", "SUNSET FOR: en: /bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg/200/Lat: 36.59744166666667")
|
|
|
|
b.AssertFileContent("public/fr/index.html", "SUNSET FOR: fr: /fr/bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg/200/Lat: 36.59744166666667")
|
|
|
|
b.AssertFileContent("public/index.html", " SUNSET2: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg/123/Lat: 36.59744166666667")
|
|
|
|
b.AssertFileContent("public/nn/index.html", " SUNSET2: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg/123/Lat: 36.59744166666667")
|
|
|
|
|
|
|
|
b.AssertImage(200, 200, "public/fr/bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg")
|
|
|
|
b.AssertImage(200, 200, "public/bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg")
|
|
|
|
|
|
|
|
// Check the file cache
|
|
|
|
b.AssertImage(200, 200, "resources/_gen/images/bundle/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x200_resize_q75_box.jpg")
|
2019-10-20 04:39:00 -04:00
|
|
|
|
|
|
|
b.AssertFileContent("resources/_gen/images/bundle/sunset_7645215769587362592.json",
|
2019-09-03 04:36:09 -04:00
|
|
|
"DateTimeDigitized|time.Time", "PENTAX")
|
|
|
|
b.AssertImage(123, 234, "resources/_gen/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg")
|
2019-10-20 04:39:00 -04:00
|
|
|
b.AssertFileContent("resources/_gen/images/sunset_7645215769587362592.json",
|
2019-09-03 04:36:09 -04:00
|
|
|
"DateTimeDigitized|time.Time", "PENTAX")
|
|
|
|
|
2019-09-06 03:28:43 -04:00
|
|
|
// TODO(bep) add this as a default assertion after Build()?
|
|
|
|
b.AssertNoDuplicateWrites()
|
2019-09-03 04:36:09 -04:00
|
|
|
}
|