...

Source file src/github.com/go-kivik/kivik/v4/mockdb/common.go

Documentation: github.com/go-kivik/kivik/v4/mockdb

     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  }
   145  

View as plain text