ae 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/HISTORY CHANGED
@@ -1,5 +1,10 @@
1
1
  = RELEASE HISTORY
2
2
 
3
+ == 1.2.3 / 2010-06-07
4
+
5
+ This release is a quick fix, which adds a missing `require 'yaml'`.
6
+
7
+
3
8
  == 1.2.2 / 2010-06-06
4
9
 
5
10
  Version 1.2.2 simply add one new feature --the ability to
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2008 Thomas Sawyer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
23
+
data/PROFILE ADDED
@@ -0,0 +1,18 @@
1
+ ---
2
+ title : AE
3
+ summary: Assertive Expressive
4
+ suite : proutils
5
+ contact: trans <transfire@gmail.com>
6
+ created: 2008-08-17 09:00:06
7
+ authors: Thomas Sawyer
8
+ license: MIT
9
+
10
+ description:
11
+ Assertive Expressive is an assertions library intended for reuse
12
+ by any TDD, BDD or the like system.
13
+
14
+ resources:
15
+ homepage: http://proutils.github.com/ae
16
+ repository: git://github.com/proutils/ae.git
17
+
18
+ copyright: Copyright (c) 2008 Thomas Sawyer
data/REQUIRE ADDED
@@ -0,0 +1,5 @@
1
+ development:
2
+ - syckle
3
+
4
+ development/test:
5
+ - qed
data/VERSION ADDED
@@ -0,0 +1,6 @@
1
+ name : ae
2
+ major: 1
3
+ minor: 2
4
+ patch: 3
5
+ date : 2010-06-07
6
+
data/lib/ae.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'yaml'
2
+
1
3
  module AE
2
4
  vers = YAML.load(File.read(File.dirname(__FILE__) + '/ae/version.yml'))
3
5
  VERSION = vers.values_at('major', 'minor', 'patch', 'state', 'build').compact.join('.')
