mirror of
				https://github.com/gohugoio/hugo.git
				synced 2024-05-11 05:54:58 +00: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:
		@@ -22,39 +22,36 @@ func CheckErr(err error, s ...string) {
 | 
			
		||||
 | 
			
		||||
func StopOnErr(err error, s ...string) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		doStopOnErr(err, s...)
 | 
			
		||||
		os.Exit(-1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		if len(s) == 0 {
 | 
			
		||||
			newMessage := cutUsageMessage(err.Error())
 | 
			
		||||
 | 
			
		||||
func doStopOnErr(err error, s ...string) {
 | 
			
		||||
	if len(s) == 0 {
 | 
			
		||||
		newMessage := cutUsageMessage(err.Error())
 | 
			
		||||
		// Printing an empty string results in a error with
 | 
			
		||||
		// no message, no bueno.
 | 
			
		||||
		if newMessage != "" {
 | 
			
		||||
			jww.CRITICAL.Println(newMessage)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		for _, message := range s {
 | 
			
		||||
			message := cutUsageMessage(message)
 | 
			
		||||
			// Printing an empty string results in a error with
 | 
			
		||||
			// no message, no bueno.
 | 
			
		||||
			if newMessage != "" {
 | 
			
		||||
				jww.CRITICAL.Println(newMessage)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			for _, message := range s {
 | 
			
		||||
				message := cutUsageMessage(message)
 | 
			
		||||
 | 
			
		||||
			if message != "" {
 | 
			
		||||
				jww.CRITICAL.Println(message)
 | 
			
		||||
				if message != "" {
 | 
			
		||||
					jww.CRITICAL.Println(message)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		os.Exit(-1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// cutUsageMessage splits the incoming string on the beginning of the usage
 | 
			
		||||
// 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.
 | 
			
		||||
//
 | 
			
		||||
// 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
 | 
			
		||||
func cutUsageMessage(s string) string {
 | 
			
		||||
	pieces := strings.Split(s, "Usage of")
 | 
			
		||||
	pieces :=  strings.Split(s, "Usage of") 
 | 
			
		||||
	return strings.TrimSpace(pieces[0])
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +1,22 @@
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"testing"
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	jww "github.com/spf13/jwalterweatherman"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type testData struct {
 | 
			
		||||
	logLevel        string
 | 
			
		||||
	logError        string
 | 
			
		||||
	logStr          []string
 | 
			
		||||
	logFileExpected bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCutUsageMessage(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		message    string
 | 
			
		||||
	tests := []struct{
 | 
			
		||||
		message string
 | 
			
		||||
		cutMessage string
 | 
			
		||||
	}{
 | 
			
		||||
		{"", ""},
 | 
			
		||||
		{" Usage of hugo: \n  -b, --baseUrl=...", ""},
 | 
			
		||||
		{"Some error Usage of hugo: \n", "Some error"},
 | 
			
		||||
		{"Usage of hugo: \n -b --baseU", ""},
 | 
			
		||||
		{"CRITICAL error for usage of hugo ", "CRITICAL error for usage of hugo"},
 | 
			
		||||
		{"Invalid short flag a in -abcde", "Invalid short flag a in -abcde"},
 | 
			
		||||
                {" Usage of hugo: \n  -b, --baseUrl=...", ""},
 | 
			
		||||
                {"Some error Usage of hugo: \n", "Some error"},
 | 
			
		||||
                {"Usage of hugo: \n -b --baseU", ""},
 | 
			
		||||
                {"CRITICAL error for usage of hugo ", "CRITICAL error for usage of hugo"},
 | 
			
		||||
                {"Invalid short flag a in -abcde", "Invalid short flag a in -abcde"},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user