...

Source file src/github.com/golang/mock/gomock/matchers_test.go

Documentation: github.com/golang/mock/gomock

     1  // Copyright 2010 Google Inc.
     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 gomock_test
    16  
    17  //go:generate mockgen -destination internal/mock_gomock/mock_matcher.go github.com/golang/mock/gomock Matcher
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"reflect"
    23  	"testing"
    24  
    25  	"github.com/golang/mock/gomock"
    26  	"github.com/golang/mock/gomock/internal/mock_gomock"
    27  )
    28  
    29  type A []string
    30  
    31  func TestMatchers(t *testing.T) {
    32  	type e interface{}
    33  	tests := []struct {
    34  		name    string
    35  		matcher gomock.Matcher
    36  		yes, no []e
    37  	}{
    38  		{"test Any", gomock.Any(), []e{3, nil, "foo"}, nil},
    39  		{"test All", gomock.Eq(4), []e{4}, []e{3, "blah", nil, int64(4)}},
    40  		{"test Nil", gomock.Nil(),
    41  			[]e{nil, (error)(nil), (chan bool)(nil), (*int)(nil)},
    42  			[]e{"", 0, make(chan bool), errors.New("err"), new(int)}},
    43  		{"test Not", gomock.Not(gomock.Eq(4)), []e{3, "blah", nil, int64(4)}, []e{4}},
    44  		{"test All", gomock.All(gomock.Any(), gomock.Eq(4)), []e{4}, []e{3, "blah", nil, int64(4)}},
    45  		{"test Len", gomock.Len(2),
    46  			[]e{[]int{1, 2}, "ab", map[string]int{"a": 0, "b": 1}, [2]string{"a", "b"}},
    47  			[]e{[]int{1}, "a", 42, 42.0, false, [1]string{"a"}},
    48  		},
    49  		{"test assignable types", gomock.Eq(A{"a", "b"}),
    50  			[]e{[]string{"a", "b"}, A{"a", "b"}},
    51  			[]e{[]string{"a"}, A{"b"}},
    52  		},
    53  	}
    54  	for _, tt := range tests {
    55  		t.Run(tt.name, func(t *testing.T) {
    56  			for _, x := range tt.yes {
    57  				if !tt.matcher.Matches(x) {
    58  					t.Errorf(`"%v %s": got false, want true.`, x, tt.matcher)
    59  				}
    60  			}
    61  			for _, x := range tt.no {
    62  				if tt.matcher.Matches(x) {
    63  					t.Errorf(`"%v %s": got true, want false.`, x, tt.matcher)
    64  				}
    65  			}
    66  		})
    67  	}
    68  }
    69  
    70  // A more thorough test of notMatcher
    71  func TestNotMatcher(t *testing.T) {
    72  	ctrl := gomock.NewController(t)
    73  	defer ctrl.Finish()
    74  
    75  	mockMatcher := mock_gomock.NewMockMatcher(ctrl)
    76  	notMatcher := gomock.Not(mockMatcher)
    77  
    78  	mockMatcher.EXPECT().Matches(4).Return(true)
    79  	if match := notMatcher.Matches(4); match {
    80  		t.Errorf("notMatcher should not match 4")
    81  	}
    82  
    83  	mockMatcher.EXPECT().Matches(5).Return(false)
    84  	if match := notMatcher.Matches(5); !match {
    85  		t.Errorf("notMatcher should match 5")
    86  	}
    87  }
    88  
    89  type Dog struct {
    90  	Breed, Name string
    91  }
    92  
    93  type ctxKey struct{}
    94  
    95  // A thorough test of assignableToTypeOfMatcher
    96  func TestAssignableToTypeOfMatcher(t *testing.T) {
    97  	ctrl := gomock.NewController(t)
    98  	defer ctrl.Finish()
    99  
   100  	aStr := "def"
   101  	anotherStr := "ghi"
   102  
   103  	if match := gomock.AssignableToTypeOf("abc").Matches(4); match {
   104  		t.Errorf(`AssignableToTypeOf("abc") should not match 4`)
   105  	}
   106  	if match := gomock.AssignableToTypeOf("abc").Matches(&aStr); match {
   107  		t.Errorf(`AssignableToTypeOf("abc") should not match &aStr (*string)`)
   108  	}
   109  	if match := gomock.AssignableToTypeOf("abc").Matches("def"); !match {
   110  		t.Errorf(`AssignableToTypeOf("abc") should match "def"`)
   111  	}
   112  	if match := gomock.AssignableToTypeOf(&aStr).Matches("abc"); match {
   113  		t.Errorf(`AssignableToTypeOf(&aStr) should not match "abc"`)
   114  	}
   115  	if match := gomock.AssignableToTypeOf(&aStr).Matches(&anotherStr); !match {
   116  		t.Errorf(`AssignableToTypeOf(&aStr) should match &anotherStr`)
   117  	}
   118  	if match := gomock.AssignableToTypeOf(0).Matches(4); !match {
   119  		t.Errorf(`AssignableToTypeOf(0) should match 4`)
   120  	}
   121  	if match := gomock.AssignableToTypeOf(0).Matches("def"); match {
   122  		t.Errorf(`AssignableToTypeOf(0) should not match "def"`)
   123  	}
   124  	if match := gomock.AssignableToTypeOf(Dog{}).Matches(&Dog{}); match {
   125  		t.Errorf(`AssignableToTypeOf(Dog{}) should not match &Dog{}`)
   126  	}
   127  	if match := gomock.AssignableToTypeOf(Dog{}).Matches(Dog{Breed: "pug", Name: "Fido"}); !match {
   128  		t.Errorf(`AssignableToTypeOf(Dog{}) should match Dog{Breed: "pug", Name: "Fido"}`)
   129  	}
   130  	if match := gomock.AssignableToTypeOf(&Dog{}).Matches(Dog{}); match {
   131  		t.Errorf(`AssignableToTypeOf(&Dog{}) should not match Dog{}`)
   132  	}
   133  	if match := gomock.AssignableToTypeOf(&Dog{}).Matches(&Dog{Breed: "pug", Name: "Fido"}); !match {
   134  		t.Errorf(`AssignableToTypeOf(&Dog{}) should match &Dog{Breed: "pug", Name: "Fido"}`)
   135  	}
   136  
   137  	ctxInterface := reflect.TypeOf((*context.Context)(nil)).Elem()
   138  	if match := gomock.AssignableToTypeOf(ctxInterface).Matches(context.Background()); !match {
   139  		t.Errorf(`AssignableToTypeOf(context.Context) should not match context.Background()`)
   140  	}
   141  
   142  	ctxWithValue := context.WithValue(context.Background(), ctxKey{}, "val")
   143  	if match := gomock.AssignableToTypeOf(ctxInterface).Matches(ctxWithValue); !match {
   144  		t.Errorf(`AssignableToTypeOf(context.Context) should not match ctxWithValue`)
   145  	}
   146  }
   147  
   148  func TestInAnyOrder(t *testing.T) {
   149  	tests := []struct {
   150  		name      string
   151  		wanted    interface{}
   152  		given     interface{}
   153  		wantMatch bool
   154  	}{
   155  		{
   156  			name:      "match for equal slices",
   157  			wanted:    []int{1, 2, 3},
   158  			given:     []int{1, 2, 3},
   159  			wantMatch: true,
   160  		},
   161  		{
   162  			name:      "match for slices with same elements of different order",
   163  			wanted:    []int{1, 2, 3},
   164  			given:     []int{1, 3, 2},
   165  			wantMatch: true,
   166  		},
   167  		{
   168  			name:      "not match for slices with different elements",
   169  			wanted:    []int{1, 2, 3},
   170  			given:     []int{1, 2, 4},
   171  			wantMatch: false,
   172  		},
   173  		{
   174  			name:      "not match for slices with missing elements",
   175  			wanted:    []int{1, 2, 3},
   176  			given:     []int{1, 2},
   177  			wantMatch: false,
   178  		},
   179  		{
   180  			name:      "not match for slices with extra elements",
   181  			wanted:    []int{1, 2, 3},
   182  			given:     []int{1, 2, 3, 4},
   183  			wantMatch: false,
   184  		},
   185  		{
   186  			name:      "match for empty slices",
   187  			wanted:    []int{},
   188  			given:     []int{},
   189  			wantMatch: true,
   190  		},
   191  		{
   192  			name:      "not match for equal slices of different types",
   193  			wanted:    []float64{1, 2, 3},
   194  			given:     []int{1, 2, 3},
   195  			wantMatch: false,
   196  		},
   197  		{
   198  			name:      "match for equal arrays",
   199  			wanted:    [3]int{1, 2, 3},
   200  			given:     [3]int{1, 2, 3},
   201  			wantMatch: true,
   202  		},
   203  		{
   204  			name:      "match for equal arrays of different order",
   205  			wanted:    [3]int{1, 2, 3},
   206  			given:     [3]int{1, 3, 2},
   207  			wantMatch: true,
   208  		},
   209  		{
   210  			name:      "not match for arrays of different elements",
   211  			wanted:    [3]int{1, 2, 3},
   212  			given:     [3]int{1, 2, 4},
   213  			wantMatch: false,
   214  		},
   215  		{
   216  			name:      "not match for arrays with extra elements",
   217  			wanted:    [3]int{1, 2, 3},
   218  			given:     [4]int{1, 2, 3, 4},
   219  			wantMatch: false,
   220  		},
   221  		{
   222  			name:      "not match for arrays with missing elements",
   223  			wanted:    [3]int{1, 2, 3},
   224  			given:     [2]int{1, 2},
   225  			wantMatch: false,
   226  		},
   227  		{
   228  			name:      "not match for equal strings", // matcher shouldn't treat strings as collections
   229  			wanted:    "123",
   230  			given:     "123",
   231  			wantMatch: false,
   232  		},
   233  		{
   234  			name:      "not match if x type is not iterable",
   235  			wanted:    123,
   236  			given:     []int{123},
   237  			wantMatch: false,
   238  		},
   239  		{
   240  			name:      "not match if in type is not iterable",
   241  			wanted:    []int{123},
   242  			given:     123,
   243  			wantMatch: false,
   244  		},
   245  		{
   246  			name:      "not match if both are not iterable",
   247  			wanted:    123,
   248  			given:     123,
   249  			wantMatch: false,
   250  		},
   251  		{
   252  			name:      "match for equal slices with unhashable elements",
   253  			wanted:    [][]int{{1}, {1, 2}, {1, 2, 3}},
   254  			given:     [][]int{{1}, {1, 2}, {1, 2, 3}},
   255  			wantMatch: true,
   256  		},
   257  		{
   258  			name:      "match for equal slices with unhashable elements of different order",
   259  			wanted:    [][]int{{1}, {1, 2, 3}, {1, 2}},
   260  			given:     [][]int{{1}, {1, 2}, {1, 2, 3}},
   261  			wantMatch: true,
   262  		},
   263  		{
   264  			name:      "not match for different slices with unhashable elements",
   265  			wanted:    [][]int{{1}, {1, 2, 3}, {1, 2}},
   266  			given:     [][]int{{1}, {1, 2, 4}, {1, 3}},
   267  			wantMatch: false,
   268  		},
   269  		{
   270  			name:      "not match for unhashable missing elements",
   271  			wanted:    [][]int{{1}, {1, 2}, {1, 2, 3}},
   272  			given:     [][]int{{1}, {1, 2}},
   273  			wantMatch: false,
   274  		},
   275  		{
   276  			name:      "not match for unhashable extra elements",
   277  			wanted:    [][]int{{1}, {1, 2}},
   278  			given:     [][]int{{1}, {1, 2}, {1, 2, 3}},
   279  			wantMatch: false,
   280  		},
   281  		{
   282  			name:      "match for equal slices of assignable types",
   283  			wanted:    [][]string{{"a", "b"}},
   284  			given:     []A{{"a", "b"}},
   285  			wantMatch: true,
   286  		},
   287  	}
   288  	for _, tt := range tests {
   289  		t.Run(tt.name, func(t *testing.T) {
   290  			if got := gomock.InAnyOrder(tt.wanted).Matches(tt.given); got != tt.wantMatch {
   291  				t.Errorf("got = %v, wantMatch %v", got, tt.wantMatch)
   292  			}
   293  		})
   294  	}
   295  }
   296  

View as plain text