github.com/freetocompute/snapd@v0.0.0-20210618182524-2fb355d72fd9/testutil/containschecker_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2015-2018 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package testutil_test
    21  
    22  import (
    23  	"runtime"
    24  
    25  	"gopkg.in/check.v1"
    26  
    27  	. "github.com/snapcore/snapd/testutil"
    28  )
    29  
    30  type containsCheckerSuite struct{}
    31  
    32  var _ = check.Suite(&containsCheckerSuite{})
    33  
    34  func (*containsCheckerSuite) TestUnsupportedTypes(c *check.C) {
    35  	testInfo(c, Contains, "Contains", []string{"container", "elem"})
    36  	testCheck(c, Contains, false, "int is not a supported container", 5, nil)
    37  	testCheck(c, Contains, false, "bool is not a supported container", false, nil)
    38  	testCheck(c, Contains, false, "element is a int but expected a string", "container", 1)
    39  }
    40  
    41  func (*containsCheckerSuite) TestContainsVerifiesTypes(c *check.C) {
    42  	testInfo(c, Contains, "Contains", []string{"container", "elem"})
    43  	testCheck(c, Contains,
    44  		false, "container has items of type int but expected element is a string",
    45  		[...]int{1, 2, 3}, "foo")
    46  	testCheck(c, Contains,
    47  		false, "container has items of type int but expected element is a string",
    48  		[]int{1, 2, 3}, "foo")
    49  	// This looks tricky, Contains looks at _values_, not at keys
    50  	testCheck(c, Contains,
    51  		false, "container has items of type int but expected element is a string",
    52  		map[string]int{"foo": 1, "bar": 2}, "foo")
    53  	testCheck(c, Contains,
    54  		false, "container has items of type int but expected element is a string",
    55  		map[string]int{"foo": 1, "bar": 2}, "foo")
    56  }
    57  
    58  type animal interface {
    59  	Sound() string
    60  }
    61  
    62  type dog struct{}
    63  
    64  func (d *dog) Sound() string {
    65  	return "bark"
    66  }
    67  
    68  type cat struct{}
    69  
    70  func (c *cat) Sound() string {
    71  	return "meow"
    72  }
    73  
    74  type tree struct{}
    75  
    76  func (*containsCheckerSuite) TestContainsVerifiesInterfaceTypes(c *check.C) {
    77  	testCheck(c, Contains,
    78  		false, "container has items of interface type testutil_test.animal but expected element does not implement it",
    79  		[...]animal{&dog{}, &cat{}}, &tree{})
    80  	testCheck(c, Contains,
    81  		false, "container has items of interface type testutil_test.animal but expected element does not implement it",
    82  		[]animal{&dog{}, &cat{}}, &tree{})
    83  	testCheck(c, Contains,
    84  		false, "container has items of interface type testutil_test.animal but expected element does not implement it",
    85  		map[string]animal{"dog": &dog{}, "cat": &cat{}}, &tree{})
    86  }
    87  
    88  func (*containsCheckerSuite) TestContainsString(c *check.C) {
    89  	c.Assert("foo", Contains, "f")
    90  	c.Assert("foo", Contains, "fo")
    91  	c.Assert("foo", check.Not(Contains), "foobar")
    92  }
    93  
    94  type myString string
    95  
    96  func (*containsCheckerSuite) TestContainsCustomString(c *check.C) {
    97  	c.Assert(myString("foo"), Contains, myString("f"))
    98  	c.Assert(myString("foo"), Contains, myString("fo"))
    99  	c.Assert(myString("foo"), check.Not(Contains), myString("foobar"))
   100  	c.Assert("foo", Contains, myString("f"))
   101  	c.Assert("foo", Contains, myString("fo"))
   102  	c.Assert("foo", check.Not(Contains), myString("foobar"))
   103  	c.Assert(myString("foo"), Contains, "f")
   104  	c.Assert(myString("foo"), Contains, "fo")
   105  	c.Assert(myString("foo"), check.Not(Contains), "foobar")
   106  }
   107  
   108  func (*containsCheckerSuite) TestContainsArray(c *check.C) {
   109  	c.Assert([...]int{1, 2, 3}, Contains, 1)
   110  	c.Assert([...]int{1, 2, 3}, Contains, 2)
   111  	c.Assert([...]int{1, 2, 3}, Contains, 3)
   112  	c.Assert([...]int{1, 2, 3}, check.Not(Contains), 4)
   113  	c.Assert([...]animal{&dog{}, &cat{}}, Contains, &dog{})
   114  	c.Assert([...]animal{&cat{}}, check.Not(Contains), &dog{})
   115  }
   116  
   117  func (*containsCheckerSuite) TestContainsSlice(c *check.C) {
   118  	c.Assert([]int{1, 2, 3}, Contains, 1)
   119  	c.Assert([]int{1, 2, 3}, Contains, 2)
   120  	c.Assert([]int{1, 2, 3}, Contains, 3)
   121  	c.Assert([]int{1, 2, 3}, check.Not(Contains), 4)
   122  	c.Assert([]animal{&dog{}, &cat{}}, Contains, &dog{})
   123  	c.Assert([]animal{&cat{}}, check.Not(Contains), &dog{})
   124  }
   125  
   126  func (*containsCheckerSuite) TestContainsMap(c *check.C) {
   127  	c.Assert(map[string]int{"foo": 1, "bar": 2}, Contains, 1)
   128  	c.Assert(map[string]int{"foo": 1, "bar": 2}, Contains, 2)
   129  	c.Assert(map[string]int{"foo": 1, "bar": 2}, check.Not(Contains), 3)
   130  	c.Assert(map[string]animal{"dog": &dog{}, "cat": &cat{}}, Contains, &dog{})
   131  	c.Assert(map[string]animal{"cat": &cat{}}, check.Not(Contains), &dog{})
   132  }
   133  
   134  // Arbitrary type that is not comparable
   135  type myStruct struct {
   136  	attrs map[string]string
   137  }
   138  
   139  func (*containsCheckerSuite) TestContainsUncomparableType(c *check.C) {
   140  	if runtime.Compiler != "gc" {
   141  		c.Skip("this test only works on go (not gccgo)")
   142  	}
   143  
   144  	elem := myStruct{map[string]string{"k": "v"}}
   145  	containerArray := [...]myStruct{elem}
   146  	containerSlice := []myStruct{elem}
   147  	containerMap := map[string]myStruct{"foo": elem}
   148  	errMsg := "runtime error: comparing uncomparable type testutil_test.myStruct"
   149  	testInfo(c, Contains, "Contains", []string{"container", "elem"})
   150  	testCheck(c, Contains, false, errMsg, containerArray, elem)
   151  	testCheck(c, Contains, false, errMsg, containerSlice, elem)
   152  	testCheck(c, Contains, false, errMsg, containerMap, elem)
   153  }
   154  
   155  func (*containsCheckerSuite) TestDeepContainsUnsupportedTypes(c *check.C) {
   156  	testInfo(c, DeepContains, "DeepContains", []string{"container", "elem"})
   157  	testCheck(c, DeepContains, false, "int is not a supported container", 5, nil)
   158  	testCheck(c, DeepContains, false, "bool is not a supported container", false, nil)
   159  	testCheck(c, DeepContains, false, "element is a int but expected a string", "container", 1)
   160  }
   161  
   162  func (*containsCheckerSuite) TestDeepContainsVerifiesTypes(c *check.C) {
   163  	testInfo(c, DeepContains, "DeepContains", []string{"container", "elem"})
   164  	testCheck(c, DeepContains,
   165  		false, "container has items of type int but expected element is a string",
   166  		[...]int{1, 2, 3}, "foo")
   167  	testCheck(c, DeepContains,
   168  		false, "container has items of type int but expected element is a string",
   169  		[]int{1, 2, 3}, "foo")
   170  	// This looks tricky, DeepContains looks at _values_, not at keys
   171  	testCheck(c, DeepContains,
   172  		false, "container has items of type int but expected element is a string",
   173  		map[string]int{"foo": 1, "bar": 2}, "foo")
   174  }
   175  
   176  func (*containsCheckerSuite) TestDeepContainsString(c *check.C) {
   177  	c.Assert("foo", DeepContains, "f")
   178  	c.Assert("foo", DeepContains, "fo")
   179  	c.Assert("foo", check.Not(DeepContains), "foobar")
   180  }
   181  
   182  func (*containsCheckerSuite) TestDeepContainsCustomString(c *check.C) {
   183  	c.Assert(myString("foo"), DeepContains, myString("f"))
   184  	c.Assert(myString("foo"), DeepContains, myString("fo"))
   185  	c.Assert(myString("foo"), check.Not(DeepContains), myString("foobar"))
   186  	c.Assert("foo", DeepContains, myString("f"))
   187  	c.Assert("foo", DeepContains, myString("fo"))
   188  	c.Assert("foo", check.Not(DeepContains), myString("foobar"))
   189  	c.Assert(myString("foo"), DeepContains, "f")
   190  	c.Assert(myString("foo"), DeepContains, "fo")
   191  	c.Assert(myString("foo"), check.Not(DeepContains), "foobar")
   192  }
   193  
   194  func (*containsCheckerSuite) TestDeepContainsArray(c *check.C) {
   195  	c.Assert([...]int{1, 2, 3}, DeepContains, 1)
   196  	c.Assert([...]int{1, 2, 3}, DeepContains, 2)
   197  	c.Assert([...]int{1, 2, 3}, DeepContains, 3)
   198  	c.Assert([...]int{1, 2, 3}, check.Not(DeepContains), 4)
   199  }
   200  
   201  func (*containsCheckerSuite) TestDeepContainsSlice(c *check.C) {
   202  	c.Assert([]int{1, 2, 3}, DeepContains, 1)
   203  	c.Assert([]int{1, 2, 3}, DeepContains, 2)
   204  	c.Assert([]int{1, 2, 3}, DeepContains, 3)
   205  	c.Assert([]int{1, 2, 3}, check.Not(DeepContains), 4)
   206  }
   207  
   208  func (*containsCheckerSuite) TestDeepContainsMap(c *check.C) {
   209  	c.Assert(map[string]int{"foo": 1, "bar": 2}, DeepContains, 1)
   210  	c.Assert(map[string]int{"foo": 1, "bar": 2}, DeepContains, 2)
   211  	c.Assert(map[string]int{"foo": 1, "bar": 2}, check.Not(DeepContains), 3)
   212  }
   213  
   214  func (*containsCheckerSuite) TestDeepContainsUncomparableType(c *check.C) {
   215  	elem := myStruct{map[string]string{"k": "v"}}
   216  	containerArray := [...]myStruct{elem}
   217  	containerSlice := []myStruct{elem}
   218  	containerMap := map[string]myStruct{"foo": elem}
   219  	testInfo(c, DeepContains, "DeepContains", []string{"container", "elem"})
   220  	testCheck(c, DeepContains, true, "", containerArray, elem)
   221  	testCheck(c, DeepContains, true, "", containerSlice, elem)
   222  	testCheck(c, DeepContains, true, "", containerMap, elem)
   223  }