Skip to content

Commit 0b42308

Browse files
committed
Merge github.com/mndrix/tap-go into util
This commit migrates github.com/mndrix/tap-go with commit history into a new directory util as part of fixing problematic dependencies. tap-go dependency has not been maintained for a long time and it is currently archieved. Signed-off-by: Muyassarov, Feruzjon <[email protected]>
2 parents e931285 + 5181037 commit 0b42308

File tree

3 files changed

+210
-0
lines changed

3 files changed

+210
-0
lines changed

util/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/yaml_json.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// +build !yaml
2+
3+
package tap
4+
5+
import (
6+
"encoding/json"
7+
)
8+
9+
// yaml serializes a message to YAML. This implementation uses JSON,
10+
// which is a subset of YAML [1] and is implemented by Go's standard
11+
// library.
12+
//
13+
// [1]: http://www.yaml.org/spec/1.2/spec.html#id2759572
14+
func yaml(message interface{}, prefix string) (marshaled []byte, err error) {
15+
marshaled, err = json.MarshalIndent(message, prefix, " ")
16+
if err != nil {
17+
return marshaled, err
18+
}
19+
20+
marshaled = append(marshaled, []byte("\n")...)
21+
return marshaled, err
22+
}

util/yaml_yaml.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// +build yaml
2+
3+
package tap
4+
5+
import (
6+
"bytes"
7+
8+
goyaml "gopkg.in/yaml.v2"
9+
)
10+
11+
// yaml serializes a message to YAML. This implementation uses
12+
// non-JSON YAML, which has better prove support [1].
13+
//
14+
// [1]: https://rt.cpan.org/Public/Bug/Display.html?id=121606
15+
func yaml(message interface{}, prefix string) (marshaled []byte, err error) {
16+
marshaled, err = goyaml.Marshal(message)
17+
if err != nil {
18+
return marshaled, err
19+
}
20+
21+
marshaled = bytes.Replace(marshaled, []byte("\n"), []byte("\n"+prefix), -1)
22+
return marshaled[:len(marshaled)-len(prefix)], err
23+
}

0 commit comments

Comments
 (0)