123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package gbytes
- import (
- "fmt"
- "regexp"
- "github.com/onsi/gomega/format"
- )
- //Objects satisfying the BufferProvider can be used with the Say matcher.
- type BufferProvider interface {
- Buffer() *Buffer
- }
- /*
- Say is a Gomega matcher that operates on gbytes.Buffers:
- Expect(buffer).Should(Say("something"))
- will succeed if the unread portion of the buffer matches the regular expression "something".
- When Say succeeds, it fast forwards the gbytes.Buffer's read cursor to just after the succesful match.
- Thus, subsequent calls to Say will only match against the unread portion of the buffer
- Say pairs very well with Eventually. To assert that a buffer eventually receives data matching "[123]-star" within 3 seconds you can:
- Eventually(buffer, 3).Should(Say("[123]-star"))
- Ditto with consistently. To assert that a buffer does not receive data matching "never-see-this" for 1 second you can:
- Consistently(buffer, 1).ShouldNot(Say("never-see-this"))
- In addition to bytes.Buffers, Say can operate on objects that implement the gbytes.BufferProvider interface.
- In such cases, Say simply operates on the *gbytes.Buffer returned by Buffer()
- If the buffer is closed, the Say matcher will tell Eventually to abort.
- */
- func Say(expected string, args ...interface{}) *sayMatcher {
- if len(args) > 0 {
- expected = fmt.Sprintf(expected, args...)
- }
- return &sayMatcher{
- re: regexp.MustCompile(expected),
- }
- }
- type sayMatcher struct {
- re *regexp.Regexp
- receivedSayings []byte
- }
- func (m *sayMatcher) buffer(actual interface{}) (*Buffer, bool) {
- var buffer *Buffer
- switch x := actual.(type) {
- case *Buffer:
- buffer = x
- case BufferProvider:
- buffer = x.Buffer()
- default:
- return nil, false
- }
- return buffer, true
- }
- func (m *sayMatcher) Match(actual interface{}) (success bool, err error) {
- buffer, ok := m.buffer(actual)
- if !ok {
- return false, fmt.Errorf("Say must be passed a *gbytes.Buffer or BufferProvider. Got:\n%s", format.Object(actual, 1))
- }
- didSay, sayings := buffer.didSay(m.re)
- m.receivedSayings = sayings
- return didSay, nil
- }
- func (m *sayMatcher) FailureMessage(actual interface{}) (message string) {
- return fmt.Sprintf(
- "Got stuck at:\n%s\nWaiting for:\n%s",
- format.IndentString(string(m.receivedSayings), 1),
- format.IndentString(m.re.String(), 1),
- )
- }
- func (m *sayMatcher) NegatedFailureMessage(actual interface{}) (message string) {
- return fmt.Sprintf(
- "Saw:\n%s\nWhich matches the unexpected:\n%s",
- format.IndentString(string(m.receivedSayings), 1),
- format.IndentString(m.re.String(), 1),
- )
- }
- func (m *sayMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
- switch x := actual.(type) {
- case *Buffer:
- return !x.Closed()
- case BufferProvider:
- return !x.Buffer().Closed()
- default:
- return true
- }
- }
|