ae 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MANIFEST CHANGED
@@ -4,6 +4,7 @@ demo/01_overview.rdoc
4
4
  demo/02_assertion.rdoc
5
5
  demo/03_assert.rdoc
6
6
  demo/04_subjunctive.rdoc
7
+ demo/05_expect.qed
7
8
  doc/qedoc
8
9
  doc/qedoc/index.html
9
10
  doc/qedoc/jquery.js
@@ -13,6 +14,7 @@ lib/ae/assert.rb
13
14
  lib/ae/assertion.rb
14
15
  lib/ae/assertor.rb
15
16
  lib/ae/core_ext.rb
17
+ lib/ae/expect.rb
16
18
  lib/ae/subjunctive
17
19
  lib/ae/subjunctive/must.rb
18
20
  lib/ae/subjunctive/should.rb
@@ -35,5 +37,5 @@ meta/title
35
37
  meta/version
36
38
  test
37
39
  LICENSE
38
- README
40
+ README.rdoc
39
41
  HISTORY
@@ -1,11 +1,11 @@
1
1
  = A.E. -- Assertive Expressive
2
2
 
3
- * http://protuils.rubyforge.org/ae
3
+ * http://proutils.rubyforge.org/ae/
4
4
 
5
5
 
6
6
  == DESCRIPTION
7
7
 
8
- Assertions Expressive (A.E.) is an assertions framework
8
+ Assertive Expressive (A.E.) is an assertions framework
9
9
  intended for reuse by any TDD, BDD or similar system.
10
10
 
11
11
 
@@ -14,7 +14,7 @@ intended for reuse by any TDD, BDD or similar system.
14
14
  * Clear, simple and concise syntax.
15
15
  * Uses higher-order functions and fluid notation.
16
16
  * Reusable core extensions ease assertion construction.
17
- * Core extensions are stable and standardized via Ruby Facets.
17
+ * Core extensions are standardized around Ruby Facets.
18
18
  * Facets is an optional dependency; extensions are built-in.
19
19
  * Easily extensible allowing for alternate notations.
20
20
  * Eats it's own dog food.
@@ -38,12 +38,11 @@ the result of which is likewise verified.
38
38
 
39
39
  assert{true}
40
40
 
41
- But these are simply legacy compatibility modes. The true power the
42
- AE's +assert+ method, lies in it's use without argument or block.
43
- In this case, it returns an +Assertor+ instance. An +Assertor+ is an
44
- Assertion Functor, or Higher-Order Function, which is a function
45
- that operates on another function. With it we can make assertions
46
- like:
41
+ However, the true power the AE's +assert+ method, lies in it's use
42
+ without argument or block. In this case, it returns an instance of
43
+ +Assertor+. An +Assertor+ is an <i>Assertions Functor</i> --also
44
+ called a Higher-Order Function, it is a function that operates on
45
+ another function. With it, we can make assertions like:
47
46
 
48
47
  x.assert == y
49
48
 
@@ -53,22 +52,46 @@ like:
53
52
  ...
54
53
  end
55
54
 
56
- And so forth. AE's abilities in this areas are quite extensive.
57
- You are encouraged to read the QEDocs to learn more.
55
+ And so forth. Any method can be used in conjunction with +assert+
56
+ to make an assertion. Eg.
57
+
58
+ class String
59
+ def daffy?
60
+ /daffy/i =~ self
61
+ end
62
+ end
63
+
64
+ "Daffy Duck".assert.daffy?
65
+
66
+ Please have a look at the QEDocs and RDocs to learn more.
58
67
 
59
68
 
60
69
  == HOW TO INSTALL
61
70
 
62
- To install with RubyGems simply open a console and type:
71
+ === Gem Installs
72
+
73
+ AE releases it's gems via Gemcutter. If you don't have Gemcutter
74
+ installed do:
75
+
76
+ $ gem install gemcutter
77
+ $ gem tumble
78
+
79
+ Then you can install AE with:
63
80
 
64
81
  gem install ae
65
82
 
66
- Local installation requires Setup.rb (gem install setup),
67
- then download the tarball package and type:
83
+ === Site Installs
84
+
85
+ Local installation requires Setup.rb.
86
+
87
+ gem install setup
88
+
89
+ Then download the tarball package from GitHub (under pack/ directory)
90
+ and do:
68
91
 
