Skip to content

Commit 48a14c3

Browse files
committed
Merge github.com/mndrix/tap-go into util
Signed-off-by: Muyassarov, Feruzjon <[email protected]>
2 parents e931285 + d68106f commit 48a14c3

File tree

17 files changed

+495
-0
lines changed

17 files changed

+495
-0
lines changed

util/tap/LICENSE

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
This is free and unencumbered software released into the public domain.
2+
3+
Anyone is free to copy, modify, publish, use, compile, sell, or
4+
distribute this software, either in source code form or as a compiled
5+
binary, for any purpose, commercial or non-commercial, and by any
6+
means.
7+
8+
In jurisdictions that recognize copyright laws, the author or authors
9+
of this software dedicate any and all copyright interest in the
10+
software to the public domain. We make this dedication for the benefit
11+
of the public at large and to the detriment of our heirs and
12+
successors. We intend this dedication to be an overt act of
13+
relinquishment in perpetuity of all present and future rights to this
14+
software under copyright law.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
23+
24+
For more information, please refer to <http://unlicense.org>

util/tap/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
TESTS = auto check diagnostic failing known skip todo writer yaml
2+
GOPATH ?= $(CURDIR)/gopath
3+
4+
.PHONY: $(TESTS)
5+
6+
all: $(foreach t,$(TESTS),test/$(t)/test)
7+
prove -v -e '' test/*/test
8+
9+
clean:
10+
rm -f test/*/test
11+
12+
test/%/test: test/%/*.go tap.go yaml_json.go yaml_yaml.go
13+
go build -o $@ -tags yaml ./test/$*
14+
15+
$(TESTS): %: test/%/test
16+
prove -v -e '' test/$@/test

util/tap/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Test Anything Protocol for Go
2+
3+
The [Test Anything Protocol](http://testanything.org/) ("TAP") is a text-based
4+
interface between tests and a test harness. This package helps Go to generate
5+
TAP output.
6+
7+
Read the [full package documentation](https://godoc.org/github.com/mndrix/tap-go)

util/tap/tap.go

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Package tap provides support for automated Test Anything Protocol ("TAP")
2+
// tests in Go. For example:
3+
//
4+
// package main
5+
//
6+
// import "github.com/mndrix/tap-go"
7+
//
8+
// func main() {
9+
// t := tap.New()
10+
// t.Header(2)
11+
// t.Ok(true, "first test")
12+
// t.Ok(true, "second test")
13+
// }
14+
//
15+
// generates the following output
16+
//
17+
// TAP version 13
18+
// 1..2
19+
// ok 1 - first test
20+
// ok 2 - second test
21+
package tap // import "github.com/mndrix/tap-go"
22+
23+
import (
24+
"fmt"
25+
"io"
26+
"os"
27+
"strings"
28+
)
29+
import "testing/quick"
30+
31+
// T is a type to encapsulate test state. Methods on this type generate TAP
32+
// output.
33+
type T struct {
34+
nextTestNumber *int
35+
36+
// TODO toggles the TODO directive for Ok, Fail, Pass, and similar.
37+
TODO bool
38+
39+
// Writer indicates where TAP output should be sent. The default is os.Stdout.
40+
Writer io.Writer
41+
}
42+
43+
// New creates a new Tap value
44+
func New() *T {
45+
nextTestNumber := 1
46+
return &T{
47+
nextTestNumber: &nextTestNumber,
48+
}
49+
}
50+
51+
func (t *T) w() io.Writer {
52+
if t.Writer == nil {
53+
return os.Stdout
54+
}
55+
return t.Writer
56+
}
57+
58+
func (t *T) printf(format string, a ...interface{}) {
59+
fmt.Fprintf(t.w(), format, a...)
60+
}
61+
62+
// Header displays a TAP header including version number and expected
63+
// number of tests to run. For an unknown number of tests, set
64+
// testCount to zero (in which case the plan is not written); this is
65+
// useful with AutoPlan.
66+
func (t *T) Header(testCount int) {
67+
t.printf("TAP version 13\n")
68+
if testCount > 0 {
69+
t.printf("1..%d\n", testCount)
70+
}
71+
}
72+
73+
// Ok generates TAP output indicating whether a test passed or failed.
74+
func (t *T) Ok(test bool, description string) {
75+
// did the test pass or not?
76+
ok := "ok"
77+
if !test {
78+
ok = "not ok"
79+
}
80+
81+
if t.TODO {
82+
t.printf("%s %d # TODO %s\n", ok, *t.nextTestNumber, description)
83+
} else {
84+
t.printf("%s %d - %s\n", ok, *t.nextTestNumber, description)
85+
}
86+
(*t.nextTestNumber)++
87+
}
88+
89+
// Fail indicates that a test has failed. This is typically only used when the
90+
// logic is too complex to fit naturally into an Ok() call.
91+
func (t *T) Fail(description string) {
92+
t.Ok(false, description)
93+
}
94+
95+
// Pass indicates that a test has passed. This is typically only used when the
96+
// logic is too complex to fit naturally into an Ok() call.
97+
func (t *T) Pass(description string) {
98+
t.Ok(true, description)
99+
}
100+
101+
// Check runs randomized tests against a function just as "testing/quick.Check"
102+
// does. Success or failure generate appropriate TAP output.
103+
func (t *T) Check(function interface{}, description string) {
104+
err := quick.Check(function, nil)
105+
if err == nil {
106+
t.Ok(true, description)
107+
return
108+
}
109+
110+
t.Diagnostic(err.Error())
111+
t.Ok(false, description)
112+
}
113+
114+
// Count returns the number of tests completed so far.
115+
func (t *T) Count() int {
116+
return *t.nextTestNumber - 1
117+
}
118+
119+
// AutoPlan generates a test plan based on the number of tests that were run.
120+
func (t *T) AutoPlan() {
121+
t.printf("1..%d\n", t.Count())
122+
}
123+
124+
func escapeNewlines(s string) string {
125+
return strings.Replace(strings.TrimRight(s, "\n"), "\n", "\n# ", -1)
126+
}
127+
128+
// Todo returns copy of the test-state with TODO set.
129+
func (t *T) Todo() *T {
130+
newT := *t
131+
newT.TODO = true
132+
return &newT
133+
}
134+
135+
// Skip indicates that a test has been skipped.
136+
func (t *T) Skip(count int, description string) {
137+
for i := 0; i < count; i++ {
138+
t.printf("ok %d # SKIP %s\n", *t.nextTestNumber, description)
139+
(*t.nextTestNumber)++
140+
}
141+
}
142+
143+
// Diagnostic generates a diagnostic from the message,
144+
// which may span multiple lines.
145+
func (t *T) Diagnostic(message string) {
146+
t.printf("# %s\n", escapeNewlines(message))
147+
}
148+
149+
// Diagnosticf generates a diagnostic from the format string and arguments,
150+
// which may span multiple lines.
151+
func (t *T) Diagnosticf(format string, a ...interface{}) {
152+
t.printf("# "+escapeNewlines(format)+"\n", a...)
153+
}
154+
155+
// YAML generates a YAML block from the message.
156+
func (t *T) YAML(message interface{}) error {
157+
bytes, err := yaml(message, " ")
158+
if err != nil {
159+
return err
160+
}
161+
t.printf(" ---\n ")
162+
t.printf(string(bytes))
163+
t.printf(" ...\n")
164+
return nil
165+
}

util/tap/test/auto/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import "github.com/mndrix/tap-go"
4+
5+
func main() {
6+
t := tap.New()
7+
t.Header(0)
8+
t.Ok(true, "first test")
9+
t.Ok(true, "second test")
10+
t.AutoPlan()
11+
}

util/tap/test/check/main.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package main
2+
3+
import "github.com/mndrix/tap-go"
4+
5+
func main() {
6+
add := func(x int) bool { return x+3 > x }
7+
sub := func(x int) bool { return x-3 < x }
8+
one := func(x int) bool { return x*1 == x }
9+
10+
t := tap.New()
11+
t.Header(0)
12+
t.Check(add, "addition makes numbers larger")
13+
t.Check(sub, "subtraction makes numbers smaller")
14+
t.Check(one, "1 is a multiplicative identity")
15+
t.AutoPlan()
16+
}

util/tap/test/diagnostic/main.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"io"
6+
"os"
7+
8+
tap "github.com/mndrix/tap-go"
9+
)
10+
11+
func main() {
12+
// collect output for comparison later
13+
buf := new(bytes.Buffer)
14+
t := tap.New()
15+
t.Writer = io.MultiWriter(os.Stdout, buf)
16+
17+
t.Header(1)
18+
t.Diagnostic("expecting all to be well")
19+
t.Diagnosticf("here's some perfectly magical output: %d %s 0x%X.", 6, "abracadabra", 28)
20+
t.Diagnostic("some\nmultiline\ntext\n")
21+
t.Diagnosticf("%d lines\n%s multiline\ntext", 3, "more")
22+
23+
got := buf.String()
24+
t.Ok(got == expected, "diagnostics gave expected output")
25+
}
26+
27+
const expected = `TAP version 13
28+
1..1
29+
# expecting all to be well
30+
# here's some perfectly magical output: 6 abracadabra 0x1C.
31+
# some
32+
# multiline
33+
# text
34+
# 3 lines
35+
# more multiline
36+
# text
37+
`

util/tap/test/failing/main.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
6+
"github.com/mndrix/tap-go"
7+
)
8+
9+
func main() {
10+
t1 := tap.New()
11+
t1.Header(2)
12+
13+
buf := new(bytes.Buffer)
14+
t2 := tap.New()
15+
t2.Writer = buf
16+
t2.Header(2)
17+
18+
buf.Reset()
19+
t2.Ok(false, "first test")
20+
t1.Ok(buf.String() == "not ok 1 - first test\n", "Ok(false, ...) produces appropriate output")
21+
22+
buf.Reset()
23+
t2.Fail("second test")
24+
t1.Ok(buf.String() == "not ok 2 - second test\n", "Fail(...) produces appropriate output")
25+
}

util/tap/test/known/main.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package main
2+
3+
import "github.com/mndrix/tap-go"
4+
5+
func main() {
6+
t := tap.New()
7+
t.Header(2)
8+
t.Ok(true, "first test")
9+
t.Pass("second test")
10+
}

util/tap/test/skip/main.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"io"
6+
"os"
7+
8+
tap "github.com/mndrix/tap-go"
9+
)
10+
11+
func main() {
12+
// collect output for comparison later
13+
buf := new(bytes.Buffer)
14+
t := tap.New()
15+
t.Writer = io.MultiWriter(os.Stdout, buf)
16+
17+
t.Header(4)
18+
t.Skip(1, "insufficient flogiston pressure")
19+
t.Skip(2, "no /sys directory")
20+
21+
got := buf.String()
22+
t.Ok(got == expected, "skip gave expected output")
23+
}
24+
25+
const expected = `TAP version 13
26+
1..4
27+
ok 1 # SKIP insufficient flogiston pressure
28+
ok 2 # SKIP no /sys directory
29+
ok 3 # SKIP no /sys directory
30+
`

0 commit comments

Comments
 (0)