github.com/go-kivik/kivik/v4@v4.3.2/mockdb/common.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 package mockdb 14 15 import ( 16 "context" 17 "fmt" 18 "strings" 19 "sync" 20 "time" 21 22 kivik "github.com/go-kivik/kivik/v4" 23 "github.com/go-kivik/kivik/v4/driver" 24 ) 25 26 type expectation interface { 27 fulfill() 28 fulfilled() bool 29 Lock() 30 Unlock() 31 fmt.Stringer 32 // method should return the name of the method that would trigger this 33 // condition. If verbose is true, the output should disambiguate between 34 // different calls to the same method. 35 method(verbose bool) string 36 error() error 37 wait(context.Context) error 38 // met is called on the actual value, and returns true if the expectation 39 // is met. 40 met(expectation) bool 41 // for DB methods, this returns the associated *DB object 42 dbo() *DB 43 opts() kivik.Option 44 } 45 46 // commonExpectation satisfies the expectation interface, except the String() 47 // and method() methods. 48 type commonExpectation struct { 49 sync.Mutex 50 triggered bool 51 err error // nolint: structcheck 52 delay time.Duration 53 options kivik.Option 54 db *DB 55 } 56 57 func (e *commonExpectation) opts() kivik.Option { 58 return e.options 59 } 60 61 func (e *commonExpectation) dbo() *DB { 62 return e.db 63 } 64 65 func (e *commonExpectation) fulfill() { 66 e.triggered = true 67 } 68 69 func (e *commonExpectation) fulfilled() bool { 70 return e.triggered 71 } 72 73 func (e *commonExpectation) error() error { 74 return e.err 75 } 76 77 // wait blocks until e.delay expires, or ctx is cancelled. If e.delay expires, 78 // e.err is returned, otherwise ctx.Err() is returned. 79 func (e *commonExpectation) wait(ctx context.Context) error { 80 if e.delay == 0 { 81 return e.err 82 } 83 if err := pause(ctx, e.delay); err != nil { 84 return err 85 } 86 return e.err 87 } 88 89 func pause(ctx context.Context, delay time.Duration) error { 90 if delay == 0 { 91 return nil 92 } 93 t := time.NewTimer(delay) 94 defer t.Stop() 95 select { 96 case <-t.C: 97 return nil 98 case <-ctx.Done(): 99 return ctx.Err() 100 } 101 } 102 103 const ( 104 defaultOptionPlaceholder = "[?]" 105 ) 106 107 func formatOptions(o driver.Options) string { 108 if o != nil { 109 if str := fmt.Sprintf("%v", o); str != "" { 110 return str 111 } 112 } 113 return defaultOptionPlaceholder 114 } 115 116 type multiOptions []kivik.Option 117 118 var _ kivik.Option = (multiOptions)(nil) 119 120 func (mo multiOptions) Apply(t interface{}) { 121 if mo == nil { 122 return 123 } 124 for _, opt := range mo { 125 if opt != nil { 126 opt.Apply(t) 127 } 128 } 129 } 130 131 func (mo multiOptions) String() string { 132 if mo == nil { 133 return "" 134 } 135 parts := make([]string, 0, len(mo)) 136 for _, o := range mo { 137 if o != nil { 138 if part := fmt.Sprintf("%s", o); part != "" { 139 parts = append(parts, part) 140 } 141 } 142 } 143 return strings.Join(parts, ",") 144 }