[tap] Add support for producing YAML blocks
Change-Id: I9907639e20d6dee66ee9b3b1f0a665a9509848f2
diff --git a/tap/producer.go b/tap/producer.go
index 53d6194..f203a0c 100644
--- a/tap/producer.go
+++ b/tap/producer.go
@@ -62,6 +62,16 @@
p.directive = None
}
+// YAML produces a YAML block from the given input. This will indent the input data. The
+// caller should not do this themselves.
+func (p *Producer) YAML(input []byte) {
+ // Chomp empty lines from the end of the document.
+ content := strings.TrimSuffix(string(input), "\n")
+ p.writeln(p.indent("---"))
+ p.writeln(p.indent(content))
+ p.writeln(p.indent("..."))
+}
+
// Todo returns a new Producer that prints TODO directives.
func (p *Producer) Todo() *Producer {
p.directive = Todo
@@ -75,8 +85,7 @@
}
func (p *Producer) writeln(format string, args ...interface{}) {
- line := strings.TrimSpace(fmt.Sprintf(format, args...)) + "\n"
- fmt.Fprintf(p.writer(), line)
+ fmt.Fprintln(p.writer(), fmt.Sprintf(format, args...))
}
// writer initializes the Writer to use for this Producer, in case the Producer was
@@ -87,3 +96,22 @@
}
return p.output
}
+
+// Indent indents every line of the input text with a single space.
+func (p *Producer) indent(input string) string {
+ return string(p.indentBytes([]byte(input)))
+}
+
+// IndentBytes indents every line of the input text with a single space.
+func (p *Producer) indentBytes(input []byte) []byte {
+ var output []byte
+ startOfLine := true
+ for _, c := range input {
+ if startOfLine && c != '\n' {
+ output = append(output, ' ')
+ }
+ output = append(output, c)
+ startOfLine = c == '\n'
+ }
+ return output
+}
diff --git a/tap/producer_test.go b/tap/producer_test.go
index 8e56ebb..e5a5632 100644
--- a/tap/producer_test.go
+++ b/tap/producer_test.go
@@ -6,8 +6,10 @@
import (
"os"
+ "time"
"fuchsia.googlesource.com/tools/tap"
+ "gopkg.in/yaml.v2"
)
func ExampleProducer_single_test() {
@@ -45,15 +47,11 @@
p.Plan(4)
p.Ok(true, "- this test passed")
p.Ok(false, "")
- p.Ok(false, "- this test failed")
- p.Skip().Ok(true, "this test is skippable")
// Output:
// TAP version 13
// 1..4
// ok 1 - this test passed
// not ok 2
- // not ok 3 - this test failed
- // ok 4 # SKIP this test is skippable
}
func ExampleProducer_skip_todo_alternating() {
@@ -71,3 +69,31 @@
// not ok 3 # SKIP skipped another
// ok 4 # TODO please don't write code like this
}
+
+func ExampleProducer_YAML() {
+ p := tap.NewProducer(os.Stdout)
+ p.Plan(1)
+ p.Ok(true, "passed")
+ bytes, err := yaml.Marshal(struct {
+ Name string `yaml:"name"`
+ Start time.Time `yaml:"start_time"`
+ End time.Time `yaml:"end_time"`
+ }{
+ Name: "foo_test",
+ Start: time.Date(2019, 1, 1, 12, 30, 0, 0, time.UTC),
+ End: time.Date(2019, 1, 1, 12, 40, 0, 0, time.UTC),
+ })
+ if err != nil {
+ panic(err)
+ }
+ p.YAML(bytes)
+ // Output:
+ // TAP version 13
+ // 1..1
+ // ok 1 passed
+ // ---
+ // name: foo_test
+ // start_time: 2019-01-01T12:30:00Z
+ // end_time: 2019-01-01T12:40:00Z
+ // ...
+}