New Upstream Snapshot - golang-github-karlseguin-expect
Ready changes
Summary
Merged new upstream version: 1.0.8 (was: 1.0.1+git20160716.12.5c2eadb).
Resulting package
Built on 2022-11-19T03:34 (took 3m51s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-snapshots golang-github-karlseguin-expect-dev
Lintian Result
Diff
diff --git a/debian/changelog b/debian/changelog
index 3bfd27d..a2e57b6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-karlseguin-expect (1.0.8-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Sat, 19 Nov 2022 03:31:33 -0000
+
golang-github-karlseguin-expect (1.0.1+git20160716.12.5c2eadb-2) unstable; urgency=medium
* Team Upload.
diff --git a/debian/patches/0001-fix-parsing-flags.patch b/debian/patches/0001-fix-parsing-flags.patch
index efed141..c5aee59 100644
--- a/debian/patches/0001-fix-parsing-flags.patch
+++ b/debian/patches/0001-fix-parsing-flags.patch
@@ -1,7 +1,9 @@
Description: Initialize test so that test flags can be parsed during execution.
---- a/runner.go
-+++ b/runner.go
-@@ -30,6 +30,11 @@
+Index: golang-github-karlseguin-expect.git/runner.go
+===================================================================
+--- golang-github-karlseguin-expect.git.orig/runner.go
++++ golang-github-karlseguin-expect.git/runner.go
+@@ -34,6 +34,11 @@ var (
summaryPattern = regexp.MustCompile(`(?s)(\d+) passed.*?(\d+) failed`)
)
@@ -12,4 +14,4 @@ Description: Initialize test so that test flags can be parsed during execution.
+
func init() {
os.Setenv("GO_TEST", "true")
-
+ }
diff --git a/expect.go b/expect.go
index 8e6683b..1ff2ee9 100644
--- a/expect.go
+++ b/expect.go
@@ -110,7 +110,7 @@ func (e *ToExpectation) Equal(expected interface{}, others ...interface{}) PostH
assertion.invert = e.invert
failed := !equal(assertion, e.actual, expected)
- if len(others) != len(e.others) {
+ if len(others) > len(e.others) {
Errorf("mismatch number of values and expectations %d != %d", len(e.others)+1, len(others)+1)
failed = true
} else {
@@ -128,10 +128,10 @@ func (e *ToExpectation) Equal(expected interface{}, others ...interface{}) PostH
}
func (e *ToExpectation) Eql(expected interface{}, others ...interface{}) PostHandler {
- if len(others) == len(e.others) {
- expected = coerce(e.actual, expected)
+ if len(others) <= len(e.others) {
+ e.actual, expected = coerce(e.actual, expected)
for i := 0; i < len(others); i++ {
- others[i] = coerce(e.others[i], others[i])
+ e.others[i], others[i] = coerce(e.others[i], others[i])
}
}
@@ -328,11 +328,26 @@ func convertFromJson(value interface{}) string {
return string(bytes)
}
-func coerce(actual interface{}, expected interface{}) interface{} {
+func coerce(actual interface{}, expected interface{}) (interface{}, interface{}) {
at := reflect.TypeOf(actual)
et := reflect.TypeOf(expected)
+
+ if et == nil || at == nil {
+ return actual, expected
+ }
+
if et.ConvertibleTo(at) {
- return reflect.ValueOf(expected).Convert(at).Interface()
+ return actual, reflect.ValueOf(expected).Convert(at).Interface()
+ }
+
+ if et.String() == "string" {
+ if error, ok := actual.(interface{ Error() string }); ok {
+ return error.Error(), expected
+ }
+ if stringer, ok := actual.(interface{ String() string }); ok {
+ return stringer.String(), expected
+ }
}
- return expected
+
+ return actual, expected
}
diff --git a/expect_test.go b/expect_test.go
index c60a7d4..42169ce 100644
--- a/expect_test.go
+++ b/expect_test.go
@@ -1,6 +1,7 @@
package expect
import (
+ "errors"
"fmt"
"testing"
)
@@ -113,12 +114,11 @@ func (_ ExpectTests) Contain_Failures() {
func (_ ExpectTests) ExpectMulipleValues_Success() {
Expect(1, true, "over 9000").To.Equal(1, true, "over 9000")
+ Expect([]byte("123"), nil).To.Equal([]byte("123"))
+ Expect([]byte("123"), nil).To.Eql("123")
}
func (_ ExpectTests) ExpectMulipleValues_Failure() {
- failing("mismatch number of values and expectations 3 != 2", 1, func() {
- Expect(1, true, "over 9000").To.Equal(1, true)
- })
failing("mismatch number of values and expectations 2 != 3", 1, func() {
Expect(1, true).To.Equal(1, true, "a")
})
@@ -219,6 +219,18 @@ func (_ ExpectTests) EqlForStringAndBytes() {
Expect("CD").To.Eql([]byte{67, 68})
}
+func (_ ExpectTests) EqlForStringAndError() {
+ Expect(errors.New("an error")).To.Eql("an error")
+
+ failing("expected \"an error\" to be equal to \"123\"", 1, func() {
+ Expect(errors.New("an error")).To.Eql("123")
+ })
+
+ failing("expected <nil> to be equal to 123", 1, func() {
+ Expect(nil).To.Eql("123")
+ })
+}
+
func failing(expected string, count int, f func()) {
actuals := make([]string, 0, 5)
Errorf = func(format string, args ...interface{}) {
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..b8fd454
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/karlseguin/expect
+
+go 1.14
+
+require github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..a766ef9
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
+github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
diff --git a/posthandler.go b/posthandler.go
index 6caeb7e..4adf1a4 100644
--- a/posthandler.go
+++ b/posthandler.go
@@ -6,7 +6,10 @@ import (
)
var (
- SuccessHandler = &SuccessPostHandler{}
+ SuccessHandler = &SuccessPostHandler{}
+ FailureHandlerFactory = func(expected, actual interface{}) PostHandler {
+ return &FailurePostHandler{expected, actual}
+ }
)
type PostHandler interface {
@@ -19,7 +22,7 @@ type FailurePostHandler struct {
}
func NewFailureHandler(expected, actual interface{}) PostHandler {
- return &FailurePostHandler{expected, actual}
+ return FailureHandlerFactory(expected, actual)
}
func (h *FailurePostHandler) Message(format string, args ...interface{}) {
diff --git a/readme.md b/readme.md
index bc03b34..f519ebc 100644
--- a/readme.md
+++ b/readme.md
@@ -44,6 +44,9 @@ Run tests as you normally would via `go test`. However, to run specific tests, u
go test -m AddsTwo
+### Exit On Error
+Use the -e flag to exit on a failed assertion.
+
## Expectations
Two similar syntaxes of expectations are supported
@@ -61,7 +64,7 @@ All expectations can be reversed by starting the chain with `Not.`:
* `Not.GreaterOrEqual.To(x)` or `Not.GreaterOrEqualTo(x)`
* `Not.Less.Than(x)` or `Not.LessThan(x)`
* `Not.LessOrEqual.To(x)` or `Not.LessOrEqualTo(x)`
-
+verbose
### Eql
The `Equal` method is strict. This will fail:
@@ -123,21 +126,24 @@ Expect(res.Code).To.Equal(404).Message("Expected %d got %d")
## Multiple Values
-`Expect` throws away all but the first value. This is convenient when a method returns an error which you don't care to test:
+`Expect` will only compare the number of values expected. This is useful for ignoring nil errors:
```go
Expect(ioutil.ReadFile("blah")).To.Equal([]byte{1, 2, 3, 4})
```
-However, using `To.Equal` multiple values can be provided:
+Multiple expected values can be provided and they'll be compared to the corresponding value:
```go
+Expect(1, true, "a").To.Equal(1, true)
Expect(1, true, "a").To.Equal(1, true, "a")
+
+Expect(1, true, "a").To.Equal(1, true, "a", "NOPE") // will fail
```
## stdout
-Go's testing package has no hooks into its reporting. `Expect` takes the drastic step of occasionally silencing `os.Stdout`, which many packages uses (such as `fmt.Print`). However, within your test, `os.Stdout` **will** work.
+Go's testing package has no hooks into its reporting. `Expect` takes the drastic step of occasionally silencing `os.Stdout`, which many packages use (such as `fmt.Print`). However, within your test, `os.Stdout` **will** work.
If you print anything outside of your test, say during `init`, it'll likely be silenced by `Expect`. You can disable this behavior with the `-vv` flag (use `-v` and `-vv` in combination to change the behavior of both `Expect` and Go's library)
@@ -162,7 +168,7 @@ func (ct *CalculatorTests) n() *Calculator {
}
```
-Futhermore, when you setup the runner, you can setup code to before or after running tests (once for all tests, not once per test):
+Furthermore, when you setup the runner, you can setup code to before or after running tests (once for all tests, not once per test):
```go
func Test_Caculator(t *testing.T) {
@@ -203,14 +209,16 @@ a brief summary beyond what Go's test runner provides (I always worry that every
What we can do is use the `-summary <PATH>` flag and provide a path where summary data will be stored / updated. Therefore, even if multiple processes are launched, and even if we can't output to stdout, with a bit of work invoking the tests, we can get a summary. For example, I recommend a simple Makefile:
```Makefile
- TEMPFILE := $(shell mktemp -u -t testsummary)
-
- test:
- go test ./... -summary $(TEMPFILE)
- @if [ -a $(TEMPFILE) ] ; \
- then \
- awk '{s+=$$1} END {print "\033[1;32m", s, "passed"}' $(TEMPFILE); rm $(TEMPFILE) ;\
- fi;
+TMPDIR := $(shell dirname $(shell mktemp -u))
+TEST_SUMMARY := $(TMPDIR)/$$(go list).go.summary
+
+test:
+ go test ./... -summary $(TEST_SUMMARY)
+ @if [ -a $(TEST_SUMMARY) ] ; \
+ then \
+ awk '{s+=$$1} END {print "\033[1;32m", s, "passed"}' $(TEST_SUMMARY); rm $(TEST_SUMMARY) ;\
+ fi;
+```
# Mocks
diff --git a/runner.go b/runner.go
index 742c9b6..50d1be4 100644
--- a/runner.go
+++ b/runner.go
@@ -9,6 +9,7 @@ import (
"runtime"
"strconv"
"strings"
+ "sync"
"testing"
"time"
@@ -16,7 +17,10 @@ import (
)
var (
+ loaded = false
+ loadLock = new(sync.Mutex)
showStdout = flag.Bool("vv", false, "turn on stdout")
+ exitOnFailure = flag.Bool("e", false, "exit on failures")
matchFlag = flag.String("m", "", "Regular expression selecting which tests to run")
notMatchFlag = flag.String("M", "", "Regular expression selecting which tests not to run")
summaryPath = flag.String("summary", "", "Path to write a summary file to")
@@ -32,21 +36,38 @@ var (
func init() {
os.Setenv("GO_TEST", "true")
-
- flag.Parse()
- if len(*matchFlag) != 0 {
- pattern = regexp.MustCompile("(?i)" + *matchFlag)
- }
- if len(*notMatchFlag) != 0 {
- notPattern = regexp.MustCompile("(?i)" + *notMatchFlag)
- }
- if *showStdout == true {
- silentOut = stdout
- }
- os.Stdout = silentOut
}
func Expectify(suite interface{}, t *testing.T) {
+ loadLock.Lock()
+ if !loaded {
+ flag.Parse()
+ if len(*matchFlag) != 0 {
+ pattern = regexp.MustCompile("(?i)" + *matchFlag)
+ }
+ if len(*notMatchFlag) != 0 {
+ notPattern = regexp.MustCompile("(?i)" + *notMatchFlag)
+ }
+ if *showStdout == true {
+ silentOut = stdout
+ }
+ os.Stdout = silentOut
+ loaded = true
+
+ if *exitOnFailure {
+ FailureHandlerFactory = func(actual, expected interface{}) PostHandler {
+ for _, res := range runner.results {
+ if !res.Passed() || testing.Verbose() {
+ res.Report()
+ }
+ }
+ os.Exit(1)
+ return nil
+ }
+ }
+ }
+ loadLock.Unlock()
+
var name string
var res *result
defer func() {
@@ -192,27 +213,32 @@ func (r *Runner) Skip(format string, args ...interface{}) {
}
func (r *Runner) Errorf(format string, args ...interface{}) {
- file := "???"
- line := 1
- ok := false
- for i := 3; i < 10; i++ {
- _, file, line, ok = runtime.Caller(i)
- if ok == false || strings.HasSuffix(file, "_test.go") {
+ collecting := false
+ stacks := make([]string, 0, 5)
+
+ for i := 0; i < 20; i++ {
+ _, file, line, ok := runtime.Caller(i)
+ if ok == false {
break
}
- }
- if ok {
- if index := strings.LastIndex(file, "/"); index >= 0 {
- file = file[index+1:]
- } else if index = strings.LastIndex(file, "\\"); index >= 0 {
- file = file[index+1:]
+ isTest := strings.HasSuffix(file, "_test.go")
+ if collecting == false && isTest {
+ collecting = true
+ }
+
+ // we're no longer in the _test.go stack, stop collecting
+ if collecting == true && !isTest {
+ break
+ }
+ if collecting {
+ stacks = append(stacks, fmt.Sprintf(" %s:%d", file, line))
}
}
failure := &Failure{
message: fmt.Sprintf(format, args...),
- location: fmt.Sprintf("%s:%d", file, line),
+ location: strings.Join(stacks, "\n") + "\n",
}
r.current.failures = append(r.current.failures, failure)
}
@@ -266,8 +292,8 @@ func (r *result) Report() {
color.Println(" @g✓", info)
} else {
color.Println(" @r×", info)
- for _, failure := range r.failures {
- color.Printf(" @.%-40s%s\n", failure.location, failure.message)
+ for i, failure := range r.failures {
+ color.Printf(" %d. %s\n@.%-40s\n", i+1, failure.message, failure.location)
}
}
}
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/share/gocode/src/github.com/karlseguin/expect/go.mod -rw-r--r-- root/root /usr/share/gocode/src/github.com/karlseguin/expect/go.sum
No differences were encountered in the control files