69
- tar -xvzf ae-1.0.0.tgz
70
- cd ae-1.0.0.tgz
71
- sudo setup.rb all
92
+ $ tar -xvzf ae-1.0.0.tgz
93
+ $ cd ae-1.0.0.tgz
94
+ $ sudo setup.rb all
72
95
 
73
96
  Windows users use 'ruby setup.rb all'.
74
97
 
@@ -14,19 +14,16 @@ Requiring the AE library.
14
14
  require 'ae'
15
15
 
16
16
  Loads two classes, +Assertion+ and +Assertor+, the Kernel
17
- method +assert+ and it's ancillaries +assert!+ and +refute+
17
+ method +assert+ and it's ancillaries <tt>assert!</tt> and +refute+
18
18
  and a set of core extensions that make writing certain types
19
19
  of assertions easier.
20
20
 
21
21
 
22
22
  == Assertion and Assertor Classes
23
23
 
24
- The +Assertion+ class is a subclass of +Exception+. It is the
25
- error raised when an assertion fails.
26
-
27
24
  The +Assertion+ class is at the heart of AE. All other AE
28
- method resolve by... The +Assertion+ class is at subclass
29
- of Exception. When an assertion is made, and fails, it is
25
+ methods depend on it. The +Assertion+ class is a subclass
26
+ of Exception. When an assertion is made and fails, it is
30
27
  an instance of Assertion that is raised.
31
28
 
32
29
  Assertion.assert.raised? do
@@ -35,33 +32,31 @@ an instance of Assertion that is raised.
35
32
  end
36
33
 
37
34
  Like any raised exception, the last Assertion message is available
38
- via +$!+.
35
+ via <tt>$!</tt>.
39
36
 
40
- (FYI, in Test::Unit the equivalent class was called AssertionFailureError.
41
- AE has adopted the shortened term for my fingers sake ;) Also, recently
42
- it was discoverd to be the choosen term in minitest --proving good ideas
43
- find their way to the top.)
37
+ (FYI, in Test::Unit the equivalent class was called +AssertionFailedError+.)
44
38
 
45
- Assertions themsevles are not generally used in creating tests or
46
- behavior specifications. Rather they are used to create additonal
39
+ Assertions themselves are not generally used in creating tests or
40
+ behavior specifications. Rather they are used to create additional
47
41
  types of assertion methods.
48
42
 
49
- As mentioned above the +Assertor+ class is a type of Functor,
50
- or Higher-Order function, which intercedes with a normal message
43
+ As mentioned above the +Assertor+ class is a type of Higher-Order
44
+ function, or Functor, which intercedes with a normal message
51
45
  invocation to monitor for failed conditions, upon which is raises
52
46
  Assertion exceptions.
53
47
 
54
48
 
55
49
  == Assertion Methods
56
50
 
57
- The three methods, +assert+, +assert!+ and +refute+ all return
58
- an Assertor instance when used fluidly, i.e. magic-dot notation,
59
- higher-order notation, functor notation, whatever you prefer
60
- to call it.
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.
61
55
 
62
56
  assert(Assertor === assert)
63
57
 
64
- This allows us to write statements like:
58
+ Through the use of +method_missing+, the Assertor allows us to write
59
+ statements like:
65
60
 
66
61
  1.assert == 1
67
62
 
@@ -72,20 +67,20 @@ is raised.
72
67
  1.assert == 2
73
68
  end
74
69
 
75
- The methods +assert!+ and +refute+ are just like +assert+ expect
76
- they purport the negative condition. Patterned after Ruby's own
77
- use of +!+ as meaning +not+, +assert!+ should be read "assert not".
78
- While +refute+ exists for the sake of those that find the use of
79
- a "bang method" for this purpose unsuited to them.
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.
80
75
 
81
76
 
82
- == How It All Works
77
+ == How It Works
83
78
 
84
79
  An Assertor essentially sits in wait for a method call (via
85
- method_missing). When that happens it applies the method to
86
- the original receiver, but wrapped in a clause that raises
87
- an Assertion should the statement fail. If we wanted to
88
- be pedantic, we could write our assertions like:
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:
89
84
 
90
85
  raise Assertion.new("1 != 1") unless 1 == 1
91
86
 
@@ -2,10 +2,10 @@
2
2
 
3
3
  == Compatible with Test::Unit
4
4
 
