-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
test.go
80 lines (71 loc) · 1.72 KB
/
test.go
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
package zli
import (
"bytes"
"os"
"testing"
"unsafe"
)
// TestExit records the exit code and aborts the normal program execution. It's
// intended to test exit codes in a program.
//
// The Exit() method call is a replacement for zli.Exit:
//
// exit := TestExit(-1)
// Exit = exit.Exit
// defer func() { Exit = os.Exit }()
//
// This can be recovered like so:
//
// func() {
// defer exit.Recover()
// Fatal("oh noes!")
// }()
// fmt.Println("Exit", exit)
//
// The function wrapper is needed so that the test function itself doesn't get
// aborted.
type TestExit int
// Exit sets TestExit to the given status code and panics with itself.
func (t *TestExit) Exit(c int) {
*t = TestExit(c)
panic(t)
}
// Want checks that the recorded exit code matches the given code and issues a
// t.Error() if it doesn't.
func (t *TestExit) Want(tt *testing.T, c int) {
tt.Helper()
if int(*t) != c {
tt.Errorf("wrong exit: %d; want: %d", *t, c)
}
}
// Recover any panics where the argument is this TestExit instance. it will
// re-panic on any other errors (including other TestExit instances).
func (t *TestExit) Recover() {
r := recover()
if r == nil {
return
}
exit, ok := r.(*TestExit)
if !ok || unsafe.Pointer(t) != unsafe.Pointer(exit) {
panic(r)
}
}
// Test replaces Stdin, Stdout, Stderr, and Exit for testing.
//
// The code points to the latest zli.Exit() return code;
func Test() (exit *TestExit, in, out *bytes.Buffer, reset func()) {
in = new(bytes.Buffer)
Stdin = in
out = new(bytes.Buffer)
Stdout = out
Stderr = out
exit = new(TestExit)
*exit = -1
Exit = exit.Exit
return exit, in, out, func() {
Exit = os.Exit
Stdin = os.Stdin
Stdout = os.Stdout
Stderr = os.Stderr
}
}