diff --git a/parser/test-common.go b/parser/test-common.go index 80ee2fd..d16e35f 100644 --- a/parser/test-common.go +++ b/parser/test-common.go @@ -1,78 +1,13 @@ package parser -import "io" import "os" -import "strings" import "testing" import "path/filepath" +import "git.tebibyte.media/arf/arf/testCommon" func checkTree (modulePath string, skim bool, correct string, test *testing.T) { cwd, _ := os.Getwd() modulePath = filepath.Join(cwd, modulePath) tree, err := Fetch(modulePath, skim) - - treeString := tree.ToString(0) - treeRunes := []rune(treeString) - - test.Log("CORRECT TREE:") - logWithLineNumbers(correct, test) - test.Log("WHAT WAS PARSED:") - logWithLineNumbers(treeString, test) - - if err != io.EOF && err != nil { - test.Log("returned error:") - test.Log(err.Error()) - test.Fail() - return - } - - equal := true - line := 0 - column := 0 - - for index, correctChar := range correct { - if index >= len(treeRunes) { - test.Log ( - "parsed is too short at line", line + 1, - "col", column + 1) - test.Fail() - return - } - - if correctChar != treeRunes[index] { - test.Log ( - "trees not equal at line", line + 1, - "col", column + 1) - test.Log("correct: [" + string(correctChar) + "]") - test.Log("got: [" + string(treeRunes[index]) + "]") - test.Fail() - return - } - - if correctChar == '\n' { - line ++ - column = 0 - } else { - column ++ - } - } - - if len(treeString) > len(correct) { - test.Log("parsed is too long") - test.Fail() - return - } - - if !equal { - return - } -} - -func logWithLineNumbers (bigString string, test *testing.T) { - lines := strings.Split ( - strings.Replace(bigString, "\t", " ", -1), "\n") - - for index, line := range lines { - test.Logf("%3d | %s", index + 1, line) - } + testCommon.CheckStrings(test, tree, err, correct) } diff --git a/testCommon/test-common.go b/testCommon/test-common.go new file mode 100644 index 0000000..9d3ad4e --- /dev/null +++ b/testCommon/test-common.go @@ -0,0 +1,91 @@ +package testCommon + +import "io" +import "strings" +import "testing" + +// Stringable encompasses any type that can be converted into a string, given +// an indentation level. +type Stringable interface { + ToString (indent int) (output string) +} + +// CheckStrings takes in an error, a result value that is able to provide a +// string, and a correct string to check the result value's string against, and +// a test pointer. This function will detect the presence of an error, or +// differences in the result string and the correct string, and fail the test +// if needed. It also provides detailed output logs to facilitate the correction +// of test failues. +func CheckStrings ( + test *testing.T, + result Stringable, + err error, + correct string, +) { + treeString := result.ToString(0) + treeRunes := []rune(treeString) + + test.Log("CORRECT:") + logWithLineNumbers(correct, test) + test.Log("RESULT:") + logWithLineNumbers(treeString, test) + + if err != io.EOF && err != nil { + test.Log("returned error:") + test.Log(err.Error()) + test.Fail() + return + } + + equal := true + line := 0 + column := 0 + + for index, correctChar := range correct { + if index >= len(treeRunes) { + test.Log ( + "result is too short at line", line + 1, + "col", column + 1) + test.Fail() + return + } + + if correctChar != treeRunes[index] { + test.Log ( + "strings not equal at line", line + 1, + "col", column + 1) + test.Log("correct: [" + string(correctChar) + "]") + test.Log("got: [" + string(treeRunes[index]) + "]") + test.Fail() + return + } + + if correctChar == '\n' { + line ++ + column = 0 + } else { + column ++ + } + } + + if len(treeString) > len(correct) { + test.Log("result is too long") + test.Fail() + return + } + + if !equal { + return + } +} + +// logWithLineNumbers logs a multi-line, indented string with line numbers. It +// also converts all tabs to spaces for consistent indentation. +func logWithLineNumbers (bigString string, test *testing.T) { + lines := strings.Split ( + strings.Replace(bigString, "\t", " ", -1), "\n") + + for index, line := range lines { + test.Logf("%3d | %s", index + 1, line) + } +}