Merge lp:~waigani/juju-core/remove-checkers-dir into lp:~go-bot/juju-core/trunk

Proposed by Jesse Meek
Status: Merged
Approved by: Jesse Meek
Approved revision: no longer in the source branch.
Merged at revision: 2435
Proposed branch: lp:~waigani/juju-core/remove-checkers-dir
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 1774 lines (+1/-1698)
13 files modified
testing/checkers/bool.go (+0/-115)
testing/checkers/bool_test.go (+0/-120)
testing/checkers/checker.go (+0/-202)
testing/checkers/checker_test.go (+0/-119)
testing/checkers/deepequal.go (+0/-303)
testing/checkers/deepequal_test.go (+0/-171)
testing/checkers/file.go (+0/-154)
testing/checkers/file_test.go (+0/-165)
testing/checkers/log.go (+0/-109)
testing/checkers/log_test.go (+0/-111)
testing/checkers/relop.go (+0/-93)
testing/checkers/relop_test.go (+0/-35)
worker/instancepoller/aggregate_test.go (+1/-1)
To merge this branch: bzr merge lp:~waigani/juju-core/remove-checkers-dir
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+210935@code.launchpad.net

Commit message

Remove Checkers Dir

We now get checkers from github branch.

Description of the change

Remove Checkers Dir

We now get checkers from github branch.

https://codereview.appspot.com/75630044/

To post a comment you must log in.
Revision history for this message
Jesse Meek (waigani) wrote :

Reviewers: mp+210935_code.launchpad.net,

Message:
Please take a look.

Description:
Remove Checkers Dir

We now get checkers from github branch.

https://code.launchpad.net/~waigani/juju-core/remove-checkers-dir/+merge/210935

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/75630044/

Affected files (+2, -1697 lines):
   A [revision details]
   D testing/checkers/bool.go
   D testing/checkers/bool_test.go
   D testing/checkers/checker.go
   D testing/checkers/checker_test.go
   D testing/checkers/deepequal.go
   D testing/checkers/deepequal_test.go
   D testing/checkers/file.go
   D testing/checkers/file_test.go
   D testing/checkers/log.go
   D testing/checkers/log_test.go
   D testing/checkers/relop.go
   D testing/checkers/relop_test.go

Revision history for this message
Andrew Wilkins (axwalk) wrote :

On 2014/03/13 23:19:53, waigani wrote:
> Please take a look.

LGTM

https://codereview.appspot.com/75630044/

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (10.1 KiB)

The attempt to merge lp:~waigani/juju-core/remove-checkers-dir into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.012s
ok launchpad.net/juju-core/agent 1.008s
ok launchpad.net/juju-core/agent/mongo 0.528s
ok launchpad.net/juju-core/agent/tools 0.207s
ok launchpad.net/juju-core/bzr 5.529s
ok launchpad.net/juju-core/cert 2.377s
ok launchpad.net/juju-core/charm 0.395s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.029s
ok launchpad.net/juju-core/cloudinit/sshinit 0.804s
ok launchpad.net/juju-core/cmd 0.149s
ok launchpad.net/juju-core/cmd/charm-admin 0.767s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 186.802s
ok launchpad.net/juju-core/cmd/jujud 62.283s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 8.487s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.236s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.029s
ok launchpad.net/juju-core/container 0.050s
ok launchpad.net/juju-core/container/factory 0.053s
ok launchpad.net/juju-core/container/kvm 0.233s
ok launchpad.net/juju-core/container/kvm/mock 0.047s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.392s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.236s
ok launchpad.net/juju-core/environs 2.233s
ok launchpad.net/juju-core/environs/bootstrap 3.284s
ok launchpad.net/juju-core/environs/cloudinit 0.476s
ok launchpad.net/juju-core/environs/config 1.986s
ok launchpad.net/juju-core/environs/configstore 0.029s
ok launchpad.net/juju-core/environs/filestorage 0.027s
ok launchpad.net/juju-core/environs/httpstorage 0.628s
ok launchpad.net/juju-core/environs/imagemetadata 0.461s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.048s
ok launchpad.net/juju-core/environs/jujutest 0.195s
ok launchpad.net/juju-core/environs/manual 12.169s
ok launchpad.net/juju-core/environs/simplestreams 0.280s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.922s
ok launchpad.net/juju-core/environs/storage 0.798s
ok launchpad.net/juju-core/environs/sync 43.451s
ok launchpad.net/juju-core/environs/testing 0.136s
ok launchpad.net/juju-core/environs/tools 4.773s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.011s
ok launchpad.net/juju-core/instance 0.016s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 16.873s
ok launchpad.net/juju-core/juju/osenv 0.023s
?...

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (9.9 KiB)

The attempt to merge lp:~waigani/juju-core/remove-checkers-dir into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.011s
ok launchpad.net/juju-core/agent 1.098s
ok launchpad.net/juju-core/agent/mongo 0.549s
ok launchpad.net/juju-core/agent/tools 0.179s
ok launchpad.net/juju-core/bzr 5.574s
ok launchpad.net/juju-core/cert 2.515s
ok launchpad.net/juju-core/charm 0.402s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.029s
ok launchpad.net/juju-core/cloudinit/sshinit 0.769s
ok launchpad.net/juju-core/cmd 0.186s
ok launchpad.net/juju-core/cmd/charm-admin 0.757s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 188.192s
ok launchpad.net/juju-core/cmd/jujud 67.618s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 10.087s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.169s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.028s
ok launchpad.net/juju-core/container 0.037s
ok launchpad.net/juju-core/container/factory 0.049s
ok launchpad.net/juju-core/container/kvm 0.211s
ok launchpad.net/juju-core/container/kvm/mock 0.042s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.289s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.227s
ok launchpad.net/juju-core/environs 2.297s
ok launchpad.net/juju-core/environs/bootstrap 3.068s
ok launchpad.net/juju-core/environs/cloudinit 0.409s
ok launchpad.net/juju-core/environs/config 2.060s
ok launchpad.net/juju-core/environs/configstore 0.028s
ok launchpad.net/juju-core/environs/filestorage 0.023s
ok launchpad.net/juju-core/environs/httpstorage 0.680s
ok launchpad.net/juju-core/environs/imagemetadata 0.507s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.066s
ok launchpad.net/juju-core/environs/jujutest 0.184s
ok launchpad.net/juju-core/environs/manual 12.007s
ok launchpad.net/juju-core/environs/simplestreams 0.248s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 0.980s
ok launchpad.net/juju-core/environs/storage 0.865s
ok launchpad.net/juju-core/environs/sync 43.249s
ok launchpad.net/juju-core/environs/testing 0.125s
ok launchpad.net/juju-core/environs/tools 4.763s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.012s
ok launchpad.net/juju-core/instance 0.023s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 19.015s
ok launchpad.net/juju-core/juju/arch 0.046s
o...

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (46.7 KiB)

The attempt to merge lp:~waigani/juju-core/remove-checkers-dir into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.013s
ok launchpad.net/juju-core/agent 1.047s
ok launchpad.net/juju-core/agent/mongo 0.534s
ok launchpad.net/juju-core/agent/tools 0.178s
ok launchpad.net/juju-core/bzr 5.193s
ok launchpad.net/juju-core/cert 2.399s
ok launchpad.net/juju-core/charm 0.403s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.029s
ok launchpad.net/juju-core/cloudinit/sshinit 0.782s
ok launchpad.net/juju-core/cmd 0.194s
ok launchpad.net/juju-core/cmd/charm-admin 0.744s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 185.876s
ok launchpad.net/juju-core/cmd/jujud 65.179s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 13.179s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/cmd/plugins/local 0.194s
? launchpad.net/juju-core/cmd/plugins/local/juju-local [no test files]
ok launchpad.net/juju-core/constraints 0.030s
ok launchpad.net/juju-core/container 0.043s
ok launchpad.net/juju-core/container/factory 0.044s
ok launchpad.net/juju-core/container/kvm 0.187s
ok launchpad.net/juju-core/container/kvm/mock 0.042s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 4.250s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.224s
ok launchpad.net/juju-core/environs 2.080s
ok launchpad.net/juju-core/environs/bootstrap 3.335s
ok launchpad.net/juju-core/environs/cloudinit 0.559s
ok launchpad.net/juju-core/environs/config 2.217s
ok launchpad.net/juju-core/environs/configstore 0.032s
ok launchpad.net/juju-core/environs/filestorage 0.026s
ok launchpad.net/juju-core/environs/httpstorage 0.737s
ok launchpad.net/juju-core/environs/imagemetadata 0.492s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.049s
ok launchpad.net/juju-core/environs/jujutest 0.207s
ok launchpad.net/juju-core/environs/manual 11.642s
ok launchpad.net/juju-core/environs/simplestreams 0.298s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]

----------------------------------------------------------------------
FAIL: storage_test.go:169: storageSuite.TestWriteFailure

[LOG] 12.41139 DEBUG juju.utils.ssh running: ssh -o "StrictHostKeyChecking no" -o "PasswordAuthentication no" "example.com" 'true'
storage_test.go:196:
    c.Assert(err, gc.IsNil)
