Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add assert/opt for creating gocmp.Options #62

Merged
merged 1 commit into from
Mar 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions assert/opt/opt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*Package opt provides common go-cmp.Options for use with assert.DeepEqual.
*/
package opt

import (
"time"

gocmp "github.com/google/go-cmp/cmp"
)

// DurationWithThreshold returns a gocmp.Comparer for comparing time.Duration. The
// Comparer returns true if the difference between the two Duration values is
// within the threshold and neither value is zero.
func DurationWithThreshold(threshold time.Duration) gocmp.Option {
return gocmp.Comparer(cmpDuration(threshold))
}

func cmpDuration(threshold time.Duration) func(x, y time.Duration) bool {
return func(x, y time.Duration) bool {
if x == 0 || y == 0 {
return false
}
delta := x - y
return delta <= threshold && delta >= -threshold
}
}

// TimeWithThreshold returns a gocmp.Comparer for comparing time.Time. The
// Comparer returns true if the difference between the two Time values is
// within the threshold and neither value is zero.
func TimeWithThreshold(threshold time.Duration) gocmp.Option {
return gocmp.Comparer(cmpTime(threshold))
}

func cmpTime(threshold time.Duration) func(x, y time.Time) bool {
return func(x, y time.Time) bool {
if x.IsZero() || y.IsZero() {
return false
}
delta := x.Sub(y)
return delta <= threshold && delta >= -threshold
}
}
141 changes: 141 additions & 0 deletions assert/opt/opt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package opt

import (
"testing"
"time"

"github.com/gotestyourself/gotestyourself/assert"
)

func TestDurationWithThreshold(t *testing.T) {
var testcases = []struct {
name string
x, y, threshold time.Duration
expected bool
}{
{
name: "delta is threshold",
threshold: time.Second,
x: 3 * time.Second,
y: 2 * time.Second,
expected: true,
},
{
name: "delta is negative threshold",
threshold: time.Second,
x: 2 * time.Second,
y: 3 * time.Second,
expected: true,
},
{
name: "delta within threshold",
threshold: time.Second,
x: 300 * time.Millisecond,
y: 100 * time.Millisecond,
expected: true,
},
{
name: "delta within negative threshold",
threshold: time.Second,
x: 100 * time.Millisecond,
y: 300 * time.Millisecond,
expected: true,
},
{
name: "delta outside threshold",
threshold: time.Second,
x: 5 * time.Second,
y: 300 * time.Millisecond,
},
{
name: "delta outside negative threshold",
threshold: time.Second,
x: 300 * time.Millisecond,
y: 5 * time.Second,
},
{
name: "x is 0",
threshold: time.Second,
y: 5 * time.Millisecond,
},
{
name: "y is 0",
threshold: time.Second,
x: 5 * time.Millisecond,
},
}
for _, testcase := range testcases {
t.Run(testcase.name, func(t *testing.T) {
actual := cmpDuration(testcase.threshold)(testcase.x, testcase.y)
assert.Equal(t, actual, testcase.expected)
})
}
}

func TestTimeWithThreshold(t *testing.T) {
var now = time.Now()

var testcases = []struct {
name string
x, y time.Time
threshold time.Duration
expected bool
}{
{
name: "delta is threshold",
threshold: time.Minute,
x: now,
y: now.Add(time.Minute),
expected: true,
},
{
name: "delta is negative threshold",
threshold: time.Minute,
x: now,
y: now.Add(-time.Minute),
expected: true,
},
{
name: "delta within threshold",
threshold: time.Hour,
x: now,
y: now.Add(time.Minute),
expected: true,
},
{
name: "delta within negative threshold",
threshold: time.Hour,
x: now,
y: now.Add(-time.Minute),
expected: true,
},
{
name: "delta outside threshold",
threshold: time.Second,
x: now,
y: now.Add(time.Minute),
},
{
name: "delta outside negative threshold",
threshold: time.Second,
x: now,
y: now.Add(-time.Minute),
},
{
name: "x is 0",
threshold: time.Second,
y: now,
},
{
name: "y is 0",
threshold: time.Second,
x: now,
},
}
for _, testcase := range testcases {
t.Run(testcase.name, func(t *testing.T) {
actual := cmpTime(testcase.threshold)(testcase.x, testcase.y)
assert.Equal(t, actual, testcase.expected)
})
}
}
42 changes: 21 additions & 21 deletions testsum/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,26 @@ import (
gocmp "github.com/google/go-cmp/cmp"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/assert/opt"
)

