pull oracle matcher into its own package
diff --git a/internal/asyncassertion/async_assertion.go b/internal/asyncassertion/async_assertion.go
index b007383..bce0853 100644
--- a/internal/asyncassertion/async_assertion.go
+++ b/internal/asyncassertion/async_assertion.go
@@ -6,6 +6,7 @@
"reflect"
"time"
+ "github.com/onsi/gomega/internal/oraclematcher"
"github.com/onsi/gomega/types"
)
@@ -86,27 +87,12 @@
return assertion.actualInput, nil
}
-type oracleMatcher interface {
- MatchMayChangeInTheFuture(actual interface{}) bool
-}
-
func (assertion *AsyncAssertion) matcherMayChange(matcher types.GomegaMatcher, value interface{}) bool {
if assertion.actualInputIsAFunction() {
return true
}
- return MatchMayChangeInTheFuture(matcher, value)
-}
-
-//MatchMayChangeInTheFuture is a helper to call MatchMayChangeInTheFuture on an unknown matcher.
-//If matcher implements oracleMatcher, it will call the method. Otherwise just returns true.
-func MatchMayChangeInTheFuture(matcher types.GomegaMatcher, value interface{}) bool {
- oracleMatcher, ok := matcher.(oracleMatcher)
- if !ok {
- return true
- }
-
- return oracleMatcher.MatchMayChangeInTheFuture(value)
+ return oraclematcher.MatchMayChangeInTheFuture(matcher, value)
}
func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
diff --git a/internal/oraclematcher/oracle_matcher.go b/internal/oraclematcher/oracle_matcher.go
new file mode 100644
index 0000000..66cad88
--- /dev/null
+++ b/internal/oraclematcher/oracle_matcher.go
@@ -0,0 +1,25 @@
+package oraclematcher
+
+import "github.com/onsi/gomega/types"
+
+/*
+GomegaMatchers that also match the OracleMatcher interface can convey information about
+whether or not their result will change upon future attempts.
+
+This allows `Eventually` and `Consistently` to short circuit if success becomes impossible.
+
+For example, a process' exit code can never change. So, gexec's Exit matcher returns `true`
+for `MatchMayChangeInTheFuture` until the process exits, at which point it returns `false` forevermore.
+*/
+type OracleMatcher interface {
+ MatchMayChangeInTheFuture(actual interface{}) bool
+}
+
+func MatchMayChangeInTheFuture(matcher types.GomegaMatcher, value interface{}) bool {
+ oracleMatcher, ok := matcher.(OracleMatcher)
+ if !ok {
+ return true
+ }
+
+ return oracleMatcher.MatchMayChangeInTheFuture(value)
+}
diff --git a/matchers/and.go b/matchers/and.go
index 5257b76..94c42a7 100644
--- a/matchers/and.go
+++ b/matchers/and.go
@@ -2,8 +2,9 @@
import (
"fmt"
+
"github.com/onsi/gomega/format"
- "github.com/onsi/gomega/internal/asyncassertion"
+ "github.com/onsi/gomega/internal/oraclematcher"
"github.com/onsi/gomega/types"
)
@@ -51,13 +52,13 @@
if m.firstFailedMatcher == nil {
// so all matchers succeeded.. Any one of them changing would change the result.
for _, matcher := range m.Matchers {
- if asyncassertion.MatchMayChangeInTheFuture(matcher, actual) {
+ if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
return true
}
}
return false // none of were going to change
} else {
// one of the matchers failed.. it must be able to change in order to affect the result
- return asyncassertion.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
+ return oraclematcher.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
}
}
diff --git a/matchers/matcher_tests_suite_test.go b/matchers/matcher_tests_suite_test.go
index 4bc6d9d..01b11b9 100644
--- a/matchers/matcher_tests_suite_test.go
+++ b/matchers/matcher_tests_suite_test.go
@@ -2,6 +2,7 @@
import (
"testing"
+
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@@ -25,5 +26,5 @@
func Test(t *testing.T) {
RegisterFailHandler(Fail)
- RunSpecs(t, "Gomega")
+ RunSpecs(t, "Gomega Matchers")
}
diff --git a/matchers/not.go b/matchers/not.go
index 6aed858..2c91670 100644
--- a/matchers/not.go
+++ b/matchers/not.go
@@ -1,7 +1,7 @@
package matchers
import (
- "github.com/onsi/gomega/internal/asyncassertion"
+ "github.com/onsi/gomega/internal/oraclematcher"
"github.com/onsi/gomega/types"
)
@@ -26,5 +26,5 @@
}
func (m *NotMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
- return asyncassertion.MatchMayChangeInTheFuture(m.Matcher, actual) // just return m.Matcher's value
+ return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, actual) // just return m.Matcher's value
}
diff --git a/matchers/or.go b/matchers/or.go
index 29ad5c6..3bf7998 100644
--- a/matchers/or.go
+++ b/matchers/or.go
@@ -2,8 +2,9 @@
import (
"fmt"
+
"github.com/onsi/gomega/format"
- "github.com/onsi/gomega/internal/asyncassertion"
+ "github.com/onsi/gomega/internal/oraclematcher"
"github.com/onsi/gomega/types"
)
@@ -53,11 +54,11 @@
if m.firstSuccessfulMatcher != nil {
// one of the matchers succeeded.. it must be able to change in order to affect the result
- return asyncassertion.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual)
+ return oraclematcher.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual)
} else {
// so all matchers failed.. Any one of them changing would change the result.
for _, matcher := range m.Matchers {
- if asyncassertion.MatchMayChangeInTheFuture(matcher, actual) {
+ if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
return true
}
}
diff --git a/matchers/with_transform.go b/matchers/with_transform.go
index 21d9fe0..8e58d8a 100644
--- a/matchers/with_transform.go
+++ b/matchers/with_transform.go
@@ -2,9 +2,10 @@
import (
"fmt"
- "github.com/onsi/gomega/internal/asyncassertion"
- "github.com/onsi/gomega/types"
"reflect"
+
+ "github.com/onsi/gomega/internal/oraclematcher"
+ "github.com/onsi/gomega/types"
)
type WithTransformMatcher struct {
@@ -67,5 +68,5 @@
// Querying the next matcher is fine if the transformer always will return the same value.
// But if the transformer is non-deterministic and returns a different value each time, then there
// is no point in querying the next matcher, since it can only comment on the last transformed value.
- return asyncassertion.MatchMayChangeInTheFuture(m.Matcher, m.transformedValue)
+ return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, m.transformedValue)
}