test_helpers.go (3760B)
1 // Copyright 2019 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 htesting 15 16 import ( 17 "math/rand" 18 "os" 19 "regexp" 20 "runtime" 21 "strconv" 22 "strings" 23 "time" 24 25 "github.com/spf13/afero" 26 ) 27 28 // IsTest reports whether we're running as a test. 29 var IsTest bool 30 31 func init() { 32 for _, arg := range os.Args { 33 if strings.HasPrefix(arg, "-test.") { 34 IsTest = true 35 break 36 } 37 } 38 } 39 40 // CreateTempDir creates a temp dir in the given filesystem and 41 // returns the dirnam and a func that removes it when done. 42 func CreateTempDir(fs afero.Fs, prefix string) (string, func(), error) { 43 tempDir, err := afero.TempDir(fs, "", prefix) 44 if err != nil { 45 return "", nil, err 46 } 47 48 _, isOsFs := fs.(*afero.OsFs) 49 50 if isOsFs && runtime.GOOS == "darwin" && !strings.HasPrefix(tempDir, "/private") { 51 // To get the entry folder in line with the rest. This its a little bit 52 // mysterious, but so be it. 53 tempDir = "/private" + tempDir 54 } 55 return tempDir, func() { fs.RemoveAll(tempDir) }, nil 56 } 57 58 // BailOut panics with a stack trace after the given duration. Useful for 59 // hanging tests. 60 func BailOut(after time.Duration) { 61 time.AfterFunc(after, func() { 62 buf := make([]byte, 1<<16) 63 runtime.Stack(buf, true) 64 panic(string(buf)) 65 }) 66 } 67 68 // Rnd is used only for testing. 69 var Rnd = rand.New(rand.NewSource(time.Now().UnixNano())) 70 71 func RandBool() bool { 72 return Rnd.Intn(2) != 0 73 } 74 75 // DiffStringSlices returns the difference between two string slices. 76 // Useful in tests. 77 // See: 78 // http://stackoverflow.com/questions/19374219/how-to-find-the-difference-between-two-slices-of-strings-in-golang 79 func DiffStringSlices(slice1 []string, slice2 []string) []string { 80 diffStr := []string{} 81 m := map[string]int{} 82 83 for _, s1Val := range slice1 { 84 m[s1Val] = 1 85 } 86 for _, s2Val := range slice2 { 87 m[s2Val] = m[s2Val] + 1 88 } 89 90 for mKey, mVal := range m { 91 if mVal == 1 { 92 diffStr = append(diffStr, mKey) 93 } 94 } 95 96 return diffStr 97 } 98 99 // DiffStrings splits the strings into fields and runs it into DiffStringSlices. 100 // Useful for tests. 101 func DiffStrings(s1, s2 string) []string { 102 return DiffStringSlices(strings.Fields(s1), strings.Fields(s2)) 103 } 104 105 // IsCI reports whether we're running in a CI server. 106 func IsCI() bool { 107 return (os.Getenv("CI") != "" || os.Getenv("CI_LOCAL") != "") && os.Getenv("CIRCLE_BRANCH") == "" 108 } 109 110 // IsGitHubAction reports whether we're running in a GitHub Action. 111 func IsGitHubAction() bool { 112 return os.Getenv("GITHUB_ACTION") != "" 113 } 114 115 // SupportsAll reports whether the running system supports all Hugo features, 116 // e.g. Asciidoc, Pandoc etc. 117 func SupportsAll() bool { 118 return IsGitHubAction() || os.Getenv("CI_LOCAL") != "" 119 } 120 121 // GoMinorVersion returns the minor version of the current Go version, 122 // e.g. 16 for Go 1.16. 123 func GoMinorVersion() int { 124 return extractMinorVersionFromGoTag(runtime.Version()) 125 } 126 127 var goMinorVersionRe = regexp.MustCompile(`go1.(\d*)`) 128 129 func extractMinorVersionFromGoTag(tag string) int { 130 // The tag may be on the form go1.17, go1.17.5 go1.17rc2 -- or just a commit hash. 131 match := goMinorVersionRe.FindStringSubmatch(tag) 132 133 if len(match) == 2 { 134 i, err := strconv.Atoi(match[1]) 135 if err != nil { 136 return -1 137 } 138 return i 139 } 140 141 // a commit hash, not useful. 142 return -1 143 144 }