var cmpSummary = gocmp.Options{
gocmp.AllowUnexported(Failure{}),
gocmp.FilterPath(
func(path gocmp.Path) bool {
return path.Last().String() == ".Elapsed"
},
gocmp.Ignore()),
gocmp.FilterPath(fieldpath("Elapsed"), cmpElapsed()),
}

func fieldpath(spec string) func(gocmp.Path) bool {
return func(path gocmp.Path) bool {
return path.String() == spec
}
}

func cmpElapsed(elapsed time.Duration) is.Comparison {
return func() is.Result {
// appveyor reports 0 seconds elapsed.
if elapsed != 0 || runtime.GOOS == "windows" {
return is.ResultSuccess
}
return is.ResultFailure("expected non-zero duration")
func cmpElapsed() gocmp.Option {
// appveyor reports 0 seconds elapsed.
if runtime.GOOS == "windows" {
return gocmp.Ignore()
}
return opt.DurationWithThreshold(time.Millisecond)
}

func TestScanNoFailures(t *testing.T) {
Expand Down Expand Up @@ -57,10 +58,10 @@ ok github.com/gotestyourself/gotestyourself/icmd 1.256s
out := new(bytes.Buffer)
summary, err := Scan(strings.NewReader(source), out)
assert.NilError(t, err)
assert.Check(t, cmpElapsed(summary.Elapsed))
assert.Check(t, is.DeepEqual(&Summary{Total: 8, Skipped: 1}, summary, cmpSummary))
assert.Equal(t, source, out.String())

expected := &Summary{Total: 8, Skipped: 1, Elapsed: 10 * time.Microsecond}
assert.Check(t, is.DeepEqual(summary, expected, cmpSummary))
assert.Equal(t, source, out.String())
}

func TestScanWithFailure(t *testing.T) {
Expand All @@ -82,11 +83,11 @@ FAIL github.com/gotestyourself/gotestyourself/testsum 0.002s
out := new(bytes.Buffer)
summary, err := Scan(strings.NewReader(source), out)
assert.NilError(t, err)
assert.Check(t, cmpElapsed(summary.Elapsed))
assert.Check(t, is.Equal(source, out.String()))

expected := &Summary{
Total: 3,
Total: 3,
Elapsed: 10 * time.Microsecond,
Failures: []Failure{
{
name: "TestThisShouldFail",
Expand Down Expand Up @@ -115,9 +116,8 @@ PASS

summary, err := Scan(strings.NewReader(source), ioutil.Discard)
assert.NilError(t, err)
assert.Check(t, cmpElapsed(summary.Elapsed))

expected := &Summary{Total: 1}
expected := &Summary{Total: 1, Elapsed: 10 * time.Microsecond}
assert.Check(t, is.DeepEqual(expected, summary, cmpSummary))
}

Expand All @@ -142,7 +142,6 @@ exit status 1

summary, err := Scan(strings.NewReader(source), ioutil.Discard)
assert.NilError(t, err)
assert.Check(t, cmpElapsed(summary.Elapsed))

expectedOutput := `=== RUN TestNested/a
Output from a
Expand All @@ -160,7 +159,8 @@ Output from c
`

expected := &Summary{
Total: 1,
Total: 1,
Elapsed: 10 * time.Microsecond,
Failures: []Failure{
{name: "TestNested", output: expectedOutput, logs: expectedLogs},
},
Expand Down