Skip to content

Commit

Permalink
Improvements on top of #37
Browse files Browse the repository at this point in the history
- Integrations tests need to always test the actual output
- file.golden wasn't a golden file
- covered quoting around the option
  • Loading branch information
lucapette committed May 26, 2017
1 parent 6b9ecfe commit 7ad6a5c
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 63 deletions.
71 changes: 31 additions & 40 deletions integration/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ import (
"testing"

"reflect"
"strings"

"github.com/kr/pretty"
)

// In the following tests, there's a lot going on.
// Please have a look at the following article for a longer explanation:
// http://lucapette.me/writing-integration-tests-for-a-go-cli-application

var update = flag.Bool("update", false, "update golden files")

const binaryName = "fakedata"

var binaryPath string

func diff(expected, actual interface{}) []string {
return pretty.Diff(expected, actual)
}
Expand Down Expand Up @@ -56,7 +57,6 @@ func TestCliArgs(t *testing.T) {
name string
args []string
fixture string
match func(string, string) bool
}{
{
name: "no arguments",
Expand Down Expand Up @@ -118,27 +118,14 @@ func TestCliArgs(t *testing.T) {
args: []string{"-f=sql", "-t=USERS", "int,42..42", "enum,foo..foo"},
fixture: "sql-format-with-table-name.golden",
},
{
name: "file generator",
args: []string{"file,integration/file.golden"},
fixture: "file.golden",
match: func(actual, expected string) bool {
for _, line := range strings.Split(actual, "\n") {
if !strings.Contains(expected+"\n", line+"\n") {
return false
}
}
return true
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := exec.Command(binaryPath, tt.args...)
cmd := exec.Command(binaryName, tt.args...)
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatal(err, "\n", string(output))
t.Fatalf("output: %s\nerr: %v", output, err)
}

if *update {
Expand All @@ -148,33 +135,43 @@ func TestCliArgs(t *testing.T) {
actual := string(output)
expected := loadFixture(t, tt.fixture)

if tt.match != nil {
if !tt.match(actual, expected) {
t.Fatalf("values do not match: \n%v\n%v", actual, expected)
}
} else if !reflect.DeepEqual(actual, expected) {
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("diff: %v", diff(expected, actual))
}
})
}
}

func TestCliErr(t *testing.T) {
func TestFileGenerator(t *testing.T) {
tests := []struct {
name string
args []string
name string
args []string
fixture string
wantErr bool
}{
{"no file", []string{"file"}},
{"no file,", []string{"file,"}},
{"no file,''", []string{"file,''"}},
{`no file,""`, []string{`file,""`}},
{"file does not exist", []string{`file,'this file does not exist.txt'`}},
{"no file", []string{"file"}, "path-empty.golden", true},
{"no file,", []string{"file,"}, "path-empty.golden", true},
{"file does not exist", []string{`file,'this file does not exist.txt'`}, "file-empty.golden", true},
{"file exists", []string{`file,integration/file.txt`}, "file-exist.golden", false},
{"file exists with quotes", []string{`file,'integration/file.txt'`}, "file-exist.golden", false},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := exec.Command(binaryPath, tt.args...).Run(); err == nil {
t.Fatalf("expected to fail with args: %v", tt.args)
cmd := exec.Command(binaryName, tt.args...)
output, err := cmd.CombinedOutput()
if (err != nil) != tt.wantErr {
t.Fatalf("%s\nexpected (err != nil) to be %v, but got %v. err: %v", output, tt.wantErr, err != nil, err)
}
if *update {
writeFixture(t, tt.fixture, output)
}

actual := string(output)
expected := loadFixture(t, tt.fixture)

if !reflect.DeepEqual(actual, expected) {
t.Fatalf("diff: %v", diff(expected, actual))
}
})
}
Expand All @@ -192,11 +189,5 @@ func TestMain(m *testing.M) {
fmt.Printf("could not make binary for %s: %v", binaryName, err)
os.Exit(1)
}
binaryPath, err = filepath.Abs(binaryName)
if err != nil {
fmt.Printf("could not get binary path: %v", err)
os.Exit(1)
}

os.Exit(m.Run())
}
1 change: 1 addition & 0 deletions integration/file-empty.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
could not read file this file does not exist.txt: open this file does not exist.txt: no such file or directory
10 changes: 10 additions & 0 deletions integration/file-exist.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
10 changes: 0 additions & 10 deletions integration/file.golden

This file was deleted.

10 changes: 10 additions & 0 deletions integration/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
from-an-existing-file
1 change: 1 addition & 0 deletions integration/path-empty.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file: no file path given
30 changes: 17 additions & 13 deletions pkg/fakedata/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io/ioutil"
"log"
"math/rand"
"os"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -181,22 +182,25 @@ var enum = func(column Column) string {
var fileCache map[string][]string

var file = func(column Column) string {
p := column.Constraints
if p == "" {
log.Fatalf("%s: no file path given", column.Name)
}
// Try to get file from cache
f := fileCache[p]
// Load file if cache is empty
if f == nil {
content, err := ioutil.ReadFile(p)
constraint := column.Constraints
if len(constraint) == 0 {
fmt.Printf("%s: no file path given", column.Name)
os.Exit(1)
}

filePath := strings.Trim(constraint, "'\"")

This comment has been minimized.

Copy link
@lucapette

lucapette May 26, 2017

Author Owner

@jorinvo now that all the tests check the actual output of the binary I could catch this. It wasn't obvious :)


list, ok := fileCache[filePath]
if !ok {
content, err := ioutil.ReadFile(filePath)
if err != nil {
log.Fatalf("%s: no readable file found at '%s'", column.Name, p)
fmt.Printf("could not read file %s: %v", filePath, err)
os.Exit(1)
}
f = strings.Split(string(content), "\n")
list = strings.Split(string(content), "\n")
}
// Return random line
return f[rand.Intn(len(f))]

return list[rand.Intn(len(list))]
}

func init() {
Expand Down

0 comments on commit 7ad6a5c

Please sign in to comment.