initial commit
[govpp.git] / vendor / github.com / onsi / gomega / gbytes / say_matcher.go
1 package gbytes
2
3 import (
4         "fmt"
5         "regexp"
6
7         "github.com/onsi/gomega/format"
8 )
9
10 //Objects satisfying the BufferProvider can be used with the Say matcher.
11 type BufferProvider interface {
12         Buffer() *Buffer
13 }
14
15 /*
16 Say is a Gomega matcher that operates on gbytes.Buffers:
17
18         Ω(buffer).Should(Say("something"))
19
20 will succeed if the unread portion of the buffer matches the regular expression "something".
21
22 When Say succeeds, it fast forwards the gbytes.Buffer's read cursor to just after the succesful match.
23 Thus, subsequent calls to Say will only match against the unread portion of the buffer
24
25 Say pairs very well with Eventually.  To assert that a buffer eventually receives data matching "[123]-star" within 3 seconds you can:
26
27         Eventually(buffer, 3).Should(Say("[123]-star"))
28
29 Ditto with consistently.  To assert that a buffer does not receive data matching "never-see-this" for 1 second you can:
30
31         Consistently(buffer, 1).ShouldNot(Say("never-see-this"))
32
33 In addition to bytes.Buffers, Say can operate on objects that implement the gbytes.BufferProvider interface.
34 In such cases, Say simply operates on the *gbytes.Buffer returned by Buffer()
35
36 If the buffer is closed, the Say matcher will tell Eventually to abort.
37 */
38 func Say(expected string, args ...interface{}) *sayMatcher {
39         formattedRegexp := expected
40         if len(args) > 0 {
41                 formattedRegexp = fmt.Sprintf(expected, args...)
42         }
43         return &sayMatcher{
44                 re: regexp.MustCompile(formattedRegexp),
45         }
46 }
47
48 type sayMatcher struct {
49         re              *regexp.Regexp
50         receivedSayings []byte
51 }
52
53 func (m *sayMatcher) buffer(actual interface{}) (*Buffer, bool) {
54         var buffer *Buffer
55
56         switch x := actual.(type) {
57         case *Buffer:
58                 buffer = x
59         case BufferProvider:
60                 buffer = x.Buffer()
61         default:
62                 return nil, false
63         }
64
65         return buffer, true
66 }
67
68 func (m *sayMatcher) Match(actual interface{}) (success bool, err error) {
69         buffer, ok := m.buffer(actual)
70         if !ok {
71                 return false, fmt.Errorf("Say must be passed a *gbytes.Buffer or BufferProvider.  Got:\n%s", format.Object(actual, 1))
72         }
73
74         didSay, sayings := buffer.didSay(m.re)
75         m.receivedSayings = sayings
76
77         return didSay, nil
78 }
79
80 func (m *sayMatcher) FailureMessage(actual interface{}) (message string) {
81         return fmt.Sprintf(
82                 "Got stuck at:\n%s\nWaiting for:\n%s",
83                 format.IndentString(string(m.receivedSayings), 1),
84                 format.IndentString(m.re.String(), 1),
85         )
86 }
87
88 func (m *sayMatcher) NegatedFailureMessage(actual interface{}) (message string) {
89         return fmt.Sprintf(
90                 "Saw:\n%s\nWhich matches the unexpected:\n%s",
91                 format.IndentString(string(m.receivedSayings), 1),
92                 format.IndentString(m.re.String(), 1),
93         )
94 }
95
96 func (m *sayMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
97         switch x := actual.(type) {
98         case *Buffer:
99                 return !x.Closed()
100         case BufferProvider:
101                 return !x.Buffer().Closed()
102         default:
103                 return true
104         }
105 }