Merge lp:~waigani/juju-core/remove-checkers-dir into lp:~go-bot/juju-core/trunk
- remove-checkers-dir
- Merge into trunk
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 |
Related bugs: |
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.
Jesse Meek (waigani) wrote : | # |
Andrew Wilkins (axwalk) wrote : | # |
On 2014/03/13 23:19:53, waigani wrote:
> Please take a look.
LGTM
Go Bot (go-bot) wrote : | # |
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.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
?...
Go Bot (go-bot) wrote : | # |
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.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
o...
Go Bot (go-bot) wrote : | # |
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.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
? launchpad.
? launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
ok launchpad.
? launchpad.
-------
FAIL: storage_
[LOG] 12.41139 DEBUG juju.utils.ssh running: ssh -o "StrictHostKeyC
storage_
c.Assert(err, gc.IsNil)
... value *errors.errorString = &errors.
OOPS: 21 passed, 1 FAILED
--- FAIL: Test (0.95 seconds)
FAIL
FAIL launchpad.
Preview Diff
1 | === removed directory 'testing/checkers' | |||
2 | === removed file 'testing/checkers/bool.go' | |||
3 | --- testing/checkers/bool.go 2014-01-13 15:00:49 +0000 | |||
4 | +++ testing/checkers/bool.go 1970-01-01 00:00:00 +0000 | |||
5 | @@ -1,115 +0,0 @@ | |||
6 | 1 | // Copyright 2013 Canonical Ltd. | ||
7 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
8 | 3 | |||
9 | 4 | package checkers | ||
10 | 5 | |||
11 | 6 | import ( | ||
12 | 7 | "fmt" | ||
13 | 8 | "reflect" | ||
14 | 9 | |||
15 | 10 | gc "launchpad.net/gocheck" | ||
16 | 11 | ) | ||
17 | 12 | |||
18 | 13 | type isTrueChecker struct { | ||
19 | 14 | *gc.CheckerInfo | ||
20 | 15 | } | ||
21 | 16 | |||
22 | 17 | // IsTrue checks whether a value has an underlying | ||
23 | 18 | // boolean type and is true. | ||
24 | 19 | var IsTrue gc.Checker = &isTrueChecker{ | ||
25 | 20 | &gc.CheckerInfo{Name: "IsTrue", Params: []string{"obtained"}}, | ||
26 | 21 | } | ||
27 | 22 | |||
28 | 23 | // IsTrue checks whether a value has an underlying | ||
29 | 24 | // boolean type and is false. | ||
30 | 25 | var IsFalse gc.Checker = gc.Not(IsTrue) | ||
31 | 26 | |||
32 | 27 | func (checker *isTrueChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
33 | 28 | |||
34 | 29 | value := reflect.ValueOf(params[0]) | ||
35 | 30 | |||
36 | 31 | switch value.Kind() { | ||
37 | 32 | case reflect.Bool: | ||
38 | 33 | return value.Bool(), "" | ||
39 | 34 | } | ||
40 | 35 | |||
41 | 36 | return false, fmt.Sprintf("expected type bool, received type %s", value.Type()) | ||
42 | 37 | } | ||
43 | 38 | |||
44 | 39 | type satisfiesChecker struct { | ||
45 | 40 | *gc.CheckerInfo | ||
46 | 41 | } | ||
47 | 42 | |||
48 | 43 | // Satisfies checks whether a value causes the argument | ||
49 | 44 | // function to return true. The function must be of | ||
50 | 45 | // type func(T) bool where the value being checked | ||
51 | 46 | // is assignable to T. | ||
52 | 47 | var Satisfies gc.Checker = &satisfiesChecker{ | ||
53 | 48 | &gc.CheckerInfo{ | ||
54 | 49 | Name: "Satisfies", | ||
55 | 50 | Params: []string{"obtained", "func(T) bool"}, | ||
56 | 51 | }, | ||
57 | 52 | } | ||
58 | 53 | |||
59 | 54 | func (checker *satisfiesChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
60 | 55 | f := reflect.ValueOf(params[1]) | ||
61 | 56 | ft := f.Type() | ||
62 | 57 | if ft.Kind() != reflect.Func || | ||
63 | 58 | ft.NumIn() != 1 || | ||
64 | 59 | ft.NumOut() != 1 || | ||
65 | 60 | ft.Out(0) != reflect.TypeOf(true) { | ||
66 | 61 | return false, fmt.Sprintf("expected func(T) bool, got %s", ft) | ||
67 | 62 | } | ||
68 | 63 | v := reflect.ValueOf(params[0]) | ||
69 | 64 | if !v.IsValid() { | ||
70 | 65 | if !canBeNil(ft.In(0)) { | ||
71 | 66 | return false, fmt.Sprintf("cannot assign nil to argument %T", ft.In(0)) | ||
72 | 67 | } | ||
73 | 68 | v = reflect.Zero(ft.In(0)) | ||
74 | 69 | } | ||
75 | 70 | if !v.Type().AssignableTo(ft.In(0)) { | ||
76 | 71 | return false, fmt.Sprintf("wrong argument type %s for %s", v.Type(), ft) | ||
77 | 72 | } | ||
78 | 73 | return f.Call([]reflect.Value{v})[0].Interface().(bool), "" | ||
79 | 74 | } | ||
80 | 75 | |||
81 | 76 | func canBeNil(t reflect.Type) bool { | ||
82 | 77 | switch t.Kind() { | ||
83 | 78 | case reflect.Chan, | ||
84 | 79 | reflect.Func, | ||
85 | 80 | reflect.Interface, | ||
86 | 81 | reflect.Map, | ||
87 | 82 | reflect.Ptr, | ||
88 | 83 | reflect.Slice: | ||
89 | 84 | return true | ||
90 | 85 | } | ||
91 | 86 | return false | ||
92 | 87 | } | ||
93 | 88 | |||
94 | 89 | type deepEqualsChecker struct { | ||
95 | 90 | *gc.CheckerInfo | ||
96 | 91 | } | ||
97 | 92 | |||
98 | 93 | // The DeepEquals checker verifies that the obtained value is deep-equal to | ||
99 | 94 | // the expected value. The check will work correctly even when facing | ||
100 | 95 | // slices, interfaces, and values of different types (which always fail | ||
101 | 96 | // the test). | ||
102 | 97 | // | ||
103 | 98 | // For example: | ||
104 | 99 | // | ||
105 | 100 | // c.Assert(value, DeepEquals, 42) | ||
106 | 101 | // c.Assert(array, DeepEquals, []string{"hi", "there"}) | ||
107 | 102 | // | ||
108 | 103 | // This checker differs from gocheck.DeepEquals in that | ||
109 | 104 | // it will compare a nil slice equal to an empty slice, | ||
110 | 105 | // and a nil map equal to an empty map. | ||
111 | 106 | var DeepEquals gc.Checker = &deepEqualsChecker{ | ||
112 | 107 | &gc.CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}}, | ||
113 | 108 | } | ||
114 | 109 | |||
115 | 110 | func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
116 | 111 | if ok, err := DeepEqual(params[0], params[1]); !ok { | ||
117 | 112 | return false, err.Error() | ||
118 | 113 | } | ||
119 | 114 | return true, "" | ||
120 | 115 | } | ||
121 | 116 | 0 | ||
122 | === removed file 'testing/checkers/bool_test.go' | |||
123 | --- testing/checkers/bool_test.go 2014-03-13 07:54:56 +0000 | |||
124 | +++ testing/checkers/bool_test.go 1970-01-01 00:00:00 +0000 | |||
125 | @@ -1,120 +0,0 @@ | |||
126 | 1 | // Copyright 2013 Canonical Ltd. | ||
127 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
128 | 3 | |||
129 | 4 | package checkers_test | ||
130 | 5 | |||
131 | 6 | import ( | ||
132 | 7 | "errors" | ||
133 | 8 | "os" | ||
134 | 9 | |||
135 | 10 | jc "github.com/juju/testing/checkers" | ||
136 | 11 | gc "launchpad.net/gocheck" | ||
137 | 12 | ) | ||
138 | 13 | |||
139 | 14 | type BoolSuite struct{} | ||
140 | 15 | |||
141 | 16 | var _ = gc.Suite(&BoolSuite{}) | ||
142 | 17 | |||
143 | 18 | func (s *BoolSuite) TestIsTrue(c *gc.C) { | ||
144 | 19 | c.Assert(true, jc.IsTrue) | ||
145 | 20 | c.Assert(false, gc.Not(jc.IsTrue)) | ||
146 | 21 | |||
147 | 22 | result, msg := jc.IsTrue.Check([]interface{}{false}, nil) | ||
148 | 23 | c.Assert(result, gc.Equals, false) | ||
149 | 24 | c.Assert(msg, gc.Equals, "") | ||
150 | 25 | |||
151 | 26 | result, msg = jc.IsTrue.Check([]interface{}{"foo"}, nil) | ||
152 | 27 | c.Assert(result, gc.Equals, false) | ||
153 | 28 | c.Check(msg, gc.Equals, `expected type bool, received type string`) | ||
154 | 29 | |||
155 | 30 | result, msg = jc.IsTrue.Check([]interface{}{42}, nil) | ||
156 | 31 | c.Assert(result, gc.Equals, false) | ||
157 | 32 | c.Assert(msg, gc.Equals, `expected type bool, received type int`) | ||
158 | 33 | } | ||
159 | 34 | |||
160 | 35 | func (s *BoolSuite) TestIsFalse(c *gc.C) { | ||
161 | 36 | c.Assert(false, jc.IsFalse) | ||
162 | 37 | c.Assert(true, gc.Not(jc.IsFalse)) | ||
163 | 38 | } | ||
164 | 39 | |||
165 | 40 | func is42(i int) bool { | ||
166 | 41 | return i == 42 | ||
167 | 42 | } | ||
168 | 43 | |||
169 | 44 | var satisfiesTests = []struct { | ||
170 | 45 | f interface{} | ||
171 | 46 | arg interface{} | ||
172 | 47 | result bool | ||
173 | 48 | msg string | ||
174 | 49 | }{{ | ||
175 | 50 | f: is42, | ||
176 | 51 | arg: 42, | ||
177 | 52 | result: true, | ||
178 | 53 | }, { | ||
179 | 54 | f: is42, | ||
180 | 55 | arg: 41, | ||
181 | 56 | result: false, | ||
182 | 57 | }, { | ||
183 | 58 | f: is42, | ||
184 | 59 | arg: "", | ||
185 | 60 | result: false, | ||
186 | 61 | msg: "wrong argument type string for func(int) bool", | ||
187 | 62 | }, { | ||
188 | 63 | f: os.IsNotExist, | ||
189 | 64 | arg: errors.New("foo"), | ||
190 | 65 | result: false, | ||
191 | 66 | }, { | ||
192 | 67 | f: os.IsNotExist, | ||
193 | 68 | arg: os.ErrNotExist, | ||
194 | 69 | result: true, | ||
195 | 70 | }, { | ||
196 | 71 | f: os.IsNotExist, | ||
197 | 72 | arg: nil, | ||
198 | 73 | result: false, | ||
199 | 74 | }, { | ||
200 | 75 | f: func(chan int) bool { return true }, | ||
201 | 76 | arg: nil, | ||
202 | 77 | result: true, | ||
203 | 78 | }, { | ||
204 | 79 | f: func(func()) bool { return true }, | ||
205 | 80 | arg: nil, | ||
206 | 81 | result: true, | ||
207 | 82 | }, { | ||
208 | 83 | f: func(interface{}) bool { return true }, | ||
209 | 84 | arg: nil, | ||
210 | 85 | result: true, | ||
211 | 86 | }, { | ||
212 | 87 | f: func(map[string]bool) bool { return true }, | ||
213 | 88 | arg: nil, | ||
214 | 89 | result: true, | ||
215 | 90 | }, { | ||
216 | 91 | f: func(*int) bool { return true }, | ||
217 | 92 | arg: nil, | ||
218 | 93 | result: true, | ||
219 | 94 | }, { | ||
220 | 95 | f: func([]string) bool { return true }, | ||
221 | 96 | arg: nil, | ||
222 | 97 | result: true, | ||
223 | 98 | }} | ||
224 | 99 | |||
225 | 100 | func (s *BoolSuite) TestSatisfies(c *gc.C) { | ||
226 | 101 | for i, test := range satisfiesTests { | ||
227 | 102 | c.Logf("test %d. %T %T", i, test.f, test.arg) | ||
228 | 103 | result, msg := jc.Satisfies.Check([]interface{}{test.arg, test.f}, nil) | ||
229 | 104 | c.Check(result, gc.Equals, test.result) | ||
230 | 105 | c.Check(msg, gc.Equals, test.msg) | ||
231 | 106 | } | ||
232 | 107 | } | ||
233 | 108 | |||
234 | 109 | func (s *BoolSuite) TestDeepEquals(c *gc.C) { | ||
235 | 110 | for i, test := range deepEqualTests { | ||
236 | 111 | c.Logf("test %d. %v == %v is %v", i, test.a, test.b, test.eq) | ||
237 | 112 | result, msg := jc.DeepEquals.Check([]interface{}{test.a, test.b}, nil) | ||
238 | 113 | c.Check(result, gc.Equals, test.eq) | ||
239 | 114 | if test.eq { | ||
240 | 115 | c.Check(msg, gc.Equals, "") | ||
241 | 116 | } else { | ||
242 | 117 | c.Check(msg, gc.Not(gc.Equals), "") | ||
243 | 118 | } | ||
244 | 119 | } | ||
245 | 120 | } | ||
246 | 121 | 0 | ||
247 | === removed file 'testing/checkers/checker.go' | |||
248 | --- testing/checkers/checker.go 2013-09-13 14:48:13 +0000 | |||
249 | +++ testing/checkers/checker.go 1970-01-01 00:00:00 +0000 | |||
250 | @@ -1,202 +0,0 @@ | |||
251 | 1 | // Copyright 2012, 2013 Canonical Ltd. | ||
252 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
253 | 3 | |||
254 | 4 | package checkers | ||
255 | 5 | |||
256 | 6 | import ( | ||
257 | 7 | "fmt" | ||
258 | 8 | "reflect" | ||
259 | 9 | "strings" | ||
260 | 10 | "time" | ||
261 | 11 | |||
262 | 12 | gc "launchpad.net/gocheck" | ||
263 | 13 | ) | ||
264 | 14 | |||
265 | 15 | func TimeBetween(start, end time.Time) gc.Checker { | ||
266 | 16 | if end.Before(start) { | ||
267 | 17 | return &timeBetweenChecker{end, start} | ||
268 | 18 | } | ||
269 | 19 | return &timeBetweenChecker{start, end} | ||
270 | 20 | } | ||
271 | 21 | |||
272 | 22 | type timeBetweenChecker struct { | ||
273 | 23 | start, end time.Time | ||
274 | 24 | } | ||
275 | 25 | |||
276 | 26 | func (checker *timeBetweenChecker) Info() *gc.CheckerInfo { | ||
277 | 27 | info := gc.CheckerInfo{ | ||
278 | 28 | Name: "TimeBetween", | ||
279 | 29 | Params: []string{"obtained"}, | ||
280 | 30 | } | ||
281 | 31 | return &info | ||
282 | 32 | } | ||
283 | 33 | |||
284 | 34 | func (checker *timeBetweenChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
285 | 35 | when, ok := params[0].(time.Time) | ||
286 | 36 | if !ok { | ||
287 | 37 | return false, "obtained value type must be time.Time" | ||
288 | 38 | } | ||
289 | 39 | if when.Before(checker.start) { | ||
290 | 40 | return false, fmt.Sprintf("obtained value %#v type must before start value of %#v", when, checker.start) | ||
291 | 41 | } | ||
292 | 42 | if when.After(checker.end) { | ||
293 | 43 | return false, fmt.Sprintf("obtained value %#v type must after end value of %#v", when, checker.end) | ||
294 | 44 | } | ||
295 | 45 | return true, "" | ||
296 | 46 | } | ||
297 | 47 | |||
298 | 48 | // DurationLessThan checker | ||
299 | 49 | |||
300 | 50 | type durationLessThanChecker struct { | ||
301 | 51 | *gc.CheckerInfo | ||
302 | 52 | } | ||
303 | 53 | |||
304 | 54 | var DurationLessThan gc.Checker = &durationLessThanChecker{ | ||
305 | 55 | &gc.CheckerInfo{Name: "DurationLessThan", Params: []string{"obtained", "expected"}}, | ||
306 | 56 | } | ||
307 | 57 | |||
308 | 58 | func (checker *durationLessThanChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
309 | 59 | obtained, ok := params[0].(time.Duration) | ||
310 | 60 | if !ok { | ||
311 | 61 | return false, "obtained value type must be time.Duration" | ||
312 | 62 | } | ||
313 | 63 | expected, ok := params[1].(time.Duration) | ||
314 | 64 | if !ok { | ||
315 | 65 | return false, "expected value type must be time.Duration" | ||
316 | 66 | } | ||
317 | 67 | return obtained.Nanoseconds() < expected.Nanoseconds(), "" | ||
318 | 68 | } | ||
319 | 69 | |||
320 | 70 | // HasPrefix checker for checking strings | ||
321 | 71 | |||
322 | 72 | func stringOrStringer(value interface{}) (string, bool) { | ||
323 | 73 | result, isString := value.(string) | ||
324 | 74 | if !isString { | ||
325 | 75 | if stringer, isStringer := value.(fmt.Stringer); isStringer { | ||
326 | 76 | result, isString = stringer.String(), true | ||
327 | 77 | } | ||
328 | 78 | } | ||
329 | 79 | return result, isString | ||
330 | 80 | } | ||
331 | 81 | |||
332 | 82 | type hasPrefixChecker struct { | ||
333 | 83 | *gc.CheckerInfo | ||
334 | 84 | } | ||
335 | 85 | |||
336 | 86 | var HasPrefix gc.Checker = &hasPrefixChecker{ | ||
337 | 87 | &gc.CheckerInfo{Name: "HasPrefix", Params: []string{"obtained", "expected"}}, | ||
338 | 88 | } | ||
339 | 89 | |||
340 | 90 | func (checker *hasPrefixChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
341 | 91 | expected, ok := params[1].(string) | ||
342 | 92 | if !ok { | ||
343 | 93 | return false, "expected must be a string" | ||
344 | 94 | } | ||
345 | 95 | |||
346 | 96 | obtained, isString := stringOrStringer(params[0]) | ||
347 | 97 | if isString { | ||
348 | 98 | return strings.HasPrefix(obtained, expected), "" | ||
349 | 99 | } | ||
350 | 100 | |||
351 | 101 | return false, "Obtained value is not a string and has no .String()" | ||
352 | 102 | } | ||
353 | 103 | |||
354 | 104 | type hasSuffixChecker struct { | ||
355 | 105 | *gc.CheckerInfo | ||
356 | 106 | } | ||
357 | 107 | |||
358 | 108 | var HasSuffix gc.Checker = &hasSuffixChecker{ | ||
359 | 109 | &gc.CheckerInfo{Name: "HasSuffix", Params: []string{"obtained", "expected"}}, | ||
360 | 110 | } | ||
361 | 111 | |||
362 | 112 | func (checker *hasSuffixChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
363 | 113 | expected, ok := params[1].(string) | ||
364 | 114 | if !ok { | ||
365 | 115 | return false, "expected must be a string" | ||
366 | 116 | } | ||
367 | 117 | |||
368 | 118 | obtained, isString := stringOrStringer(params[0]) | ||
369 | 119 | if isString { | ||
370 | 120 | return strings.HasSuffix(obtained, expected), "" | ||
371 | 121 | } | ||
372 | 122 | |||
373 | 123 | return false, "Obtained value is not a string and has no .String()" | ||
374 | 124 | } | ||
375 | 125 | |||
376 | 126 | type containsChecker struct { | ||
377 | 127 | *gc.CheckerInfo | ||
378 | 128 | } | ||
379 | 129 | |||
380 | 130 | var Contains gc.Checker = &containsChecker{ | ||
381 | 131 | &gc.CheckerInfo{Name: "Contains", Params: []string{"obtained", "expected"}}, | ||
382 | 132 | } | ||
383 | 133 | |||
384 | 134 | func (checker *containsChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
385 | 135 | expected, ok := params[1].(string) | ||
386 | 136 | if !ok { | ||
387 | 137 | return false, "expected must be a string" | ||
388 | 138 | } | ||
389 | 139 | |||
390 | 140 | obtained, isString := stringOrStringer(params[0]) | ||
391 | 141 | if isString { | ||
392 | 142 | return strings.Contains(obtained, expected), "" | ||
393 | 143 | } | ||
394 | 144 | |||
395 | 145 | return false, "Obtained value is not a string and has no .String()" | ||
396 | 146 | } | ||
397 | 147 | |||
398 | 148 | type sameContents struct { | ||
399 | 149 | *gc.CheckerInfo | ||
400 | 150 | } | ||
401 | 151 | |||
402 | 152 | // SameContents checks that the obtained slice contains all the values (and | ||
403 | 153 | // same number of values) of the expected slice and vice versa, without respect | ||
404 | 154 | // to order or duplicates. Uses DeepEquals on mapped contents to compare. | ||
405 | 155 | var SameContents gc.Checker = &sameContents{ | ||
406 | 156 | &gc.CheckerInfo{Name: "SameContents", Params: []string{"obtained", "expected"}}, | ||
407 | 157 | } | ||
408 | 158 | |||
409 | 159 | func (checker *sameContents) Check(params []interface{}, names []string) (result bool, error string) { | ||
410 | 160 | if len(params) != 2 { | ||
411 | 161 | return false, "SameContents expects two slice arguments" | ||
412 | 162 | } | ||
413 | 163 | obtained := params[0] | ||
414 | 164 | expected := params[1] | ||
415 | 165 | |||
416 | 166 | tob := reflect.TypeOf(obtained) | ||
417 | 167 | if tob.Kind() != reflect.Slice { | ||
418 | 168 | return false, fmt.Sprintf("SameContents expects the obtained value to be a slice, got %q", | ||
419 | 169 | tob.Kind()) | ||
420 | 170 | } | ||
421 | 171 | |||
422 | 172 | texp := reflect.TypeOf(expected) | ||
423 | 173 | if texp.Kind() != reflect.Slice { | ||
424 | 174 | return false, fmt.Sprintf("SameContents expects the expected value to be a slice, got %q", | ||
425 | 175 | texp.Kind()) | ||
426 | 176 | } | ||
427 | 177 | |||
428 | 178 | if texp != tob { | ||
429 | 179 | return false, fmt.Sprintf( | ||
430 | 180 | "SameContents expects two slices of the same type, expected: %q, got: %q", | ||
431 | 181 | texp, tob) | ||
432 | 182 | } | ||
433 | 183 | |||
434 | 184 | vexp := reflect.ValueOf(expected) | ||
435 | 185 | vob := reflect.ValueOf(obtained) | ||
436 | 186 | length := vexp.Len() | ||
437 | 187 | |||
438 | 188 | if vob.Len() != length { | ||
439 | 189 | // Slice has incorrect number of elements | ||
440 | 190 | return false, "" | ||
441 | 191 | } | ||
442 | 192 | |||
443 | 193 | // spin up maps with the entries as keys and the counts as values | ||
444 | 194 | mob := make(map[interface{}]int, length) | ||
445 | 195 | mexp := make(map[interface{}]int, length) | ||
446 | 196 | |||
447 | 197 | for i := 0; i < length; i++ { | ||
448 | 198 | mexp[vexp.Index(i).Interface()]++ | ||
449 | 199 | mob[vob.Index(i).Interface()]++ | ||
450 | 200 | } | ||
451 | 201 | return reflect.DeepEqual(mob, mexp), "" | ||
452 | 202 | } | ||
453 | 203 | 0 | ||
454 | === removed file 'testing/checkers/checker_test.go' | |||
455 | --- testing/checkers/checker_test.go 2014-03-13 07:54:56 +0000 | |||
456 | +++ testing/checkers/checker_test.go 1970-01-01 00:00:00 +0000 | |||
457 | @@ -1,119 +0,0 @@ | |||
458 | 1 | // Copyright 2013 Canonical Ltd. | ||
459 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
460 | 3 | |||
461 | 4 | package checkers_test | ||
462 | 5 | |||
463 | 6 | import ( | ||
464 | 7 | "testing" | ||
465 | 8 | |||
466 | 9 | jc "github.com/juju/testing/checkers" | ||
467 | 10 | gc "launchpad.net/gocheck" | ||
468 | 11 | ) | ||
469 | 12 | |||
470 | 13 | func Test(t *testing.T) { gc.TestingT(t) } | ||
471 | 14 | |||
472 | 15 | type CheckerSuite struct{} | ||
473 | 16 | |||
474 | 17 | var _ = gc.Suite(&CheckerSuite{}) | ||
475 | 18 | |||
476 | 19 | func (s *CheckerSuite) TestHasPrefix(c *gc.C) { | ||
477 | 20 | c.Assert("foo bar", jc.HasPrefix, "foo") | ||
478 | 21 | c.Assert("foo bar", gc.Not(jc.HasPrefix), "omg") | ||
479 | 22 | } | ||
480 | 23 | |||
481 | 24 | func (s *CheckerSuite) TestHasSuffix(c *gc.C) { | ||
482 | 25 | c.Assert("foo bar", jc.HasSuffix, "bar") | ||
483 | 26 | c.Assert("foo bar", gc.Not(jc.HasSuffix), "omg") | ||
484 | 27 | } | ||
485 | 28 | |||
486 | 29 | func (s *CheckerSuite) TestContains(c *gc.C) { | ||
487 | 30 | c.Assert("foo bar baz", jc.Contains, "foo") | ||
488 | 31 | c.Assert("foo bar baz", jc.Contains, "bar") | ||
489 | 32 | c.Assert("foo bar baz", jc.Contains, "baz") | ||
490 | 33 | c.Assert("foo bar baz", gc.Not(jc.Contains), "omg") | ||
491 | 34 | } | ||
492 | 35 | |||
493 | 36 | func (s *CheckerSuite) TestSameContents(c *gc.C) { | ||
494 | 37 | //// positive cases //// | ||
495 | 38 | |||
496 | 39 | // same | ||
497 | 40 | c.Check( | ||
498 | 41 | []int{1, 2, 3}, jc.SameContents, | ||
499 | 42 | []int{1, 2, 3}) | ||
500 | 43 | |||
501 | 44 | // empty | ||
502 | 45 | c.Check( | ||
503 | 46 | []int{}, jc.SameContents, | ||
504 | 47 | []int{}) | ||
505 | 48 | |||
506 | 49 | // single | ||
507 | 50 | c.Check( | ||
508 | 51 | []int{1}, jc.SameContents, | ||
509 | 52 | []int{1}) | ||
510 | 53 | |||
511 | 54 | // different order | ||
512 | 55 | c.Check( | ||
513 | 56 | []int{1, 2, 3}, jc.SameContents, | ||
514 | 57 | []int{3, 2, 1}) | ||
515 | 58 | |||
516 | 59 | // multiple copies of same | ||
517 | 60 | c.Check( | ||
518 | 61 | []int{1, 1, 2}, jc.SameContents, | ||
519 | 62 | []int{2, 1, 1}) | ||
520 | 63 | |||
521 | 64 | type test struct { | ||
522 | 65 | s string | ||
523 | 66 | i int | ||
524 | 67 | } | ||
525 | 68 | |||
526 | 69 | // test structs | ||
527 | 70 | c.Check( | ||
528 | 71 | []test{{"a", 1}, {"b", 2}}, jc.SameContents, | ||
529 | 72 | []test{{"b", 2}, {"a", 1}}) | ||
530 | 73 | |||
531 | 74 | //// negative cases //// | ||
532 | 75 | |||
533 | 76 | // different contents | ||
534 | 77 | c.Check( | ||
535 | 78 | []int{1, 3, 2, 5}, gc.Not(jc.SameContents), | ||
536 | 79 | []int{5, 2, 3, 4}) | ||
537 | 80 | |||
538 | 81 | // different size slices | ||
539 | 82 | c.Check( | ||
540 | 83 | []int{1, 2, 3}, gc.Not(jc.SameContents), | ||
541 | 84 | []int{1, 2}) | ||
542 | 85 | |||
543 | 86 | // different counts of same items | ||
544 | 87 | c.Check( | ||
545 | 88 | []int{1, 1, 2}, gc.Not(jc.SameContents), | ||
546 | 89 | []int{1, 2, 2}) | ||
547 | 90 | |||
548 | 91 | /// Error cases /// | ||
549 | 92 | // note: for these tests, we can't use gc.Not, since Not passes the error value through | ||
550 | 93 | // and checks with a non-empty error always count as failed | ||
551 | 94 | // Oddly, there doesn't seem to actually be a way to check for an error from a Checker. | ||
552 | 95 | |||
553 | 96 | // different type | ||
554 | 97 | res, err := jc.SameContents.Check([]interface{}{ | ||
555 | 98 | []string{"1", "2"}, | ||
556 | 99 | []int{1, 2}, | ||
557 | 100 | }, []string{}) | ||
558 | 101 | c.Check(res, jc.IsFalse) | ||
559 | 102 | c.Check(err, gc.Not(gc.Equals), "") | ||
560 | 103 | |||
561 | 104 | // obtained not a slice | ||
562 | 105 | res, err = jc.SameContents.Check([]interface{}{ | ||
563 | 106 | "test", | ||
564 | 107 | []int{1}, | ||
565 | 108 | }, []string{}) | ||
566 | 109 | c.Check(res, jc.IsFalse) | ||
567 | 110 | c.Check(err, gc.Not(gc.Equals), "") | ||
568 | 111 | |||
569 | 112 | // expected not a slice | ||
570 | 113 | res, err = jc.SameContents.Check([]interface{}{ | ||
571 | 114 | []int{1}, | ||
572 | 115 | "test", | ||
573 | 116 | }, []string{}) | ||
574 | 117 | c.Check(res, jc.IsFalse) | ||
575 | 118 | c.Check(err, gc.Not(gc.Equals), "") | ||
576 | 119 | } | ||
577 | 120 | 0 | ||
578 | === removed file 'testing/checkers/deepequal.go' | |||
579 | --- testing/checkers/deepequal.go 2014-01-13 16:04:29 +0000 | |||
580 | +++ testing/checkers/deepequal.go 1970-01-01 00:00:00 +0000 | |||
581 | @@ -1,303 +0,0 @@ | |||
582 | 1 | // Copied with small adaptations from the reflect package in the | ||
583 | 2 | // Go source tree. | ||
584 | 3 | |||
585 | 4 | // Copyright 2009 The Go Authors. All rights reserved. | ||
586 | 5 | // Use of this source code is governed by a BSD-style | ||
587 | 6 | // license that can be found in the LICENSE file. | ||
588 | 7 | |||
589 | 8 | package checkers | ||
590 | 9 | |||
591 | 10 | import ( | ||
592 | 11 | "fmt" | ||
593 | 12 | "reflect" | ||
594 | 13 | "unsafe" | ||
595 | 14 | ) | ||
596 | 15 | |||
597 | 16 | // During deepValueEqual, must keep track of checks that are | ||
598 | 17 | // in progress. The comparison algorithm assumes that all | ||
599 | 18 | // checks in progress are true when it reencounters them. | ||
600 | 19 | // Visited comparisons are stored in a map indexed by visit. | ||
601 | 20 | type visit struct { | ||
602 | 21 | a1 uintptr | ||
603 | 22 | a2 uintptr | ||
604 | 23 | typ reflect.Type | ||
605 | 24 | } | ||
606 | 25 | |||
607 | 26 | type mismatchError struct { | ||
608 | 27 | v1, v2 reflect.Value | ||
609 | 28 | path string | ||
610 | 29 | how string | ||
611 | 30 | } | ||
612 | 31 | |||
613 | 32 | func (err *mismatchError) Error() string { | ||
614 | 33 | path := err.path | ||
615 | 34 | if path == "" { | ||
616 | 35 | path = "top level" | ||
617 | 36 | } | ||
618 | 37 | return fmt.Sprintf("mismatch at %s: %s; obtained %#v; expected %#v", path, err.how, interfaceOf(err.v1), interfaceOf(err.v2)) | ||
619 | 38 | } | ||
620 | 39 | |||
621 | 40 | // Tests for deep equality using reflected types. The map argument tracks | ||
622 | 41 | // comparisons that have already been seen, which allows short circuiting on | ||
623 | 42 | // recursive types. | ||
624 | 43 | func deepValueEqual(path string, v1, v2 reflect.Value, visited map[visit]bool, depth int) (ok bool, err error) { | ||
625 | 44 | errorf := func(f string, a ...interface{}) error { | ||
626 | 45 | return &mismatchError{ | ||
627 | 46 | v1: v1, | ||
628 | 47 | v2: v2, | ||
629 | 48 | path: path, | ||
630 | 49 | how: fmt.Sprintf(f, a...), | ||
631 | 50 | } | ||
632 | 51 | } | ||
633 | 52 | if !v1.IsValid() || !v2.IsValid() { | ||
634 | 53 | if v1.IsValid() == v2.IsValid() { | ||
635 | 54 | return true, nil | ||
636 | 55 | } | ||
637 | 56 | return false, errorf("validity mismatch") | ||
638 | 57 | } | ||
639 | 58 | if v1.Type() != v2.Type() { | ||
640 | 59 | return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type()) | ||
641 | 60 | } | ||
642 | 61 | |||
643 | 62 | // if depth > 10 { panic("deepValueEqual") } // for debugging | ||
644 | 63 | hard := func(k reflect.Kind) bool { | ||
645 | 64 | switch k { | ||
646 | 65 | case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct: | ||
647 | 66 | return true | ||
648 | 67 | } | ||
649 | 68 | return false | ||
650 | 69 | } | ||
651 | 70 | |||
652 | 71 | if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) { | ||
653 | 72 | addr1 := v1.UnsafeAddr() | ||
654 | 73 | addr2 := v2.UnsafeAddr() | ||
655 | 74 | if addr1 > addr2 { | ||
656 | 75 | // Canonicalize order to reduce number of entries in visited. | ||
657 | 76 | addr1, addr2 = addr2, addr1 | ||
658 | 77 | } | ||
659 | 78 | |||
660 | 79 | // Short circuit if references are identical ... | ||
661 | 80 | if addr1 == addr2 { | ||
662 | 81 | return true, nil | ||
663 | 82 | } | ||
664 | 83 | |||
665 | 84 | // ... or already seen | ||
666 | 85 | typ := v1.Type() | ||
667 | 86 | v := visit{addr1, addr2, typ} | ||
668 | 87 | if visited[v] { | ||
669 | 88 | return true, nil | ||
670 | 89 | } | ||
671 | 90 | |||
672 | 91 | // Remember for later. | ||
673 | 92 | visited[v] = true | ||
674 | 93 | } | ||
675 | 94 | |||
676 | 95 | switch v1.Kind() { | ||
677 | 96 | case reflect.Array: | ||
678 | 97 | if v1.Len() != v2.Len() { | ||
679 | 98 | // can't happen! | ||
680 | 99 | return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len()) | ||
681 | 100 | } | ||
682 | 101 | for i := 0; i < v1.Len(); i++ { | ||
683 | 102 | if ok, err := deepValueEqual( | ||
684 | 103 | fmt.Sprintf("%s[%d]", path, i), | ||
685 | 104 | v1.Index(i), v2.Index(i), visited, depth+1); !ok { | ||
686 | 105 | return false, err | ||
687 | 106 | } | ||
688 | 107 | } | ||
689 | 108 | return true, nil | ||
690 | 109 | case reflect.Slice: | ||
691 | 110 | // We treat a nil slice the same as an empty slice. | ||
692 | 111 | if v1.Len() != v2.Len() { | ||
693 | 112 | return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len()) | ||
694 | 113 | } | ||
695 | 114 | if v1.Pointer() == v2.Pointer() { | ||
696 | 115 | return true, nil | ||
697 | 116 | } | ||
698 | 117 | for i := 0; i < v1.Len(); i++ { | ||
699 | 118 | if ok, err := deepValueEqual( | ||
700 | 119 | fmt.Sprintf("%s[%d]", path, i), | ||
701 | 120 | v1.Index(i), v2.Index(i), visited, depth+1); !ok { | ||
702 | 121 | return false, err | ||
703 | 122 | } | ||
704 | 123 | } | ||
705 | 124 | return true, nil | ||
706 | 125 | case reflect.Interface: | ||
707 | 126 | if v1.IsNil() || v2.IsNil() { | ||
708 | 127 | if v1.IsNil() != v2.IsNil() { | ||
709 | 128 | return false, fmt.Errorf("nil vs non-nil interface mismatch") | ||
710 | 129 | } | ||
711 | 130 | return true, nil | ||
712 | 131 | } | ||
713 | 132 | return deepValueEqual(path, v1.Elem(), v2.Elem(), visited, depth+1) | ||
714 | 133 | case reflect.Ptr: | ||
715 | 134 | return deepValueEqual("(*"+path+")", v1.Elem(), v2.Elem(), visited, depth+1) | ||
716 | 135 | case reflect.Struct: | ||
717 | 136 | for i, n := 0, v1.NumField(); i < n; i++ { | ||
718 | 137 | path := path + "." + v1.Type().Field(i).Name | ||
719 | 138 | if ok, err := deepValueEqual(path, v1.Field(i), v2.Field(i), visited, depth+1); !ok { | ||
720 | 139 | return false, err | ||
721 | 140 | } | ||
722 | 141 | } | ||
723 | 142 | return true, nil | ||
724 | 143 | case reflect.Map: | ||
725 | 144 | if v1.IsNil() != v2.IsNil() { | ||
726 | 145 | return false, errorf("nil vs non-nil mismatch") | ||
727 | 146 | } | ||
728 | 147 | if v1.Len() != v2.Len() { | ||
729 | 148 | return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len()) | ||
730 | 149 | } | ||
731 | 150 | if v1.Pointer() == v2.Pointer() { | ||
732 | 151 | return true, nil | ||
733 | 152 | } | ||
734 | 153 | for _, k := range v1.MapKeys() { | ||
735 | 154 | var p string | ||
736 | 155 | if k.CanInterface() { | ||
737 | 156 | p = path + "[" + fmt.Sprintf("%#v", k.Interface()) + "]" | ||
738 | 157 | } else { | ||
739 | 158 | p = path + "[someKey]" | ||
740 | 159 | } | ||
741 | 160 | if ok, err := deepValueEqual(p, v1.MapIndex(k), v2.MapIndex(k), visited, depth+1); !ok { | ||
742 | 161 | return false, err | ||
743 | 162 | } | ||
744 | 163 | } | ||
745 | 164 | return true, nil | ||
746 | 165 | case reflect.Func: | ||
747 | 166 | if v1.IsNil() && v2.IsNil() { | ||
748 | 167 | return true, nil | ||
749 | 168 | } | ||
750 | 169 | // Can't do better than this: | ||
751 | 170 | return false, errorf("non-nil functions") | ||
752 | 171 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||
753 | 172 | if v1.Int() != v2.Int() { | ||
754 | 173 | return false, errorf("unequal") | ||
755 | 174 | } | ||
756 | 175 | return true, nil | ||
757 | 176 | case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||
758 | 177 | if v1.Uint() != v2.Uint() { | ||
759 | 178 | return false, errorf("unequal") | ||
760 | 179 | } | ||
761 | 180 | return true, nil | ||
762 | 181 | case reflect.Float32, reflect.Float64: | ||
763 | 182 | if v1.Float() != v2.Float() { | ||
764 | 183 | return false, errorf("unequal") | ||
765 | 184 | } | ||
766 | 185 | return true, nil | ||
767 | 186 | case reflect.Complex64, reflect.Complex128: | ||
768 | 187 | if v1.Complex() != v2.Complex() { | ||
769 | 188 | return false, errorf("unequal") | ||
770 | 189 | } | ||
771 | 190 | return true, nil | ||
772 | 191 | case reflect.Bool: | ||
773 | 192 | if v1.Bool() != v2.Bool() { | ||
774 | 193 | return false, errorf("unequal") | ||
775 | 194 | } | ||
776 | 195 | return true, nil | ||
777 | 196 | case reflect.String: | ||
778 | 197 | if v1.String() != v2.String() { | ||
779 | 198 | return false, errorf("unequal") | ||
780 | 199 | } | ||
781 | 200 | return true, nil | ||
782 | 201 | case reflect.Chan, reflect.UnsafePointer: | ||
783 | 202 | if v1.Pointer() != v2.Pointer() { | ||
784 | 203 | return false, errorf("unequal") | ||
785 | 204 | } | ||
786 | 205 | return true, nil | ||
787 | 206 | default: | ||
788 | 207 | panic("unexpected type " + v1.Type().String()) | ||
789 | 208 | } | ||
790 | 209 | } | ||
791 | 210 | |||
792 | 211 | // DeepEqual tests for deep equality. It uses normal == equality where | ||
793 | 212 | // possible but will scan elements of arrays, slices, maps, and fields | ||
794 | 213 | // of structs. In maps, keys are compared with == but elements use deep | ||
795 | 214 | // equality. DeepEqual correctly handles recursive types. Functions are | ||
796 | 215 | // equal only if they are both nil. | ||
797 | 216 | // | ||
798 | 217 | // DeepEqual differs from reflect.DeepEqual in that an empty slice is | ||
799 | 218 | // equal to a nil slice. If the two values compare unequal, the | ||
800 | 219 | // resulting error holds the first difference encountered. | ||
801 | 220 | func DeepEqual(a1, a2 interface{}) (bool, error) { | ||
802 | 221 | errorf := func(f string, a ...interface{}) error { | ||
803 | 222 | return &mismatchError{ | ||
804 | 223 | v1: reflect.ValueOf(a1), | ||
805 | 224 | v2: reflect.ValueOf(a2), | ||
806 | 225 | path: "", | ||
807 | 226 | how: fmt.Sprintf(f, a...), | ||
808 | 227 | } | ||
809 | 228 | } | ||
810 | 229 | if a1 == nil || a2 == nil { | ||
811 | 230 | if a1 == a2 { | ||
812 | 231 | return true, nil | ||
813 | 232 | } | ||
814 | 233 | return false, errorf("nil vs non-nil mismatch") | ||
815 | 234 | } | ||
816 | 235 | v1 := reflect.ValueOf(a1) | ||
817 | 236 | v2 := reflect.ValueOf(a2) | ||
818 | 237 | if v1.Type() != v2.Type() { | ||
819 | 238 | return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type()) | ||
820 | 239 | } | ||
821 | 240 | return deepValueEqual("", v1, v2, make(map[visit]bool), 0) | ||
822 | 241 | } | ||
823 | 242 | |||
824 | 243 | // interfaceOf returns v.Interface() even if v.CanInterface() == false. | ||
825 | 244 | // This enables us to call fmt.Printf on a value even if it's derived | ||
826 | 245 | // from inside an unexported field. | ||
827 | 246 | func interfaceOf(v reflect.Value) interface{} { | ||
828 | 247 | if !v.IsValid() { | ||
829 | 248 | return nil | ||
830 | 249 | } | ||
831 | 250 | return bypassCanInterface(v).Interface() | ||
832 | 251 | } | ||
833 | 252 | |||
834 | 253 | type flag uintptr | ||
835 | 254 | |||
836 | 255 | // copied from reflect/value.go | ||
837 | 256 | const ( | ||
838 | 257 | flagRO flag = 1 << iota | ||
839 | 258 | ) | ||
840 | 259 | |||
841 | 260 | var flagValOffset = func() uintptr { | ||
842 | 261 | field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") | ||
843 | 262 | if !ok { | ||
844 | 263 | panic("reflect.Value has no flag field") | ||
845 | 264 | } | ||
846 | 265 | return field.Offset | ||
847 | 266 | }() | ||
848 | 267 | |||
849 | 268 | func flagField(v *reflect.Value) *flag { | ||
850 | 269 | return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) | ||
851 | 270 | } | ||
852 | 271 | |||
853 | 272 | // bypassCanInterface returns a version of v that | ||
854 | 273 | // bypasses the CanInterface check. | ||
855 | 274 | func bypassCanInterface(v reflect.Value) reflect.Value { | ||
856 | 275 | if !v.IsValid() || v.CanInterface() { | ||
857 | 276 | return v | ||
858 | 277 | } | ||
859 | 278 | *flagField(&v) &^= flagRO | ||
860 | 279 | return v | ||
861 | 280 | } | ||
862 | 281 | |||
863 | 282 | // Sanity checks against future reflect package changes | ||
864 | 283 | // to the type or semantics of the Value.flag field. | ||
865 | 284 | func init() { | ||
866 | 285 | field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") | ||
867 | 286 | if !ok { | ||
868 | 287 | panic("reflect.Value has no flag field") | ||
869 | 288 | } | ||
870 | 289 | if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { | ||
871 | 290 | panic("reflect.Value flag field has changed kind") | ||
872 | 291 | } | ||
873 | 292 | var t struct { | ||
874 | 293 | a int | ||
875 | 294 | A int | ||
876 | 295 | } | ||
877 | 296 | vA := reflect.ValueOf(t).FieldByName("A") | ||
878 | 297 | va := reflect.ValueOf(t).FieldByName("a") | ||
879 | 298 | flagA := *flagField(&vA) | ||
880 | 299 | flaga := *flagField(&va) | ||
881 | 300 | if flagA&flagRO != 0 || flaga&flagRO == 0 { | ||
882 | 301 | panic("reflect.Value read-only flag has changed value") | ||
883 | 302 | } | ||
884 | 303 | } | ||
885 | 304 | 0 | ||
886 | === removed file 'testing/checkers/deepequal_test.go' | |||
887 | --- testing/checkers/deepequal_test.go 2014-03-13 07:54:56 +0000 | |||
888 | +++ testing/checkers/deepequal_test.go 1970-01-01 00:00:00 +0000 | |||
889 | @@ -1,171 +0,0 @@ | |||
890 | 1 | // Copied with small adaptations from the reflect package in the | ||
891 | 2 | // Go source tree. We use testing rather than gocheck to preserve | ||
892 | 3 | // as much source equivalence as possible. | ||
893 | 4 | |||
894 | 5 | // TODO tests for error messages | ||
895 | 6 | |||
896 | 7 | // Copyright 2009 The Go Authors. All rights reserved. | ||
897 | 8 | // Use of this source code is governed by a BSD-style | ||
898 | 9 | // license that can be found in the LICENSE file. | ||
899 | 10 | |||
900 | 11 | package checkers_test | ||
901 | 12 | |||
902 | 13 | import ( | ||
903 | 14 | "regexp" | ||
904 | 15 | "testing" | ||
905 | 16 | |||
906 | 17 | "github.com/juju/testing/checkers" | ||
907 | 18 | ) | ||
908 | 19 | |||
909 | 20 | func deepEqual(a1, a2 interface{}) bool { | ||
910 | 21 | ok, _ := checkers.DeepEqual(a1, a2) | ||
911 | 22 | return ok | ||
912 | 23 | } | ||
913 | 24 | |||
914 | 25 | type Basic struct { | ||
915 | 26 | x int | ||
916 | 27 | y float32 | ||
917 | 28 | } | ||
918 | 29 | |||
919 | 30 | type NotBasic Basic | ||
920 | 31 | |||
921 | 32 | type DeepEqualTest struct { | ||
922 | 33 | a, b interface{} | ||
923 | 34 | eq bool | ||
924 | 35 | msg string | ||
925 | 36 | } | ||
926 | 37 | |||
927 | 38 | // Simple functions for DeepEqual tests. | ||
928 | 39 | var ( | ||
929 | 40 | fn1 func() // nil. | ||
930 | 41 | fn2 func() // nil. | ||
931 | 42 | fn3 = func() { fn1() } // Not nil. | ||
932 | 43 | ) | ||
933 | 44 | |||
934 | 45 | var deepEqualTests = []DeepEqualTest{ | ||
935 | 46 | // Equalities | ||
936 | 47 | {nil, nil, true, ""}, | ||
937 | 48 | {1, 1, true, ""}, | ||
938 | 49 | {int32(1), int32(1), true, ""}, | ||
939 | 50 | {0.5, 0.5, true, ""}, | ||
940 | 51 | {float32(0.5), float32(0.5), true, ""}, | ||
941 | 52 | {"hello", "hello", true, ""}, | ||
942 | 53 | {make([]int, 10), make([]int, 10), true, ""}, | ||
943 | 54 | {&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true, ""}, | ||
944 | 55 | {Basic{1, 0.5}, Basic{1, 0.5}, true, ""}, | ||
945 | 56 | {error(nil), error(nil), true, ""}, | ||
946 | 57 | {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true, ""}, | ||
947 | 58 | {fn1, fn2, true, ""}, | ||
948 | 59 | |||
949 | 60 | // Inequalities | ||
950 | 61 | {1, 2, false, `mismatch at top level: unequal; obtained 1; expected 2`}, | ||
951 | 62 | {int32(1), int32(2), false, `mismatch at top level: unequal; obtained 1; expected 2`}, | ||
952 | 63 | {0.5, 0.6, false, `mismatch at top level: unequal; obtained 0\.5; expected 0\.6`}, | ||
953 | 64 | {float32(0.5), float32(0.6), false, `mismatch at top level: unequal; obtained 0\.5; expected 0\.6`}, | ||
954 | 65 | {"hello", "hey", false, `mismatch at top level: unequal; obtained "hello"; expected "hey"`}, | ||
955 | 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\}`}, | ||
956 | 67 | {&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false, `mismatch at \(\*\)\[2\]: unequal; obtained 3; expected 4`}, | ||
957 | 68 | {Basic{1, 0.5}, Basic{1, 0.6}, false, `mismatch at \.y: unequal; obtained 0\.5; expected 0\.6`}, | ||
958 | 69 | {Basic{1, 0}, Basic{2, 0}, false, `mismatch at \.x: unequal; obtained 1; expected 2`}, | ||
959 | 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>`}, | ||
960 | 71 | {map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false, `mismatch at \[2\]: unequal; obtained "txo"; expected "two"`}, | ||
961 | 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"\}`}, | ||
962 | 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"\}`}, | ||
963 | 74 | {nil, 1, false, `mismatch at top level: nil vs non-nil mismatch; obtained <nil>; expected 1`}, | ||
964 | 75 | {1, nil, false, `mismatch at top level: nil vs non-nil mismatch; obtained 1; expected <nil>`}, | ||
965 | 76 | {fn1, fn3, false, `mismatch at top level: non-nil functions; obtained \(func\(\)\)\(nil\); expected \(func\(\)\)\(0x[0-9a-f]+\)`}, | ||
966 | 77 | {fn3, fn3, false, `mismatch at top level: non-nil functions; obtained \(func\(\)\)\(0x[0-9a-f]+\); expected \(func\(\)\)\(0x[0-9a-f]+\)`}, | ||
967 | 78 | |||
968 | 79 | // Nil vs empty: they're the same (difference from normal DeepEqual) | ||
969 | 80 | {[]int{}, []int(nil), true, ""}, | ||
970 | 81 | {[]int{}, []int{}, true, ""}, | ||
971 | 82 | {[]int(nil), []int(nil), true, ""}, | ||
972 | 83 | |||
973 | 84 | // Mismatched types | ||
974 | 85 | {1, 1.0, false, `mismatch at top level: type mismatch int vs float64; obtained 1; expected 1`}, | ||
975 | 86 | {int32(1), int64(1), false, `mismatch at top level: type mismatch int32 vs int64; obtained 1; expected 1`}, | ||
976 | 87 | {0.5, "hello", false, `mismatch at top level: type mismatch float64 vs string; obtained 0\.5; expected "hello"`}, | ||
977 | 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\}`}, | ||
978 | 89 | {&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false, `mismatch at \(\*\)\[2\]: type mismatch int vs string; obtained 4; expected "s"`}, | ||
979 | 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\}`}, | ||
980 | 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"\}`}, | ||
981 | 92 | } | ||
982 | 93 | |||
983 | 94 | func TestDeepEqual(t *testing.T) { | ||
984 | 95 | for _, test := range deepEqualTests { | ||
985 | 96 | r, err := checkers.DeepEqual(test.a, test.b) | ||
986 | 97 | if r != test.eq { | ||
987 | 98 | t.Errorf("deepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq) | ||
988 | 99 | } | ||
989 | 100 | if test.eq { | ||
990 | 101 | if err != nil { | ||
991 | 102 | t.Errorf("deepEqual(%v, %v): unexpected error message %q when equal", test.a, test.b, err) | ||
992 | 103 | } | ||
993 | 104 | } else { | ||
994 | 105 | if ok, _ := regexp.MatchString(test.msg, err.Error()); !ok { | ||
995 | 106 | t.Errorf("deepEqual(%v, %v); unexpected error %q, want %q", test.a, test.b, err.Error(), test.msg) | ||
996 | 107 | } | ||
997 | 108 | } | ||
998 | 109 | } | ||
999 | 110 | } | ||
1000 | 111 | |||
1001 | 112 | type Recursive struct { | ||
1002 | 113 | x int | ||
1003 | 114 | r *Recursive | ||
1004 | 115 | } | ||
1005 | 116 | |||
1006 | 117 | func TestDeepEqualRecursiveStruct(t *testing.T) { | ||
1007 | 118 | a, b := new(Recursive), new(Recursive) | ||
1008 | 119 | *a = Recursive{12, a} | ||
1009 | 120 | *b = Recursive{12, b} | ||
1010 | 121 | if !deepEqual(a, b) { | ||
1011 | 122 | t.Error("deepEqual(recursive same) = false, want true") | ||
1012 | 123 | } | ||
1013 | 124 | } | ||
1014 | 125 | |||
1015 | 126 | type _Complex struct { | ||
1016 | 127 | a int | ||
1017 | 128 | b [3]*_Complex | ||
1018 | 129 | c *string | ||
1019 | 130 | d map[float64]float64 | ||
1020 | 131 | } | ||
1021 | 132 | |||
1022 | 133 | func TestDeepEqualComplexStruct(t *testing.T) { | ||
1023 | 134 | m := make(map[float64]float64) | ||
1024 | 135 | stra, strb := "hello", "hello" | ||
1025 | 136 | a, b := new(_Complex), new(_Complex) | ||
1026 | 137 | *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m} | ||
1027 | 138 | *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m} | ||
1028 | 139 | if !deepEqual(a, b) { | ||
1029 | 140 | t.Error("deepEqual(complex same) = false, want true") | ||
1030 | 141 | } | ||
1031 | 142 | } | ||
1032 | 143 | |||
1033 | 144 | func TestDeepEqualComplexStructInequality(t *testing.T) { | ||
1034 | 145 | m := make(map[float64]float64) | ||
1035 | 146 | stra, strb := "hello", "helloo" // Difference is here | ||
1036 | 147 | a, b := new(_Complex), new(_Complex) | ||
1037 | 148 | *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m} | ||
1038 | 149 | *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m} | ||
1039 | 150 | if deepEqual(a, b) { | ||
1040 | 151 | t.Error("deepEqual(complex different) = true, want false") | ||
1041 | 152 | } | ||
1042 | 153 | } | ||
1043 | 154 | |||
1044 | 155 | type UnexpT struct { | ||
1045 | 156 | m map[int]int | ||
1046 | 157 | } | ||
1047 | 158 | |||
1048 | 159 | func TestDeepEqualUnexportedMap(t *testing.T) { | ||
1049 | 160 | // Check that DeepEqual can look at unexported fields. | ||
1050 | 161 | x1 := UnexpT{map[int]int{1: 2}} | ||
1051 | 162 | x2 := UnexpT{map[int]int{1: 2}} | ||
1052 | 163 | if !deepEqual(&x1, &x2) { | ||
1053 | 164 | t.Error("deepEqual(x1, x2) = false, want true") | ||
1054 | 165 | } | ||
1055 | 166 | |||
1056 | 167 | y1 := UnexpT{map[int]int{2: 3}} | ||
1057 | 168 | if deepEqual(&x1, &y1) { | ||
1058 | 169 | t.Error("deepEqual(x1, y1) = true, want false") | ||
1059 | 170 | } | ||
1060 | 171 | } | ||
1061 | 172 | 0 | ||
1062 | === removed file 'testing/checkers/file.go' | |||
1063 | --- testing/checkers/file.go 2013-10-01 21:20:11 +0000 | |||
1064 | +++ testing/checkers/file.go 1970-01-01 00:00:00 +0000 | |||
1065 | @@ -1,154 +0,0 @@ | |||
1066 | 1 | // Copyright 2013 Canonical Ltd. | ||
1067 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
1068 | 3 | |||
1069 | 4 | package checkers | ||
1070 | 5 | |||
1071 | 6 | import ( | ||
1072 | 7 | "fmt" | ||
1073 | 8 | "os" | ||
1074 | 9 | "reflect" | ||
1075 | 10 | |||
1076 | 11 | gc "launchpad.net/gocheck" | ||
1077 | 12 | ) | ||
1078 | 13 | |||
1079 | 14 | // IsNonEmptyFile checker | ||
1080 | 15 | |||
1081 | 16 | type isNonEmptyFileChecker struct { | ||
1082 | 17 | *gc.CheckerInfo | ||
1083 | 18 | } | ||
1084 | 19 | |||
1085 | 20 | var IsNonEmptyFile gc.Checker = &isNonEmptyFileChecker{ | ||
1086 | 21 | &gc.CheckerInfo{Name: "IsNonEmptyFile", Params: []string{"obtained"}}, | ||
1087 | 22 | } | ||
1088 | 23 | |||
1089 | 24 | func (checker *isNonEmptyFileChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
1090 | 25 | filename, isString := stringOrStringer(params[0]) | ||
1091 | 26 | if isString { | ||
1092 | 27 | fileInfo, err := os.Stat(filename) | ||
1093 | 28 | if os.IsNotExist(err) { | ||
1094 | 29 | return false, fmt.Sprintf("%s does not exist", filename) | ||
1095 | 30 | } else if err != nil { | ||
1096 | 31 | return false, fmt.Sprintf("other stat error: %v", err) | ||
1097 | 32 | } | ||
1098 | 33 | if fileInfo.Size() > 0 { | ||
1099 | 34 | return true, "" | ||
1100 | 35 | } else { | ||
1101 | 36 | return false, fmt.Sprintf("%s is empty", filename) | ||
1102 | 37 | } | ||
1103 | 38 | } | ||
1104 | 39 | |||
1105 | 40 | value := reflect.ValueOf(params[0]) | ||
1106 | 41 | return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0]) | ||
1107 | 42 | } | ||
1108 | 43 | |||
1109 | 44 | // IsDirectory checker | ||
1110 | 45 | |||
1111 | 46 | type isDirectoryChecker struct { | ||
1112 | 47 | *gc.CheckerInfo | ||
1113 | 48 | } | ||
1114 | 49 | |||
1115 | 50 | var IsDirectory gc.Checker = &isDirectoryChecker{ | ||
1116 | 51 | &gc.CheckerInfo{Name: "IsDirectory", Params: []string{"obtained"}}, | ||
1117 | 52 | } | ||
1118 | 53 | |||
1119 | 54 | func (checker *isDirectoryChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
1120 | 55 | path, isString := stringOrStringer(params[0]) | ||
1121 | 56 | if isString { | ||
1122 | 57 | fileInfo, err := os.Stat(path) | ||
1123 | 58 | if os.IsNotExist(err) { | ||
1124 | 59 | return false, fmt.Sprintf("%s does not exist", path) | ||
1125 | 60 | } else if err != nil { | ||
1126 | 61 | return false, fmt.Sprintf("other stat error: %v", err) | ||
1127 | 62 | } | ||
1128 | 63 | if fileInfo.IsDir() { | ||
1129 | 64 | return true, "" | ||
1130 | 65 | } else { | ||
1131 | 66 | return false, fmt.Sprintf("%s is not a directory", path) | ||
1132 | 67 | } | ||
1133 | 68 | } | ||
1134 | 69 | |||
1135 | 70 | value := reflect.ValueOf(params[0]) | ||
1136 | 71 | return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0]) | ||
1137 | 72 | } | ||
1138 | 73 | |||
1139 | 74 | // IsSymlink checker | ||
1140 | 75 | |||
1141 | 76 | type isSymlinkChecker struct { | ||
1142 | 77 | *gc.CheckerInfo | ||
1143 | 78 | } | ||
1144 | 79 | |||
1145 | 80 | var IsSymlink gc.Checker = &isSymlinkChecker{ | ||
1146 | 81 | &gc.CheckerInfo{Name: "IsSymlink", Params: []string{"obtained"}}, | ||
1147 | 82 | } | ||
1148 | 83 | |||
1149 | 84 | func (checker *isSymlinkChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
1150 | 85 | path, isString := stringOrStringer(params[0]) | ||
1151 | 86 | if isString { | ||
1152 | 87 | fileInfo, err := os.Lstat(path) | ||
1153 | 88 | if os.IsNotExist(err) { | ||
1154 | 89 | return false, fmt.Sprintf("%s does not exist", path) | ||
1155 | 90 | } else if err != nil { | ||
1156 | 91 | return false, fmt.Sprintf("other stat error: %v", err) | ||
1157 | 92 | } | ||
1158 | 93 | if fileInfo.Mode()&os.ModeSymlink != 0 { | ||
1159 | 94 | return true, "" | ||
1160 | 95 | } else { | ||
1161 | 96 | return false, fmt.Sprintf("%s is not a symlink: %+v", path, fileInfo) | ||
1162 | 97 | } | ||
1163 | 98 | } | ||
1164 | 99 | |||
1165 | 100 | value := reflect.ValueOf(params[0]) | ||
1166 | 101 | return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0]) | ||
1167 | 102 | } | ||
1168 | 103 | |||
1169 | 104 | // DoesNotExist checker makes sure the path specified doesn't exist. | ||
1170 | 105 | |||
1171 | 106 | type doesNotExistChecker struct { | ||
1172 | 107 | *gc.CheckerInfo | ||
1173 | 108 | } | ||
1174 | 109 | |||
1175 | 110 | var DoesNotExist gc.Checker = &doesNotExistChecker{ | ||
1176 | 111 | &gc.CheckerInfo{Name: "DoesNotExist", Params: []string{"obtained"}}, | ||
1177 | 112 | } | ||
1178 | 113 | |||
1179 | 114 | func (checker *doesNotExistChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
1180 | 115 | path, isString := stringOrStringer(params[0]) | ||
1181 | 116 | if isString { | ||
1182 | 117 | _, err := os.Stat(path) | ||
1183 | 118 | if os.IsNotExist(err) { | ||
1184 | 119 | return true, "" | ||
1185 | 120 | } else if err != nil { | ||
1186 | 121 | return false, fmt.Sprintf("other stat error: %v", err) | ||
1187 | 122 | } | ||
1188 | 123 | return false, fmt.Sprintf("%s exists", path) | ||
1189 | 124 | } | ||
1190 | 125 | |||
1191 | 126 | value := reflect.ValueOf(params[0]) | ||
1192 | 127 | return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0]) | ||
1193 | 128 | } | ||
1194 | 129 | |||
1195 | 130 | // SymlinkDoesNotExist checker makes sure the path specified doesn't exist. | ||
1196 | 131 | |||
1197 | 132 | type symlinkDoesNotExistChecker struct { | ||
1198 | 133 | *gc.CheckerInfo | ||
1199 | 134 | } | ||
1200 | 135 | |||
1201 | 136 | var SymlinkDoesNotExist gc.Checker = &symlinkDoesNotExistChecker{ | ||
1202 | 137 | &gc.CheckerInfo{Name: "SymlinkDoesNotExist", Params: []string{"obtained"}}, | ||
1203 | 138 | } | ||
1204 | 139 | |||
1205 | 140 | func (checker *symlinkDoesNotExistChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
1206 | 141 | path, isString := stringOrStringer(params[0]) | ||
1207 | 142 | if isString { | ||
1208 | 143 | _, err := os.Lstat(path) | ||
1209 | 144 | if os.IsNotExist(err) { | ||
1210 | 145 | return true, "" | ||
1211 | 146 | } else if err != nil { | ||
1212 | 147 | return false, fmt.Sprintf("other stat error: %v", err) | ||
1213 | 148 | } | ||
1214 | 149 | return false, fmt.Sprintf("%s exists", path) | ||
1215 | 150 | } | ||
1216 | 151 | |||
1217 | 152 | value := reflect.ValueOf(params[0]) | ||
1218 | 153 | return false, fmt.Sprintf("obtained value is not a string and has no .String(), %s:%#v", value.Kind(), params[0]) | ||
1219 | 154 | } | ||
1220 | 155 | 0 | ||
1221 | === removed file 'testing/checkers/file_test.go' | |||
1222 | --- testing/checkers/file_test.go 2014-03-13 07:54:56 +0000 | |||
1223 | +++ testing/checkers/file_test.go 1970-01-01 00:00:00 +0000 | |||
1224 | @@ -1,165 +0,0 @@ | |||
1225 | 1 | // Copyright 2013 Canonical Ltd. | ||
1226 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
1227 | 3 | |||
1228 | 4 | package checkers_test | ||
1229 | 5 | |||
1230 | 6 | import ( | ||
1231 | 7 | "fmt" | ||
1232 | 8 | "io/ioutil" | ||
1233 | 9 | "os" | ||
1234 | 10 | "path/filepath" | ||
1235 | 11 | |||
1236 | 12 | jc "github.com/juju/testing/checkers" | ||
1237 | 13 | gc "launchpad.net/gocheck" | ||
1238 | 14 | ) | ||
1239 | 15 | |||
1240 | 16 | type FileSuite struct{} | ||
1241 | 17 | |||
1242 | 18 | var _ = gc.Suite(&FileSuite{}) | ||
1243 | 19 | |||
1244 | 20 | func (s *FileSuite) TestIsNonEmptyFile(c *gc.C) { | ||
1245 | 21 | file, err := ioutil.TempFile(c.MkDir(), "") | ||
1246 | 22 | c.Assert(err, gc.IsNil) | ||
1247 | 23 | fmt.Fprintf(file, "something") | ||
1248 | 24 | file.Close() | ||
1249 | 25 | |||
1250 | 26 | c.Assert(file.Name(), jc.IsNonEmptyFile) | ||
1251 | 27 | } | ||
1252 | 28 | |||
1253 | 29 | func (s *FileSuite) TestIsNonEmptyFileWithEmptyFile(c *gc.C) { | ||
1254 | 30 | file, err := ioutil.TempFile(c.MkDir(), "") | ||
1255 | 31 | c.Assert(err, gc.IsNil) | ||
1256 | 32 | file.Close() | ||
1257 | 33 | |||
1258 | 34 | result, message := jc.IsNonEmptyFile.Check([]interface{}{file.Name()}, nil) | ||
1259 | 35 | c.Assert(result, jc.IsFalse) | ||
1260 | 36 | c.Assert(message, gc.Equals, file.Name()+" is empty") | ||
1261 | 37 | } | ||
1262 | 38 | |||
1263 | 39 | func (s *FileSuite) TestIsNonEmptyFileWithMissingFile(c *gc.C) { | ||
1264 | 40 | name := filepath.Join(c.MkDir(), "missing") | ||
1265 | 41 | |||
1266 | 42 | result, message := jc.IsNonEmptyFile.Check([]interface{}{name}, nil) | ||
1267 | 43 | c.Assert(result, jc.IsFalse) | ||
1268 | 44 | c.Assert(message, gc.Equals, name+" does not exist") | ||
1269 | 45 | } | ||
1270 | 46 | |||
1271 | 47 | func (s *FileSuite) TestIsNonEmptyFileWithNumber(c *gc.C) { | ||
1272 | 48 | result, message := jc.IsNonEmptyFile.Check([]interface{}{42}, nil) | ||
1273 | 49 | c.Assert(result, jc.IsFalse) | ||
1274 | 50 | c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42") | ||
1275 | 51 | } | ||
1276 | 52 | |||
1277 | 53 | func (s *FileSuite) TestIsDirectory(c *gc.C) { | ||
1278 | 54 | dir := c.MkDir() | ||
1279 | 55 | c.Assert(dir, jc.IsDirectory) | ||
1280 | 56 | } | ||
1281 | 57 | |||
1282 | 58 | func (s *FileSuite) TestIsDirectoryMissing(c *gc.C) { | ||
1283 | 59 | absentDir := filepath.Join(c.MkDir(), "foo") | ||
1284 | 60 | |||
1285 | 61 | result, message := jc.IsDirectory.Check([]interface{}{absentDir}, nil) | ||
1286 | 62 | c.Assert(result, jc.IsFalse) | ||
1287 | 63 | c.Assert(message, gc.Equals, absentDir+" does not exist") | ||
1288 | 64 | } | ||
1289 | 65 | |||
1290 | 66 | func (s *FileSuite) TestIsDirectoryWithFile(c *gc.C) { | ||
1291 | 67 | file, err := ioutil.TempFile(c.MkDir(), "") | ||
1292 | 68 | c.Assert(err, gc.IsNil) | ||
1293 | 69 | file.Close() | ||
1294 | 70 | |||
1295 | 71 | result, message := jc.IsDirectory.Check([]interface{}{file.Name()}, nil) | ||
1296 | 72 | c.Assert(result, jc.IsFalse) | ||
1297 | 73 | c.Assert(message, gc.Equals, file.Name()+" is not a directory") | ||
1298 | 74 | } | ||
1299 | 75 | |||
1300 | 76 | func (s *FileSuite) TestIsDirectoryWithNumber(c *gc.C) { | ||
1301 | 77 | result, message := jc.IsDirectory.Check([]interface{}{42}, nil) | ||
1302 | 78 | c.Assert(result, jc.IsFalse) | ||
1303 | 79 | c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42") | ||
1304 | 80 | } | ||
1305 | 81 | |||
1306 | 82 | func (s *FileSuite) TestDoesNotExist(c *gc.C) { | ||
1307 | 83 | absentDir := filepath.Join(c.MkDir(), "foo") | ||
1308 | 84 | c.Assert(absentDir, jc.DoesNotExist) | ||
1309 | 85 | } | ||
1310 | 86 | |||
1311 | 87 | func (s *FileSuite) TestDoesNotExistWithPath(c *gc.C) { | ||
1312 | 88 | dir := c.MkDir() | ||
1313 | 89 | result, message := jc.DoesNotExist.Check([]interface{}{dir}, nil) | ||
1314 | 90 | c.Assert(result, jc.IsFalse) | ||
1315 | 91 | c.Assert(message, gc.Equals, dir+" exists") | ||
1316 | 92 | } | ||
1317 | 93 | |||
1318 | 94 | func (s *FileSuite) TestDoesNotExistWithSymlink(c *gc.C) { | ||
1319 | 95 | dir := c.MkDir() | ||
1320 | 96 | deadPath := filepath.Join(dir, "dead") | ||
1321 | 97 | symlinkPath := filepath.Join(dir, "a-symlink") | ||
1322 | 98 | err := os.Symlink(deadPath, symlinkPath) | ||
1323 | 99 | c.Assert(err, gc.IsNil) | ||
1324 | 100 | // A valid symlink pointing to something that doesn't exist passes. | ||
1325 | 101 | // Use SymlinkDoesNotExist to check for the non-existence of the link itself. | ||
1326 | 102 | c.Assert(symlinkPath, jc.DoesNotExist) | ||
1327 | 103 | } | ||
1328 | 104 | |||
1329 | 105 | func (s *FileSuite) TestDoesNotExistWithNumber(c *gc.C) { | ||
1330 | 106 | result, message := jc.DoesNotExist.Check([]interface{}{42}, nil) | ||
1331 | 107 | c.Assert(result, jc.IsFalse) | ||
1332 | 108 | c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42") | ||
1333 | 109 | } | ||
1334 | 110 | |||
1335 | 111 | func (s *FileSuite) TestSymlinkDoesNotExist(c *gc.C) { | ||
1336 | 112 | absentDir := filepath.Join(c.MkDir(), "foo") | ||
1337 | 113 | c.Assert(absentDir, jc.SymlinkDoesNotExist) | ||
1338 | 114 | } | ||
1339 | 115 | |||
1340 | 116 | func (s *FileSuite) TestSymlinkDoesNotExistWithPath(c *gc.C) { | ||
1341 | 117 | dir := c.MkDir() | ||
1342 | 118 | result, message := jc.SymlinkDoesNotExist.Check([]interface{}{dir}, nil) | ||
1343 | 119 | c.Assert(result, jc.IsFalse) | ||
1344 | 120 | c.Assert(message, gc.Equals, dir+" exists") | ||
1345 | 121 | } | ||
1346 | 122 | |||
1347 | 123 | func (s *FileSuite) TestSymlinkDoesNotExistWithSymlink(c *gc.C) { | ||
1348 | 124 | dir := c.MkDir() | ||
1349 | 125 | deadPath := filepath.Join(dir, "dead") | ||
1350 | 126 | symlinkPath := filepath.Join(dir, "a-symlink") | ||
1351 | 127 | err := os.Symlink(deadPath, symlinkPath) | ||
1352 | 128 | c.Assert(err, gc.IsNil) | ||
1353 | 129 | |||
1354 | 130 | result, message := jc.SymlinkDoesNotExist.Check([]interface{}{symlinkPath}, nil) | ||
1355 | 131 | c.Assert(result, jc.IsFalse) | ||
1356 | 132 | c.Assert(message, gc.Equals, symlinkPath+" exists") | ||
1357 | 133 | } | ||
1358 | 134 | |||
1359 | 135 | func (s *FileSuite) TestSymlinkDoesNotExistWithNumber(c *gc.C) { | ||
1360 | 136 | result, message := jc.SymlinkDoesNotExist.Check([]interface{}{42}, nil) | ||
1361 | 137 | c.Assert(result, jc.IsFalse) | ||
1362 | 138 | c.Assert(message, gc.Equals, "obtained value is not a string and has no .String(), int:42") | ||
1363 | 139 | } | ||
1364 | 140 | |||
1365 | 141 | func (s *FileSuite) TestIsSymlink(c *gc.C) { | ||
1366 | 142 | file, err := ioutil.TempFile(c.MkDir(), "") | ||
1367 | 143 | c.Assert(err, gc.IsNil) | ||
1368 | 144 | c.Log(file.Name()) | ||
1369 | 145 | c.Log(filepath.Dir(file.Name())) | ||
1370 | 146 | symlinkPath := filepath.Join(filepath.Dir(file.Name()), "a-symlink") | ||
1371 | 147 | err = os.Symlink(file.Name(), symlinkPath) | ||
1372 | 148 | c.Assert(err, gc.IsNil) | ||
1373 | 149 | |||
1374 | 150 | c.Assert(symlinkPath, jc.IsSymlink) | ||
1375 | 151 | } | ||
1376 | 152 | |||
1377 | 153 | func (s *FileSuite) TestIsSymlinkWithFile(c *gc.C) { | ||
1378 | 154 | file, err := ioutil.TempFile(c.MkDir(), "") | ||
1379 | 155 | c.Assert(err, gc.IsNil) | ||
1380 | 156 | result, message := jc.IsSymlink.Check([]interface{}{file.Name()}, nil) | ||
1381 | 157 | c.Assert(result, jc.IsFalse) | ||
1382 | 158 | c.Assert(message, jc.Contains, " is not a symlink") | ||
1383 | 159 | } | ||
1384 | 160 | |||
1385 | 161 | func (s *FileSuite) TestIsSymlinkWithDir(c *gc.C) { | ||
1386 | 162 | result, message := jc.IsSymlink.Check([]interface{}{c.MkDir()}, nil) | ||
1387 | 163 | c.Assert(result, jc.IsFalse) | ||
1388 | 164 | c.Assert(message, jc.Contains, " is not a symlink") | ||
1389 | 165 | } | ||
1390 | 166 | 0 | ||
1391 | === removed file 'testing/checkers/log.go' | |||
1392 | --- testing/checkers/log.go 2014-03-05 19:41:34 +0000 | |||
1393 | +++ testing/checkers/log.go 1970-01-01 00:00:00 +0000 | |||
1394 | @@ -1,109 +0,0 @@ | |||
1395 | 1 | // Copyright 2012, 2013 Canonical Ltd. | ||
1396 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
1397 | 3 | |||
1398 | 4 | package checkers | ||
1399 | 5 | |||
1400 | 6 | import ( | ||
1401 | 7 | "fmt" | ||
1402 | 8 | "regexp" | ||
1403 | 9 | "strings" | ||
1404 | 10 | |||
1405 | 11 | "github.com/juju/loggo" | ||
1406 | 12 | gc "launchpad.net/gocheck" | ||
1407 | 13 | ) | ||
1408 | 14 | |||
1409 | 15 | type SimpleMessage struct { | ||
1410 | 16 | Level loggo.Level | ||
1411 | 17 | Message string | ||
1412 | 18 | } | ||
1413 | 19 | |||
1414 | 20 | type SimpleMessages []SimpleMessage | ||
1415 | 21 | |||
1416 | 22 | func (s SimpleMessage) String() string { | ||
1417 | 23 | return fmt.Sprintf("%s %s", s.Level, s.Message) | ||
1418 | 24 | } | ||
1419 | 25 | |||
1420 | 26 | func (s SimpleMessages) GoString() string { | ||
1421 | 27 | out := make([]string, len(s)) | ||
1422 | 28 | for i, m := range s { | ||
1423 | 29 | out[i] = m.String() | ||
1424 | 30 | } | ||
1425 | 31 | return fmt.Sprintf("SimpleMessages{\n%s\n}", strings.Join(out, "\n")) | ||
1426 | 32 | } | ||
1427 | 33 | |||
1428 | 34 | func logToSimpleMessages(log []loggo.TestLogValues) SimpleMessages { | ||
1429 | 35 | out := make(SimpleMessages, len(log)) | ||
1430 | 36 | for i, val := range log { | ||
1431 | 37 | out[i].Level = val.Level | ||
1432 | 38 | out[i].Message = val.Message | ||
1433 | 39 | } | ||
1434 | 40 | return out | ||
1435 | 41 | } | ||
1436 | 42 | |||
1437 | 43 | type logMatches struct { | ||
1438 | 44 | *gc.CheckerInfo | ||
1439 | 45 | } | ||
1440 | 46 | |||
1441 | 47 | func (checker *logMatches) Check(params []interface{}, names []string) (result bool, error string) { | ||
1442 | 48 | var obtained SimpleMessages | ||
1443 | 49 | switch params[0].(type) { | ||
1444 | 50 | case []loggo.TestLogValues: | ||
1445 | 51 | obtained = logToSimpleMessages(params[0].([]loggo.TestLogValues)) | ||
1446 | 52 | default: | ||
1447 | 53 | return false, "Obtained value must be of type []loggo.TestLogValues or SimpleMessage" | ||
1448 | 54 | } | ||
1449 | 55 | |||
1450 | 56 | var expected SimpleMessages | ||
1451 | 57 | switch param := params[1].(type) { | ||
1452 | 58 | case []SimpleMessage: | ||
1453 | 59 | expected = SimpleMessages(param) | ||
1454 | 60 | case SimpleMessages: | ||
1455 | 61 | expected = param | ||
1456 | 62 | case []string: | ||
1457 | 63 | expected = make(SimpleMessages, len(param)) | ||
1458 | 64 | for i, s := range param { | ||
1459 | 65 | expected[i] = SimpleMessage{ | ||
1460 | 66 | Message: s, | ||
1461 | 67 | Level: loggo.UNSPECIFIED, | ||
1462 | 68 | } | ||
1463 | 69 | } | ||
1464 | 70 | default: | ||
1465 | 71 | return false, "Expected value must be of type []string or []SimpleMessage" | ||
1466 | 72 | } | ||
1467 | 73 | |||
1468 | 74 | obtainedSinceLastMatch := obtained | ||
1469 | 75 | for len(expected) > 0 && len(obtained) >= len(expected) { | ||
1470 | 76 | var msg SimpleMessage | ||
1471 | 77 | msg, obtained = obtained[0], obtained[1:] | ||
1472 | 78 | expect := expected[0] | ||
1473 | 79 | if expect.Level != loggo.UNSPECIFIED && msg.Level != expect.Level { | ||
1474 | 80 | continue | ||
1475 | 81 | } | ||
1476 | 82 | matched, err := regexp.MatchString(expect.Message, msg.Message) | ||
1477 | 83 | if err != nil { | ||
1478 | 84 | return false, fmt.Sprintf("bad message regexp %q: %v", expect.Message, err) | ||
1479 | 85 | } else if !matched { | ||
1480 | 86 | continue | ||
1481 | 87 | } | ||
1482 | 88 | expected = expected[1:] | ||
1483 | 89 | obtainedSinceLastMatch = obtained | ||
1484 | 90 | } | ||
1485 | 91 | if len(obtained) < len(expected) { | ||
1486 | 92 | params[0] = obtainedSinceLastMatch | ||
1487 | 93 | params[1] = expected | ||
1488 | 94 | return false, "" | ||
1489 | 95 | } | ||
1490 | 96 | return true, "" | ||
1491 | 97 | } | ||
1492 | 98 | |||
1493 | 99 | // LogMatches checks whether a given TestLogValues actually contains the log | ||
1494 | 100 | // messages we expected. If you compare it against a list of strings, we only | ||
1495 | 101 | // compare that the strings in the messages are correct. You can alternatively | ||
1496 | 102 | // pass a slice of SimpleMessage and we will check that the log levels are | ||
1497 | 103 | // also correct. | ||
1498 | 104 | // | ||
1499 | 105 | // The log may contain additional messages before and after each of the specified | ||
1500 | 106 | // expected messages. | ||
1501 | 107 | var LogMatches gc.Checker = &logMatches{ | ||
1502 | 108 | &gc.CheckerInfo{Name: "LogMatches", Params: []string{"obtained", "expected"}}, | ||
1503 | 109 | } | ||
1504 | 110 | 0 | ||
1505 | === removed file 'testing/checkers/log_test.go' | |||
1506 | --- testing/checkers/log_test.go 2014-03-13 07:54:56 +0000 | |||
1507 | +++ testing/checkers/log_test.go 1970-01-01 00:00:00 +0000 | |||
1508 | @@ -1,111 +0,0 @@ | |||
1509 | 1 | // Copyright 2013 Canonical Ltd. | ||
1510 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
1511 | 3 | |||
1512 | 4 | package checkers_test | ||
1513 | 5 | |||
1514 | 6 | import ( | ||
1515 | 7 | "github.com/juju/loggo" | ||
1516 | 8 | jc "github.com/juju/testing/checkers" | ||
1517 | 9 | gc "launchpad.net/gocheck" | ||
1518 | 10 | ) | ||
1519 | 11 | |||
1520 | 12 | type LogMatchesSuite struct{} | ||
1521 | 13 | |||
1522 | 14 | var _ = gc.Suite(&LogMatchesSuite{}) | ||
1523 | 15 | |||
1524 | 16 | func (s *LogMatchesSuite) TestMatchSimpleMessage(c *gc.C) { | ||
1525 | 17 | log := []loggo.TestLogValues{ | ||
1526 | 18 | {Level: loggo.INFO, Message: "foo bar"}, | ||
1527 | 19 | {Level: loggo.INFO, Message: "12345"}, | ||
1528 | 20 | } | ||
1529 | 21 | c.Check(log, jc.LogMatches, []jc.SimpleMessage{ | ||
1530 | 22 | {loggo.INFO, "foo bar"}, | ||
1531 | 23 | {loggo.INFO, "12345"}, | ||
1532 | 24 | }) | ||
1533 | 25 | c.Check(log, jc.LogMatches, []jc.SimpleMessage{ | ||
1534 | 26 | {loggo.INFO, "foo .*"}, | ||
1535 | 27 | {loggo.INFO, "12345"}, | ||
1536 | 28 | }) | ||
1537 | 29 | // UNSPECIFIED means we don't care what the level is, | ||
1538 | 30 | // just check the message string matches. | ||
1539 | 31 | c.Check(log, jc.LogMatches, []jc.SimpleMessage{ | ||
1540 | 32 | {loggo.UNSPECIFIED, "foo .*"}, | ||
1541 | 33 | {loggo.INFO, "12345"}, | ||
1542 | 34 | }) | ||
1543 | 35 | c.Check(log, gc.Not(jc.LogMatches), []jc.SimpleMessage{ | ||
1544 | 36 | {loggo.INFO, "foo bar"}, | ||
1545 | 37 | {loggo.DEBUG, "12345"}, | ||
1546 | 38 | }) | ||
1547 | 39 | } | ||
1548 | 40 | |||
1549 | 41 | func (s *LogMatchesSuite) TestMatchStrings(c *gc.C) { | ||
1550 | 42 | log := []loggo.TestLogValues{ | ||
1551 | 43 | {Level: loggo.INFO, Message: "foo bar"}, | ||
1552 | 44 | {Level: loggo.INFO, Message: "12345"}, | ||
1553 | 45 | } | ||
1554 | 46 | c.Check(log, jc.LogMatches, []string{"foo bar", "12345"}) | ||
1555 | 47 | c.Check(log, jc.LogMatches, []string{"foo .*", "12345"}) | ||
1556 | 48 | c.Check(log, gc.Not(jc.LogMatches), []string{"baz", "bing"}) | ||
1557 | 49 | } | ||
1558 | 50 | |||
1559 | 51 | func (s *LogMatchesSuite) TestMatchInexact(c *gc.C) { | ||
1560 | 52 | log := []loggo.TestLogValues{ | ||
1561 | 53 | {Level: loggo.INFO, Message: "foo bar"}, | ||
1562 | 54 | {Level: loggo.INFO, Message: "baz"}, | ||
1563 | 55 | {Level: loggo.DEBUG, Message: "12345"}, | ||
1564 | 56 | {Level: loggo.ERROR, Message: "12345"}, | ||
1565 | 57 | {Level: loggo.INFO, Message: "67890"}, | ||
1566 | 58 | } | ||
1567 | 59 | c.Check(log, jc.LogMatches, []string{"foo bar", "12345"}) | ||
1568 | 60 | c.Check(log, jc.LogMatches, []string{"foo .*", "12345"}) | ||
1569 | 61 | c.Check(log, jc.LogMatches, []string{"foo .*", "67890"}) | ||
1570 | 62 | c.Check(log, jc.LogMatches, []string{"67890"}) | ||
1571 | 63 | |||
1572 | 64 | // Matches are always left-most after the previous match. | ||
1573 | 65 | c.Check(log, jc.LogMatches, []string{".*", "baz"}) | ||
1574 | 66 | c.Check(log, jc.LogMatches, []string{"foo bar", ".*", "12345"}) | ||
1575 | 67 | c.Check(log, jc.LogMatches, []string{"foo bar", ".*", "67890"}) | ||
1576 | 68 | |||
1577 | 69 | // Order is important: 67890 advances to the last item in obtained, | ||
1578 | 70 | // and so there's nothing after to match against ".*". | ||
1579 | 71 | c.Check(log, gc.Not(jc.LogMatches), []string{"67890", ".*"}) | ||
1580 | 72 | // ALL specified patterns MUST match in the order given. | ||
1581 | 73 | c.Check(log, gc.Not(jc.LogMatches), []string{".*", "foo bar"}) | ||
1582 | 74 | |||
1583 | 75 | // Check that levels are matched. | ||
1584 | 76 | c.Check(log, jc.LogMatches, []jc.SimpleMessage{ | ||
1585 | 77 | {loggo.UNSPECIFIED, "12345"}, | ||
1586 | 78 | {loggo.UNSPECIFIED, "12345"}, | ||
1587 | 79 | }) | ||
1588 | 80 | c.Check(log, jc.LogMatches, []jc.SimpleMessage{ | ||
1589 | 81 | {loggo.DEBUG, "12345"}, | ||
1590 | 82 | {loggo.ERROR, "12345"}, | ||
1591 | 83 | }) | ||
1592 | 84 | c.Check(log, jc.LogMatches, []jc.SimpleMessage{ | ||
1593 | 85 | {loggo.DEBUG, "12345"}, | ||
1594 | 86 | {loggo.INFO, ".*"}, | ||
1595 | 87 | }) | ||
1596 | 88 | c.Check(log, gc.Not(jc.LogMatches), []jc.SimpleMessage{ | ||
1597 | 89 | {loggo.DEBUG, "12345"}, | ||
1598 | 90 | {loggo.INFO, ".*"}, | ||
1599 | 91 | {loggo.UNSPECIFIED, ".*"}, | ||
1600 | 92 | }) | ||
1601 | 93 | } | ||
1602 | 94 | |||
1603 | 95 | func (s *LogMatchesSuite) TestFromLogMatches(c *gc.C) { | ||
1604 | 96 | tw := &loggo.TestWriter{} | ||
1605 | 97 | _, err := loggo.ReplaceDefaultWriter(tw) | ||
1606 | 98 | c.Assert(err, gc.IsNil) | ||
1607 | 99 | defer loggo.ResetWriters() | ||
1608 | 100 | logger := loggo.GetLogger("test") | ||
1609 | 101 | logger.SetLogLevel(loggo.DEBUG) | ||
1610 | 102 | logger.Infof("foo") | ||
1611 | 103 | logger.Debugf("bar") | ||
1612 | 104 | logger.Tracef("hidden") | ||
1613 | 105 | c.Check(tw.Log, jc.LogMatches, []string{"foo", "bar"}) | ||
1614 | 106 | c.Check(tw.Log, gc.Not(jc.LogMatches), []string{"foo", "bad"}) | ||
1615 | 107 | c.Check(tw.Log, gc.Not(jc.LogMatches), []jc.SimpleMessage{ | ||
1616 | 108 | {loggo.INFO, "foo"}, | ||
1617 | 109 | {loggo.INFO, "bar"}, | ||
1618 | 110 | }) | ||
1619 | 111 | } | ||
1620 | 112 | 0 | ||
1621 | === removed file 'testing/checkers/relop.go' | |||
1622 | --- testing/checkers/relop.go 2013-09-13 14:48:13 +0000 | |||
1623 | +++ testing/checkers/relop.go 1970-01-01 00:00:00 +0000 | |||
1624 | @@ -1,93 +0,0 @@ | |||
1625 | 1 | // Copyright 2013 Canonical Ltd. | ||
1626 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
1627 | 3 | |||
1628 | 4 | package checkers | ||
1629 | 5 | |||
1630 | 6 | import ( | ||
1631 | 7 | "fmt" | ||
1632 | 8 | "reflect" | ||
1633 | 9 | |||
1634 | 10 | gc "launchpad.net/gocheck" | ||
1635 | 11 | ) | ||
1636 | 12 | |||
1637 | 13 | // GreaterThan checker | ||
1638 | 14 | |||
1639 | 15 | type greaterThanChecker struct { | ||
1640 | 16 | *gc.CheckerInfo | ||
1641 | 17 | } | ||
1642 | 18 | |||
1643 | 19 | var GreaterThan gc.Checker = &greaterThanChecker{ | ||
1644 | 20 | &gc.CheckerInfo{Name: "GreaterThan", Params: []string{"obtained", "expected"}}, | ||
1645 | 21 | } | ||
1646 | 22 | |||
1647 | 23 | func (checker *greaterThanChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
1648 | 24 | defer func() { | ||
1649 | 25 | if v := recover(); v != nil { | ||
1650 | 26 | result = false | ||
1651 | 27 | error = fmt.Sprint(v) | ||
1652 | 28 | } | ||
1653 | 29 | }() | ||
1654 | 30 | |||
1655 | 31 | p0value := reflect.ValueOf(params[0]) | ||
1656 | 32 | p1value := reflect.ValueOf(params[1]) | ||
1657 | 33 | switch p0value.Kind() { | ||
1658 | 34 | case reflect.Int, | ||
1659 | 35 | reflect.Int8, | ||
1660 | 36 | reflect.Int16, | ||
1661 | 37 | reflect.Int32, | ||
1662 | 38 | reflect.Int64: | ||
1663 | 39 | return p0value.Int() > p1value.Int(), "" | ||
1664 | 40 | case reflect.Uint, | ||
1665 | 41 | reflect.Uint8, | ||
1666 | 42 | reflect.Uint16, | ||
1667 | 43 | reflect.Uint32, | ||
1668 | 44 | reflect.Uint64: | ||
1669 | 45 | return p0value.Uint() > p1value.Uint(), "" | ||
1670 | 46 | case reflect.Float32, | ||
1671 | 47 | reflect.Float64: | ||
1672 | 48 | return p0value.Float() > p1value.Float(), "" | ||
1673 | 49 | default: | ||
1674 | 50 | } | ||
1675 | 51 | return false, fmt.Sprintf("obtained value %s:%#v not supported", p0value.Kind(), params[0]) | ||
1676 | 52 | } | ||
1677 | 53 | |||
1678 | 54 | // LessThan checker | ||
1679 | 55 | |||
1680 | 56 | type lessThanChecker struct { | ||
1681 | 57 | *gc.CheckerInfo | ||
1682 | 58 | } | ||
1683 | 59 | |||
1684 | 60 | var LessThan gc.Checker = &lessThanChecker{ | ||
1685 | 61 | &gc.CheckerInfo{Name: "LessThan", Params: []string{"obtained", "expected"}}, | ||
1686 | 62 | } | ||
1687 | 63 | |||
1688 | 64 | func (checker *lessThanChecker) Check(params []interface{}, names []string) (result bool, error string) { | ||
1689 | 65 | defer func() { | ||
1690 | 66 | if v := recover(); v != nil { | ||
1691 | 67 | result = false | ||
1692 | 68 | error = fmt.Sprint(v) | ||
1693 | 69 | } | ||
1694 | 70 | }() | ||
1695 | 71 | |||
1696 | 72 | p0value := reflect.ValueOf(params[0]) | ||
1697 | 73 | p1value := reflect.ValueOf(params[1]) | ||
1698 | 74 | switch p0value.Kind() { | ||
1699 | 75 | case reflect.Int, | ||
1700 | 76 | reflect.Int8, | ||
1701 | 77 | reflect.Int16, | ||
1702 | 78 | reflect.Int32, | ||
1703 | 79 | reflect.Int64: | ||
1704 | 80 | return p0value.Int() < p1value.Int(), "" | ||
1705 | 81 | case reflect.Uint, | ||
1706 | 82 | reflect.Uint8, | ||
1707 | 83 | reflect.Uint16, | ||
1708 | 84 | reflect.Uint32, | ||
1709 | 85 | reflect.Uint64: | ||
1710 | 86 | return p0value.Uint() < p1value.Uint(), "" | ||
1711 | 87 | case reflect.Float32, | ||
1712 | 88 | reflect.Float64: | ||
1713 | 89 | return p0value.Float() < p1value.Float(), "" | ||
1714 | 90 | default: | ||
1715 | 91 | } | ||
1716 | 92 | return false, fmt.Sprintf("obtained value %s:%#v not supported", p0value.Kind(), params[0]) | ||
1717 | 93 | } | ||
1718 | 94 | 0 | ||
1719 | === removed file 'testing/checkers/relop_test.go' | |||
1720 | --- testing/checkers/relop_test.go 2014-03-13 07:54:56 +0000 | |||
1721 | +++ testing/checkers/relop_test.go 1970-01-01 00:00:00 +0000 | |||
1722 | @@ -1,35 +0,0 @@ | |||
1723 | 1 | // Copyright 2013 Canonical Ltd. | ||
1724 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
1725 | 3 | |||
1726 | 4 | package checkers_test | ||
1727 | 5 | |||
1728 | 6 | import ( | ||
1729 | 7 | jc "github.com/juju/testing/checkers" | ||
1730 | 8 | gc "launchpad.net/gocheck" | ||
1731 | 9 | ) | ||
1732 | 10 | |||
1733 | 11 | type RelopSuite struct{} | ||
1734 | 12 | |||
1735 | 13 | var _ = gc.Suite(&RelopSuite{}) | ||
1736 | 14 | |||
1737 | 15 | func (s *RelopSuite) TestGreaterThan(c *gc.C) { | ||
1738 | 16 | c.Assert(45, jc.GreaterThan, 42) | ||
1739 | 17 | c.Assert(2.25, jc.GreaterThan, 1.0) | ||
1740 | 18 | c.Assert(42, gc.Not(jc.GreaterThan), 42) | ||
1741 | 19 | c.Assert(10, gc.Not(jc.GreaterThan), 42) | ||
1742 | 20 | |||
1743 | 21 | result, msg := jc.GreaterThan.Check([]interface{}{"Hello", "World"}, nil) | ||
1744 | 22 | c.Assert(result, jc.IsFalse) | ||
1745 | 23 | c.Assert(msg, gc.Equals, `obtained value string:"Hello" not supported`) | ||
1746 | 24 | } | ||
1747 | 25 | |||
1748 | 26 | func (s *RelopSuite) TestLessThan(c *gc.C) { | ||
1749 | 27 | c.Assert(42, jc.LessThan, 45) | ||
1750 | 28 | c.Assert(1.0, jc.LessThan, 2.25) | ||
1751 | 29 | c.Assert(42, gc.Not(jc.LessThan), 42) | ||
1752 | 30 | c.Assert(42, gc.Not(jc.LessThan), 10) | ||
1753 | 31 | |||
1754 | 32 | result, msg := jc.LessThan.Check([]interface{}{"Hello", "World"}, nil) | ||
1755 | 33 | c.Assert(result, jc.IsFalse) | ||
1756 | 34 | c.Assert(msg, gc.Equals, `obtained value string:"Hello" not supported`) | ||
1757 | 35 | } | ||
1758 | 36 | 0 | ||
1759 | === modified file 'worker/instancepoller/aggregate_test.go' | |||
1760 | --- worker/instancepoller/aggregate_test.go 2014-03-13 18:40:06 +0000 | |||
1761 | +++ worker/instancepoller/aggregate_test.go 2014-03-18 02:58:54 +0000 | |||
1762 | @@ -9,12 +9,12 @@ | |||
1763 | 9 | "sync/atomic" | 9 | "sync/atomic" |
1764 | 10 | "time" | 10 | "time" |
1765 | 11 | 11 | ||
1766 | 12 | jc "github.com/juju/testing/checkers" | ||
1767 | 12 | gc "launchpad.net/gocheck" | 13 | gc "launchpad.net/gocheck" |
1768 | 13 | 14 | ||
1769 | 14 | "launchpad.net/juju-core/environs" | 15 | "launchpad.net/juju-core/environs" |
1770 | 15 | "launchpad.net/juju-core/errors" | 16 | "launchpad.net/juju-core/errors" |
1771 | 16 | "launchpad.net/juju-core/instance" | 17 | "launchpad.net/juju-core/instance" |
1772 | 17 | jc "launchpad.net/juju-core/testing/checkers" | ||
1773 | 18 | "launchpad.net/juju-core/testing/testbase" | 18 | "launchpad.net/juju-core/testing/testbase" |
1774 | 19 | ) | 19 | ) |
1775 | 20 | 20 |
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): checkers/ bool.go checkers/ bool_test. go checkers/ checker. go checkers/ checker_ test.go checkers/ deepequal. go checkers/ deepequal_ test.go checkers/ file.go checkers/ file_test. go checkers/ log.go checkers/ log_test. go checkers/ relop.go checkers/ relop_test. go
A [revision details]
D testing/
D testing/
D testing/
D testing/
D testing/
D testing/
D testing/
D testing/
D testing/
D testing/
D testing/
D testing/