5
- The +#assert+ method is designed to be backward compatible
6
- with the same method in +Test::Unit+.
5
+ The +assert+ method is designed to be backward compatible
6
+ with the same method in <tt>Test::Unit</tt>.
7
7
 
8
- Using an argument, #assert will check that an argument evaluates
8
+ Using an argument, +assert+ will check that an argument evaluates
9
9
  to true. Optionally one can send along a meaningful message should
10
10
  the assertion fail.
11
11
 
@@ -18,7 +18,7 @@ the assertion fail.
18
18
 
19
19
  == Assert with a Block
20
20
 
21
- In addition #assert has been extended to accept a block. Like the case of the
21
+ In addition +assert+ has been extended to accept a block. Like the case of the
22
22
  argument, the block is expected to return something that evaluates as true.
23
23
 
24
24
  assert do
@@ -42,18 +42,18 @@ into the block as a block argument.
42
42
 
43
43
  == Antonyms for Assert
44
44
 
45
- We can state the opposite assertion using #assert!
45
+ We can state the opposite assertion using <tt>assert!</tt>.
46
46
 
47
47
  10.assert! == 9
48
48
 
49
- Or, because some people do not like the use of a bang method, +#refute+.
49
+ Or, because some people do not like the use of a bang method, +refute+.
50
50
 
51
51
  10.refute == 9
52
52
 
53
- These terms can be used just as #assert is used in all examples,
53
+ These terms can be used just as +assert+ is used in all examples,
54
54
  but with the opposite inference.
55
55
 
56
- Another way to get the opposite inference, is to use #not.
56
+ Another way to get the opposite inference, is to use +not+.
57
57
 
58
58
  10.assert.not == 9
59
59
 
@@ -65,11 +65,11 @@ Rather then the general form:
65
65
  x = 10
66
66
  x.assert.object_id == x.object_id
67
67
 
68
- We can use Ruby's own +equal?+ method.
68
+ We can use Ruby's own <tt>equal?</tt> method.
69
69
 
70
70
  x.assert.equal?(x)
71
71
 
72
- AE provides +identical?+ method as an alternative
72
+ AE provides <tt>identical?</tt> method as an alternative
73
73
  to make it a bit more clear.
74
74
 
75
75
  x.assert.identical?(x)
@@ -77,10 +77,10 @@ to make it a bit more clear.
77
77
 
78
78
  == Equality Assertions
79
79
 
80
- The most common assertion is that of value equality (+==_),
80
+ The most common assertion is that of value equality (<tt>==</tt>),
81
81
  as we have seen throughout this document. But other forms of
82
82
  equality can be verified as easily. We have already mentioned
83
- identity. In addition there is *Type Equality*.
83
+ identity. In addition there is <i>type equality</i>.
84
84
 
85
85
  17.assert.eql? 17
86
86
 
@@ -88,7 +88,7 @@ identity. In addition there is *Type Equality*.
88
88
  17.assert.eql? 17.0
89
89
  end
90
90
 
91
- And there is *Case Equality*.
91
+ And there is <i>case equality</i>.
92
92
 
93
93
  Numeric.assert === 3
94
94
 
@@ -98,10 +98,10 @@ And there is *Case Equality*.
98
98
  Because operators can not take blocks, and at times blocks can
99
99
  be convenient means of supplying a value to an assertion,
100
100
  AE has defined alternate renditions of the equality methods.
101
- For equal? and eql?, the method name remains the same, they simply
102
- can take a block instead of argument if need be.
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
103
 
104
- For *Value Equality*, +==+, the method is called +eq?+.
104
+ For <i>value equality</i> (<tt>==</tt>), the method is called <tt>eq?</tt>.
105
105
 
106
106
  10.assert.eq? do
107
107
  10.0
@@ -115,7 +115,7 @@ And should it fail...
115
115
  end
116
116
  end
117
117
 
118
- For *Case Equality, +===+, it is +case?+.
118
+ For <i>case equality</i> (<tt>===</tt>), it is <tt>case?</tt>.
119
119
 
120
120
  Numeric.assert.case? do
121
121
  "3".to_i
@@ -142,7 +142,7 @@ in the document to verify assertion failures.
142
142
 
143
143
  While testing or specifying the internal state of an object is
144
144
  generally considered poor form, there are times when it is
145
- necessay. Assert combined with +instance_eval+ makes it easy too.
145
+ necessary. Assert combined with +instance_eval+ makes it easy too.
146
146
 
147
147
  class X