@@ -0,0 +1,6 @@
1
+ name : ae
2
+ major: 1
3
+ minor: 2
4
+ patch: 3
5
+ date : 2010-06-07
6
+
@@ -0,0 +1,92 @@
1
+ = Introduction
2
+
3
+ AE is an assertions framework for Ruby. It's designed
4
+ around the concept of an Assertor. The Assertor is an
5
+ Assertion Functor, or Higher-Order Function, which
6
+ reroutes method calls while monitoring them for failing
7
+ conditions.
8
+
9
+
10
+ == What's Provided
11
+
12
+ Requiring the AE library.
13
+
14
+ require 'ae'
15
+
16
+ Loads two classes, +Assertion+ and +Assertor+, the Kernel
17
+ method +assert+ and it's ancillaries <tt>assert!</tt> and +refute+
18
+ and a set of core extensions that make writing certain types
19
+ of assertions easier.
20
+
21
+
22
+ == Assertion and Assertor Classes
23
+
24
+ The +Assertion+ class is at the heart of AE. All other AE
25
+ methods depend on it. The +Assertion+ class is a subclass
26
+ of Exception. When an assertion is made and fails, it is
27
+ an instance of Assertion that is raised.
28
+
29
+ Assertion.assert.raised? do
30
+ msg = "my failure message"
31
+ assert false, msg
32
+ end
33
+
34
+ Like any raised exception, the last Assertion message is available
35
+ via <tt>$!</tt>.
36
+
37
+ (FYI, in Test::Unit the equivalent class was called +AssertionFailedError+.)
38
+
39
+ Assertions themselves are not generally used in creating tests or
40
+ behavior specifications. Rather they are used to create additional
41
+ types of assertion methods.
42
+
43
+ As mentioned above the +Assertor+ class is a type of Higher-Order
44
+ function, or Functor, which intercedes with a normal message
45
+ invocation to monitor for failed conditions, upon which is raises
46
+ Assertion exceptions.
47
+
48
+
49
+ == Assertion Methods
50
+
51
+ The three methods, +assert+, <tt>assert!</tt> and +refute+ all
52
+ return an Assertor instance when used fluidly, i.e. magic-dot
53
+ notation, higher-order notation, functor notation, whatever you
54
+ prefer to call it.
55
+
56
+ assert(Assertor === assert)
57
+
58
+ Through the use of +method_missing+, the Assertor allows us to write
59
+ statements like:
60
+
61
+ 1.assert == 1
62
+
63
+ If the operation evaluates to false or nil, then an Assertion error
64
+ is raised.
65
+
66
+ Assertion.assert.raised? do
67
+ 1.assert == 2
68
+ end
69
+
70
+ The methods <tt>assert!</tt> and +refute+ are just like +assert+
71
+ expect they purport the negative condition. Patterned after Ruby's
72
+ own use of "<tt>!</tt>" as meaning +not+, <tt>assert!</tt> should be
73
+ read "assert not". While +refute+ exists for the sake of those who
74
+ find the use of a bang method for this purpose unsuited to them.
75
+
76
+
77
+ == How It Works
78
+
79
+ An Assertor essentially sits in wait for a method call (via
80
+ method_missing). When that happens it applies the method to the
81
+ original receiver, but wrapped in a clause that raises an
82
+ Assertion should the statement fail. If we wanted to be
83
+ pedantic, we could write our assertions like:
84
+
85
+ raise Assertion.new("1 != 1") unless 1 == 1
86
+
87
+ Instead of
88
+
89
+ 1.assert == 1
90
+
91
+ Obviously using Assertor methods are whole lot more concise.
92
+
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,284 @@
1
+ = Assert Method
2
+
3
+ == Compatible with Test::Unit
4
+
5
+ The +assert+ method is designed to be backward compatible
6
+ with the same method in <tt>Test::Unit</tt>.
7
+
8
+ Using an argument, +assert+ will check that an argument evaluates
9
+ to true. Optionally one can send along a meaningful message should
10
+ the assertion fail.
11
+
12
+ assert(true, "Not true!")
13
+
14
+ Assertion.assert.raised? do
15
+ assert(false, "Not true!")
16
+ end
17
+
18
+
19
+ == Assert with a Block
20
+
21
+ In addition +assert+ has been extended to accept a block. Like the case of the
22
+ argument, the block is expected to return something that evaluates as true.
23
+
24
+ assert do
25
+ true
26
+ end
27
+
28
+ Assertion.assert.raised? do
29
+ assert do
30
+ false
31
+ end
32
+ end
33
+
34
+ We should also mention that, while probably not very useful, since
35
+ the arity of a block can be checked, one can also pass the receiver
36
+ into the block as a block argument.
37
+
38
+ "hi".assert do |s|
39
+ /h/ =~ s
40
+ end
41
+
42
+
43
+ == Antonyms for Assert
44
+
45
+ We can state the opposite assertion using <tt>assert!</tt>.
46
+
47
+ 10.assert! == 9
48
+
49
+ Or, because some people do not like the use of a bang method, +refute+.
50
+
51
+ 10.refute == 9
52
+
53
+ These terms can be used just as +assert+ is used in all examples,
54
+ but with the opposite inference.
55
+
56
+ Another way to get the opposite inference, is to use +not+.
57
+
58
+ 10.assert.not == 9
59
+
60
+
61
+ == Identity Assertions
62
+
63
+ Rather then the general form:
64
+
65
+ x = 10
66
+ x.assert.object_id == x.object_id
67
+
68
+ We can use Ruby's own <tt>equal?</tt> method.
69
+
70
+ x.assert.equal?(x)
71
+
72
+ AE provides <tt>identical?</tt> method as an alternative
73
+ to make it a bit more clear.
74
+
75
+ x.assert.identical?(x)
76
+
77
+
78
+ == Equality Assertions
79
+
80
+ The most common assertion is that of value equality (<tt>==</tt>),
81
+ as we have seen throughout this document. But other forms of
82
+ equality can be verified as easily. We have already mentioned
83
+ identity. In addition there is <i>type equality</i>.
84
+
85
+ 17.assert.eql? 17
86
+
87
+ Assertion.assert.raised? do
88
+ 17.assert.eql? 17.0
89
+ end
90
+
91
+ And there is <i>case equality</i>.
92
+
93
+ Numeric.assert === 3
94
+
95
+
96
+ == Checking Equality with a Block
97
+
98
+ Because operators can not take blocks, and at times blocks can
99
+ be convenient means of supplying a value to an assertion,
100
+ AE has defined alternate renditions of the equality methods.
101
+ For equal? and eql?, the method names are the same, they simply
102
+ can take a block in place of an argument if need be.
103
+
104
+ For <i>value equality</i> (<tt>==</tt>), the method is called <tt>eq?</tt>.
105
+
106
+ 10.assert.eq? do
107
+ 10.0
108
+ end
109
+
110
+ And should it fail...
111
+
112
+ Assertion.assert.raised? do
113
+ 10.assert.eq? do
114
+ 20
115
+ end
116
+ end
117
+
118
+ == Case Equality
119
+
120
+ For <i>case equality</i> (<tt>===</tt>), it is <tt>case?</tt>.
121
+
122
+ Numeric.assert.case? do
123
+ "3".to_i
124
+ end
125
+
126
+ Assertion.assert.raised? do
127
+ Numeric.assert.case? do
128
+ "3"
129
+ end
130
+ end
131
+
132
+
133
+ == Regular Expressions
134
+
135
+ Regular Expressions can be used to make assertions in much the same way as equality.
136
+
137
+ /i/.assert =~ "i"
138
+
139
+ Assertion.assert.raised? do
140
+ /i/.assert =~ "g"
141
+ end
142
+
143
+ Conversely the String class recognizes the #=~ method as well.
144
+
145
+ "i".assert =~ /i/
146
+
147
+ Assertion.assert.raised? do
148
+ "i".assert =~ /g/
149
+ end
150
+
151
+
152
+ == Exception Assertions
153
+
154
+ Validating errors is easy too, as has already been shown
155
+ in the document to verify assertion failures.
156
+
157
+ StandardError.assert.raised? do
158
+ unknown_method
159
+ end
160
+
161
+
162
+ == Assertions on Object State
163
+
164
+ While testing or specifying the internal state of an object is
165
+ generally considered poor form, there are times when it is
166
+ necessary. Assert combined with +instance_eval+ makes it easy too.
167
+
168
+ class X
169
+ attr :a
170
+ def initialize(a); @a = a; end
171
+ end
172
+
173
+ x = X.new(1)
174
+
175
+ x.assert.instance_eval do
176
+ @a == 1
177
+ end
178
+
179
+
180
+ == Catch/Try Assertions
181
+
182
+ Catch/Try throws can be tested via <tt>Symbol#thrown?</tt>.
183
+
184
+ :hookme.assert.thrown? do
185
+ throw :hookme
186
+ end
187
+
188
+ Alternatively, a lambda containing the potential throw
189
+ can be the receiver using <tt>throws?</tt>.
190
+
191
+ hook = lambda{ throw :hookme }
192
+
193
+ hook.assert.throws?(:hookme)
194
+
195
+
196
+ == Assertions on Proc Changes
197
+
198
+ I have to admit I'm not sure how this is useful,
199
+ but I found it in the Bacon API and ported it over
200
+ just for sake of thoroughness.
201
+
202
+ a = 0
203
+
204
+ l = lambda{ a }
205
+
206
+ l.assert.change?{ a +=1 }
207
+
208
+
209
+ == Assertion on literal True, False and Nil
210
+
211
+ Ruby already provides the #nil? method.
212
+
213
+ nil.assert.nil?
214
+
215
+ AE adds <tt>true?</tt> and <tt>false?</tt> which acts accordingly.
216
+
217
+ true.assert.true?
218
+ false.assert.false?
219
+
220
+
221
+ == Send Assertions
222
+
223
+ Assert that a method can be successfully called.
224
+
225
+ "STRING".assert.send?(:upcase)
226
+
227
+
228
+ == Numeric Delta and Epsilon
229
+
230
+ You may wish to assert that a numeric value is with some
231
+ range.
232
+
233
+ 3.in_delta?(1,5)
234
+
235
+ Or minimum range.
236
+
237
+ 3.in_epsilon?(3,5)
238
+
239
+
240
+ == Custom Lambda Assertions
241
+
242
+ Passing a lambda to the subjunctive method, will use it as if it were
243
+ a block of the method. This allows for a simple way to quickly
244
+ create reusable assertions.
245
+
246
+ palindrome = lambda{ |x| x == x.reverse }
247
+
248
+ "abracarba".assert palindrome
249
+
250
+
251
+ == Verifying Object State
252
+
253
+ NOTE: <i>This functionality is not currently supported, but is being
254
+ considered for a future version.</i>
255
+
256
+ If no block parameter is designated and the receiver differs from +self+
257
+ in scope of the given block, then the block is evaluated in the scope of
258
+ the receiver via +instance_eval+. This can be also be used to verify the
259
+ state of an object.
260
+
261
+ class X
262
+ attr :a
263
+ def initialize(a); @a = a; end
264
+ end
265
+
266
+ x = X.new(4)
267
+
268
+ x.assert do
269
+ 4 == @a
270
+ end
271
+
272
+ And should it fail...
273
+
274
+ Assertion.assert.raised? do
275
+ x.assert do
276
+ 5 == @a
277
+ end
278
+ end
279
+
280
+ For some this might be considered poor form, i.e. to test underlying
281
+ implementation. You will get no argument here. It should be used
282
+ thoughtfully, but I would not bet against there being occasions
283
+ when such validations might be handy.
284
+