mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Revert "Expansion of unit tests for utils/utils.go"
Rationale: Test failing on Windows with errors like this:
utils_test.go:177: Error: Could not remove file "f".
Error: remove C:\Users\appveyor\AppData\Local\Temp\utils_test_747965610:
The process cannot access the file because it is being used by another
process.
This reverts commit 6b28e38cea
.
Sorry for my premature merge of Pull Request #818.
This commit is contained in:
parent
c2e2913872
commit
82a0888995
2 changed files with 25 additions and 179 deletions
|
@ -22,39 +22,36 @@ func CheckErr(err error, s ...string) {
|
||||||
|
|
||||||
func StopOnErr(err error, s ...string) {
|
func StopOnErr(err error, s ...string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doStopOnErr(err, s...)
|
if len(s) == 0 {
|
||||||
os.Exit(-1)
|
newMessage := cutUsageMessage(err.Error())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func doStopOnErr(err error, s ...string) {
|
// Printing an empty string results in a error with
|
||||||
if len(s) == 0 {
|
// no message, no bueno.
|
||||||
newMessage := cutUsageMessage(err.Error())
|
if newMessage != "" {
|
||||||
// Printing an empty string results in a error with
|
jww.CRITICAL.Println(newMessage)
|
||||||
// no message, no bueno.
|
}
|
||||||
if newMessage != "" {
|
} else {
|
||||||
jww.CRITICAL.Println(newMessage)
|
for _, message := range s {
|
||||||
}
|
message := cutUsageMessage(message)
|
||||||
} else {
|
|
||||||
for _, message := range s {
|
|
||||||
message := cutUsageMessage(message)
|
|
||||||
|
|
||||||
if message != "" {
|
if message != "" {
|
||||||
jww.CRITICAL.Println(message)
|
jww.CRITICAL.Println(message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cutUsageMessage splits the incoming string on the beginning of the usage
|
// cutUsageMessage splits the incoming string on the beginning of the usage
|
||||||
// message text. Anything in the first element of the returned slice, trimmed
|
// message text. Anything in the first element of the returned slice, trimmed
|
||||||
// of its Unicode defined spaces, should be returned. The 2nd element of the
|
// of its Unicode defined spaces, should be returned. The 2nd element of the
|
||||||
// slice will have the usage message that we wish to elide.
|
// slice will have the usage message that we wish to elide.
|
||||||
//
|
//
|
||||||
// This is done because Cobra already prints Hugo's usage message; not eliding
|
// This is done because Cobra already prints Hugo's usage message; not eliding
|
||||||
// would result in the usage output being printed twice, which leads to bug
|
// would result in the usage output being printed twice, which leads to bug
|
||||||
// reports, more specifically: https://github.com/spf13/hugo/issues/374
|
// reports, more specifically: https://github.com/spf13/hugo/issues/374
|
||||||
func cutUsageMessage(s string) string {
|
func cutUsageMessage(s string) string {
|
||||||
pieces := strings.Split(s, "Usage of")
|
pieces := strings.Split(s, "Usage of")
|
||||||
return strings.TrimSpace(pieces[0])
|
return strings.TrimSpace(pieces[0])
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,22 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
|
||||||
)
|
|
||||||
|
|
||||||
type testData struct {
|
|
||||||
logLevel string
|
|
||||||
logError string
|
|
||||||
logStr []string
|
|
||||||
logFileExpected bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCutUsageMessage(t *testing.T) {
|
func TestCutUsageMessage(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct{
|
||||||
message string
|
message string
|
||||||
cutMessage string
|
cutMessage string
|
||||||
}{
|
}{
|
||||||
{"", ""},
|
{"", ""},
|
||||||
{" Usage of hugo: \n -b, --baseUrl=...", ""},
|
{" Usage of hugo: \n -b, --baseUrl=...", ""},
|
||||||
{"Some error Usage of hugo: \n", "Some error"},
|
{"Some error Usage of hugo: \n", "Some error"},
|
||||||
{"Usage of hugo: \n -b --baseU", ""},
|
{"Usage of hugo: \n -b --baseU", ""},
|
||||||
{"CRITICAL error for usage of hugo ", "CRITICAL error for usage of hugo"},
|
{"CRITICAL error for usage of hugo ", "CRITICAL error for usage of hugo"},
|
||||||
{"Invalid short flag a in -abcde", "Invalid short flag a in -abcde"},
|
{"Invalid short flag a in -abcde", "Invalid short flag a in -abcde"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -39,141 +26,3 @@ func TestCutUsageMessage(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckErr(t *testing.T) {
|
|
||||||
tests := []testData{
|
|
||||||
{"ERROR", "first test case", []string{""}, true},
|
|
||||||
{"ERROR", "second test case", []string{"banana", "man"}, true},
|
|
||||||
{"ERROR", "third test case", []string{"multi-word string"}, true},
|
|
||||||
{"ERROR", "fourth test case", []string{"multiple", "multi-word strings"}, true},
|
|
||||||
{"CRITICAL", "Oops no array of strings", []string{}, true},
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
filename := setup(t)
|
|
||||||
defer teardown(t, filename)
|
|
||||||
CheckErr(errors.New(test.logError), test.logStr...) // converts the array of strings in test.logStr to a varadic - cool!
|
|
||||||
checkLogFile(t, filename, &test)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDoStopOnErr(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
message string
|
|
||||||
cutMessage string
|
|
||||||
t testData
|
|
||||||
}{
|
|
||||||
{"", "", testData{"", "", []string{}, false}},
|
|
||||||
{" Usage of hugo: \n -b, --baseUrl=...", "", testData{"", "", []string{}, false}},
|
|
||||||
{"Some error Usage of hugo: \n", "Some error", testData{"CRITICAL", "Some error", []string{}, true}},
|
|
||||||
// sould get the same output if we pass any array of strings and not via the error
|
|
||||||
{"Some error Usage of hugo: \n", "Some error", testData{"CRITICAL", "", []string{"Some error"}, true}},
|
|
||||||
{"Usage of hugo: \n -b --baseU", "", testData{"", "", []string{""}, false}},
|
|
||||||
{"CRITICAL error for usage of hugo ", "CRITICAL error for usage of hugo", testData{"CRITICAL", "CRITICAL error for usage of hugo", []string{""}, false}},
|
|
||||||
{"CRITICAL error for usage of hugo ", "CRITICAL error for usage of hugo", testData{"CRITICAL", "", []string{"CRITICAL error for usage of hugo"}, true}},
|
|
||||||
{"Invalid short flag a in -abcde", "Invalid short flag a in -abcde", testData{"CRITICAL", "Invalid short flag a in -abcde", []string{""}, false}},
|
|
||||||
{"Invalid short flag a in -abcde", "Invalid short flag a in -abcde", testData{"CRITICAL", "", []string{"Invalid short flag a in -abcde"}, true}},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
filename := setup(t)
|
|
||||||
defer teardown(t, filename)
|
|
||||||
doStopOnErr(errors.New(test.t.logError), test.t.logStr...) // converts the array of strings in test.logStr to a varadic - cool!
|
|
||||||
checkLogFile(t, filename, &test.t)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkLogFile(t *testing.T, filename string, test *testData) {
|
|
||||||
contents, err := ioutil.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Could not open the log file \"%s\". Failed with %v\n", filename, err)
|
|
||||||
}
|
|
||||||
// does the test expect to have a log file. If so, it must also have contents.
|
|
||||||
if !logFileIsExpectedAndValid(t, filename, test, &contents) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r := bytes.NewReader(contents)
|
|
||||||
scanner := bufio.NewScanner(r)
|
|
||||||
errorMessageMatches := false
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
// lines in the log file are of the form:
|
|
||||||
// <log level>: yyyy/mm/dd <string|error message>
|
|
||||||
// we pase this format left to right in three sections
|
|
||||||
checkForExpectedLogLevelOrFail(t, line, test)
|
|
||||||
errorMessageMatches = checkForExpectedErrorMsg(t, line, test)
|
|
||||||
// There was no match against the error message. So see if it matchs one of the error strings
|
|
||||||
if !errorMessageMatches {
|
|
||||||
checkForExpectedStingOrFail(t, line, test)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = scanner.Err(); err != nil {
|
|
||||||
t.Fatalf("Could not scan the next token in the log file. Failed with: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func logFileIsExpectedAndValid(t *testing.T, filename string, test *testData, contents *[]byte) bool {
|
|
||||||
if test.logFileExpected {
|
|
||||||
// yup, so then the file cannot be empty.
|
|
||||||
if len(*contents) == 0 {
|
|
||||||
t.Fatalf("Unexpected empty log file! Filename:\"%s\"\n", filename)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// we don't expect a log file for this test so bail here.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkForExpectedLogLevelOrFail(t *testing.T, line string, test *testData) {
|
|
||||||
regexpErrorLabel := "^" + test.logLevel
|
|
||||||
validErrorLevel := regexp.MustCompile(regexpErrorLabel)
|
|
||||||
if !validErrorLevel.MatchString(line) {
|
|
||||||
// can't find the expected start of line string. So fail
|
|
||||||
t.Fatalf("Did not find the expected log level \"%s\" at the start of the line \"%s\"\n", test.logLevel, line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkForExpectedErrorMsg(t *testing.T, line string, test *testData) bool {
|
|
||||||
regexpValidErrorMsg := test.logError + "$"
|
|
||||||
validErrorMsg := regexp.MustCompile(regexpValidErrorMsg)
|
|
||||||
return validErrorMsg.MatchString(line)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkForExpectedStingOrFail(t *testing.T, line string, test *testData) {
|
|
||||||
for _, s := range test.logStr {
|
|
||||||
regexpstr := s + "$"
|
|
||||||
validLineEnd := regexp.MustCompile(regexpstr)
|
|
||||||
if validLineEnd.MatchString(line) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if we reach here there was no match.
|
|
||||||
// Note: It's not possibe for this to be called with test.logStr as an empty array.
|
|
||||||
// The proceeding call to checkForExpectedErrorMsg
|
|
||||||
// in checkLogFile guarentees this. i.e. checkForExpecedErrorMsg will return true in this case.
|
|
||||||
t.Fatalf("Did not find any of the strings \"%v\" in \"%s\"\n", test.logStr, line)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setup(t *testing.T) string {
|
|
||||||
// first set the logger
|
|
||||||
// we can't use jww.UseLogTempFile for this, becase we need the file name
|
|
||||||
// so we can delete the file in teardown function.
|
|
||||||
// We should really fix jww.UseLogTempFile so we can access the temp file, or
|
|
||||||
// better yet provide a "DeleteTempLogFile" function
|
|
||||||
const logfilename = "utils_test_"
|
|
||||||
f, err := ioutil.TempFile(os.TempDir(), logfilename)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Error: Could not create temporary file for the logger. Error: %#v\n", err)
|
|
||||||
}
|
|
||||||
jww.SetStdoutThreshold(jww.LevelFatal)
|
|
||||||
// jww.SetLogFile generates the "Logging to .... " line on stdout.
|
|
||||||
// Maybe we should update jww to remove the fmt.PrintF calls?
|
|
||||||
jww.SetLogFile(f.Name())
|
|
||||||
return f.Name()
|
|
||||||
}
|
|
||||||
|
|
||||||
func teardown(t *testing.T, f string) {
|
|
||||||
if err := os.Remove(f); err != nil {
|
|
||||||
t.Errorf("Error: Could not remove file \"f\". Error: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue