Skip to content

Instantly share code, notes, and snippets.

@apmckinlay
Last active August 29, 2015 13:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apmckinlay/9997100 to your computer and use it in GitHub Desktop.
Save apmckinlay/9997100 to your computer and use it in GitHub Desktop.
A prototype of a Go implementation of Hamcrest style matchers
/*
hamcrest implements very basic hamcrest style asserts
for example:
func TestStuff(t *testing.T) {
Assert(t).That(2 * 4, Equals(6))
}
*/
package hamcrest
import "fmt"
import "reflect"
import "runtime"
import "strings"
type testing interface {
Error(err ...interface{})
}
type Asserter struct {
t testing
}
func Assert(t testing) Asserter {
return Asserter{t}
}
type tester func(interface{}) string
func (a Asserter) That(actual interface{}, test tester) {
err := test(actual)
if err != "" {
a.Fail(err)
}
}
func (a Asserter) Fail(err string) {
file, line := getLocation()
a.t.Error(err + fmt.Sprintf(" {%s:%d}", file, line))
}
func getLocation() (file string, line int) {
i := 1
for ; i < 9; i++ {
_, file, _, ok := runtime.Caller(i)
if !ok || strings.Contains(file, "testing/testing.go") {
break
}
}
_, file, line, ok := runtime.Caller(i - 1)
if ok && i > 1 && i < 9 {
// Truncate file name at last file name separator.
if index := strings.LastIndex(file, "/"); index >= 0 {
file = file[index+1:]
} else if index = strings.LastIndex(file, "\\"); index >= 0 {
file = file[index+1:]
}
} else {
file = "???"
line = 1
}
return file, line
}
// Equals checks that the actual value is equal to the expected value
// using reflect.DeepEquals
func Equals(expected interface{}) tester {
return func(actual interface{}) string {
if reflect.DeepEqual(expected, actual) {
return ""
}
return fmt.Sprintf("expected %v but got %v", expected, actual)
}
}
// Comment decorates a tester to add extra text to error messages
func (test tester) Comment(comment string) tester {
return func(actual interface{}) string {
err := test(actual)
if err == "" {
return ""
} else {
return err + " (" + comment + ")"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment