lookout 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README +10 -7
- data/Rakefile +1 -5
- data/lib/lookout-3.0/version.rb +16 -4
- metadata +248 -243
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bb581b92138321c4bd16f652fc409144819e8e8
|
4
|
+
data.tar.gz: 98671835586ef400221e6dd5027930bdfab4ab11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2cacea2da550247f2dcfb709c0b830054c54fca2f229b8095a49ede2454337e4fc39f24e8e96140158d66afcb5bd931f53b0601dc9d32bdb5ff762e52a124fb
|
7
|
+
data.tar.gz: 3a2aa060d044b736609987c5604e5868d7afbdc6ea023023bbfa493e35571593a2f3cc01d8d1cd5749be2248698e0982cf4265c846287c3db69d41c634208f3d
|
data/README
CHANGED
@@ -666,8 +666,8 @@
|
|
666
666
|
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
|
667
667
|
² Read how 37signals had problems with slow Test::Unit tests at
|
668
668
|
http://37signals.com/svn/posts/2742-the-road-to-faster-tests/
|
669
|
-
³ Visit the Lookout-rack
|
670
|
-
http://
|
669
|
+
³ Visit the Lookout-rack home page at
|
670
|
+
http://disu.se/software/lookout-rack/
|
671
671
|
⁴ Visit the Rack Rubyforge project page at
|
672
672
|
http://rack.rubyforge.org/
|
673
673
|
|
@@ -812,7 +812,7 @@
|
|
812
812
|
donation to now@disu.se¹. Thanks! Your support won’t go unnoticed!
|
813
813
|
|
814
814
|
¹ Send a donation:
|
815
|
-
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=now%40disu%2ese&item_name=
|
815
|
+
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=now%40disu%2ese&item_name=Lookout
|
816
816
|
|
817
817
|
§ Reporting Bugs
|
818
818
|
|
@@ -830,9 +830,12 @@
|
|
830
830
|
|
831
831
|
¹ Add an issue to the Lookout issue tracker at https://github.com/now/lookout/issues
|
832
832
|
|
833
|
-
§
|
833
|
+
§ Licensing
|
834
834
|
|
835
|
-
|
836
|
-
|
835
|
+
Lookout is free software: you may redistribute it and/or modify it under
|
836
|
+
the terms of the {GNU Lesser General Public License, version 3}¹ or later²,
|
837
|
+
as published by the {Free Software Foundation}³.
|
837
838
|
|
838
|
-
¹
|
839
|
+
¹ See http://disu.se/licenses/lgpl-3.0/
|
840
|
+
² See http://gnu.org/licenses/
|
841
|
+
³ See http://fsf.org/
|
data/Rakefile
CHANGED
@@ -4,11 +4,7 @@ require 'inventory-rake-1.0'
|
|
4
4
|
|
5
5
|
load File.expand_path('../lib/lookout-3.0/version.rb', __FILE__)
|
6
6
|
|
7
|
-
Inventory::Rake::Tasks.define Lookout::Version
|
8
|
-
s.author = 'Nikolai Weibull'
|
9
|
-
s.email = 'now@bitwi.se'
|
10
|
-
s.homepage = 'https://github.com/now/lookout'
|
11
|
-
}
|
7
|
+
Inventory::Rake::Tasks.define Lookout::Version
|
12
8
|
|
13
9
|
Inventory::Rake::Tasks.unless_installing_dependencies do
|
14
10
|
require 'lookout-rake-3.0'
|
data/lib/lookout-3.0/version.rb
CHANGED
@@ -3,12 +3,24 @@
|
|
3
3
|
require 'inventory-1.0'
|
4
4
|
|
5
5
|
module Lookout
|
6
|
-
Version = Inventory.new(3, 0,
|
6
|
+
Version = Inventory.new(3, 0, 1){
|
7
|
+
authors{
|
8
|
+
author 'Nikolai Weibull', 'now@disu.se'
|
9
|
+
}
|
10
|
+
|
11
|
+
homepage 'http://disu.se/software/lookout'
|
12
|
+
|
13
|
+
licenses{
|
14
|
+
license 'LGPLv3+',
|
15
|
+
'GNU Lesser General Public License, version 3 or later',
|
16
|
+
'http://www.gnu.org/licenses/'
|
17
|
+
}
|
18
|
+
|
7
19
|
def dependencies
|
8
20
|
super + Inventory::Dependencies.new{
|
9
|
-
development 'inventory-rake', 1,
|
10
|
-
development 'inventory-rake-tasks-yard', 1,
|
11
|
-
development 'lookout-rake', 3,
|
21
|
+
development 'inventory-rake', 1, 6, 0
|
22
|
+
development 'inventory-rake-tasks-yard', 1, 4, 0
|
23
|
+
development 'lookout-rake', 3, 1, 0
|
12
24
|
development 'yard', 0, 8, 0
|
13
25
|
development 'yard-heuristics', 1, 1, 0
|
14
26
|
development 'yard-value', 1, 2, 0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lookout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikolai Weibull
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04
|
11
|
+
date: 2013-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inventory
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: inventory-rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.6'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: inventory-rake-tasks-yard
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '1.
|
47
|
+
version: '1.4'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '1.
|
54
|
+
version: '1.4'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: lookout-rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '3.
|
61
|
+
version: '3.1'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '3.
|
68
|
+
version: '3.1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,7 +125,7 @@ dependencies:
|
|
125
125
|
description: |2
|
126
126
|
Lookout
|
127
127
|
|
128
|
-
Lookout is a unit testing framework for Ruby
|
128
|
+
Lookout is a unit testing framework for Ruby┬╣ that puts your results in
|
129
129
|
focus. Tests (expectations) are written as follows
|
130
130
|
|
131
131
|
expect 2 do
|
@@ -144,55 +144,55 @@ description: |2
|
|
144
144
|
[1, 2, 3].map{ |i| i * 2 }
|
145
145
|
end
|
146
146
|
|
147
|
-
Lookout is designed to encourage
|
147
|
+
Lookout is designed to encourage ΓÇô force, even ΓÇô unit testing best practices
|
148
148
|
such as
|
149
149
|
|
150
|
-
|
151
|
-
|
152
|
-
|
150
|
+
ΓÇó Setting up only one expectation per test
|
151
|
+
ΓÇó Not setting expectations on non-public APIs
|
152
|
+
ΓÇó Test isolation
|
153
153
|
|
154
154
|
This is done by
|
155
155
|
|
156
|
-
|
157
|
-
|
158
|
-
|
156
|
+
ΓÇó Only allowing one expectation to be set per test
|
157
|
+
ΓÇó Providing no (additional) way of accessing private state
|
158
|
+
ΓÇó Providing no setup and tear-down methods, nor a method of providing test
|
159
159
|
helpers
|
160
160
|
|
161
161
|
Other important points are
|
162
162
|
|
163
|
-
|
163
|
+
ΓÇó Putting the expected outcome of a test in focus with the steps of the
|
164
164
|
calculation of the actual result only as a secondary concern
|
165
|
-
|
165
|
+
ΓÇó A focus on code readability by providing no mechanism for describing an
|
166
166
|
expectation other than the code in the expectation itself
|
167
|
-
|
167
|
+
ΓÇó A unified syntax for setting up both state-based and behavior-based
|
168
168
|
expectations
|
169
169
|
|
170
|
-
The way Lookout works has been heavily influenced by expectations
|
171
|
-
{Jay Fields}
|
172
|
-
based at Subversion {revision 76}
|
173
|
-
the work past that revision are due to {Nikolai Weibull}
|
170
|
+
The way Lookout works has been heavily influenced by expectations┬▓, by
|
171
|
+
{Jay Fields}┬│. The code base was once also heavily based on expectations,
|
172
|
+
based at Subversion {revision 76}⁴. A lot has happened since then and all of
|
173
|
+
the work past that revision are due to {Nikolai Weibull}⁵.
|
174
174
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
175
|
+
┬╣ Ruby: http://ruby-lang.org/
|
176
|
+
┬▓ Expectations: http://expectations.rubyforge.org/
|
177
|
+
┬│ Jay FieldsΓÇÖs blog: http://blog.jayfields.com/
|
178
|
+
⁴ Lookout revision 76:
|
179
179
|
https://github.com/now/lookout/commit/537bedf3e5b3eb4b31c066b3266f42964ac35ebe
|
180
|
-
|
180
|
+
⁵ Nikolai Weibull’s home page: http://disu.se/
|
181
181
|
|
182
|
-
|
182
|
+
§ Installation
|
183
183
|
|
184
184
|
Install Lookout with
|
185
185
|
|
186
186
|
% gem install lookout
|
187
187
|
|
188
188
|
|
189
|
-
|
189
|
+
§ Usage
|
190
190
|
|
191
|
-
Lookout allows you to set expectations on an object
|
192
|
-
We
|
191
|
+
Lookout allows you to set expectations on an objectΓÇÖs state or behavior.
|
192
|
+
WeΓÇÖll begin by looking at state expectations and then take a look at
|
193
193
|
expectations on behavior.
|
194
194
|
|
195
|
-
|
195
|
+
§ Expectations on State: Literals
|
196
196
|
|
197
197
|
An expectation can be made on the result of a computation:
|
198
198
|
|
@@ -201,7 +201,7 @@ description: |2
|
|
201
201
|
end
|
202
202
|
|
203
203
|
Most objects, in fact, have their state expectations checked by invoking
|
204
|
-
|
204
|
+
‹#==› on the expected value with the result as its argument.
|
205
205
|
|
206
206
|
Checking that a result is within a given range is also simple:
|
207
207
|
|
@@ -209,29 +209,29 @@ description: |2
|
|
209
209
|
0.4 - 0.3
|
210
210
|
end
|
211
211
|
|
212
|
-
Here, the more general
|
212
|
+
Here, the more general ‹#===› is being used on the ‹Range›.
|
213
213
|
|
214
|
-
|
214
|
+
§ Regexps
|
215
215
|
|
216
|
-
|
216
|
+
‹Strings› of course match against ‹Strings›:
|
217
217
|
|
218
218
|
expect 'ab' do
|
219
219
|
'abc'[0..1]
|
220
220
|
end
|
221
221
|
|
222
|
-
but we can also match a
|
222
|
+
but we can also match a ‹String› against a ‹Regexp›:
|
223
223
|
|
224
224
|
expect %r{a substring} do
|
225
225
|
'a string with a substring'
|
226
226
|
end
|
227
227
|
|
228
|
-
(Note the use of
|
229
|
-
Ruby parses
|
228
|
+
(Note the use of ‹%r{…}› to avoid warnings that will be generated when
|
229
|
+
Ruby parses ‹expect /…/›.)
|
230
230
|
|
231
|
-
|
231
|
+
§ Modules
|
232
232
|
|
233
233
|
Checking that the result includes a certain module is done by expecting the
|
234
|
-
|
234
|
+
‹Module›.
|
235
235
|
|
236
236
|
expect Enumerable do
|
237
237
|
[]
|
@@ -244,13 +244,13 @@ description: |2
|
|
244
244
|
'a string'
|
245
245
|
end
|
246
246
|
|
247
|
-
This doesn
|
247
|
+
This doesn’t hinder us from expecting the actual ‹Module› itself:
|
248
248
|
|
249
249
|
expect Enumerable do
|
250
250
|
Enumerable
|
251
251
|
end
|
252
252
|
|
253
|
-
or the
|
253
|
+
or the ‹Class›:
|
254
254
|
|
255
255
|
expect String do
|
256
256
|
String
|
@@ -259,12 +259,12 @@ description: |2
|
|
259
259
|
for obvious reasons.
|
260
260
|
|
261
261
|
As you may have figured out yourself, this is accomplished by first
|
262
|
-
trying
|
263
|
-
expected
|
262
|
+
trying ‹#==› and, if it returns ‹false›, then trying ‹#===› on the
|
263
|
+
expected ‹Module›. This is also true of ‹Ranges› and ‹Regexps›.
|
264
264
|
|
265
|
-
|
265
|
+
§ Booleans
|
266
266
|
|
267
|
-
Truthfulness is expected with
|
267
|
+
Truthfulness is expected with ‹true› and ‹false›:
|
268
268
|
|
269
269
|
expect true do
|
270
270
|
1
|
@@ -274,7 +274,7 @@ description: |2
|
|
274
274
|
nil
|
275
275
|
end
|
276
276
|
|
277
|
-
Results equaling
|
277
|
+
Results equaling ‹true› or ‹false› are slightly different:
|
278
278
|
|
279
279
|
expect TrueClass do
|
280
280
|
true
|
@@ -286,9 +286,9 @@ description: |2
|
|
286
286
|
|
287
287
|
The rationale for this is that you should only care if the result of a
|
288
288
|
computation evaluates to a value that Ruby considers to be either true or
|
289
|
-
false, not the exact literals
|
289
|
+
false, not the exact literals ‹true› or ‹false›.
|
290
290
|
|
291
|
-
|
291
|
+
§ IO
|
292
292
|
|
293
293
|
Expecting output on an IO object is also common:
|
294
294
|
|
@@ -299,9 +299,9 @@ description: |2
|
|
299
299
|
This can be used to capture the output of a formatter that takes an
|
300
300
|
output object as a parameter.
|
301
301
|
|
302
|
-
|
302
|
+
§ Warnings
|
303
303
|
|
304
|
-
Expecting warnings from code isn
|
304
|
+
Expecting warnings from code isnΓÇÖt very common, but should be done:
|
305
305
|
|
306
306
|
expect warning('this is your final one!') do
|
307
307
|
warn 'this is your final one!'
|
@@ -311,9 +311,9 @@ description: |2
|
|
311
311
|
warn '%s:%d: warning: this is your final one!' % [__FILE__, __LINE__]
|
312
312
|
end
|
313
313
|
|
314
|
-
|
315
|
-
don
|
316
|
-
value of $VERBOSE, that can be done with
|
314
|
+
‹$VERBOSE› is set to ‹true› during the execution of the block, so you
|
315
|
+
donΓÇÖt need to do so yourself. If you have other code that depends on the
|
316
|
+
value of $VERBOSE, that can be done with ‹#with_verbose›
|
317
317
|
|
318
318
|
expect nil do
|
319
319
|
with_verbose nil do
|
@@ -321,10 +321,10 @@ description: |2
|
|
321
321
|
end
|
322
322
|
end
|
323
323
|
|
324
|
-
|
324
|
+
§ Errors
|
325
325
|
|
326
|
-
You should always be expecting errors from
|
327
|
-
different story
|
326
|
+
You should always be expecting errors from ΓÇô and in, but thatΓÇÖs a
|
327
|
+
different story ΓÇô your code:
|
328
328
|
|
329
329
|
expect ArgumentError do
|
330
330
|
Integer('1 + 1')
|
@@ -337,25 +337,25 @@ description: |2
|
|
337
337
|
raise StandardError.new('message')
|
338
338
|
end
|
339
339
|
|
340
|
-
As with
|
340
|
+
As with ‹Strings›, ‹Regexps› can be used to check the error description:
|
341
341
|
|
342
342
|
expect StandardError.new(/mess/) do
|
343
343
|
raise StandardError.new('message')
|
344
344
|
end
|
345
345
|
|
346
|
-
|
346
|
+
§ Queries Through Symbols
|
347
347
|
|
348
348
|
Symbols are generally matched against symbols, but as a special case,
|
349
|
-
symbols ending with
|
349
|
+
symbols ending with ‹?› are seen as expectations on the result of query
|
350
350
|
methods on the result of the block, given that the method is of zero
|
351
|
-
arity and that the result isn
|
352
|
-
ending with
|
351
|
+
arity and that the result isnΓÇÖt a Symbol itself. Simply expect a symbol
|
352
|
+
ending with ‹?›:
|
353
353
|
|
354
354
|
expect :empty? do
|
355
355
|
[]
|
356
356
|
end
|
357
357
|
|
358
|
-
To expect it
|
358
|
+
To expect it’s negation, expect the same symbol beginning with ‹not_›:
|
359
359
|
|
360
360
|
expect :not_nil? do
|
361
361
|
[1, 2, 3]
|
@@ -374,19 +374,19 @@ description: |2
|
|
374
374
|
end
|
375
375
|
|
376
376
|
but provides much clearer failure messages. It also makes the
|
377
|
-
expectation
|
377
|
+
expectationΓÇÖs intent a lot clearer.
|
378
378
|
|
379
|
-
|
379
|
+
§ Queries By Proxy
|
380
380
|
|
381
|
-
There
|
381
|
+
ThereΓÇÖs also a way to make the expectations of query methods explicit by
|
382
382
|
invoking methods on the result of the block. For example, to check that
|
383
|
-
the even elements of the Array
|
383
|
+
the even elements of the Array ‹[1, 2, 3]› include ‹1› you could write
|
384
384
|
|
385
385
|
expect result.to.include? 1 do
|
386
386
|
[1, 2, 3].reject{ |e| e.even? }
|
387
387
|
end
|
388
388
|
|
389
|
-
You could likewise check that the result doesn
|
389
|
+
You could likewise check that the result doesnΓÇÖt include 2:
|
390
390
|
|
391
391
|
expect result.not.to.include? 2 do
|
392
392
|
[1, 2, 3].reject{ |e| e.even? }
|
@@ -399,34 +399,34 @@ description: |2
|
|
399
399
|
end
|
400
400
|
|
401
401
|
but provides much clearer failure messages. Given that these two last
|
402
|
-
examples would fail, you
|
403
|
-
instead of the terser
|
402
|
+
examples would fail, youΓÇÖd get a message saying ΓÇ£[1, 2, 3]#include?(2)ΓÇ¥
|
403
|
+
instead of the terser ΓÇ£trueΓëáfalseΓÇ¥. It also clearly separates the actual
|
404
404
|
expectation from the set-up.
|
405
405
|
|
406
|
-
The keyword for this kind of expectations is
|
406
|
+
The keyword for this kind of expectations is ‹result›. This may be
|
407
407
|
followed by any of the methods
|
408
408
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
409
|
+
• ‹#not›
|
410
|
+
• ‹#to›
|
411
|
+
• ‹#be›
|
412
|
+
• ‹#have›
|
413
413
|
|
414
414
|
or any other method you will want to call on the result. The methods
|
415
|
-
|
416
|
-
|
415
|
+
‹#to›, ‹#be›, and ‹#have› do nothing except improve readability. The
|
416
|
+
‹#not› method inverts the expectation.
|
417
417
|
|
418
|
-
|
418
|
+
§ Literal Literals
|
419
419
|
|
420
420
|
If you need to literally check against any of the types of objects
|
421
421
|
otherwise treated specially, that is, any instances of
|
422
422
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
423
|
+
• ‹Module›
|
424
|
+
• ‹Range›
|
425
|
+
• ‹Regexp›
|
426
|
+
• ‹Exception›
|
427
|
+
• ‹Symbol›, given that it ends with ‹?›
|
428
428
|
|
429
|
-
you can do so by wrapping it in
|
429
|
+
you can do so by wrapping it in ‹literal(…)›:
|
430
430
|
|
431
431
|
expect literal(:empty?) do
|
432
432
|
:empty?
|
@@ -435,7 +435,7 @@ description: |2
|
|
435
435
|
You almost never need to do this, as, for all but symbols, instances will
|
436
436
|
match accordingly as well.
|
437
437
|
|
438
|
-
|
438
|
+
§ Expectations on Behavior
|
439
439
|
|
440
440
|
We expect our objects to be on their best behavior. Lookout allows you
|
441
441
|
to make sure that they are.
|
@@ -447,15 +447,15 @@ description: |2
|
|
447
447
|
o.to_str
|
448
448
|
end
|
449
449
|
|
450
|
-
Here,
|
450
|
+
Here, ‹#mock› creates a mock object, an object that doesn’t respond to
|
451
451
|
anything unless you tell it to. We tell it to expect to receive a call
|
452
|
-
to
|
452
|
+
to ‹#to_str› without arguments and have ‹#to_str› return ‹'123'› when
|
453
453
|
called. The mock object is then passed in to the block so that the
|
454
454
|
expectations placed upon it can be fulfilled.
|
455
455
|
|
456
456
|
Sometimes we only want to make sure that a method is called in the way
|
457
|
-
that we expect it to be, but we don
|
458
|
-
called on the object. A stub object, created with
|
457
|
+
that we expect it to be, but we donΓÇÖt care if any other methods are
|
458
|
+
called on the object. A stub object, created with ‹#stub›, expects any
|
459
459
|
method and returns a stub object that, again, expects any method, and
|
460
460
|
thus fits the bill.
|
461
461
|
|
@@ -463,30 +463,30 @@ description: |2
|
|
463
463
|
o.to_str if o.convertable?
|
464
464
|
end
|
465
465
|
|
466
|
-
You don
|
466
|
+
You donΓÇÖt have to use a mock object to verify that a method is called:
|
467
467
|
|
468
468
|
expect Object.to.receive.name do
|
469
469
|
Object.name
|
470
470
|
end
|
471
471
|
|
472
472
|
As you have figured out by now, the expected method call is set up by
|
473
|
-
calling
|
473
|
+
calling ‹#receive› after ‹#to›. ‹#Receive› is followed by a call to the
|
474
474
|
method to expect with any expected arguments. The body of the expected
|
475
475
|
method can be given as the block to the method. Finally, an expected
|
476
|
-
invocation count may follow the method. Let
|
476
|
+
invocation count may follow the method. LetΓÇÖs look at this formal
|
477
477
|
specification in more detail.
|
478
478
|
|
479
|
-
The expected method arguments may be given in a variety of ways. Let
|
479
|
+
The expected method arguments may be given in a variety of ways. LetΓÇÖs
|
480
480
|
introduce them by giving some examples:
|
481
481
|
|
482
482
|
expect mock.to.receive.a do |m|
|
483
483
|
m.a
|
484
484
|
end
|
485
485
|
|
486
|
-
Here, the method
|
486
|
+
Here, the method ‹#a› must be called with any number of arguments. It
|
487
487
|
may be called any number of times, but it must be called at least once.
|
488
488
|
|
489
|
-
If a method must receive exactly one argument, you can use
|
489
|
+
If a method must receive exactly one argument, you can use ‹Object›, as
|
490
490
|
the same matching rules apply for arguments as they do for state
|
491
491
|
expectations:
|
492
492
|
|
@@ -501,24 +501,24 @@ description: |2
|
|
501
501
|
end
|
502
502
|
|
503
503
|
Again, the same matching rules apply for arguments as they do for state
|
504
|
-
expectations, so the previous example expects a call to
|
505
|
-
or the Range 1..2 as an argument on
|
504
|
+
expectations, so the previous example expects a call to ‹#a› with 1, 2,
|
505
|
+
or the Range 1..2 as an argument on ‹m›.
|
506
506
|
|
507
507
|
If a method must be invoked without any arguments you can use
|
508
|
-
|
508
|
+
‹without_arguments›:
|
509
509
|
|
510
510
|
expect mock.to.receive.a(without_arguments) do |m|
|
511
511
|
m.a
|
512
512
|
end
|
513
513
|
|
514
|
-
You can of course use both
|
514
|
+
You can of course use both ‹Object› and actual arguments:
|
515
515
|
|
516
516
|
expect mock.to.receive.a(Object, 2, Object) do |m|
|
517
517
|
m.a nil, 2, '3'
|
518
518
|
end
|
519
519
|
|
520
520
|
The body of the expected method may be given as the block. Here, calling
|
521
|
-
|
521
|
+
‹#a› on ‹m› will give the result ‹1›:
|
522
522
|
|
523
523
|
expect mock.to.receive.a{ 1 } do |m|
|
524
524
|
raise 'not 1' unless m.a == 1
|
@@ -526,7 +526,7 @@ description: |2
|
|
526
526
|
|
527
527
|
If no body has been given, the result will be a stub object.
|
528
528
|
|
529
|
-
To take a block, grab a block parameter and
|
529
|
+
To take a block, grab a block parameter and ‹#call› it:
|
530
530
|
|
531
531
|
expect mock.to.receive.a{ |&b| b.call(1) } do |m|
|
532
532
|
j = 0
|
@@ -534,34 +534,34 @@ description: |2
|
|
534
534
|
raise 'not 1' unless j == 1
|
535
535
|
end
|
536
536
|
|
537
|
-
To simulate an
|
537
|
+
To simulate an ‹#each›-like method, ‹#call› the block several times.
|
538
538
|
|
539
539
|
Invocation count expectations can be set if the default expectation of
|
540
|
-
|
540
|
+
ΓÇ£at least onceΓÇ¥ isnΓÇÖt good enough. The following expectations are
|
541
541
|
possible
|
542
542
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
543
|
+
• ‹#at_most_once›
|
544
|
+
• ‹#once›
|
545
|
+
• ‹#at_least_once›
|
546
|
+
• ‹#twice›
|
547
547
|
|
548
|
-
And, for a given
|
548
|
+
And, for a given ‹N›,
|
549
549
|
|
550
|
-
|
551
|
-
|
552
|
-
|
550
|
+
• ‹#at_most(N)›
|
551
|
+
• ‹#exactly(N)›
|
552
|
+
• ‹#at_least(N)›
|
553
553
|
|
554
|
-
|
554
|
+
§ Utilities: Stubs
|
555
555
|
|
556
556
|
Method stubs are another useful thing to have in a unit testing
|
557
557
|
framework. Sometimes you need to override a method that does something a
|
558
|
-
test shouldn
|
559
|
-
|
560
|
-
have an
|
561
|
-
|
562
|
-
|
563
|
-
test we want to make sure that
|
564
|
-
accessing the database. We therefore stub out
|
558
|
+
test shouldnΓÇÖt do, like access and alter bank accounts. We can override
|
559
|
+
– stub out – a method by using the ‹#stub› method. Let’s assume that we
|
560
|
+
have an ‹Account› class that has two methods, ‹#slips› and ‹#total›.
|
561
|
+
‹#Slips› retrieves the bank slips that keep track of your deposits to the
|
562
|
+
‹Account› from a database. ‹#Total› sums the ‹#slips›. In the following
|
563
|
+
test we want to make sure that ‹#total› does what it should do without
|
564
|
+
accessing the database. We therefore stub out ‹#slips› and make it
|
565
565
|
return something that we can easily control.
|
566
566
|
|
567
567
|
expect 6 do |m|
|
@@ -576,7 +576,7 @@ description: |2
|
|
576
576
|
}.new, :slips => [1, 2, 3]){ |account| account.total }
|
577
577
|
end
|
578
578
|
|
579
|
-
To make it easy to create objects with a set of stubbed methods there
|
579
|
+
To make it easy to create objects with a set of stubbed methods thereΓÇÖs
|
580
580
|
also a convenience method:
|
581
581
|
|
582
582
|
expect 3 do
|
@@ -611,10 +611,10 @@ description: |2
|
|
611
611
|
|
612
612
|
The stub is active during the execution of the block.
|
613
613
|
|
614
|
-
|
614
|
+
§ Overriding Constants
|
615
615
|
|
616
616
|
Sometimes you need to override the value of a constant during the
|
617
|
-
execution of some code. Use
|
617
|
+
execution of some code. Use ‹#with_const› to do just that:
|
618
618
|
|
619
619
|
expect 'hello' do
|
620
620
|
with_const 'A::B::C', 'hello' do
|
@@ -622,19 +622,19 @@ description: |2
|
|
622
622
|
end
|
623
623
|
end
|
624
624
|
|
625
|
-
Here, the constant
|
626
|
-
the block. None of the constants
|
627
|
-
this to work. If a constant doesn
|
628
|
-
empty,
|
629
|
-
block returns and any constants that didn
|
625
|
+
Here, the constant ‹A::B::C› is set to ‹'hello'› during the execution of
|
626
|
+
the block. None of the constants ‹A›, ‹B›, and ‹C› need to exist for
|
627
|
+
this to work. If a constant doesnΓÇÖt exist itΓÇÖs created and set to a new,
|
628
|
+
empty, ‹Module›. The value of ‹A::B::C›, if any, is restored after the
|
629
|
+
block returns and any constants that didnΓÇÖt previously exist are removed.
|
630
630
|
|
631
|
-
|
631
|
+
§ Overriding Environment Variables
|
632
632
|
|
633
633
|
Another thing you often need to control in your tests is the value of
|
634
634
|
environment variables. Depending on such global values is, of course,
|
635
635
|
not a good practice, but is often unavoidable when working with external
|
636
|
-
libraries.
|
637
|
-
variables during the execution of a block by giving it a
|
636
|
+
libraries. ‹#With_env› allows you to override the value of environment
|
637
|
+
variables during the execution of a block by giving it a ‹Hash› of
|
638
638
|
key/value pairs where the key is the name of the environment variable and
|
639
639
|
the value is the value that it should have during the execution of that
|
640
640
|
block:
|
@@ -645,10 +645,10 @@ description: |2
|
|
645
645
|
end
|
646
646
|
end
|
647
647
|
|
648
|
-
Any overridden values are restored and any keys that weren
|
648
|
+
Any overridden values are restored and any keys that werenΓÇÖt previously a
|
649
649
|
part of the environment are removed when the block returns.
|
650
650
|
|
651
|
-
|
651
|
+
§ Overriding Globals
|
652
652
|
|
653
653
|
You may also want to override the value of a global temporarily:
|
654
654
|
|
@@ -669,9 +669,9 @@ description: |2
|
|
669
669
|
end
|
670
670
|
end
|
671
671
|
|
672
|
-
|
672
|
+
§ Integration
|
673
673
|
|
674
|
-
Lookout can be used from Rake
|
674
|
+
Lookout can be used from Rake┬╣. Simply install Lookout-Rake┬▓:
|
675
675
|
|
676
676
|
% gem install lookout-rake
|
677
677
|
|
@@ -684,17 +684,17 @@ description: |2
|
|
684
684
|
Make sure to read up on using Lookout-Rake for further benefits and
|
685
685
|
customization.
|
686
686
|
|
687
|
-
|
688
|
-
|
687
|
+
┬╣ Read more about Rake at http://rake.rubyforge.org/
|
688
|
+
┬▓ Get information on Lookout-Rake at http://disu.se/software/lookout-rake/
|
689
689
|
|
690
|
-
|
690
|
+
§ API
|
691
691
|
|
692
|
-
Lookout comes with an API
|
692
|
+
Lookout comes with an API┬╣ that letΓÇÖs you create things such as new
|
693
693
|
expected values, difference reports for your types, and so on.
|
694
694
|
|
695
|
-
|
695
|
+
┬╣ See http://disu.se/software/lookout/api/
|
696
696
|
|
697
|
-
|
697
|
+
§ Interface Design
|
698
698
|
|
699
699
|
The default output of Lookout can Spartanly be described as Spartan. If no
|
700
700
|
errors or failures occur, no output is generated. This is unconventional,
|
@@ -703,44 +703,44 @@ description: |2
|
|
703
703
|
colored text telling you that your tests passed. None of this output is
|
704
704
|
needed. Your tests should run fast enough to not require progress reports.
|
705
705
|
The lack of output provides you with the same amount of information as
|
706
|
-
reporting success. Test count summaries are only useful if you
|
707
|
-
that your tests aren
|
708
|
-
providing such output doesn
|
706
|
+
reporting success. Test count summaries are only useful if youΓÇÖre worried
|
707
|
+
that your tests arenΓÇÖt being run, but if you worry about that, then
|
708
|
+
providing such output doesnΓÇÖt really help. Testing your tests requires
|
709
709
|
something beyond reporting some arbitrary count that you would have to
|
710
710
|
verify by hand anyway.
|
711
711
|
|
712
712
|
When errors or failures do occur, however, the relevant information is
|
713
|
-
output in a format that can easily be parsed by an
|
714
|
-
or with {Compilation Mode}
|
713
|
+
output in a format that can easily be parsed by an ‹'errorformat'› for Vim
|
714
|
+
or with {Compilation Mode}┬╣ for Emacs┬▓. Diffs are generated for Strings,
|
715
715
|
Arrays, Hashes, and I/O.
|
716
716
|
|
717
|
-
|
718
|
-
|
717
|
+
┬╣ Read up on Compilation mode for Emacs at http://www.emacswiki.org/emacs/CompilationMode
|
718
|
+
┬▓ Visit The GNU FoundationΓÇÖs EmacsΓÇÖ software page at http://www.gnu.org/software/emacs/
|
719
719
|
|
720
|
-
|
720
|
+
§ External Design
|
721
721
|
|
722
|
-
Let
|
722
|
+
LetΓÇÖs now look at some of the points made in the introduction in greater
|
723
723
|
detail.
|
724
724
|
|
725
|
-
Lookout only allows you to set one expectation per test. If you
|
725
|
+
Lookout only allows you to set one expectation per test. If youΓÇÖre testing
|
726
726
|
behavior with a reception expectation, then only one method-invocation
|
727
|
-
expectation can be set. If you
|
727
|
+
expectation can be set. If youΓÇÖre testing state, then only one result can
|
728
728
|
be verified. It may seem like this would cause unnecessary duplication
|
729
729
|
between tests. While this is certainly a possibility, when you actually
|
730
730
|
begin to try to avoid such duplication you find that you often do so by
|
731
731
|
improving your interfaces. This kind of restriction tends to encourage the
|
732
732
|
use of value objects, which are easy to test, and more focused objects,
|
733
733
|
which require simpler tests, as they have less behavior to test, per
|
734
|
-
method. By keeping your interfaces focused you
|
734
|
+
method. By keeping your interfaces focused youΓÇÖre also keeping your tests
|
735
735
|
focused.
|
736
736
|
|
737
|
-
Keeping your tests focused improves, in itself, test isolation, but let
|
737
|
+
Keeping your tests focused improves, in itself, test isolation, but letΓÇÖs
|
738
738
|
look at something that hinders it: setup and tear-down methods. Most unit
|
739
739
|
testing frameworks encourage test fragmentation by providing setup and
|
740
740
|
tear-down methods.
|
741
741
|
|
742
742
|
Setup methods create objects and, perhaps, just their behavior for a set of
|
743
|
-
tests. This means that you have to look in two places to figure out what
|
743
|
+
tests. This means that you have to look in two places to figure out whatΓÇÖs
|
744
744
|
being done in a test. This may work fine for few methods with simple
|
745
745
|
set-ups, but makes things complicated when the number of tests increases
|
746
746
|
and the set-up is complex. Often, each test further adjusts the previously
|
@@ -753,32 +753,32 @@ description: |2
|
|
753
753
|
The duplication that setup methods and tear-down methods hope to remove is
|
754
754
|
better avoided by improving your interfaces. This can be done by providing
|
755
755
|
better set-up methods for your objects and using idioms such as {Resource
|
756
|
-
Acquisition Is Initialization}
|
756
|
+
Acquisition Is Initialization}┬╣ for guaranteed clean-up, test or no test.
|
757
757
|
|
758
758
|
By not using setup and tear-down methods we keep everything pertinent to a
|
759
|
-
test in the test itself, thus improving test isolation. (You also won
|
760
|
-
{slow down your tests}
|
759
|
+
test in the test itself, thus improving test isolation. (You also wonΓÇÖt
|
760
|
+
{slow down your tests}┬▓ by keeping unnecessary state.)
|
761
761
|
|
762
762
|
Most unit test frameworks also allow you to create arbitrary test helper
|
763
|
-
methods. Lookout doesn
|
763
|
+
methods. Lookout doesnΓÇÖt. The same rationale as that that has been
|
764
764
|
crystallized in the preceding paragraphs applies. If you need helpers
|
765
|
-
you
|
765
|
+
youΓÇÖre interface isnΓÇÖt good enough. It really is as simple as that.
|
766
766
|
|
767
|
-
To clarify: there
|
767
|
+
To clarify: thereΓÇÖs nothing inherently wrong with test helper methods, but
|
768
768
|
they should be general enough that they reside in their own library. The
|
769
769
|
support for mocks in Lookout is provided through a set of test helper
|
770
770
|
methods that make it easier to create mocks than it would have been without
|
771
|
-
them. Lookout-rack
|
771
|
+
them. Lookout-rack┬│ is another example of a library providing test helper
|
772
772
|
methods (well, one method, actually) that are very useful in testing web
|
773
|
-
applications that use Rack
|
773
|
+
applications that use Rack⁴.
|
774
774
|
|
775
775
|
A final point at which some unit test frameworks try to fragment tests
|
776
776
|
further is documentation. These frameworks provide ways of describing the
|
777
|
-
whats and hows of what
|
777
|
+
whats and hows of whatΓÇÖs being tested, the rationale being that this will
|
778
778
|
provide documentation of both the test and the code being tested.
|
779
779
|
Describing how a stack data structure is meant to work is a common example.
|
780
780
|
A stack is, however, a rather simple data structure, so such a description
|
781
|
-
provides little, if any, additional information that can
|
781
|
+
provides little, if any, additional information that canΓÇÖt be extracted
|
782
782
|
from the implementation and its tests themselves. The implementation and
|
783
783
|
its tests is, in fact, its own best documentation. Taking the points made
|
784
784
|
in the previous paragraphs into account, we should already have simple,
|
@@ -787,144 +787,144 @@ description: |2
|
|
787
787
|
system-design design documentation is better suited in separate
|
788
788
|
documentation focused at describing exactly those issues.
|
789
789
|
|
790
|
-
|
790
|
+
┬╣ Read the Wikipedia entry for Resource Acquisition Is Initialization at
|
791
791
|
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
|
792
|
-
|
792
|
+
┬▓ Read how 37signals had problems with slow Test::Unit tests at
|
793
793
|
http://37signals.com/svn/posts/2742-the-road-to-faster-tests/
|
794
|
-
|
795
|
-
http://
|
796
|
-
|
794
|
+
┬│ Visit the Lookout-rack home page at
|
795
|
+
http://disu.se/software/lookout-rack/
|
796
|
+
⁴ Visit the Rack Rubyforge project page at
|
797
797
|
http://rack.rubyforge.org/
|
798
798
|
|
799
|
-
|
799
|
+
§ Internal Design
|
800
800
|
|
801
801
|
The internal design of Lookout has had a couple of goals.
|
802
802
|
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
803
|
+
ΓÇó As few external dependencies as possible
|
804
|
+
ΓÇó As few internal dependencies as possible
|
805
|
+
ΓÇó Internal extensibility provides external extensibility
|
806
|
+
ΓÇó As fast load times as possible
|
807
|
+
ΓÇó As high a ratio of value objects to mutable objects as possible
|
808
|
+
ΓÇó Each object must have a simple, obvious name
|
809
|
+
ΓÇó Use mix-ins, not inheritance for shared behavior
|
810
|
+
ΓÇó As few responsibilities per object as possible
|
811
|
+
ΓÇó Optimizing for speed can only be done when you have all the facts
|
812
812
|
|
813
|
-
|
813
|
+
§ External Dependencies
|
814
814
|
|
815
815
|
Lookout used to depend on Mocha for mocks and stubs. While benchmarking I
|
816
816
|
noticed that a method in Mocha was taking up more than 300 percent of the
|
817
|
-
runtime. It turned out that Mocha
|
817
|
+
runtime. It turned out that MochaΓÇÖs method for cleaning up back-traces
|
818
818
|
generated when a mock failed was doing something incredibly stupid:
|
819
819
|
|
820
820
|
backtrace.reject{ |l| Regexp.new(@lib).match(File.expand_path(l)) }
|
821
821
|
|
822
|
-
Here
|
822
|
+
Here ‹@lib› is a ‹String› containing the path to the lib sub-directory in
|
823
823
|
the Mocha installation directory. I reported it, provided a patch five
|
824
|
-
days later, then waited. Nothing happened. {254 days later}
|
825
|
-
to {Wolfram Alpha}
|
826
|
-
as I received no notification
|
824
|
+
days later, then waited. Nothing happened. {254 days later}┬╣, according
|
825
|
+
to {Wolfram Alpha}┬▓, half of my patch was, apparently ΓÇô I say ΓÇ£apparentlyΓÇ¥,
|
826
|
+
as I received no notification ΓÇô applied. By that time I had replaced the
|
827
827
|
whole mocking-and-stubbing subsystem and dropped the dependency.
|
828
828
|
|
829
829
|
Many Ruby developers claim that Ruby and its gems are too fast-moving for
|
830
830
|
normal package-managing systems to keep up. This is testament to the fact
|
831
|
-
that this isn
|
831
|
+
that this isnΓÇÖt the case and that the real problem is instead related to
|
832
832
|
sloppy practices.
|
833
833
|
|
834
|
-
Please note that I don
|
834
|
+
Please note that I donΓÇÖt want to single out the Mocha library nor its
|
835
835
|
developers. I only want to provide an example where relying on external
|
836
|
-
dependencies can be
|
836
|
+
dependencies can be ΓÇ£considered harmfulΓÇ¥.
|
837
837
|
|
838
|
-
|
839
|
-
|
838
|
+
┬╣ See the Wolfram Alpha calculation at http://www.wolframalpha.com/input/?i=days+between+march+17%2C+2010+and+november+26%2C+2010
|
839
|
+
┬▓ Check out the Wolfram Alpha computational knowledge engine at http://www.wolframalpha.com/
|
840
840
|
|
841
|
-
|
841
|
+
§ Internal Dependencies
|
842
842
|
|
843
843
|
Lookout has been designed so as to keep each subsystem independent of any
|
844
844
|
other. The diff subsystem is, for example, completely decoupled from any
|
845
845
|
other part of the system as a whole and could be moved into its own library
|
846
|
-
at a time where that would be of interest to anyone. What
|
846
|
+
at a time where that would be of interest to anyone. WhatΓÇÖs perhaps more
|
847
847
|
interesting is that the diff subsystem is itself very modular. The data
|
848
848
|
passes through a set of filters that depends on what kind of diff has been
|
849
849
|
requested, each filter yielding modified data as it receives it. If you
|
850
850
|
want to read some rather functional Ruby I can highly recommend looking at
|
851
|
-
the code in the
|
851
|
+
the code in the ‹lib/lookout/diff› directory.
|
852
852
|
|
853
853
|
This lookout on the design of the library also makes it easy to extend
|
854
854
|
Lookout. Lookout-rack was, for example, written in about four hours and
|
855
855
|
about 5 of those 240 minutes were spent on setting up the interface between
|
856
856
|
the two.
|
857
857
|
|
858
|
-
|
858
|
+
§ Optimizing For Speed
|
859
859
|
|
860
860
|
The following paragraph is perhaps a bit personal, but might be interesting
|
861
861
|
nonetheless.
|
862
862
|
|
863
|
-
I
|
864
|
-
|
865
|
-
used to hold the result of their execution (what we now term
|
863
|
+
IΓÇÖve always worried about speed. The original Expectations library used
|
864
|
+
‹extend› a lot to add new behavior to objects. Expectations, for example,
|
865
|
+
used to hold the result of their execution (what we now term ΓÇ£evaluationΓÇ¥)
|
866
866
|
by being extended by a module representing success, failure, or error. For
|
867
867
|
the longest time I used this same method, worrying about the increased
|
868
868
|
performance cost that creating new objects for results would incur. I
|
869
869
|
finally came to a point where I felt that the code was so simple and clean
|
870
|
-
that rewriting this part of the code for a benchmark wouldn
|
870
|
+
that rewriting this part of the code for a benchmark wouldnΓÇÖt take more
|
871
871
|
than perhaps ten minutes. Well, ten minutes later I had my results and
|
872
|
-
they confirmed that creating new objects wasn
|
872
|
+
they confirmed that creating new objects wasnΓÇÖt harming performance. I was
|
873
873
|
very pleased.
|
874
874
|
|
875
|
-
|
875
|
+
§ Naming
|
876
876
|
|
877
877
|
I hate low lines (underscores). I try to avoid them in method names and I
|
878
|
-
always avoid them in file names. Since the current
|
879
|
-
Ruby community is to put
|
880
|
-
|
878
|
+
always avoid them in file names. Since the current ΓÇ£best practiceΓÇ¥ in the
|
879
|
+
Ruby community is to put ‹BeginEndStorage› in a file called
|
880
|
+
‹begin_end_storage.rb›, I only name constants using a single noun. This
|
881
881
|
has had the added benefit that classes seem to have acquired less behavior,
|
882
|
-
as using a single noun doesn
|
883
|
-
without questioning if it
|
882
|
+
as using a single noun doesnΓÇÖt allow you to tack on additional behavior
|
883
|
+
without questioning if itΓÇÖs really appropriate to do so, given the rather
|
884
884
|
limited range of interpretation for that noun. It also seems to encourage
|
885
|
-
the creation of value objects, as something named
|
886
|
-
like a value than
|
885
|
+
the creation of value objects, as something named ‹Range› feels a lot more
|
886
|
+
like a value than ‹BeginEndStorage›. (To reach object-oriented-programming
|
887
887
|
Nirvana you must achieve complete value.)
|
888
888
|
|
889
|
-
|
889
|
+
§ News
|
890
890
|
|
891
|
-
|
891
|
+
§ 3.0.0
|
892
892
|
|
893
|
-
The
|
893
|
+
The ‹xml› expectation has been dropped. It wasn’t documented, didn’t
|
894
894
|
suit very many use cases, and can be better implemented by an external
|
895
895
|
library.
|
896
896
|
|
897
|
-
The
|
898
|
-
it didn
|
897
|
+
The ‹arg› argument matcher for mock method arguments has been removed, as
|
898
|
+
it didnΓÇÖt provide any benefit over using Object.
|
899
899
|
|
900
|
-
The
|
900
|
+
The ‹#yield› and ‹#each› methods on stub and mock methods have been
|
901
901
|
removed. They were slightly weird and their use case can be implemented
|
902
902
|
using block parameters instead.
|
903
903
|
|
904
|
-
The
|
904
|
+
The ‹stub› method inside ‹expect› blocks now stubs out the methods during
|
905
905
|
the execution of a provided block instead of during the execution of the
|
906
906
|
whole except block.
|
907
907
|
|
908
908
|
When a mock method is called too many times, this is reported
|
909
909
|
immediately, with a full backtrace. This makes it easier to pin down
|
910
|
-
what
|
910
|
+
whatΓÇÖs wrong with the code.
|
911
911
|
|
912
912
|
Query expectations were added.
|
913
913
|
|
914
914
|
Explicit query expectations were added.
|
915
915
|
|
916
|
-
Fluent boolean expectations, for example,
|
917
|
-
been replaced by query expectations (
|
918
|
-
explicit query expectations (
|
916
|
+
Fluent boolean expectations, for example, ‹expect nil.to.be.nil?› have
|
917
|
+
been replaced by query expectations (‹expect :nil? do nil end›) and
|
918
|
+
explicit query expectations (‹expect result.to.be.nil? do nil end›).
|
919
919
|
This was done to discourage creating objects as the expected value and
|
920
920
|
creating objects that change during the course of the test.
|
921
921
|
|
922
|
-
The
|
922
|
+
The ‹literal› expectation was added.
|
923
923
|
|
924
|
-
Equality (
|
924
|
+
Equality (‹#==›) is now checked before “caseity” (‹#===›) for modules,
|
925
925
|
ranges, and regular expressions to match the documentation.
|
926
926
|
|
927
|
-
|
927
|
+
§ Financing
|
928
928
|
|
929
929
|
Currently, most of my time is spent at my day job and in my rather busy
|
930
930
|
private life. Please motivate me to spend time on this piece of software
|
@@ -934,34 +934,38 @@ description: |2
|
|
934
934
|
to have other people give me the things that I need to continue living
|
935
935
|
under the rules of said society. So, if you feel that this piece of
|
936
936
|
software has helped you out enough to warrant a reward, please PayPal a
|
937
|
-
donation to now@disu.se
|
937
|
+
donation to now@disu.se┬╣. Thanks! Your support wonΓÇÖt go unnoticed!
|
938
938
|
|
939
|
-
|
940
|
-
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=now%40disu%2ese&item_name=
|
939
|
+
┬╣ Send a donation:
|
940
|
+
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=now%40disu%2ese&item_name=Lookout
|
941
941
|
|
942
|
-
|
942
|
+
§ Reporting Bugs
|
943
943
|
|
944
|
-
Please report any bugs that you encounter to the {issue tracker}
|
944
|
+
Please report any bugs that you encounter to the {issue tracker}┬╣.
|
945
945
|
|
946
|
-
|
946
|
+
┬╣ See https://github.com/now/lookout/issues
|
947
947
|
|
948
|
-
|
948
|
+
§ Contributors
|
949
949
|
|
950
950
|
Contributors to the original expectations codebase are mentioned there. We
|
951
951
|
hope no one on that list feels left out of this list. Please
|
952
|
-
{let us know}
|
952
|
+
{let us know}┬╣ if you do.
|
953
953
|
|
954
|
-
|
954
|
+
ΓÇó Nikolai Weibull
|
955
955
|
|
956
|
-
|
956
|
+
┬╣ Add an issue to the Lookout issue tracker at https://github.com/now/lookout/issues
|
957
957
|
|
958
|
-
|
958
|
+
§ Licensing
|
959
959
|
|
960
|
-
|
961
|
-
|
960
|
+
Lookout is free software: you may redistribute it and/or modify it under
|
961
|
+
the terms of the {GNU Lesser General Public License, version 3}┬╣ or later┬▓,
|
962
|
+
as published by the {Free Software Foundation}┬│.
|
962
963
|
|
963
|
-
|
964
|
-
|
964
|
+
┬╣ See http://disu.se/licenses/lgpl-3.0/
|
965
|
+
┬▓ See http://gnu.org/licenses/
|
966
|
+
┬│ See http://fsf.org/
|
967
|
+
email:
|
968
|
+
- now@disu.se
|
965
969
|
executables: []
|
966
970
|
extensions: []
|
967
971
|
extra_rdoc_files: []
|
@@ -1177,8 +1181,9 @@ files:
|
|
1177
1181
|
- test/unit/examples.rb
|
1178
1182
|
- README
|
1179
1183
|
- Rakefile
|
1180
|
-
homepage:
|
1181
|
-
licenses:
|
1184
|
+
homepage: http://disu.se/software/lookout
|
1185
|
+
licenses:
|
1186
|
+
- LGPLv3+
|
1182
1187
|
metadata: {}
|
1183
1188
|
post_install_message:
|
1184
1189
|
rdoc_options: []
|
@@ -1196,7 +1201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1196
1201
|
version: '0'
|
1197
1202
|
requirements: []
|
1198
1203
|
rubyforge_project:
|
1199
|
-
rubygems_version: 2.0.
|
1204
|
+
rubygems_version: 2.0.2
|
1200
1205
|
signing_key:
|
1201
1206
|
specification_version: 4
|
1202
1207
|
summary: focus.
|