1package flags
2
3import (
4	"fmt"
5	"io"
6	"io/ioutil"
7	"os"
8	"os/exec"
9	"path"
10	"runtime"
11	"testing"
12)
13
14func assertCallerInfo() (string, int) {
15	ptr := make([]uintptr, 15)
16	n := runtime.Callers(1, ptr)
17
18	if n == 0 {
19		return "", 0
20	}
21
22	mef := runtime.FuncForPC(ptr[0])
23	mefile, meline := mef.FileLine(ptr[0])
24
25	for i := 2; i < n; i++ {
26		f := runtime.FuncForPC(ptr[i])
27		file, line := f.FileLine(ptr[i])
28
29		if file != mefile {
30			return file, line
31		}
32	}
33
34	return mefile, meline
35}
36
37func assertErrorf(t *testing.T, format string, args ...interface{}) {
38	msg := fmt.Sprintf(format, args...)
39
40	file, line := assertCallerInfo()
41
42	t.Errorf("%s:%d: %s", path.Base(file), line, msg)
43}
44
45func assertFatalf(t *testing.T, format string, args ...interface{}) {
46	msg := fmt.Sprintf(format, args...)
47
48	file, line := assertCallerInfo()
49
50	t.Fatalf("%s:%d: %s", path.Base(file), line, msg)
51}
52
53func assertString(t *testing.T, a string, b string) {
54	if a != b {
55		assertErrorf(t, "Expected %#v, but got %#v", b, a)
56	}
57}
58
59func assertStringArray(t *testing.T, a []string, b []string) {
60	if len(a) != len(b) {
61		assertErrorf(t, "Expected %#v, but got %#v", b, a)
62		return
63	}
64
65	for i, v := range a {
66		if b[i] != v {
67			assertErrorf(t, "Expected %#v, but got %#v", b, a)
68			return
69		}
70	}
71}
72
73func assertBoolArray(t *testing.T, a []bool, b []bool) {
74	if len(a) != len(b) {
75		assertErrorf(t, "Expected %#v, but got %#v", b, a)
76		return
77	}
78
79	for i, v := range a {
80		if b[i] != v {
81			assertErrorf(t, "Expected %#v, but got %#v", b, a)
82			return
83		}
84	}
85}
86
87func assertParserSuccess(t *testing.T, data interface{}, args ...string) (*Parser, []string) {
88	parser := NewParser(data, Default&^PrintErrors)
89	ret, err := parser.ParseArgs(args)
90
91	if err != nil {
92		t.Fatalf("Unexpected parse error: %s", err)
93		return nil, nil
94	}
95
96	return parser, ret
97}
98
99func assertParseSuccess(t *testing.T, data interface{}, args ...string) []string {
100	_, ret := assertParserSuccess(t, data, args...)
101	return ret
102}
103
104func assertError(t *testing.T, err error, typ ErrorType, msg string) {
105	if err == nil {
106		assertFatalf(t, "Expected error: %s", msg)
107		return
108	}
109
110	if e, ok := err.(*Error); !ok {
111		assertFatalf(t, "Expected Error type, but got %#v", err)
112	} else {
113		if e.Type != typ {
114			assertErrorf(t, "Expected error type {%s}, but got {%s}", typ, e.Type)
115		}
116
117		if e.Message != msg {
118			assertErrorf(t, "Expected error message %#v, but got %#v", msg, e.Message)
119		}
120	}
121}
122
123func assertParseFail(t *testing.T, typ ErrorType, msg string, data interface{}, args ...string) []string {
124	parser := NewParser(data, Default&^PrintErrors)
125	ret, err := parser.ParseArgs(args)
126
127	assertError(t, err, typ, msg)
128	return ret
129}
130
131func diff(a, b string) (string, error) {
132	atmp, err := ioutil.TempFile("", "help-diff")
133
134	if err != nil {
135		return "", err
136	}
137
138	btmp, err := ioutil.TempFile("", "help-diff")
139
140	if err != nil {
141		return "", err
142	}
143
144	if _, err := io.WriteString(atmp, a); err != nil {
145		return "", err
146	}
147
148	if _, err := io.WriteString(btmp, b); err != nil {
149		return "", err
150	}
151
152	ret, err := exec.Command("diff", "-u", "-d", "--label", "got", atmp.Name(), "--label", "expected", btmp.Name()).Output()
153
154	os.Remove(atmp.Name())
155	os.Remove(btmp.Name())
156
157	if err.Error() == "exit status 1" {
158		return string(ret), nil
159	}
160
161	return string(ret), err
162}
163
164func assertDiff(t *testing.T, actual, expected, msg string) {
165	if actual == expected {
166		return
167	}
168
169	ret, err := diff(actual, expected)
170
171	if err != nil {
172		assertErrorf(t, "Unexpected diff error: %s", err)
173		assertErrorf(t, "Unexpected %s, expected:\n\n%s\n\nbut got\n\n%s", msg, expected, actual)
174	} else {
175		assertErrorf(t, "Unexpected %s:\n\n%s", msg, ret)
176	}
177}
178