github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/htesting/test_helpers.go (about)

     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  }