148
148
  attr :a
@@ -158,14 +158,14 @@ necessay. Assert combined with +instance_eval+ makes it easy too.
158
158
 
159
159
  == Catch/Try Assertions
160
160
 
161
- Catch/Try throws can be tested via +Symbol#thrown?+.
161
+ Catch/Try throws can be tested via <tt>Symbol#thrown?</tt>.
162
162
 
163
163
  :hookme.assert.thrown? do
164
164
  throw :hookme
165
165
  end
166
166
 
167
167
  Alternatively, a lambda containing the potential throw
168
- can be the receiver using +throws?+.
168
+ can be the receiver using <tt>throws?</tt>.
169
169
 
170
170
  hook = lambda{ throw :hookme }
171
171
 
@@ -191,7 +191,7 @@ Ruby already provides the #nil? method.
191
191
 
192
192
  nil.assert.nil?
193
193
 
194
- AE add true? and false? which acts accordingly.
194
+ AE adds <tt>true?</tt> and <tt>false?</tt> which acts accordingly.
195
195
 
196
196
  true.assert.true?
197
197
  false.assert.false?
@@ -226,5 +226,38 @@ create reusable assertions.
226
226
 
227
227
  "abracarba".assert palindrome
228
228
 
229
- QED.
229
+
230
+ == Verifying Object State
231
+
232
+ NOTE: <i>This functionality is not currently supported, but is being
233
+ considered for a future version.</i>
234
+
235
+ If no block parameter is designated and the receiver differs from +self+
236
+ in scope of the given block, then the block is evaluated in the scope of
237
+ the receiver via +instance_eval+. This can be also be used to verify the
238
+ state of an object.
239
+
240
+ class X
241
+ attr :a
242
+ def initialize(a); @a = a; end
243
+ end
244
+
245
+ x = X.new(4)
246
+
247
+ x.must do
248
+ 4 == @a
249
+ end
250
+
251
+ And should it fail...
252
+
253
+ Assertion.assert.raised? do
254
+ x.must do
255
+ 5 == @a
256
+ end
257
+ end
258
+
259
+ For some this might be considered poor form, i.e. to test underlying
260
+ implementation. You will get no argument here. It should be used
261
+ thoughtfully, but I would not bet against there being occasions
262
+ when such validations might be handy.
230
263
 
@@ -1,51 +1,50 @@
1
1
  = Subjunctives
2
2
 
3
- Okay. I can hear the BDDers rumbling, "where's the 'should'?"
4
- Well, AE has nothing against 'should', but there are different
3
+ Okay. I can hear the BDDers rumbling, "where's the *should?*"
4
+ AE has nothing against "should", but there are different
5
5
  approaches for utilizing should nomenclature in specifications,
6
6
  and AE wants to be open to these techniques. One of which
