Skip to content

Commit

Permalink
settings: support for supplying cmp.Option to some assertions (#92)
Browse files Browse the repository at this point in the history
* settings: introduce concept of settings

* settings: support for supplying cmp.Option settings

* maps: bring back mapeq func

* settings: rename files

* readme: update readme with options

* docs: add doc strings for settings
  • Loading branch information
shoenig authored Jan 7, 2023
1 parent 6219c20 commit 487172e
Show file tree
Hide file tree
Showing 23 changed files with 1,009 additions and 733 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ There are four key packages,

### Changes

:crown: v0.6.0 adds support for custom `cmp.Option` values

- Adds ability to customize cmp.Equal behavior via cmp.Option arguments
- Adds assertions for existence of single map key
- Fixes some error outputs

:rocket: v0.5.0 contains new packages `wait` and `portal`

- Package for waiting on conditionals
Expand Down Expand Up @@ -85,7 +91,8 @@ Functions like `Eq` and `Contains` work on any type, using the `cmp.Equal` or `r
functions to determine equivalence. Although this is the easiest / most compatible way
to "just compare stuff", it the least deterministic way of comparing instances of a type.
Changes to the underlying types may cause unexpected changes in their equivalence (e.g.
the addition of unexported fields, function field types, etc.).
the addition of unexported fields, function field types, etc.). Assertions that make
use of `cmp.Equal` configured with custom `cmp.Option` values.

#### output

Expand All @@ -103,6 +110,25 @@ a failure. Sometimes it is helpful for a test case to continue running even thou
occurred (e.g. contains cleanup logic not captured via a `t.Cleanup` function). Other times it
make sense to fail immediately and stop the test case execution.

### go-cmp Options

The test assertions that rely on `cmp.Equal` can be customized in how objects
are compared by [specifying custom](https://github.com/google/go-cmp/blob/master/cmp/options.go#L16)
`cmp.Option` values. These can be configured through `test.Cmp` and `must.Cmp` helpers.
Google provides some common custom behaviors in the [cmdopts](https://github.com/google/go-cmp/tree/master/cmp/cmpopts)
package.

Here is an example of comparing two slices, but using a custom Option to sort
the slices so that the order of elements does not matter.

```go
a := []int{3, 5, 1, 6, 7}
b := []int{1, 7, 6, 3, 5}
must.Eq(t, a, b, must.Cmp(cmpopts.SortSlices(func(i, j int) bool {
return i < j
})))
```

### PostScripts

Some tests are large and complex (like e2e testing). It can be helpful to provide more context
Expand Down
24 changes: 2 additions & 22 deletions assert.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
// Package test provides a modern generic testing assertions library.
package test

import (
"strings"

"github.com/shoenig/test/internal/assertions"
)

// T is the minimal set of functions to be implemented by any testing framework
// compatible with the test package.
type T interface {
Helper()
Errorf(string, ...any)
}

func passing(result string) bool {
return result == ""
}

func fail(t T, msg string, scripts ...PostScript) {
c := assertions.Caller()
s := c + msg + "\n" + run(scripts...)
t.Errorf("\n" + strings.TrimSpace(s) + "\n")
}

func invoke(t T, result string, scripts ...PostScript) {
result = strings.TrimSpace(result)
if !passing(result) {
fail(t, result, scripts...)
}
func errorf(t T, msg string, args ...any) {
t.Errorf(msg, args...)
}
65 changes: 0 additions & 65 deletions assert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,8 @@ package test
import (
"fmt"
"strings"
"testing"
)

type testScript struct {
label string
content string
}

func (ts *testScript) Label() string {
return ts.label
}

func (ts *testScript) Content() string {
return ts.content
}

type internalTest struct {
t *testing.T
trigger bool
helper bool
exp string
capture string
}

func (it *internalTest) PS(s string) PostScript {
return &testScript{
label: "label: " + s,
content: "content: " + s,
}
}

func (it *internalTest) Helper() {
it.helper = true
}

func (it *internalTest) Errorf(s string, args ...any) {
if !it.trigger {
it.trigger = true
Expand All @@ -46,35 +13,3 @@ func (it *internalTest) Errorf(s string, args ...any) {
it.capture = msg
fmt.Println(msg)
}

func (it *internalTest) assert() {
if !it.helper {
it.t.Fatal("should be marked as helper")
}
if !it.trigger {
it.t.Fatalf("condition expected to trigger; did not")
}
if !strings.Contains(it.capture, it.exp) {
it.t.Fatalf("expected message %q in output, got %q", it.exp, it.capture)
}
}

func (it *internalTest) post() {
if !strings.Contains(it.capture, "PostScript |") {
it.t.Fatal("expected post-script output")
}
}

func newCase(t *testing.T, msg string) *internalTest {
return &internalTest{
t: t,
trigger: false,
exp: msg,
}
}

func newCapture(t *testing.T) *internalTest {
return &internalTest{
t: t,
}
}
Loading

0 comments on commit 487172e

Please sign in to comment.