github.com/bartle-stripe/trillian@v1.2.1/storage/testonly/matchers.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package testonly
    16  
    17  import (
    18  	"fmt"
    19  	"reflect"
    20  	"sort"
    21  
    22  	"github.com/golang/mock/gomock"
    23  	"github.com/google/trillian/storage"
    24  )
    25  
    26  type nodeIDEq struct {
    27  	expectedID storage.NodeID
    28  }
    29  
    30  func (m nodeIDEq) Matches(x interface{}) bool {
    31  	n, ok := x.(storage.NodeID)
    32  	if !ok {
    33  		return false
    34  	}
    35  	return n.Equivalent(m.expectedID)
    36  }
    37  
    38  func (m nodeIDEq) String() string {
    39  	return fmt.Sprintf("is %s", m.expectedID.String())
    40  }
    41  
    42  // NodeIDEq returns a matcher that expects the specified NodeID.
    43  func NodeIDEq(n storage.NodeID) gomock.Matcher {
    44  	return nodeIDEq{n}
    45  }
    46  
    47  // We need a stable order to match the mock expectations so we sort them by
    48  // prefix len before passing them to the mock library. Might need extending
    49  // if we have more complex tests.
    50  func prefixLen(n1, n2 *storage.Node) bool {
    51  	return n1.NodeID.PrefixLenBits < n2.NodeID.PrefixLenBits
    52  }
    53  
    54  // NodeSet returns a matcher that expects the given set of Nodes.
    55  func NodeSet(nodes []storage.Node) gomock.Matcher {
    56  	by(prefixLen).sort(nodes)
    57  	return nodeSet{nodes}
    58  }
    59  
    60  type nodeSet struct {
    61  	other []storage.Node
    62  }
    63  
    64  func (n nodeSet) Matches(x interface{}) bool {
    65  	nodes, ok := x.([]storage.Node)
    66  	if !ok {
    67  		return false
    68  	}
    69  	by(prefixLen).sort(nodes)
    70  	return reflect.DeepEqual(nodes, n.other)
    71  }
    72  
    73  func (n nodeSet) String() string {
    74  	return fmt.Sprintf("equivalent to %v", n.other)
    75  }
    76  
    77  // Node sorting boilerplate below.
    78  
    79  type by func(n1, n2 *storage.Node) bool
    80  
    81  func (by by) sort(nodes []storage.Node) {
    82  	ns := &nodeSorter{nodes: nodes, by: by}
    83  	sort.Sort(ns)
    84  }
    85  
    86  type nodeSorter struct {
    87  	nodes []storage.Node
    88  	by    func(n1, n2 *storage.Node) bool
    89  }
    90  
    91  func (n *nodeSorter) Len() int {
    92  	return len(n.nodes)
    93  }
    94  
    95  func (n *nodeSorter) Swap(i, j int) {
    96  	n.nodes[i], n.nodes[j] = n.nodes[j], n.nodes[i]
    97  }
    98  
    99  func (n *nodeSorter) Less(i, j int) bool {
   100  	return n.by(&n.nodes[i], &n.nodes[j])
   101  }
   102  
   103  // End sorting boilerplate.