diff --git a/hugolib/testhelpers_test.go b/hugolib/testhelpers_test.go index 7a87245a6..f43ac6907 100644 --- a/hugolib/testhelpers_test.go +++ b/hugolib/testhelpers_test.go @@ -3,10 +3,12 @@ package hugolib import ( "image/jpeg" "io" + "math/rand" "path/filepath" "runtime" "strconv" "testing" + "time" "unicode/utf8" "github.com/gohugoio/hugo/output" @@ -63,7 +65,7 @@ type sitesBuilder struct { *qt.C logger *loggers.Logger - + rnd *rand.Rand dumper litter.Options // Used to test partial rebuilds. @@ -89,17 +91,22 @@ type sitesBuilder struct { addNothing bool // Base data/content - contentFilePairs []string - templateFilePairs []string - i18nFilePairs []string - dataFilePairs []string + contentFilePairs []filenameContent + templateFilePairs []filenameContent + i18nFilePairs []filenameContent + dataFilePairs []filenameContent // Additional data/content. // As in "use the base, but add these on top". - contentFilePairsAdded []string - templateFilePairsAdded []string - i18nFilePairsAdded []string - dataFilePairsAdded []string + contentFilePairsAdded []filenameContent + templateFilePairsAdded []filenameContent + i18nFilePairsAdded []filenameContent + dataFilePairsAdded []filenameContent +} + +type filenameContent struct { + filename string + content string } func newTestSitesBuilder(t testing.TB) *sitesBuilder { @@ -112,7 +119,8 @@ func newTestSitesBuilder(t testing.TB) *sitesBuilder { Separator: " ", } - return &sitesBuilder{T: t, C: qt.New(t), Fs: fs, configFormat: "toml", dumper: litterOptions} + return &sitesBuilder{T: t, C: qt.New(t), Fs: fs, configFormat: "toml", + dumper: litterOptions, rnd: rand.New(rand.NewSource(time.Now().Unix()))} } func newTestSitesBuilderFromDepsCfg(t testing.TB, d deps.DepsCfg) *sitesBuilder { @@ -124,7 +132,7 @@ func newTestSitesBuilderFromDepsCfg(t testing.TB, d deps.DepsCfg) *sitesBuilder Separator: " ", } - b := &sitesBuilder{T: t, C: c, depsCfg: d, Fs: d.Fs, dumper: litterOptions} + b := &sitesBuilder{T: t, C: c, depsCfg: d, Fs: d.Fs, dumper: litterOptions, rnd: rand.New(rand.NewSource(time.Now().Unix()))} workingDir := d.Cfg.GetString("workingDir") b.WithWorkingDir(workingDir) @@ -349,43 +357,62 @@ func (s *sitesBuilder) WithSunset(in string) { src.Close() } +func (s *sitesBuilder) createFilenameContent(pairs []string) []filenameContent { + var slice []filenameContent + s.appendFilenameContent(&slice, pairs...) + return slice +} + +func (s *sitesBuilder) appendFilenameContent(slice *[]filenameContent, pairs ...string) { + if len(pairs)%2 != 0 { + panic("file content mismatch") + } + for i := 0; i < len(pairs); i += 2 { + c := filenameContent{ + filename: pairs[i], + content: pairs[i+1], + } + *slice = append(*slice, c) + } +} + func (s *sitesBuilder) WithContent(filenameContent ...string) *sitesBuilder { - s.contentFilePairs = append(s.contentFilePairs, filenameContent...) + s.appendFilenameContent(&s.contentFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithContentAdded(filenameContent ...string) *sitesBuilder { - s.contentFilePairsAdded = append(s.contentFilePairsAdded, filenameContent...) + s.appendFilenameContent(&s.contentFilePairsAdded, filenameContent...) return s } func (s *sitesBuilder) WithTemplates(filenameContent ...string) *sitesBuilder { - s.templateFilePairs = append(s.templateFilePairs, filenameContent...) + s.appendFilenameContent(&s.templateFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithTemplatesAdded(filenameContent ...string) *sitesBuilder { - s.templateFilePairsAdded = append(s.templateFilePairsAdded, filenameContent...) + s.appendFilenameContent(&s.templateFilePairsAdded, filenameContent...) return s } func (s *sitesBuilder) WithData(filenameContent ...string) *sitesBuilder { - s.dataFilePairs = append(s.dataFilePairs, filenameContent...) + s.appendFilenameContent(&s.dataFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithDataAdded(filenameContent ...string) *sitesBuilder { - s.dataFilePairsAdded = append(s.dataFilePairsAdded, filenameContent...) + s.appendFilenameContent(&s.dataFilePairsAdded, filenameContent...) return s } func (s *sitesBuilder) WithI18n(filenameContent ...string) *sitesBuilder { - s.i18nFilePairs = append(s.i18nFilePairs, filenameContent...) + s.appendFilenameContent(&s.i18nFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithI18nAdded(filenameContent ...string) *sitesBuilder { - s.i18nFilePairsAdded = append(s.i18nFilePairsAdded, filenameContent...) + s.appendFilenameContent(&s.i18nFilePairsAdded, filenameContent...) return s } @@ -409,15 +436,17 @@ func (s *sitesBuilder) RemoveFiles(filenames ...string) *sitesBuilder { return s } -func (s *sitesBuilder) writeFilePairs(folder string, filenameContent []string) *sitesBuilder { - if len(filenameContent)%2 != 0 { - s.Fatalf("expect filenameContent for %q in pairs (%d)", folder, len(filenameContent)) - } - for i := 0; i < len(filenameContent); i += 2 { - filename, content := filenameContent[i], filenameContent[i+1] +func (s *sitesBuilder) writeFilePairs(folder string, files []filenameContent) *sitesBuilder { + // We have had some "filesystem ordering" bugs that we have not discovered in + // our tests running with the in memory filesystem. + // That file system is backed by a map so not sure how this helps, but some + // randomness in tests doesn't hurt. + s.rnd.Shuffle(len(files), func(i, j int) { files[i], files[j] = files[j], files[i] }) + + for _, fc := range files { target := folder // TODO(bep) clean up this magic. - if strings.HasPrefix(filename, folder) { + if strings.HasPrefix(fc.filename, folder) { target = "" } @@ -425,7 +454,7 @@ func (s *sitesBuilder) writeFilePairs(folder string, filenameContent []string) * target = filepath.Join(s.workingDir, target) } - writeSource(s.T, s.Fs, filepath.Join(target, filename), content) + writeSource(s.T, s.Fs, filepath.Join(target, fc.filename), fc.content) } return s } @@ -640,16 +669,17 @@ hello: ) if len(s.contentFilePairs) == 0 { - s.writeFilePairs("content", defaultContent) + s.writeFilePairs("content", s.createFilenameContent(defaultContent)) } + if len(s.templateFilePairs) == 0 { - s.writeFilePairs("layouts", defaultTemplates) + s.writeFilePairs("layouts", s.createFilenameContent(defaultTemplates)) } if len(s.dataFilePairs) == 0 { - s.writeFilePairs("data", defaultData) + s.writeFilePairs("data", s.createFilenameContent(defaultData)) } if len(s.i18nFilePairs) == 0 { - s.writeFilePairs("i18n", defaultI18n) + s.writeFilePairs("i18n", s.createFilenameContent(defaultI18n)) } }