Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
Printer: add tests (#126)
Browse files Browse the repository at this point in the history
* printer: add tests

* printer: add license to test file

* Update printer/printer_test.go

Co-Authored-By: Miguel de la Cruz <mgdelacroix@gmail.com>

* Update printer/printer_test.go

Co-Authored-By: Miguel de la Cruz <mgdelacroix@gmail.com>

* printer: incorporate review comments

* printer: add tests for check to if json output clears buffer

Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Co-authored-by: Miguel de la Cruz <mgdelacroix@gmail.com>
  • Loading branch information
3 people committed Mar 16, 2020
1 parent 6d06580 commit cef1dc6
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 12 deletions.
33 changes: 21 additions & 12 deletions printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
"text/template"
)
Expand All @@ -17,6 +18,9 @@ const (
)

type Printer struct {
writer io.Writer
eWriter io.Writer

Format string
Single bool
Lines []interface{}
Expand All @@ -25,20 +29,25 @@ type Printer struct {

var printer Printer

// Sets the format for the final output of the printer
func init() {
printer.writer = os.Stdout
printer.eWriter = os.Stderr
}

// SetFormat sets the format for the final output of the printer
func SetFormat(t string) {
printer.Format = t
}

// Sets the single flag on the printer. If this flag is set, the
// SetSingle sets the single flag on the printer. If this flag is set, the
// printer will check the size of stored elements before printing, and
// if there is only one, it will be printed on its own instead of
// inside a list
func SetSingle(single bool) {
printer.Single = single
}

// Prints an element. Depending on the format, the element can be
// PrintT prints an element. Depending on the format, the element can be
// formatted and printed as a structure or used to populate the
// template
func PrintT(templateString string, v interface{}) {
Expand All @@ -51,20 +60,20 @@ func PrintT(templateString string, v interface{}) {
}
tplString := tpl.String()
printer.Lines = append(printer.Lines, tplString)
fmt.Println(tplString)
fmt.Fprintln(printer.writer, tplString)
case FormatJSON:
printer.Lines = append(printer.Lines, v)
}
}

// Prints an element. If the format requires a template, the element
// Print an element. If the format requires a template, the element
// will be printed as a structure with field names using the print
// verb %+v
func Print(v interface{}) {
PrintT("{{printf \"%+v\" .}}", v)
}

// Prints the elements accumulated in the printer
// Flush writes the elements accumulated in the printer
func Flush() {
if printer.Format == FormatJSON {
var b []byte
Expand All @@ -74,29 +83,29 @@ func Flush() {
b, _ = json.MarshalIndent(printer.Lines, "", " ")
}

fmt.Println(string(b))
fmt.Fprintln(printer.writer, string(b))
printer.Lines = []interface{}{}
}
}

// Resets the printer's accumulated lines
// Clean resets the printer's accumulated lines
func Clean() {
printer.Lines = []interface{}{}
printer.ErrorLines = []interface{}{}
}

// Returns the printer's accumulated lines
// GetLines returns the printer's accumulated lines
func GetLines() []interface{} {
return printer.Lines
}

// Returns the printer's accumulated error lines
// GetErrorLines returns the printer's accumulated error lines
func GetErrorLines() []interface{} {
return printer.ErrorLines
}

// Prints an error string to the stderr.
// PrintError prints to the stderr.
func PrintError(msg string) {
printer.ErrorLines = append(printer.ErrorLines, msg)
fmt.Fprintln(os.Stderr, msg)
fmt.Fprintln(printer.eWriter, msg)
}
81 changes: 81 additions & 0 deletions printer/printer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

package printer

import (
"bufio"
"bytes"
"testing"

"github.com/stretchr/testify/assert"
)

type mockWriter []byte

func (w *mockWriter) Write(b []byte) (n int, err error) {
*w = append(*w, b...)
return len(*w) - len(b), nil
}

func TestPrintT(t *testing.T) {
w := bufio.NewWriter(&bytes.Buffer{})
printer.writer = w
printer.Format = FormatPlain

ts := struct {
ID int
}{
ID: 123,
}

t.Run("should execute template", func(t *testing.T) {
tpl := `testing template {{.ID}}`
PrintT(tpl, ts)
assert.Len(t, GetLines(), 1)

Flush()
assert.Equal(t, "testing template 123", printer.Lines[0])
})

t.Run("should fail to execute, no method or field", func(t *testing.T) {
Clean()
tpl := `testing template {{.Name}}`
PrintT(tpl, ts)
assert.Len(t, GetErrorLines(), 1)

Flush()
assert.Equal(t, "Can't print the message using the provided template: "+tpl, printer.ErrorLines[0])
})
}

func TestFlush(t *testing.T) {
printer.Format = FormatJSON

t.Run("should print a line in JSON format", func(t *testing.T) {
mw := &mockWriter{}
printer.writer = mw
Clean()

Print("test string")
assert.Len(t, GetLines(), 1)

Flush()
assert.Equal(t, "[\n \"test string\"\n]\n", string(*mw))
assert.Empty(t, GetLines(), 0)
})

t.Run("should print multi line in JSON format", func(t *testing.T) {
mw := &mockWriter{}
printer.writer = mw

Clean()
Print("test string-1")
Print("test string-2")
assert.Len(t, GetLines(), 2)

Flush()
assert.Equal(t, "[\n \"test string-1\",\n \"test string-2\"\n]\n", string(*mw))
assert.Empty(t, GetLines(), 0)
})
}

0 comments on commit cef1dc6

Please sign in to comment.