File: st.go

package info (click to toggle)
golang-github-nbio-st 0.0~git20140626.e9e8d98-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid
  • size: 92 kB
  • sloc: makefile: 3
file content (95 lines) | stat: -rw-r--r-- 2,686 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2014 nb.io, LLC
// Author: Cameron Walters <cameron@nb.io>

// Package st, pronounced "ghost", is a tiny test framework for
// making short, useful assertions in your Go tests.
//
// To abort a test immediately with t.Fatal, use
// Assert(t, have, want) and Refute(t, have, want)
//
// To allow a test to continue, reporting failure at the end with t.Error, use
// Expect(t, have, want) and Reject(t, have, want)
package st

import (
	"fmt"
	"reflect"
	"runtime"
	"strings"
)

const (
	equal   = "\n%s:%d: should be == \n%s \thave: (%T) %+v\n\twant: (%T) %+v"
	unequal = "\n%s:%d: should be != \n%s \thave: (%T) %+v\n\tand : (%T) %+v"
)

// Errorf is satisfied by testing.T and testing.B.
type Errorf interface {
	Errorf(format string, args ...interface{})
}

// Fatalf is satisfied by testing.T and testing.B.
type Fatalf interface {
	Fatalf(format string, args ...interface{})
}

// Expect calls t.Error and prints a nice comparison message when have != want.
// Especially useful in table-based tests when passing the loop index as iter.
func Expect(t Errorf, have, want interface{}, iter ...int) {
	if !reflect.DeepEqual(have, want) {
		file, line := caller()
		t.Errorf(equal, file, line, exampleNum(iter), have, have, want, want)
	}
}

// Reject calls t.Error and prints a nice comparison message when have == want.
// Especially useful in table-based tests when passing the loop index as iter.
func Reject(t Errorf, have, want interface{}, iter ...int) {
	if reflect.DeepEqual(have, want) {
		file, line := caller()
		t.Errorf(unequal, file, line, exampleNum(iter), have, have, want, want)
	}
}

// Assert calls t.Fatal to abort the test immediately and prints a nice
// comparison message when have != want.
func Assert(t Fatalf, have, want interface{}) {
	if !reflect.DeepEqual(have, want) {
		file, line := caller()
		t.Fatalf(equal, file, line, "", have, have, want, want)
	}
}

// Refute calls t.Fatal to abort the test immediately and prints a nice
// comparison message when have != want.
func Refute(t Fatalf, have, want interface{}) {
	if reflect.DeepEqual(have, want) {
		file, line := caller()
		t.Fatalf(unequal, file, line, "", have, have, want, want)
	}
}

// returns file and line two stack frames above its invocation
func caller() (file string, line int) {
	var ok bool
	_, file, line, ok = runtime.Caller(2)
	if !ok {
		file = "???"
		line = 1
	} else {
		slash := strings.LastIndex(file, "/")
		if slash >= 0 {
			file = file[slash+1:]
		}
	}
	return
}

// returns an example number from the optional zero-based loop iterator n, if
// provided.
func exampleNum(n []int) string {
	if len(n) == 1 {
		return fmt.Sprintf("%d.", n[0])
	}
	return ""
}