pull oracle matcher into its own package
Onsi Fakhouri
8 years ago
5 | 5 |
"reflect"
|
6 | 6 |
"time"
|
7 | 7 |
|
|
8 |
"github.com/onsi/gomega/internal/oraclematcher"
|
8 | 9 |
"github.com/onsi/gomega/types"
|
9 | 10 |
)
|
10 | 11 |
|
|
85 | 86 |
return assertion.actualInput, nil
|
86 | 87 |
}
|
87 | 88 |
|
88 | |
type oracleMatcher interface {
|
89 | |
MatchMayChangeInTheFuture(actual interface{}) bool
|
90 | |
}
|
91 | |
|
92 | 89 |
func (assertion *AsyncAssertion) matcherMayChange(matcher types.GomegaMatcher, value interface{}) bool {
|
93 | 90 |
if assertion.actualInputIsAFunction() {
|
94 | 91 |
return true
|
95 | 92 |
}
|
96 | 93 |
|
97 | |
return MatchMayChangeInTheFuture(matcher, value)
|
98 | |
}
|
99 | |
|
100 | |
//MatchMayChangeInTheFuture is a helper to call MatchMayChangeInTheFuture on an unknown matcher.
|
101 | |
//If matcher implements oracleMatcher, it will call the method. Otherwise just returns true.
|
102 | |
func MatchMayChangeInTheFuture(matcher types.GomegaMatcher, value interface{}) bool {
|
103 | |
oracleMatcher, ok := matcher.(oracleMatcher)
|
104 | |
if !ok {
|
105 | |
return true
|
106 | |
}
|
107 | |
|
108 | |
return oracleMatcher.MatchMayChangeInTheFuture(value)
|
|
94 |
return oraclematcher.MatchMayChangeInTheFuture(matcher, value)
|
109 | 95 |
}
|
110 | 96 |
|
111 | 97 |
func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
|
|
0 |
package oraclematcher
|
|
1 |
|
|
2 |
import "github.com/onsi/gomega/types"
|
|
3 |
|
|
4 |
/*
|
|
5 |
GomegaMatchers that also match the OracleMatcher interface can convey information about
|
|
6 |
whether or not their result will change upon future attempts.
|
|
7 |
|
|
8 |
This allows `Eventually` and `Consistently` to short circuit if success becomes impossible.
|
|
9 |
|
|
10 |
For example, a process' exit code can never change. So, gexec's Exit matcher returns `true`
|
|
11 |
for `MatchMayChangeInTheFuture` until the process exits, at which point it returns `false` forevermore.
|
|
12 |
*/
|
|
13 |
type OracleMatcher interface {
|
|
14 |
MatchMayChangeInTheFuture(actual interface{}) bool
|
|
15 |
}
|
|
16 |
|
|
17 |
func MatchMayChangeInTheFuture(matcher types.GomegaMatcher, value interface{}) bool {
|
|
18 |
oracleMatcher, ok := matcher.(OracleMatcher)
|
|
19 |
if !ok {
|
|
20 |
return true
|
|
21 |
}
|
|
22 |
|
|
23 |
return oracleMatcher.MatchMayChangeInTheFuture(value)
|
|
24 |
}
|
1 | 1 |
|
2 | 2 |
import (
|
3 | 3 |
"fmt"
|
|
4 |
|
4 | 5 |
"github.com/onsi/gomega/format"
|
5 | |
"github.com/onsi/gomega/internal/asyncassertion"
|
|
6 |
"github.com/onsi/gomega/internal/oraclematcher"
|
6 | 7 |
"github.com/onsi/gomega/types"
|
7 | 8 |
)
|
8 | 9 |
|
|
50 | 51 |
if m.firstFailedMatcher == nil {
|
51 | 52 |
// so all matchers succeeded.. Any one of them changing would change the result.
|
52 | 53 |
for _, matcher := range m.Matchers {
|
53 | |
if asyncassertion.MatchMayChangeInTheFuture(matcher, actual) {
|
|
54 |
if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
|
54 | 55 |
return true
|
55 | 56 |
}
|
56 | 57 |
}
|
57 | 58 |
return false // none of were going to change
|
58 | 59 |
} else {
|
59 | 60 |
// one of the matchers failed.. it must be able to change in order to affect the result
|
60 | |
return asyncassertion.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
|
|
61 |
return oraclematcher.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
|
61 | 62 |
}
|
62 | 63 |
}
|
1 | 1 |
|
2 | 2 |
import (
|
3 | 3 |
"testing"
|
|
4 |
|
4 | 5 |
. "github.com/onsi/ginkgo"
|
5 | 6 |
. "github.com/onsi/gomega"
|
6 | 7 |
)
|
|
24 | 25 |
|
25 | 26 |
func Test(t *testing.T) {
|
26 | 27 |
RegisterFailHandler(Fail)
|
27 | |
RunSpecs(t, "Gomega")
|
|
28 |
RunSpecs(t, "Gomega Matchers")
|
28 | 29 |
}
|
0 | 0 |
package matchers
|
1 | 1 |
|
2 | 2 |
import (
|
3 | |
"github.com/onsi/gomega/internal/asyncassertion"
|
|
3 |
"github.com/onsi/gomega/internal/oraclematcher"
|
4 | 4 |
"github.com/onsi/gomega/types"
|
5 | 5 |
)
|
6 | 6 |
|
|
25 | 25 |
}
|
26 | 26 |
|
27 | 27 |
func (m *NotMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
|
28 | |
return asyncassertion.MatchMayChangeInTheFuture(m.Matcher, actual) // just return m.Matcher's value
|
|
28 |
return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, actual) // just return m.Matcher's value
|
29 | 29 |
}
|
1 | 1 |
|
2 | 2 |
import (
|
3 | 3 |
"fmt"
|
|
4 |
|
4 | 5 |
"github.com/onsi/gomega/format"
|
5 | |
"github.com/onsi/gomega/internal/asyncassertion"
|
|
6 |
"github.com/onsi/gomega/internal/oraclematcher"
|
6 | 7 |
"github.com/onsi/gomega/types"
|
7 | 8 |
)
|
8 | 9 |
|
|
52 | 53 |
|
53 | 54 |
if m.firstSuccessfulMatcher != nil {
|
54 | 55 |
// one of the matchers succeeded.. it must be able to change in order to affect the result
|
55 | |
return asyncassertion.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual)
|
|
56 |
return oraclematcher.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual)
|
56 | 57 |
} else {
|
57 | 58 |
// so all matchers failed.. Any one of them changing would change the result.
|
58 | 59 |
for _, matcher := range m.Matchers {
|
59 | |
if asyncassertion.MatchMayChangeInTheFuture(matcher, actual) {
|
|
60 |
if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
|
60 | 61 |
return true
|
61 | 62 |
}
|
62 | 63 |
}
|
1 | 1 |
|
2 | 2 |
import (
|
3 | 3 |
"fmt"
|
4 | |
"github.com/onsi/gomega/internal/asyncassertion"
|
|
4 |
"reflect"
|
|
5 |
|
|
6 |
"github.com/onsi/gomega/internal/oraclematcher"
|
5 | 7 |
"github.com/onsi/gomega/types"
|
6 | |
"reflect"
|
7 | 8 |
)
|
8 | 9 |
|
9 | 10 |
type WithTransformMatcher struct {
|
|
66 | 67 |
// Querying the next matcher is fine if the transformer always will return the same value.
|
67 | 68 |
// But if the transformer is non-deterministic and returns a different value each time, then there
|
68 | 69 |
// is no point in querying the next matcher, since it can only comment on the last transformed value.
|
69 | |
return asyncassertion.MatchMayChangeInTheFuture(m.Matcher, m.transformedValue)
|
|
70 |
return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, m.transformedValue)
|
70 | 71 |
}
|