... value *errors.errorString = &errors.errorString{s:"failed to create storage dir: write |1: broken pipe ()"} ("failed to create storage dir: write |1: broken pipe ()")

OOPS: 21 passed, 1 FAILED
--- FAIL: Test (0.95 seconds)
FAIL
FAIL launchpad.net/juju-core...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed directory 'testing/checkers'
=== removed file 'testing/checkers/bool.go'
--- testing/checkers/bool.go 2014-01-13 15:00:49 +0000
+++ testing/checkers/bool.go 1970-01-01 00:00:00 +0000
@@ -1,115 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers
5
6import (
7 "fmt"
8 "reflect"
9
10 gc "launchpad.net/gocheck"
11)
12
13type isTrueChecker struct {
14 *gc.CheckerInfo
15}
16
17// IsTrue checks whether a value has an underlying
18// boolean type and is true.
19var IsTrue gc.Checker = &isTrueChecker{
20 &gc.CheckerInfo{Name: "IsTrue", Params: []string{"obtained"}},
21}
22
23// IsTrue checks whether a value has an underlying
24// boolean type and is false.
25var IsFalse gc.Checker = gc.Not(IsTrue)
26
27func (checker *isTrueChecker) Check(params []interface{}, names []string) (result bool, error string) {
28
29 value := reflect.ValueOf(params[0])
30
31 switch value.Kind() {
32 case reflect.Bool:
33 return value.Bool(), ""
34 }
35
36 return false, fmt.Sprintf("expected type bool, received type %s", value.Type())
37}
38
39type satisfiesChecker struct {
40 *gc.CheckerInfo
41}
42
43// Satisfies checks whether a value causes the argument
44// function to return true. The function must be of
45// type func(T) bool where the value being checked
46// is assignable to T.
47var Satisfies gc.Checker = &satisfiesChecker{
48 &gc.CheckerInfo{
49 Name: "Satisfies",
50 Params: []string{"obtained", "func(T) bool"},
51 },
52}
53
54func (checker *satisfiesChecker) Check(params []interface{}, names []string) (result bool, error string) {
55 f := reflect.ValueOf(params[1])
56 ft := f.Type()
57 if ft.Kind() != reflect.Func ||
58 ft.NumIn() != 1 ||
59 ft.NumOut() != 1 ||
60 ft.Out(0) != reflect.TypeOf(true) {
61 return false, fmt.Sprintf("expected func(T) bool, got %s", ft)
62 }
63 v := reflect.ValueOf(params[0])
64 if !v.IsValid() {
65 if !canBeNil(ft.In(0)) {
66 return false, fmt.Sprintf("cannot assign nil to argument %T", ft.In(0))
67 }
68 v = reflect.Zero(ft.In(0))
69 }
70 if !v.Type().AssignableTo(ft.In(0)) {
71 return false, fmt.Sprintf("wrong argument type %s for %s", v.Type(), ft)
72 }
73 return f.Call([]reflect.Value{v})[0].Interface().(bool), ""
74}
75
76func canBeNil(t reflect.Type) bool {
77 switch t.Kind() {
78 case reflect.Chan,
79 reflect.Func,
80 reflect.Interface,
81 reflect.Map,
82 reflect.Ptr,
83 reflect.Slice:
84 return true
85 }
86 return false
87}
88
89type deepEqualsChecker struct {
90 *gc.CheckerInfo
91}
92
93// The DeepEquals checker verifies that the obtained value is deep-equal to
94// the expected value. The check will work correctly even when facing
95// slices, interfaces, and values of different types (which always fail
96// the test).
97//
98// For example:
99//
100// c.Assert(value, DeepEquals, 42)
101// c.Assert(array, DeepEquals, []string{"hi", "there"})
102//
103// This checker differs from gocheck.DeepEquals in that
104// it will compare a nil slice equal to an empty slice,
105// and a nil map equal to an empty map.
106var DeepEquals gc.Checker = &deepEqualsChecker{
107 &gc.CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}},
108}
109
110func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) {
111 if ok, err := DeepEqual(params[0], params[1]); !ok {
112 return false, err.Error()
113 }
114 return true, ""
115}
1160
=== removed file 'testing/checkers/bool_test.go'
--- testing/checkers/bool_test.go 2014-03-13 07:54:56 +0000
+++ testing/checkers/bool_test.go 1970-01-01 00:00:00 +0000
@@ -1,120 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers_test
5
6import (
7 "errors"
8 "os"
9
10 jc "github.com/juju/testing/checkers"
11 gc "launchpad.net/gocheck"
12)
13
14type BoolSuite struct{}
15
16var _ = gc.Suite(&BoolSuite{})
17
18func (s *BoolSuite) TestIsTrue(c *gc.C) {
19 c.Assert(true, jc.IsTrue)
20 c.Assert(false, gc.Not(jc.IsTrue))
21
22 result, msg := jc.IsTrue.Check([]interface{}{false}, nil)
23 c.Assert(result, gc.Equals, false)
24 c.Assert(msg, gc.Equals, "")
25
26 result, msg = jc.IsTrue.Check([]interface{}{"foo"}, nil)
27 c.Assert(result, gc.Equals, false)
28 c.Check(msg, gc.Equals, `expected type bool, received type string`)
29
30 result, msg = jc.IsTrue.Check([]interface{}{42}, nil)
31 c.Assert(result, gc.Equals, false)
32 c.Assert(msg, gc.Equals, `expected type bool, received type int`)
33}
34
35func (s *BoolSuite) TestIsFalse(c *gc.C) {
36 c.Assert(false, jc.IsFalse)
37 c.Assert(true, gc.Not(jc.IsFalse))
38}
39
40func is42(i int) bool {
41 return i == 42
42}
43
44var satisfiesTests = []struct {
45 f interface{}
46 arg interface{}
47 result bool
48 msg string
49}{{
50 f: is42,
51 arg: 42,
52 result: true,
53}, {
54 f: is42,
55 arg: 41,
56 result: false,
57}, {
58 f: is42,
59 arg: "",
60 result: false,
61 msg: "wrong argument type string for func(int) bool",
62}, {
63 f: os.IsNotExist,
64 arg: errors.New("foo"),
65 result: false,
66}, {
67 f: os.IsNotExist,
68 arg: os.ErrNotExist,
69 result: true,
70}, {
71 f: os.IsNotExist,
72 arg: nil,
73 result: false,
74}, {
75 f: func(chan int) bool { return true },
76 arg: nil,
77 result: true,
78}, {
79 f: func(func()) bool { return true },
80 arg: nil,
81 result: true,
82}, {
83 f: func(interface{}) bool { return true },
84 arg: nil,
85 result: true,
86}, {
87 f: func(map[string]bool) bool { return true },
88 arg: nil,
89 result: true,
90}, {
91 f: func(*int) bool { return true },
92 arg: nil,
93 result: true,
94}, {
95 f: func([]string) bool { return true },
96 arg: nil,
97 result: true,
98}}
99
100func (s *BoolSuite) TestSatisfies(c *gc.C) {
101 for i, test := range satisfiesTests {
102 c.Logf("test %d. %T %T", i, test.f, test.arg)
103 result, msg := jc.Satisfies.Check([]interface{}{test.arg, test.f}, nil)
104 c.Check(result, gc.Equals, test.result)
105 c.Check(msg, gc.Equals, test.msg)
106 }
107}
108
109func (s *BoolSuite) TestDeepEquals(c *gc.C) {
110 for i, test := range deepEqualTests {
111 c.Logf("test %d. %v == %v is %v", i, test.a, test.b, test.eq)
112 result, msg := jc.DeepEquals.Check([]interface{}{test.a, test.b}, nil)
113 c.Check(result, gc.Equals, test.eq)
114 if test.eq {
115 c.Check(msg, gc.Equals, "")
116 } else {
117 c.Check(msg, gc.Not(gc.Equals), "")
118 }
119 }
120}
1210
=== removed file 'testing/checkers/checker.go'
--- testing/checkers/checker.go 2013-09-13 14:48:13 +0000
+++ testing/checkers/checker.go 1970-01-01 00:00:00 +0000
@@ -1,202 +0,0 @@
1// Copyright 2012, 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers
5
6import (
7 "fmt"
8 "reflect"
9 "strings"
10 "time"
11
12 gc "launchpad.net/gocheck"
13)
14
15func TimeBetween(start, end time.Time) gc.Checker {
16 if end.Before(start) {
17 return &timeBetweenChecker{end, start}
18 }
19 return &timeBetweenChecker{start, end}
20}
21
22type timeBetweenChecker struct {
23 start, end time.Time
24}
25
26func (checker *timeBetweenChecker) Info() *gc.CheckerInfo {
27 info := gc.CheckerInfo{
28 Name: "TimeBetween",
29 Params: []string{"obtained"},
30 }
31 return &info
32}
33
34func (checker *timeBetweenChecker) Check(params []interface{}, names []string) (result bool, error string) {
35 when, ok := params[0].(time.Time)
36 if !ok {
37 return false, "obtained value type must be time.Time"
38 }
39 if when.Before(checker.start) {
40 return false, fmt.Sprintf("obtained value %#v type must before start value of %#v", when, checker.start)
41 }
42 if when.After(checker.end) {
43 return false, fmt.Sprintf("obtained value %#v type must after end value of %#v", when, checker.end)
44 }
45 return true, ""
46}
47
48// DurationLessThan checker
49
50type durationLessThanChecker struct {
51 *gc.CheckerInfo
52}
53
54var DurationLessThan gc.Checker = &durationLessThanChecker{
55 &gc.CheckerInfo{Name: "DurationLessThan", Params: []string{"obtained", "expected"}},
56}
57
58func (checker *durationLessThanChecker) Check(params []interface{}, names []string) (result bool, error string) {
59 obtained, ok := params[0].(time.Duration)
60 if !ok {
61 return false, "obtained value type must be time.Duration"
62 }
63 expected, ok := params[1].(time.Duration)
64 if !ok {
65 return false, "expected value type must be time.Duration"
66 }
67 return obtained.Nanoseconds() < expected.Nanoseconds(), ""
68}
69
70// HasPrefix checker for checking strings
71
72func stringOrStringer(value interface{}) (string, bool) {
73 result, isString := value.(string)
74 if !isString {
75 if stringer, isStringer := value.(fmt.Stringer); isStringer {
76 result, isString = stringer.String(), true
77 }
78 }
79 return result, isString
80}
81
82type hasPrefixChecker struct {
83 *gc.CheckerInfo
84}
85
86var HasPrefix gc.Checker = &hasPrefixChecker{
87 &gc.CheckerInfo{Name: "HasPrefix", Params: []string{"obtained", "expected"}},
88}
89
90func (checker *hasPrefixChecker) Check(params []interface{}, names []string) (result bool, error string) {
91 expected, ok := params[1].(string)
92 if !ok {
93 return false, "expected must be a string"
94 }
95
96 obtained, isString := stringOrStringer(params[0])
97 if isString {
98 return strings.HasPrefix(obtained, expected), ""
99 }
100
101 return false, "Obtained value is not a string and has no .String()"
102}
103
104type hasSuffixChecker struct {
105 *gc.CheckerInfo
106}
107
108var HasSuffix gc.Checker = &hasSuffixChecker{
109 &gc.CheckerInfo{Name: "HasSuffix", Params: []string{"obtained", "expected"}},
110}
111
112func (checker *hasSuffixChecker) Check(params []interface{}, names []string) (result bool, error string) {
113 expected, ok := params[1].(string)
114 if !ok {
115 return false, "expected must be a string"
116 }
117
118 obtained, isString := stringOrStringer(params[0])
119 if isString {
120 return strings.HasSuffix(obtained, expected), ""
121 }
122
123 return false, "Obtained value is not a string and has no .String()"
124}
125
126type containsChecker struct {
127 *gc.CheckerInfo
128}
129
130var Contains gc.Checker = &containsChecker{
131 &gc.CheckerInfo{Name: "Contains", Params: []string{"obtained", "expected"}},
132}
133
134func (checker *containsChecker) Check(params []interface{}, names []string) (result bool, error string) {
135 expected, ok := params[1].(string)
136 if !ok {
137 return false, "expected must be a string"
138 }
139
140 obtained, isString := stringOrStringer(params[0])
141 if isString {
142 return strings.Contains(obtained, expected), ""
143 }
144
145 return false, "Obtained value is not a string and has no .String()"
146}
147
148type sameContents struct {
149 *gc.CheckerInfo
150}
151
152// SameContents checks that the obtained slice contains all the values (and
153// same number of values) of the expected slice and vice versa, without respect
154// to order or duplicates. Uses DeepEquals on mapped contents to compare.
155var SameContents gc.Checker = &sameContents{
156 &gc.CheckerInfo{Name: "SameContents", Params: []string{"obtained", "expected"}},
157}
158
159func (checker *sameContents) Check(params []interface{}, names []string) (result bool, error string) {
160 if len(params) != 2 {
161 return false, "SameContents expects two slice arguments"
162 }
163 obtained := params[0]
164 expected := params[1]
165
166 tob := reflect.TypeOf(obtained)
167 if tob.Kind() != reflect.Slice {
168 return false, fmt.Sprintf("SameContents expects the obtained value to be a slice, got %q",
169 tob.Kind())
170 }
171
172 texp := reflect.TypeOf(expected)
173 if texp.Kind() != reflect.Slice {
174 return false, fmt.Sprintf("SameContents expects the expected value to be a slice, got %q",
175 texp.Kind())
176 }
177
178 if texp != tob {
179 return false, fmt.Sprintf(
180 "SameContents expects two slices of the same type, expected: %q, got: %q",
181 texp, tob)
182 }
183
184 vexp := reflect.ValueOf(expected)
185 vob := reflect.ValueOf(obtained)
186 length := vexp.Len()
187
188 if vob.Len() != length {
189 // Slice has incorrect number of elements
190 return false, ""
191 }
192
193 // spin up maps with the entries as keys and the counts as values
194 mob := make(map[interface{}]int, length)
195 mexp := make(map[interface{}]int, length)
196
197 for i := 0; i < length; i++ {
198 mexp[vexp.Index(i).Interface()]++
199 mob[vob.Index(i).Interface()]++
200 }
201 return reflect.DeepEqual(mob, mexp), ""
202}
2030
=== removed file 'testing/checkers/checker_test.go'
--- testing/checkers/checker_test.go 2014-03-13 07:54:56 +0000
+++ testing/checkers/checker_test.go 1970-01-01 00:00:00 +0000
@@ -1,119 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers_test
5
6import (
7 "testing"
8
9 jc "github.com/juju/testing/checkers"
10 gc "launchpad.net/gocheck"
11)
12
13func Test(t *testing.T) { gc.TestingT(t) }
14
15type CheckerSuite struct{}
16
17var _ = gc.Suite(&CheckerSuite{})
18
19func (s *CheckerSuite) TestHasPrefix(c *gc.C) {
20 c.Assert("foo bar", jc.HasPrefix, "foo")
21 c.Assert("foo bar", gc.Not(jc.HasPrefix), "omg")
22}
23
24func (s *CheckerSuite) TestHasSuffix(c *gc.C) {
25 c.Assert("foo bar", jc.HasSuffix, "bar")
26 c.Assert("foo bar", gc.Not(jc.HasSuffix), "omg")
27}
28
29func (s *CheckerSuite) TestContains(c *gc.C) {
30 c.Assert("foo bar baz", jc.Contains, "foo")
31 c.Assert("foo bar baz", jc.Contains, "bar")
32 c.Assert("foo bar baz", jc.Contains, "baz")
33 c.Assert("foo bar baz", gc.Not(jc.Contains), "omg")
34}
35
36func (s *CheckerSuite) TestSameContents(c *gc.C) {
37 //// positive cases ////
38
39 // same
40 c.Check(
41 []int{1, 2, 3}, jc.SameContents,
42 []int{1, 2, 3})
43
44 // empty
45 c.Check(
46 []int{}, jc.SameContents,
47 []int{})
48
49 // single
50 c.Check(
51 []int{1}, jc.SameContents,
52 []int{1})
53
54 // different order
55 c.Check(
56 []int{1, 2, 3}, jc.SameContents,
57 []int{3, 2, 1})
58
59 // multiple copies of same
60 c.Check(
61 []int{1, 1, 2}, jc.SameContents,
62 []int{2, 1, 1})
63
64 type test struct {
65 s string
66 i int
67 }
68
69 // test structs
70 c.Check(
71 []test{{"a", 1}, {"b", 2}}, jc.SameContents,
72 []test{{"b", 2}, {"a", 1}})
73
74 //// negative cases ////
75
76 // different contents
77 c.Check(
78 []int{1, 3, 2, 5}, gc.Not(jc.SameContents),
79 []int{5, 2, 3, 4})
80
81 // different size slices
82 c.Check(
83 []int{1, 2, 3}, gc.Not(jc.SameContents),
84 []int{1, 2})
85
86 // different counts of same items
87 c.Check(
88 []int{1, 1, 2}, gc.Not(jc.SameContents),
89 []int{1, 2, 2})
90
91 /// Error cases ///
92 // note: for these tests, we can't use gc.Not, since Not passes the error value through
93 // and checks with a non-empty error always count as failed
94 // Oddly, there doesn't seem to actually be a way to check for an error from a Checker.
95
96 // different type
97 res, err := jc.SameContents.Check([]interface{}{
98 []string{"1", "2"},
99 []int{1, 2},
100 }, []string{})
101 c.Check(res, jc.IsFalse)
102 c.Check(err, gc.Not(gc.Equals), "")
103
104 // obtained not a slice
105 res, err = jc.SameContents.Check([]interface{}{
106 "test",
107 []int{1},
108 }, []string{})
109 c.Check(res, jc.IsFalse)
110 c.Check(err, gc.Not(gc.Equals), "")
111
112 // expected not a slice
113 res, err = jc.SameContents.Check([]interface{}{
114 []int{1},
115 "test",
116 }, []string{})
117 c.Check(res, jc.IsFalse)
118 c.Check(err, gc.Not(gc.Equals), "")
119}
1200
=== removed file 'testing/checkers/deepequal.go'
--- testing/checkers/deepequal.go 2014-01-13 16:04:29 +0000
+++ testing/checkers/deepequal.go 1970-01-01 00:00:00 +0000
@@ -1,303 +0,0 @@
1// Copied with small adaptations from the reflect package in the
2// Go source tree.
3
4// Copyright 2009 The Go Authors. All rights reserved.
5// Use of this source code is governed by a BSD-style
6// license that can be found in the LICENSE file.
7
8package checkers
9
10import (
11 "fmt"
12 "reflect"
13 "unsafe"
14)
15
16// During deepValueEqual, must keep track of checks that are
17// in progress. The comparison algorithm assumes that all
18// checks in progress are true when it reencounters them.
19// Visited comparisons are stored in a map indexed by visit.
20type visit struct {
21 a1 uintptr
22 a2 uintptr
23 typ reflect.Type
24}
25
26type mismatchError struct {
27 v1, v2 reflect.Value
28 path string
29 how string
30}
31
32func (err *mismatchError) Error() string {
33 path := err.path
34 if path == "" {
35 path = "top level"
36 }
37 return fmt.Sprintf("mismatch at %s: %s; obtained %#v; expected %#v", path, err.how, interfaceOf(err.v1), interfaceOf(err.v2))
38}
39
40// Tests for deep equality using reflected types. The map argument tracks
41// comparisons that have already been seen, which allows short circuiting on
42// recursive types.
43func deepValueEqual(path string, v1, v2 reflect.Value, visited map[visit]bool, depth int) (ok bool, err error) {
44 errorf := func(f string, a ...interface{}) error {
45 return &mismatchError{
46 v1: v1,
47 v2: v2,
48 path: path,
49 how: fmt.Sprintf(f, a...),
50 }
51 }
52 if !v1.IsValid() || !v2.IsValid() {
53 if v1.IsValid() == v2.IsValid() {
54 return true, nil
55 }
56 return false, errorf("validity mismatch")
57 }
58 if v1.Type() != v2.Type() {
59 return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
60 }
61
62 // if depth > 10 { panic("deepValueEqual") } // for debugging
63 hard := func(k reflect.Kind) bool {
64 switch k {
65 case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
66 return true
67 }
68 return false
69 }
70
71 if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
72 addr1 := v1.UnsafeAddr()
73 addr2 := v2.UnsafeAddr()
74 if addr1 > addr2 {
75 // Canonicalize order to reduce number of entries in visited.
76 addr1, addr2 = addr2, addr1
77 }
78
79 // Short circuit if references are identical ...
80 if addr1 == addr2 {
81 return true, nil
82 }
83
84 // ... or already seen
85 typ := v1.Type()
86 v := visit{addr1, addr2, typ}
87 if visited[v] {
88 return true, nil
89 }
90
91 // Remember for later.
92 visited[v] = true
93 }
94
95 switch v1.Kind() {
96 case reflect.Array:
97 if v1.Len() != v2.Len() {
98 // can't happen!
99 return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
100 }
101 for i := 0; i < v1.Len(); i++ {
102 if ok, err := deepValueEqual(
103 fmt.Sprintf("%s[%d]", path, i),
104 v1.Index(i), v2.Index(i), visited, depth+1); !ok {
105 return false, err
106 }
107 }
108 return true, nil
109 case reflect.Slice:
110 // We treat a nil slice the same as an empty slice.
111 if v1.Len() != v2.Len() {
112 return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
113 }
114 if v1.Pointer() == v2.Pointer() {
115 return true, nil
116 }
117 for i := 0; i < v1.Len(); i++ {
118 if ok, err := deepValueEqual(
119 fmt.Sprintf("%s[%d]", path, i),
120 v1.Index(i), v2.Index(i), visited, depth+1); !ok {
121 return false, err
122 }
123 }
124 return true, nil
125 case reflect.Interface:
126 if v1.IsNil() || v2.IsNil() {
127 if v1.IsNil() != v2.IsNil() {
128 return false, fmt.Errorf("nil vs non-nil interface mismatch")
129 }
130 return true, nil
131 }
132 return deepValueEqual(path, v1.Elem(), v2.Elem(), visited, depth+1)
133 case reflect.Ptr:
134 return deepValueEqual("(*"+path+")", v1.Elem(), v2.Elem(), visited, depth+1)
135 case reflect.Struct:
136 for i, n := 0, v1.NumField(); i < n; i++ {
137 path := path + "." + v1.Type().Field(i).Name
138 if ok, err := deepValueEqual(path, v1.Field(i), v2.Field(i), visited, depth+1); !ok {
139 return false, err
140 }
141 }
142 return true, nil
143 case reflect.Map:
144 if v1.IsNil() != v2.IsNil() {
145 return false, errorf("nil vs non-nil mismatch")
146 }
147 if v1.Len() != v2.Len() {
148 return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
149 }
150 if v1.Pointer() == v2.Pointer() {
151 return true, nil
152 }
153 for _, k := range v1.MapKeys() {
154 var p string
155 if k.CanInterface() {
156 p = path + "[" + fmt.Sprintf("%#v", k.Interface()) + "]"
157 } else {
158 p = path + "[someKey]"
159 }
160 if ok, err := deepValueEqual(p, v1.MapIndex(k), v2.MapIndex(k), visited, depth+1); !ok {
161 return false, err
162 }
163 }
164 return true, nil
165 case reflect.Func:
166 if v1.IsNil() && v2.IsNil() {
167 return true, nil
168 }
169 // Can't do better than this:
170 return false, errorf("non-nil functions")
171 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
172 if v1.Int() != v2.Int() {
173 return false, errorf("unequal")
174 }
175 return true, nil
176 case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
177 if v1.Uint() != v2.Uint() {
178 return false, errorf("unequal")
179 }
180 return true, nil
181 case reflect.Float32, reflect.Float64:
182 if v1.Float() != v2.Float() {
183 return false, errorf("unequal")
184 }
185 return true, nil
186 case reflect.Complex64, reflect.Complex128:
187 if v1.Complex() != v2.Complex() {
188 return false, errorf("unequal")
189 }
190 return true, nil
191 case reflect.Bool:
192 if v1.Bool() != v2.Bool() {
193 return false, errorf("unequal")
194 }
195 return true, nil
196 case reflect.String:
197 if v1.String() != v2.String() {
198 return false, errorf("unequal")
199 }
200 return true, nil
201 case reflect.Chan, reflect.UnsafePointer:
202 if v1.Pointer() != v2.Pointer() {
203 return false, errorf("unequal")
204 }
205 return true, nil
206 default:
207 panic("unexpected type " + v1.Type().String())
208 }
209}
210
211// DeepEqual tests for deep equality. It uses normal == equality where
212// possible but will scan elements of arrays, slices, maps, and fields
213// of structs. In maps, keys are compared with == but elements use deep
214// equality. DeepEqual correctly handles recursive types. Functions are
215// equal only if they are both nil.
216//
217// DeepEqual differs from reflect.DeepEqual in that an empty slice is
218// equal to a nil slice. If the two values compare unequal, the
219// resulting error holds the first difference encountered.
220func DeepEqual(a1, a2 interface{}) (bool, error) {
221 errorf := func(f string, a ...interface{}) error {
222 return &mismatchError{
223 v1: reflect.ValueOf(a1),
224 v2: reflect.ValueOf(a2),
225 path: "",
226 how: fmt.Sprintf(f, a...),
227 }
228 }
229 if a1 == nil || a2 == nil {
230 if a1 == a2 {
231 return true, nil
232 }
233 return false, errorf("nil vs non-nil mismatch")
234 }
235 v1 := reflect.ValueOf(a1)
236 v2 := reflect.ValueOf(a2)
237 if v1.Type() != v2.Type() {
238 return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
239 }
240 return deepValueEqual("", v1, v2, make(map[visit]bool), 0)
241}
242
243// interfaceOf returns v.Interface() even if v.CanInterface() == false.
244// This enables us to call fmt.Printf on a value even if it's derived
245// from inside an unexported field.
246func interfaceOf(v reflect.Value) interface{} {
247 if !v.IsValid() {
248 return nil
249 }
250 return bypassCanInterface(v).Interface()
251}
252
253type flag uintptr
254
255// copied from reflect/value.go
256const (
257 flagRO flag = 1 << iota
258)
259
260var flagValOffset = func() uintptr {
261 field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
262 if !ok {
263 panic("reflect.Value has no flag field")
264 }
265 return field.Offset
266}()
267
268func flagField(v *reflect.Value) *flag {
269 return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
270}
271
272// bypassCanInterface returns a version of v that
273// bypasses the CanInterface check.
274func bypassCanInterface(v reflect.Value) reflect.Value {
275 if !v.IsValid() || v.CanInterface() {
276 return v
277 }
278 *flagField(&v) &^= flagRO
279 return v
280}
281
282// Sanity checks against future reflect package changes
283// to the type or semantics of the Value.flag field.
284func init() {
285 field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
286 if !ok {
287 panic("reflect.Value has no flag field")
288 }
289 if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
290 panic("reflect.Value flag field has changed kind")
291 }
292 var t struct {
293 a int
294 A int
295 }
296 vA := reflect.ValueOf(t).FieldByName("A")
297 va := reflect.ValueOf(t).FieldByName("a")
298 flagA := *flagField(&vA)
299 flaga := *flagField(&va)
300 if flagA&flagRO != 0 || flaga&flagRO == 0 {
301 panic("reflect.Value read-only flag has changed value")
302 }
303}
3040
=== removed file 'testing/checkers/deepequal_test.go'
--- testing/checkers/deepequal_test.go 2014-03-13 07:54:56 +0000
+++ testing/checkers/deepequal_test.go 1970-01-01 00:00:00 +0000
@@ -1,171 +0,0 @@
1// Copied with small adaptations from the reflect package in the
2// Go source tree. We use testing rather than gocheck to preserve
3// as much source equivalence as possible.
4
5// TODO tests for error messages
6
7// Copyright 2009 The Go Authors. All rights reserved.
8// Use of this source code is governed by a BSD-style
9// license that can be found in the LICENSE file.
10
11package checkers_test
12
13import (
14 "regexp"
15 "testing"
16
17 "github.com/juju/testing/checkers"
18)
19
20func deepEqual(a1, a2 interface{}) bool {
21 ok, _ := checkers.DeepEqual(a1, a2)
22 return ok
23}
24
25type Basic struct {
26 x int
27 y float32
28}
29
30type NotBasic Basic
31
32type DeepEqualTest struct {
33 a, b interface{}
34 eq bool
35 msg string
36}
37
38// Simple functions for DeepEqual tests.
39var (
40 fn1 func() // nil.
41 fn2 func() // nil.
42 fn3 = func() { fn1() } // Not nil.
43)
44
45var deepEqualTests = []DeepEqualTest{
46 // Equalities
47 {nil, nil, true, ""},
48 {1, 1, true, ""},
49 {int32(1), int32(1), true, ""},
50 {0.5, 0.5, true, ""},
51 {float32(0.5), float32(0.5), true, ""},
52 {"hello", "hello", true, ""},
53 {make([]int, 10), make([]int, 10), true, ""},
54 {&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true, ""},
55 {Basic{1, 0.5}, Basic{1, 0.5}, true, ""},
56 {error(nil), error(nil), true, ""},
57 {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true, ""},
58 {fn1, fn2, true, ""},
59
60 // Inequalities
61 {1, 2, false, `mismatch at top level: unequal; obtained 1; expected 2`},
62 {int32(1), int32(2), false, `mismatch at top level: unequal; obtained 1; expected 2`},
63 {0.5, 0.6, false, `mismatch at top level: unequal; obtained 0\.5; expected 0\.6`},
64 {float32(0.5), float32(0.6), false, `mismatch at top level: unequal; obtained 0\.5; expected 0\.6`},
65 {"hello", "hey", false, `mismatch at top level: unequal; obtained "hello"; expected "hey"`},
66 {make([]int, 10), make([]int, 11), false, `mismatch at top level: length mismatch, 10 vs 11; obtained \[\]int\{0, 0, 0, 0, 0, 0, 0, 0, 0, 0\}; expected \[\]int\{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\}`},
67 {&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false, `mismatch at \(\*\)\[2\]: unequal; obtained 3; expected 4`},
68 {Basic{1, 0.5}, Basic{1, 0.6}, false, `mismatch at \.y: unequal; obtained 0\.5; expected 0\.6`},
69 {Basic{1, 0}, Basic{2, 0}, false, `mismatch at \.x: unequal; obtained 1; expected 2`},
70 {map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at \[3\]: validity mismatch; obtained "two"; expected <nil>`},
71 {map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at \[2\]: unequal; obtained "txo"; expected "two"`},
72 {map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at top level: length mismatch, 1 vs 2; obtained map\[int\]string\{1:"one"\}; expected map\[int\]string\{2:"two", 1:"one"\}`},
73 {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false, `mismatch at top level: length mismatch, 2 vs 1; obtained map\[int\]string\{2:"two", 1:"one"\}; expected map\[int\]string\{1:"one"\}`},
74 {nil, 1, false, `mismatch at top level: nil vs non-nil mismatch; obtained <nil>; expected 1`},
75 {1, nil, false, `mismatch at top level: nil vs non-nil mismatch; obtained 1; expected <nil>`},
76 {fn1, fn3, false, `mismatch at top level: non-nil functions; obtained \(func\(\)\)\(nil\); expected \(func\(\)\)\(0x[0-9a-f]+\)`},
77 {fn3, fn3, false, `mismatch at top level: non-nil functions; obtained \(func\(\)\)\(0x[0-9a-f]+\); expected \(func\(\)\)\(0x[0-9a-f]+\)`},
78
79 // Nil vs empty: they're the same (difference from normal DeepEqual)
80 {[]int{}, []int(nil), true, ""},
81 {[]int{}, []int{}, true, ""},
82 {[]int(nil), []int(nil), true, ""},
83
84 // Mismatched types
85 {1, 1.0, false, `mismatch at top level: type mismatch int vs float64; obtained 1; expected 1`},
86 {int32(1), int64(1), false, `mismatch at top level: type mismatch int32 vs int64; obtained 1; expected 1`},
87 {0.5, "hello", false, `mismatch at top level: type mismatch float64 vs string; obtained 0\.5; expected "hello"`},
88 {[]int{1, 2, 3}, [3]int{1, 2, 3}, false, `mismatch at top level: type mismatch \[\]int vs \[3\]int; obtained \[\]int\{1, 2, 3\}; expected \[3\]int\{1, 2, 3\}`},
89 {&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false, `mismatch at \(\*\)\[2\]: type mismatch int vs string; obtained 4; expected "s"`},
90 {Basic{1, 0.5}, NotBasic{1, 0.5}, false, `mismatch at top level: type mismatch checkers_test\.Basic vs checkers_test\.NotBasic; obtained checkers_test\.Basic\{x:1, y:0\.5\}; expected checkers_test\.NotBasic\{x:1, y:0\.5\}`},
91 {map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at top level: type mismatch map\[uint\]string vs map\[int\]string; obtained map\[uint\]string\{0x1:"one", 0x2:"two"\}; expected map\[int\]string\{2:"two", 1:"one"\}`},
92}
93
94func TestDeepEqual(t *testing.T) {
95 for _, test := range deepEqualTests {
96 r, err := checkers.DeepEqual(test.a, test.b)
97 if r != test.eq {
98 t.Errorf("deepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq)
99 }
100 if test.eq {
101 if err != nil {
102 t.Errorf("deepEqual(%v, %v): unexpected error message %q when equal", test.a, test.b, err)
103 }
104 } else {
105 if ok, _ := regexp.MatchString(test.msg, err.Error()); !ok {
106 t.Errorf("deepEqual(%v, %v); unexpected error %q, want %q", test.a, test.b, err.Error(), test.msg)
107 }
108 }
109 }
110}
111
112type Recursive struct {
113 x int
114 r *Recursive
115}
116
117func TestDeepEqualRecursiveStruct(t *testing.T) {
118 a, b := new(Recursive), new(Recursive)
119 *a = Recursive{12, a}
120 *b = Recursive{12, b}
121 if !deepEqual(a, b) {
122 t.Error("deepEqual(recursive same) = false, want true")
123 }
124}
125
126type _Complex struct {
127 a int
128 b [3]*_Complex
129 c *string
130 d map[float64]float64
131}
132
133func TestDeepEqualComplexStruct(t *testing.T) {
134 m := make(map[float64]float64)
135 stra, strb := "hello", "hello"
136 a, b := new(_Complex), new(_Complex)
137 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
138 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
139 if !deepEqual(a, b) {
140 t.Error("deepEqual(complex same) = false, want true")
141 }
142}
143
144func TestDeepEqualComplexStructInequality(t *testing.T) {
145 m := make(map[float64]float64)
146 stra, strb := "hello", "helloo" // Difference is here
147 a, b := new(_Complex), new(_Complex)
148 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
149 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
150 if deepEqual(a, b) {
151 t.Error("deepEqual(complex different) = true, want false")
152 }
153}
154
155type UnexpT struct {
156 m map[int]int
157}
158
159func TestDeepEqualUnexportedMap(t *testing.T) {
160 // Check that DeepEqual can look at unexported fields.
161 x1 := UnexpT{map[int]int{1: 2}}
162 x2 := UnexpT{map[int]int{1: 2}}
163 if !deepEqual(&x1, &x2) {
164 t.Error("deepEqual(x1, x2) = false, want true")
165 }
166
167 y1 := UnexpT{map[int]int{2: 3}}
168 if deepEqual(&x1, &y1) {
169 t.Error("deepEqual(x1, y1) = true, want false")
170 }
171}
1720
=== removed file 'testing/checkers/file.go'
--- testing/checkers/file.go 2013-10-01 21:20:11 +0000
+++ testing/checkers/file.go 1970-01-01 00:00:00 +0000
@@ -1,154 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers
5
6import (
7 "fmt"
8 "os"
9 "reflect"
10
11 gc "launchpad.net/gocheck"
12)
13
14// IsNonEmptyFile checker
15
16type isNonEmptyFileChecker struct {
17 *gc.CheckerInfo
18}
19
20var IsNonEmptyFile gc.Checker = &isNonEmptyFileChecker{
21 &gc.CheckerInfo{Name: "IsNonEmptyFile", Params: []string{"obtained"}},
22}
23
24func (checker *isNonEmptyFileChecker) Check(params []interface{}, names []string) (result bool, error string) {
25 filename, isString := stringOrStringer(params[0])
26 if isString {
27 fileInfo, err := os.Stat(filename)
28 if os.IsNotExist(err) {
29 return false, fmt.Sprintf("%s does not exist", filename)
30 } else if err != nil {
31 return false, fmt.Sprintf("other stat error: %v", err)
32 }
33 if fileInfo.Size() > 0 {
34 return true, ""
35 } else {
36 return false, fmt.Sprintf("%s is empty", filename)
37 }
38 }
39
40 value := reflect.ValueOf(params[0])
41 return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
42}
43
44// IsDirectory checker
45
46type isDirectoryChecker struct {
47 *gc.CheckerInfo
48}
49
50var IsDirectory gc.Checker = &isDirectoryChecker{
51 &gc.CheckerInfo{Name: "IsDirectory", Params: []string{"obtained"}},
52}
53
54func (checker *isDirectoryChecker) Check(params []interface{}, names []string) (result bool, error string) {
55 path, isString := stringOrStringer(params[0])
56 if isString {
57 fileInfo, err := os.Stat(path)
58 if os.IsNotExist(err) {
59 return false, fmt.Sprintf("%s does not exist", path)
60 } else if err != nil {
61 return false, fmt.Sprintf("other stat error: %v", err)
62 }
63 if fileInfo.IsDir() {
64 return true, ""
65 } else {
66 return false, fmt.Sprintf("%s is not a directory", path)
67 }
68 }
69
70 value := reflect.ValueOf(params[0])
71 return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
72}
73
74// IsSymlink checker
75
76type isSymlinkChecker struct {
77 *gc.CheckerInfo
78}
79
80var IsSymlink gc.Checker = &isSymlinkChecker{
81 &gc.CheckerInfo{Name: "IsSymlink", Params: []string{"obtained"}},
82}
83
84func (checker *isSymlinkChecker) Check(params []interface{}, names []string) (result bool, error string) {
85 path, isString := stringOrStringer(params[0])
86 if isString {
87 fileInfo, err := os.Lstat(path)
88 if os.IsNotExist(err) {
89 return false, fmt.Sprintf("%s does not exist", path)
90 } else if err != nil {
91 return false, fmt.Sprintf("other stat error: %v", err)
92 }
93 if fileInfo.Mode()&os.ModeSymlink != 0 {
94 return true, ""
95 } else {
96 return false, fmt.Sprintf("%s is not a symlink: %+v", path, fileInfo)
97 }
98 }
99
100 value := reflect.ValueOf(params[0])
101 return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
102}
103
104// DoesNotExist checker makes sure the path specified doesn't exist.
105
106type doesNotExistChecker struct {
107 *gc.CheckerInfo
108}
109
110var DoesNotExist gc.Checker = &doesNotExistChecker{
111 &gc.CheckerInfo{Name: "DoesNotExist", Params: []string{"obtained"}},
112}
113
114func (checker *doesNotExistChecker) Check(params []interface{}, names []string) (result bool, error string) {
115 path, isString := stringOrStringer(params[0])
116 if isString {
117 _, err := os.Stat(path)
118 if os.IsNotExist(err) {
119 return true, ""
120 } else if err != nil {
121 return false, fmt.Sprintf("other stat error: %v", err)
122 }
123 return false, fmt.Sprintf("%s exists", path)
124 }
125
126 value := reflect.ValueOf(params[0])
127 return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
128}
129
130// SymlinkDoesNotExist checker makes sure the path specified doesn't exist.
131
132type symlinkDoesNotExistChecker struct {
133 *gc.CheckerInfo
134}
135
136var SymlinkDoesNotExist gc.Checker = &symlinkDoesNotExistChecker{
137 &gc.CheckerInfo{Name: "SymlinkDoesNotExist", Params: []string{"obtained"}},
138}
139
140func (checker *symlinkDoesNotExistChecker) Check(params []interface{}, names []string) (result bool, error string) {
141 path, isString := stringOrStringer(params[0])
142 if isString {
143 _, err := os.Lstat(path)
144 if os.IsNotExist(err) {
145 return true, ""
146 } else if err != nil {
147 return false, fmt.Sprintf("other stat error: %v", err)
148 }
149 return false, fmt.Sprintf("%s exists", path)
150 }
151
152 value := reflect.ValueOf(params[0])
153 return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0])
154}
1550
=== removed file 'testing/checkers/file_test.go'
--- testing/checkers/file_test.go 2014-03-13 07:54:56 +0000
+++ testing/checkers/file_test.go 1970-01-01 00:00:00 +0000
@@ -1,165 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers_test
5
6import (
7 "fmt"
8 "io/ioutil"
9 "os"
10 "path/filepath"
11
12 jc "github.com/juju/testing/checkers"
13 gc "launchpad.net/gocheck"
14)
15
16type FileSuite struct{}
17
18var _ = gc.Suite(&FileSuite{})
19
20func (s *FileSuite) TestIsNonEmptyFile(c *gc.C) {
21 file, err := ioutil.TempFile(c.MkDir(), "")
22 c.Assert(err, gc.IsNil)
23 fmt.Fprintf(file, "something")
24 file.Close()
25
26 c.Assert(file.Name(), jc.IsNonEmptyFile)
27}
28
29func (s *FileSuite) TestIsNonEmptyFileWithEmptyFile(c *gc.C) {
30 file, err := ioutil.TempFile(c.MkDir(), "")
31 c.Assert(err, gc.IsNil)
32 file.Close()
33
34 result, message := jc.IsNonEmptyFile.Check([]interface{}{file.Name()}, nil)
35 c.Assert(result, jc.IsFalse)
36 c.Assert(message, gc.Equals, file.Name()+" is empty")
37}
38
39func (s *FileSuite) TestIsNonEmptyFileWithMissingFile(c *gc.C) {
40 name := filepath.Join(c.MkDir(), "missing")
41
42 result, message := jc.IsNonEmptyFile.Check([]interface{}{name}, nil)
43 c.Assert(result, jc.IsFalse)
44 c.Assert(message, gc.Equals, name+" does not exist")
45}
46
47func (s *FileSuite) TestIsNonEmptyFileWithNumber(c *gc.C) {
48 result, message := jc.IsNonEmptyFile.Check([]interface{}{42}, nil)
49 c.Assert(result, jc.IsFalse)
50 c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42")
51}
52
53func (s *FileSuite) TestIsDirectory(c *gc.C) {
54 dir := c.MkDir()
55 c.Assert(dir, jc.IsDirectory)
56}
57
58func (s *FileSuite) TestIsDirectoryMissing(c *gc.C) {
59 absentDir := filepath.Join(c.MkDir(), "foo")
60
61 result, message := jc.IsDirectory.Check([]interface{}{absentDir}, nil)
62 c.Assert(result, jc.IsFalse)
63 c.Assert(message, gc.Equals, absentDir+" does not exist")
64}
65
66func (s *FileSuite) TestIsDirectoryWithFile(c *gc.C) {
67 file, err := ioutil.TempFile(c.MkDir(), "")
68 c.Assert(err, gc.IsNil)
69 file.Close()
70
71 result, message := jc.IsDirectory.Check([]interface{}{file.Name()}, nil)
72 c.Assert(result, jc.IsFalse)
73 c.Assert(message, gc.Equals, file.Name()+" is not a directory")
74}
75
76func (s *FileSuite) TestIsDirectoryWithNumber(c *gc.C) {
77 result, message := jc.IsDirectory.Check([]interface{}{42}, nil)
78 c.Assert(result, jc.IsFalse)
79 c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42")
80}
81
82func (s *FileSuite) TestDoesNotExist(c *gc.C) {
83 absentDir := filepath.Join(c.MkDir(), "foo")
84 c.Assert(absentDir, jc.DoesNotExist)
85}
86
87func (s *FileSuite) TestDoesNotExistWithPath(c *gc.C) {
88 dir := c.MkDir()
89 result, message := jc.DoesNotExist.Check([]interface{}{dir}, nil)
90 c.Assert(result, jc.IsFalse)
91 c.Assert(message, gc.Equals, dir+" exists")
92}
93
94func (s *FileSuite) TestDoesNotExistWithSymlink(c *gc.C) {
95 dir := c.MkDir()
96 deadPath := filepath.Join(dir, "dead")
97 symlinkPath := filepath.Join(dir, "a-symlink")
98 err := os.Symlink(deadPath, symlinkPath)
99 c.Assert(err, gc.IsNil)
100 // A valid symlink pointing to something that doesn't exist passes.
101 // Use SymlinkDoesNotExist to check for the non-existence of the link itself.
102 c.Assert(symlinkPath, jc.DoesNotExist)
103}
104
105func (s *FileSuite) TestDoesNotExistWithNumber(c *gc.C) {
106 result, message := jc.DoesNotExist.Check([]interface{}{42}, nil)
107 c.Assert(result, jc.IsFalse)
108 c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42")
109}
110
111func (s *FileSuite) TestSymlinkDoesNotExist(c *gc.C) {
112 absentDir := filepath.Join(c.MkDir(), "foo")
113 c.Assert(absentDir, jc.SymlinkDoesNotExist)
114}
115
116func (s *FileSuite) TestSymlinkDoesNotExistWithPath(c *gc.C) {
117 dir := c.MkDir()
118 result, message := jc.SymlinkDoesNotExist.Check([]interface{}{dir}, nil)
119 c.Assert(result, jc.IsFalse)
120 c.Assert(message, gc.Equals, dir+" exists")
121}
122
123func (s *FileSuite) TestSymlinkDoesNotExistWithSymlink(c *gc.C) {
124 dir := c.MkDir()
125 deadPath := filepath.Join(dir, "dead")
126 symlinkPath := filepath.Join(dir, "a-symlink")
127 err := os.Symlink(deadPath, symlinkPath)
128 c.Assert(err, gc.IsNil)
129
130 result, message := jc.SymlinkDoesNotExist.Check([]interface{}{symlinkPath}, nil)
131 c.Assert(result, jc.IsFalse)
132 c.Assert(message, gc.Equals, symlinkPath+" exists")
133}
134
135func (s *FileSuite) TestSymlinkDoesNotExistWithNumber(c *gc.C) {
136 result, message := jc.SymlinkDoesNotExist.Check([]interface{}{42}, nil)
137 c.Assert(result, jc.IsFalse)
138 c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42")
139}
140
141func (s *FileSuite) TestIsSymlink(c *gc.C) {
142 file, err := ioutil.TempFile(c.MkDir(), "")
143 c.Assert(err, gc.IsNil)
144 c.Log(file.Name())
145 c.Log(filepath.Dir(file.Name()))
146 symlinkPath := filepath.Join(filepath.Dir(file.Name()), "a-symlink")
147 err = os.Symlink(file.Name(), symlinkPath)
148 c.Assert(err, gc.IsNil)
149
150 c.Assert(symlinkPath, jc.IsSymlink)
151}
152
153func (s *FileSuite) TestIsSymlinkWithFile(c *gc.C) {
154 file, err := ioutil.TempFile(c.MkDir(), "")
155 c.Assert(err, gc.IsNil)
156 result, message := jc.IsSymlink.Check([]interface{}{file.Name()}, nil)
157 c.Assert(result, jc.IsFalse)
158 c.Assert(message, jc.Contains, " is not a symlink")
159}
160
161func (s *FileSuite) TestIsSymlinkWithDir(c *gc.C) {
162 result, message := jc.IsSymlink.Check([]interface{}{c.MkDir()}, nil)
163 c.Assert(result, jc.IsFalse)
164 c.Assert(message, jc.Contains, " is not a symlink")
165}
1660
=== removed file 'testing/checkers/log.go'
--- testing/checkers/log.go 2014-03-05 19:41:34 +0000
+++ testing/checkers/log.go 1970-01-01 00:00:00 +0000
@@ -1,109 +0,0 @@
1// Copyright 2012, 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers
5
6import (
7 "fmt"
8 "regexp"
9 "strings"
10
11 "github.com/juju/loggo"
12 gc "launchpad.net/gocheck"
13)
14
15type SimpleMessage struct {
16 Level loggo.Level
17 Message string
18}
19
20type SimpleMessages []SimpleMessage
21
22func (s SimpleMessage) String() string {
23 return fmt.Sprintf("%s %s", s.Level, s.Message)
24}
25
26func (s SimpleMessages) GoString() string {
27 out := make([]string, len(s))
28 for i, m := range s {
29 out[i] = m.String()
30 }
31 return fmt.Sprintf("SimpleMessages{\n%s\n}", strings.Join(out, "\n"))
32}
33
34func logToSimpleMessages(log []loggo.TestLogValues) SimpleMessages {
35 out := make(SimpleMessages, len(log))
36 for i, val := range log {
37 out[i].Level = val.Level
38 out[i].Message = val.Message
39 }
40 return out
41}
42
43type logMatches struct {
44 *gc.CheckerInfo
45}
46
47func (checker *logMatches) Check(params []interface{}, names []string) (result bool, error string) {
48 var obtained SimpleMessages
49 switch params[0].(type) {
50 case []loggo.TestLogValues:
51 obtained = logToSimpleMessages(params[0].([]loggo.TestLogValues))
52 default:
53 return false, "Obtained value must be of type []loggo.TestLogValues or SimpleMessage"
54 }
55
56 var expected SimpleMessages
57 switch param := params[1].(type) {
58 case []SimpleMessage:
59 expected = SimpleMessages(param)
60 case SimpleMessages:
61 expected = param
62 case []string:
63 expected = make(SimpleMessages, len(param))
64 for i, s := range param {
65 expected[i] = SimpleMessage{
66 Message: s,
67 Level: loggo.UNSPECIFIED,
68 }
69 }
70 default:
71 return false, "Expected value must be of type []string or []SimpleMessage"
72 }
73
74 obtainedSinceLastMatch := obtained
75 for len(expected) > 0 && len(obtained) >= len(expected) {
76 var msg SimpleMessage
77 msg, obtained = obtained[0], obtained[1:]
78 expect := expected[0]
79 if expect.Level != loggo.UNSPECIFIED && msg.Level != expect.Level {
80 continue
81 }
82 matched, err := regexp.MatchString(expect.Message, msg.Message)
83 if err != nil {
84 return false, fmt.Sprintf("bad message regexp %q: %v", expect.Message, err)
85 } else if !matched {
86 continue
87 }
88 expected = expected[1:]
89 obtainedSinceLastMatch = obtained
90 }
91 if len(obtained) < len(expected) {
92 params[0] = obtainedSinceLastMatch
93 params[1] = expected
94 return false, ""
95 }
96 return true, ""
97}
98
99// LogMatches checks whether a given TestLogValues actually contains the log
100// messages we expected. If you compare it against a list of strings, we only
101// compare that the strings in the messages are correct. You can alternatively
102// pass a slice of SimpleMessage and we will check that the log levels are
103// also correct.
104//
105// The log may contain additional messages before and after each of the specified
106// expected messages.
107var LogMatches gc.Checker = &logMatches{
108 &gc.CheckerInfo{Name: "LogMatches", Params: []string{"obtained", "expected"}},
109}
1100
=== removed file 'testing/checkers/log_test.go'
--- testing/checkers/log_test.go 2014-03-13 07:54:56 +0000
+++ testing/checkers/log_test.go 1970-01-01 00:00:00 +0000
@@ -1,111 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers_test
5
6import (
7 "github.com/juju/loggo"
8 jc "github.com/juju/testing/checkers"
9 gc "launchpad.net/gocheck"
10)
11
12type LogMatchesSuite struct{}
13
14var _ = gc.Suite(&LogMatchesSuite{})
15
16func (s *LogMatchesSuite) TestMatchSimpleMessage(c *gc.C) {
17 log := []loggo.TestLogValues{
18 {Level: loggo.INFO, Message: "foo bar"},
19 {Level: loggo.INFO, Message: "12345"},
20 }
21 c.Check(log, jc.LogMatches, []jc.SimpleMessage{
22 {loggo.INFO, "foo bar"},
23 {loggo.INFO, "12345"},
24 })
25 c.Check(log, jc.LogMatches, []jc.SimpleMessage{
26 {loggo.INFO, "foo .*"},
27 {loggo.INFO, "12345"},
28 })
29 // UNSPECIFIED means we don't care what the level is,
30 // just check the message string matches.
31 c.Check(log, jc.LogMatches, []jc.SimpleMessage{
32 {loggo.UNSPECIFIED, "foo .*"},
33 {loggo.INFO, "12345"},
34 })
35 c.Check(log, gc.Not(jc.LogMatches), []jc.SimpleMessage{
36 {loggo.INFO, "foo bar"},
37 {loggo.DEBUG, "12345"},
38 })
39}
40
41func (s *LogMatchesSuite) TestMatchStrings(c *gc.C) {
42 log := []loggo.TestLogValues{
43 {Level: loggo.INFO, Message: "foo bar"},
44 {Level: loggo.INFO, Message: "12345"},
45 }
46 c.Check(log, jc.LogMatches, []string{"foo bar", "12345"})
47 c.Check(log, jc.LogMatches, []string{"foo .*", "12345"})
48 c.Check(log, gc.Not(jc.LogMatches), []string{"baz", "bing"})
49}
50
51func (s *LogMatchesSuite) TestMatchInexact(c *gc.C) {
52 log := []loggo.TestLogValues{
53 {Level: loggo.INFO, Message: "foo bar"},
54 {Level: loggo.INFO, Message: "baz"},
55 {Level: loggo.DEBUG, Message: "12345"},
56 {Level: loggo.ERROR, Message: "12345"},
57 {Level: loggo.INFO, Message: "67890"},
58 }
59 c.Check(log, jc.LogMatches, []string{"foo bar", "12345"})
60 c.Check(log, jc.LogMatches, []string{"foo .*", "12345"})
61 c.Check(log, jc.LogMatches, []string{"foo .*", "67890"})
62 c.Check(log, jc.LogMatches, []string{"67890"})
63
64 // Matches are always left-most after the previous match.
65 c.Check(log, jc.LogMatches, []string{".*", "baz"})
66 c.Check(log, jc.LogMatches, []string{"foo bar", ".*", "12345"})
67 c.Check(log, jc.LogMatches, []string{"foo bar", ".*", "67890"})
68
69 // Order is important: 67890 advances to the last item in obtained,
70 // and so there's nothing after to match against ".*".
71 c.Check(log, gc.Not(jc.LogMatches), []string{"67890", ".*"})
72 // ALL specified patterns MUST match in the order given.
73 c.Check(log, gc.Not(jc.LogMatches), []string{".*", "foo bar"})
74
75 // Check that levels are matched.
76 c.Check(log, jc.LogMatches, []jc.SimpleMessage{
77 {loggo.UNSPECIFIED, "12345"},
78 {loggo.UNSPECIFIED, "12345"},
79 })
80 c.Check(log, jc.LogMatches, []jc.SimpleMessage{
81 {loggo.DEBUG, "12345"},
82 {loggo.ERROR, "12345"},
83 })
84 c.Check(log, jc.LogMatches, []jc.SimpleMessage{
85 {loggo.DEBUG, "12345"},
86 {loggo.INFO, ".*"},
87 })
88 c.Check(log, gc.Not(jc.LogMatches), []jc.SimpleMessage{
89 {loggo.DEBUG, "12345"},
90 {loggo.INFO, ".*"},
91 {loggo.UNSPECIFIED, ".*"},
92 })
93}
94
95func (s *LogMatchesSuite) TestFromLogMatches(c *gc.C) {
96 tw := &loggo.TestWriter{}
97 _, err := loggo.ReplaceDefaultWriter(tw)
98 c.Assert(err, gc.IsNil)
99 defer loggo.ResetWriters()
100 logger := loggo.GetLogger("test")
101 logger.SetLogLevel(loggo.DEBUG)
102 logger.Infof("foo")
103 logger.Debugf("bar")
104 logger.Tracef("hidden")
105 c.Check(tw.Log, jc.LogMatches, []string{"foo", "bar"})
106 c.Check(tw.Log, gc.Not(jc.LogMatches), []string{"foo", "bad"})
107 c.Check(tw.Log, gc.Not(jc.LogMatches), []jc.SimpleMessage{
108 {loggo.INFO, "foo"},
109 {loggo.INFO, "bar"},
110 })
111}
1120
=== removed file 'testing/checkers/relop.go'
--- testing/checkers/relop.go 2013-09-13 14:48:13 +0000
+++ testing/checkers/relop.go 1970-01-01 00:00:00 +0000
@@ -1,93 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers
5
6import (
7 "fmt"
8 "reflect"
9
10 gc "launchpad.net/gocheck"
11)
12
13// GreaterThan checker
14
15type greaterThanChecker struct {
16 *gc.CheckerInfo
17}
18
19var GreaterThan gc.Checker = &greaterThanChecker{
20 &gc.CheckerInfo{Name: "GreaterThan", Params: []string{"obtained", "expected"}},
21}
22
23func (checker *greaterThanChecker) Check(params []interface{}, names []string) (result bool, error string) {
24 defer func() {
25 if v := recover(); v != nil {
26 result = false
27 error = fmt.Sprint(v)
28 }
29 }()
30
31 p0value := reflect.ValueOf(params[0])
32 p1value := reflect.ValueOf(params[1])
33 switch p0value.Kind() {
34 case reflect.Int,
35 reflect.Int8,
36 reflect.Int16,
37 reflect.Int32,
38 reflect.Int64:
39 return p0value.Int() > p1value.Int(), ""
40 case reflect.Uint,
41 reflect.Uint8,
42 reflect.Uint16,
43 reflect.Uint32,
44 reflect.Uint64:
45 return p0value.Uint() > p1value.Uint(), ""
46 case reflect.Float32,
47 reflect.Float64:
48 return p0value.Float() > p1value.Float(), ""
49 default:
50 }
51 return false, fmt.Sprintf("obtained value %s:%#v not supported", p0value.Kind(), params[0])
52}
53
54// LessThan checker
55
56type lessThanChecker struct {
57 *gc.CheckerInfo
58}
59
60var LessThan gc.Checker = &lessThanChecker{
61 &gc.CheckerInfo{Name: "LessThan", Params: []string{"obtained", "expected"}},
62}
63
64func (checker *lessThanChecker) Check(params []interface{}, names []string) (result bool, error string) {
65 defer func() {
66 if v := recover(); v != nil {
67 result = false
68 error = fmt.Sprint(v)
69 }
70 }()
71
72 p0value := reflect.ValueOf(params[0])
73 p1value := reflect.ValueOf(params[1])
74 switch p0value.Kind() {
75 case reflect.Int,
76 reflect.Int8,
77 reflect.Int16,
78 reflect.Int32,
79 reflect.Int64:
80 return p0value.Int() < p1value.Int(), ""
81 case reflect.Uint,
82 reflect.Uint8,
83 reflect.Uint16,
84 reflect.Uint32,
85 reflect.Uint64:
86 return p0value.Uint() < p1value.Uint(), ""
87 case reflect.Float32,
88 reflect.Float64:
89 return p0value.Float() < p1value.Float(), ""
90 default:
91 }
92 return false, fmt.Sprintf("obtained value %s:%#v not supported", p0value.Kind(), params[0])
93}
940
=== removed file 'testing/checkers/relop_test.go'
--- testing/checkers/relop_test.go 2014-03-13 07:54:56 +0000
+++ testing/checkers/relop_test.go 1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
1// Copyright 2013 Canonical Ltd.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package checkers_test
5
6import (
7 jc "github.com/juju/testing/checkers"
8 gc "launchpad.net/gocheck"
9)
10
11type RelopSuite struct{}
12
13var _ = gc.Suite(&RelopSuite{})
14
15func (s *RelopSuite) TestGreaterThan(c *gc.C) {
16 c.Assert(45, jc.GreaterThan, 42)
17 c.Assert(2.25, jc.GreaterThan, 1.0)
18 c.Assert(42, gc.Not(jc.GreaterThan), 42)
19 c.Assert(10, gc.Not(jc.GreaterThan), 42)
20
21 result, msg := jc.GreaterThan.Check([]interface{}{"Hello", "World"}, nil)
22 c.Assert(result, jc.IsFalse)
23 c.Assert(msg, gc.Equals, `obtained value string:"Hello" not supported`)
24}
25
26func (s *RelopSuite) TestLessThan(c *gc.C) {
27 c.Assert(42, jc.LessThan, 45)
28 c.Assert(1.0, jc.LessThan, 2.25)
29 c.Assert(42, gc.Not(jc.LessThan), 42)
30 c.Assert(42, gc.Not(jc.LessThan), 10)
31
32 result, msg := jc.LessThan.Check([]interface{}{"Hello", "World"}, nil)
33 c.Assert(result, jc.IsFalse)
34 c.Assert(msg, gc.Equals, `obtained value string:"Hello" not supported`)
35}
360
=== modified file 'worker/instancepoller/aggregate_test.go'
--- worker/instancepoller/aggregate_test.go 2014-03-13 18:40:06 +0000
+++ worker/instancepoller/aggregate_test.go 2014-03-18 02:58:54 +0000
@@ -9,12 +9,12 @@
9 "sync/atomic"9 "sync/atomic"
10 "time"10 "time"
1111
12 jc "github.com/juju/testing/checkers"
12 gc "launchpad.net/gocheck"13 gc "launchpad.net/gocheck"
1314
14 "launchpad.net/juju-core/environs"15 "launchpad.net/juju-core/environs"
15 "launchpad.net/juju-core/errors"16 "launchpad.net/juju-core/errors"
16 "launchpad.net/juju-core/instance"17 "launchpad.net/juju-core/instance"
17 jc "launchpad.net/juju-core/testing/checkers"
18 "launchpad.net/juju-core/testing/testbase"18 "launchpad.net/juju-core/testing/testbase"
19)19)
2020

Subscribers

People subscribed via source and target branches

to status/vote changes: