-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add mocha report and update README.md file
- Loading branch information
Showing
8 changed files
with
384 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
language: go | ||
dist: xenial | ||
|
||
os: | ||
- linux | ||
|
||
env: | ||
- GO111MODULE=on | ||
|
||
go: | ||
- 1.12.x | ||
|
||
script: | ||
- go test -failfast -v -coverprofile=coverage.txt -covermode=atomic ./... | ||
|
||
after_success: | ||
- bash <(curl -s https://codecov.io/bash) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
.PHONY: test | ||
test: | ||
@echo "running tests on $(run). waiting for changes..." | ||
@-zsh -c "go test ./...; repeat 100 printf '#'; echo" | ||
@reflex -d none -r "(\.go$$)|(go.mod)" -- zsh -c "go test ./...; repeat 100 printf '#'" | ||
|
||
.PHONY: test_race | ||
test_race: | ||
@echo "running tests on $(run). waiting for changes..." | ||
@-zsh -c "go test -race ./...; repeat 100 printf '#'; echo" | ||
@reflex -d none -r "(\.go$$)|(go.mod)" -- zsh -c "go test -race ./...; repeat 100 printf '#'" | ||
|
||
.PHONY: third-party | ||
third-party: | ||
@go get -u github.com/cespare/reflex | ||
|
||
.PHONY: clean | ||
clean: | ||
go clean -cache -testcache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,151 @@ | ||
# dbtesting | ||
|
||
Utility for using with go-sqlmock library. | ||
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) | ||
[![GoDoc](https://godoc.org/github.com/arsham/dbtesting?status.svg)](http://godoc.org/github.com/arsham/dbtesting) | ||
[![Build Status](https://travis-ci.org/arsham/dbtesting.svg?branch=master)](https://travis-ci.org/arsham/dbtesting) | ||
[![Coverage Status](https://codecov.io/gh/arsham/dbtesting/branch/master/graph/badge.svg)](https://codecov.io/gh/arsham/dbtesting) | ||
|
||
This library can be used in the [go-sqlmock][go-sqlmock] test cases for cases | ||
that values are random but it is important to check the values passed in | ||
This library has a few helpers for using in tests. | ||
|
||
1. [Spec Reports](#spec-reports) | ||
* [Usage](#usage) | ||
2. [SQLMock Helpers](#sqlmock-helpers) | ||
* [ValueRecorder](#valuerecorder) | ||
* [OkValue](#okvalue) | ||
3. [Testing](#testing) | ||
4. [License](#license) | ||
|
||
## Spec Reports | ||
|
||
`Mocha` is a reporter for printing Mocha inspired reports when using | ||
[spec BDD library][spec]. | ||
|
||
### Usage | ||
|
||
```go | ||
import "github.com/arsham/dbtesting" | ||
|
||
func TestFoo(t *testing.T) { | ||
spec.Run(t, "Foo", func(t *testing.T, when spec.G, it spec.S) { | ||
// ... | ||
}, spec.Report(&dbtesting.Mocha{})) | ||
} | ||
|
||
``` | ||
|
||
You can set an `io.Writer` to `Mocha.Out` to redirect the output, otherwise it | ||
prints to the `os.Stdout`. | ||
|
||
## SQLMock Helpers | ||
|
||
There a couple of helpers for using with [go-sqlmock][go-sqlmock] test cases for | ||
cases that values are random but it is important to check the values passed in | ||
queries. | ||
|
||
## ValueRecorder | ||
### ValueRecorder | ||
|
||
If you generate a UUID and use it in multiple queries and you want to make sure | ||
the queries are passed with correct IDs. For instance if in your code you have: | ||
If you have an value and use it in multiple queries, and you want to | ||
make sure the queries are passed with correct values, you can use the | ||
`ValueRecorder`. For example UUIDs, time and random values. | ||
|
||
For instance if the first query generates a random number but it is essential to | ||
use the same value on next queries: | ||
|
||
```go | ||
import "database/sql" | ||
|
||
// ... | ||
|
||
// assume num has been generated randomly | ||
num := 666 | ||
_, err := tx.ExecContext(ctx, "INSERT INTO life (value) VALUE ($1)", num) | ||
// error check | ||
_, err := tx.ExecContext(ctx, "INSERT INTO reality (value) VALUE ($1)", num) | ||
// error check | ||
_, err := tx.ExecContext(ctx, "INSERT INTO everywhere (value) VALUE ($1)", num) | ||
// error check | ||
func TestFoo(t *testing.T) { | ||
// ... | ||
// assume num has been generated randomly | ||
num := 666 | ||
_, err := tx.ExecContext(ctx, "INSERT INTO life (value) VALUE ($1)", num) | ||
// error check | ||
_, err = tx.ExecContext(ctx, "INSERT INTO reality (value) VALUE ($1)", num) | ||
// error check | ||
_, err = tx.ExecContext(ctx, "INSERT INTO everywhere (value) VALUE ($1)", num) | ||
// error check | ||
} | ||
``` | ||
|
||
Your tests can be checked easily like this: | ||
```go | ||
import ( | ||
"github.com/arsham/dbtesting" | ||
"github.com/DATA-DOG/go-sqlmock" | ||
// ... | ||
) | ||
|
||
rec := dbtesting.NewValueRecorder() | ||
mock.ExpectExec("INSERT INTO life .+"). | ||
WithArgs(rec.Record("truth")). | ||
WillReturnResult(sqlmock.NewResult(1, 1)) | ||
mock.ExpectExec("INSERT INTO reality .+"). | ||
WithArgs(rec.For("truth")). | ||
WillReturnResult(sqlmock.NewResult(1, 1)) | ||
mock.ExpectExec("INSERT INTO everywhere .+"). | ||
WithArgs(rec.For("truth")). | ||
WillReturnResult(sqlmock.NewResult(1, 1)) | ||
func TestFoo(t *testing.T) { | ||
// ... | ||
rec := dbtesting.NewValueRecorder() | ||
mock.ExpectExec("INSERT INTO life .+"). | ||
WithArgs(rec.Record("truth")). | ||
WillReturnResult(sqlmock.NewResult(1, 1)) | ||
mock.ExpectExec("INSERT INTO reality .+"). | ||
WithArgs(rec.For("truth")). | ||
WillReturnResult(sqlmock.NewResult(1, 1)) | ||
mock.ExpectExec("INSERT INTO everywhere .+"). | ||
WithArgs(rec.For("truth")). | ||
WillReturnResult(sqlmock.NewResult(1, 1)) | ||
} | ||
``` | ||
|
||
Recorded values can be retrieved by casting to their types: | ||
```go | ||
rec.Value("true").(string) | ||
``` | ||
|
||
## OkValue | ||
There are two rules for using the `ValueRecorder`: | ||
1. You can only record for a value once. | ||
2. You should record a value before you call `For` or `Value`. | ||
|
||
It will panic if these requirements are not met. | ||
|
||
When you are only interested in checking some arguments passed to the Exec/Query | ||
### OkValue | ||
|
||
If you are only interested in checking some arguments passed to the Exec/Query | ||
functions and you don't want to check everything (maybe because thy are not | ||
relevant to the current test), you can use the `OkValue`. | ||
relevant to the current test), you can use `OkValue`. | ||
|
||
```go | ||
import ( | ||
"github.com/arsham/dbtesting" | ||
"github.com/DATA-DOG/go-sqlmock" | ||
// ... | ||
) | ||
|
||
ok := dbtesting.OkValue | ||
mock.ExpectExec("INSERT INTO life .+"). | ||
WithArgs( | ||
dbtesting.OkValue, | ||
dbtesting.OkValue, | ||
dbtesting.OkValue, | ||
"import value" | ||
dbtesting.OkValue, | ||
dbtesting.OkValue, | ||
dbtesting.OkValue, | ||
ok, | ||
ok, | ||
ok, | ||
"important value" | ||
ok, | ||
ok, | ||
ok, | ||
) | ||
``` | ||
|
||
## LICENSE | ||
## Testing | ||
|
||
To run the tests: | ||
|
||
```bash | ||
make | ||
``` | ||
or for with `-race` flag: | ||
```bash | ||
make test_race | ||
``` | ||
|
||
If you don't have `reflex` installed, run the following once: | ||
```bash | ||
make third-party | ||
``` | ||
|
||
## License | ||
|
||
Use of this source code is governed by the Apache 2.0 license. License can be | ||
found in the [LICENSE](./LICENSE) file. | ||
|
||
[go-sqlmock]: github.com/DATA-DOG/go-sqlmock | ||
[go-sqlmock]: https://github.com/DATA-DOG/go-sqlmock | ||
[spec]: https://github.com/sclevine/spec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,12 @@ | ||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= | ||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA= | ||
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package dbtesting | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
"strings" | ||
"sync" | ||
"testing" | ||
|
||
"github.com/sclevine/spec" | ||
) | ||
|
||
// Mocha prints spec reports in terminal. | ||
type Mocha struct { | ||
once sync.Once | ||
Out io.Writer // if not set it will print to stdout | ||
} | ||
|
||
func (m *Mocha) setup() { | ||
if m.Out == nil { | ||
m.Out = os.Stdout | ||
} | ||
} | ||
|
||
// Start prints some information when the suite is started. | ||
func (m *Mocha) Start(_ *testing.T, plan spec.Plan) { | ||
m.once.Do(m.setup) | ||
fmt.Fprintln(m.Out, "Suite:", plan.Text) | ||
fmt.Fprintf(m.Out, "Total: %d | Focused: %d | Pending: %d\n", plan.Total, plan.Focused, plan.Pending) | ||
if plan.HasRandom { | ||
fmt.Fprintln(m.Out, "Random seed:", plan.Seed) | ||
} | ||
if plan.HasFocus { | ||
fmt.Fprintln(m.Out, "Focus is active.") | ||
} | ||
} | ||
|
||
// Specs prints information about specs' results while suite is running. | ||
func (m *Mocha) Specs(_ *testing.T, specs <-chan spec.Spec) { | ||
m.once.Do(m.setup) | ||
var passed, failed, skipped int | ||
fs := "\033[31m" + "✘" | ||
ps := "\033[32m" + "✔" | ||
ss := "\033[32m" + "✱" | ||
for s := range specs { | ||
switch { | ||
case s.Failed: | ||
failed++ | ||
fmt.Fprint(m.Out, fs) | ||
case s.Skipped: | ||
skipped++ | ||
fmt.Fprint(m.Out, ss) | ||
default: | ||
passed++ | ||
fmt.Fprint(m.Out, ps) | ||
} | ||
for i, txt := range s.Text { | ||
fmt.Fprintln(m.Out, strings.Repeat(" ", i*3), " ", txt) | ||
} | ||
fmt.Fprint(m.Out, "\033[0m") | ||
} | ||
fmt.Fprintf(m.Out, "\nPassed: %d | Failed: %d | Skipped: %d\n\n", passed, failed, skipped) | ||
} |
Oops, something went wrong.