7
- it the way Shoulda (http://shoulda.rubyforge.org) utilizes
7
+ is how Shoulda (http://shoulda.rubyforge.org) utilizes
8
8
  +should+ in a way analogous to RSpec's use of +it+.
9
9
 
10
- Even so, AE provides a an optional mixin called Subjunctive which
11
- can be used to create assertor methods using English subjunctive
12
- terms such as +should+ (or +must+, +shall+ and +will+. Whatever you like.)
10
+ Even so, AE provides a an optional mixin called +Subjunctive+ which
11
+ can be used to create assertor methods with English subjunctive
12
+ terms, such as +should+, or +must+, +shall+ and +will+.
13
13
  To load this library use:
14
14
 
15
15
  require 'ae/subjunctive'
16
16
 
17
- Then all that is required it to define your subjunctive method for all
17
+ Then all that is required it to define a subjunctive method for all
18
18
  objects. For example:
19
19
 
20
20
  def will(*args, &block)
21
21
  Assertor.new(self, :backtrace=>caller).be(*args,&block)
22
22
  end
23
23
 
24
- It's that easy. Because of their popularity AE provides two such terms,
25
- +should+ and +must+ as optional add-ons.
24
+ It's that easy. Because of their commonality AE provides two such terms,
25
+ +should+ and +must+ as optional add-ons out-of-the-box.
26
26
 
27
27
  require 'ae/subjunctive/should'
28
28
  require 'ae/subjunctive/must'
29
29
 
30
30
  We will use these two methods interchangeable for the rest of this
31
31
  demonstration, but to be clear they both work exactly the same way,
32
- and almost exactly like #assert.
32
+ and almost exactly like +assert+.
33
33
 
34
- Keep in mind, AE "conical" functionality does not entail subjunctive
35
- forms, or +should+ or +must+ assertor methods. These are simply options
36
- you can load via your test_helper.rb, or similar script, if you prefer
37
- or need to support these nomenclatures.
34
+ Keep in mind, AE "conical" functionality does not entail the subjunctive
35
+ forms. These are simply options you can load via your <tt>test_helper.rb</tt>,
36
+ or similar script, if you prefer these nomenclatures.
38
37
 
39
38
 
40
39
  == Fluent Notation and Antonyms
41
40
 
42
- Like +assert+, +should+ and +must+ can be used as a higher order function.
41
+ Like +assert+, +should+ and +must+ can be used as higher order functions.
43
42
 
44
43
  4.should == 4
45
44
  4.must == 4
46
45
 
47
- With the antonym of +should!+ (read as "should not") or +shouldnt+, and for
48
- +must+, +must!+ or +wont+.
46
+ Antonyms provided for +should+ as <tt>should!</tt> (read "should not") and +shouldnt+.
47
+ For +must+ +must+, they are <tt>must!</tt> and +wont+.
49
48
 
50
49
  4.should! == 5
51
50
  4.shouldnt == 5
@@ -56,8 +55,8 @@ With the antonym of +should!+ (read as "should not") or +shouldnt+, and for
56
55
 
57
56
  == To Be
58
57
 
59
- On occasions where the English readability of a specification is
60
- hindered, +be+ can be used.
58
+ On occasions where the English readability of a specification is hindered,
59
+ +be+ can be used.
61
60
 
62
61
  StandardError.must.be.raised? do
63
62
  unknown_method
@@ -65,63 +64,37 @@ hindered, +be+ can be used.
65
64
 
66
65
  The +be+ method is the same as +assert+ with the single exception
67
66
  that it will compare a lone argument to the receiver using +equate?+,
68
- unlike +assert+ which simply check to see that the argument evalutates
67
+ unlike +assert+ which simply checks to see that the argument evaluates
69
68
  as true.
70
69
 
71
70
  10.should.be 10
72
71
  10.should.be 10.0
73
72
  10.should.be Numeric
74
73
 
74
+ Assertion.assert.raised? do
75
+ 10.should.be "40"
76
+ end
77
+
75
78
 
76
79
  == Indefinite Articles
77
80
 
78
- Addtional anglogic forms are 'a' and 'an', equivalent to 'be' except
79
- that they use +case?+ instead of +equate?+,
81
+ Additional English forms are +a+ and +an+, equivalent to +be+ except
82
+ that they use <tt>case?</tt> (same as <tt>#===</tt>) instead of
83
+ <tt>equate?</tt> when acting on a single argument.
80
84
 
81
85
  "hi".must.be.a String
82
86
 
83
- Otherwise they are interchangeble.
87
+ Assertion.assert.raised? do
88
+ /x/.must.be.a /x/
89
+ end
84
90
 
85
- "hi".must.be.an.instance_of?(String)
91
+ Otherwise they are interchangeable.
86
92
 
87
- The indefinite articles work well when a noun follow as an arguments.
93
+ "hi".must.be.an.instance_of?(String)
88
94
 
95
+ The indefinite articles work well when a noun follows as an arguments.
89
96
 
90
97
  palindrome = lambda{ |x| x == x.reverse }
91
98
 
92
99
  "abracarba".must.be.a palindrome
93
100
 
94
-
95
- == Verifying Object State
96
-
97
- The block notation of the subjunctive form is similar to +assert+, with
98
- the important exception that the block is is evaluated in the scope of the
99
- receiver via #instance_eval, if no block parameter is designated.
100
- This can be also be used to test the state of an object.
101
-
102
- class X
103
- attr :a
104
- def initialize(a); @a = a; end
105
- end
106
-
107
- x = X.new(4)
108
-
109
- x.must do
110
- 4 == @a
111
- end
112
-
113
- And should it fail...
114
-
115
- Assertion.assert.raised? do
116
- x.must do
117
- 5 == @a
118
- end
119
- end
120
-
121
- For some this might seem controversial --to test underlying
122
- implementation. And you will get no argument here, it should be used
123
- thoughtfully, but there are occasions when such validations are
124
- necessary.
125
-
126
- QED.
127
-