rspecial 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.index ADDED
@@ -0,0 +1,61 @@
1
+ ---
2
+ type: ruby
3
+ revision: 2013
4
+ sources:
5
+ - var
6
+ authors:
7
+ - name: Thomas Sawyer
8
+ email: transfire@gmail.com
9
+ organizations: []
10
+ requirements:
11
+ - name: assay
12
+ - groups:
13
+ - build
14
+ development: true
15
+ name: detroit
16
+ - groups:
17
+ - test
18
+ development: true
19
+ name: qed
20
+ conflicts: []
21
+ alternatives: []
22
+ resources:
23
+ - type: home
24
+ uri: http://rubyworks.github.com/rspecial
25
+ label: Homepage
26
+ - type: docs
27
+ uri: http://rubydoc.info/gems/rspecial
28
+ label: Documentation
29
+ - type: code
30
+ uri: http://github.com/rubyworks/rspecial
31
+ label: Source Code
32
+ - type: mail
33
+ uri: http://groups.google.com/groups/rubyworks-mailinglist
34
+ label: Mailing List
35
+ - type: chat
36
+ uri: http://chat.us.feenode.net/rubyworks
37
+ label: IRC Channel
38
+ repositories:
39
+ - name: upstream
40
+ scm: git
41
+ uri: git@github.com:rubyworks/rspecial.git
42
+ categories: []
43
+ load_path:
44
+ - lib
45
+ copyrights:
46
+ - holder: Rubyworks
47
+ year: '2012'
48
+ license: BSD-2-Clause
49
+ created: '2012-01-18'
50
+ summary: Brass-balled RSpec Expectations
51
+ title: RSpecial
52
+ version: 0.3.0
53
+ name: rspecial
54
+ description: ! 'RSpecial defines a set of RSpec-compatible matcher methods which
55
+
56
+ are BRASS compliant by using Assay as a backend. This allows developers
57
+
58
+ to switch to BRASS compliant test frameworks without having to change
59
+
60
+ a slew of previously written RSpec-based specifications.'
61
+ date: '2012-12-12'
data/.ruby ADDED
@@ -0,0 +1 @@
1
+ ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux]
@@ -0,0 +1,269 @@
1
+ # RSpecish
2
+
3
+ ## Setup
4
+
5
+ First we need to require the library.
6
+
7
+ require 'rspecish'
8
+
9
+ This will load Assay and the RSpec extension, which will add `#should`
10
+ and `#should_not` to `BasicObject` class, and create a module called
11
+ `RSpecish::Matchers`. This moudle is included into `Assay::Matchers`.
12
+ To make use of it, we simply need to include either of these modules into
13
+ our test scope.
14
+
15
+ include ::Assay::Matchers
16
+
17
+ With that in place, we are ready to use the matchers.
18
+
19
+
20
+ ## RSpec Should Method
21
+
22
+ ### should
23
+
24
+ Becuase the `#should` method used `=~` as the assertion operator,
25
+ you can do something a bit unexpected, such as,
26
+
27
+ 'a'.should /a/
28
+
29
+
30
+ ### should=
31
+
32
+ 10.should = 10
33
+
34
+ expect ::EqualAssay do
35
+ 10.should = 20
36
+ end
37
+
38
+ 10.should_not = 20
39
+
40
+
41
+ ## RSpec Matchers
42
+
43
+ ### should equal
44
+
45
+ 1.should = 1
46
+
47
+ expect ::EqualAssay do
48
+ 1.should = 2
49
+ end
50
+
51
+ ### be_true
52
+
53
+ true.should be_true
54
+
55
+ expect ::TrueAssay do
56
+ false.should be_true
57
+ end
58
+
59
+ ### be_false
60
+
61
+ false.should be_false
62
+
63
+ expect ::FalseAssay do
64
+ true.should be_false
65
+ end
66
+
67
+ ### be_nil
68
+
69
+ nil.should be_nil
70
+
71
+ expect ::NilAssay do
72
+ true.should be_nil
73
+ end
74
+
75
+ ### be_empty
76
+
77
+ [].should be_empty
78
+
79
+ expect ::EmptyAssay do
80
+ [1].should be_empty
81
+ end
82
+
83
+ [1].should_not be_empty
84
+
85
+ ### be_close
86
+
87
+ 1.should be_close(1.5, 2)
88
+
89
+ expect ::WithinAssay do
90
+ 1.should be_close(0.5, 2)
91
+ end
92
+
93
+ 1.should_not be_close(0.5, 2)
94
+
95
+ ### match
96
+
97
+ "abc".should match(/a/)
98
+
99
+ expect ::MatchAssay do
100
+ "abc".should match(/x/)
101
+ end
102
+
103
+ "abc".should_not match(/g/)
104
+
105
+ ### eql
106
+
107
+ 1.should eql(1)
108
+
109
+ expect ::EqualityAssay do
110
+ 1.should eql(1.0)
111
+ end
112
+
113
+ 1.should_not eql(1.0)
114
+
115
+ ### equal
116
+
117
+ :a.should equal(:a)
118
+
119
+ expect ::IdentityAssay do
120
+ "a".should equal("a")
121
+ end
122
+
123
+ :a.should_not equal('a')
124
+
125
+ ### be_instance_of
126
+
127
+ 1.should be_instance_of(Fixnum)
128
+
129
+ expect ::InstanceAssay do
130
+ 1.should be_instance_of(String)
131
+ end
132
+
133
+ 1.should_not be_instance_of(String)
134
+
135
+ ### be_kind_of
136
+
137
+ 1.should be_kind_of(Integer)
138
+
139
+ expect ::KindAssay do
140
+ 1.should be_kind_of(String)
141
+ end
142
+
143
+ 1.should_not be_kind_of(String)
144
+
145
+ ### raise_error
146
+
147
+ procedure = lambda{ raise ::ArgumentError }
148
+
149
+ procedure.should raise_error(::ArgumentError)
150
+
151
+ expect ::RaiseAssay do
152
+ procedure.should raise_error(::TypeError)
153
+ end
154
+
155
+ procedure.should_not raise_error(::TypeError)
156
+
157
+ ### respond_to
158
+
159
+ "string".should respond_to(:upcase)
160
+
161
+ expect ::RespondAssay do
162
+ "string".should respond_to(:not_a_method)
163
+ end
164
+
165
+ "string".should_not respond_to(:not_a_method)
166
+
167
+ ### satisfy
168
+
169
+ 5.should satisfy{ |x| x > 3 }
170
+
171
+ expect ::ExecutionAssay do
172
+ 5.should satisfy{ |x| x < 3 }
173
+ end
174
+
175
+ 5.should_not satisfy{ |x| x < 3 }
176
+
177
+ ### throw_symbol
178
+
179
+ procedure = lambda{ throw :foo }
180
+
181
+ procedure.should throw_symbol(:foo)
182
+
183
+ expect ::ThrowAssay do
184
+ procedure.should throw_symbol(:bar)
185
+ end
186
+
187
+ procedure.should_not throw_symbol(:bar)
188
+
189
+ ## Supplemental Matchers
190
+
191
+ ### equate_to
192
+
193
+ This is not strictly an RSpec matcher, but we have thrown it in for good measure.
194
+ It is equivalent to using the `#should=` method.
195
+
196
+ 10.should equate_to(10)
197
+
198
+ expect ::EqualityAssay do
199
+ 10.should equate_to(10.0)
200
+ end
201
+
202
+ 10.should_not equate_to(10.0)
203
+
204
+ ### be_like
205
+
206
+ The `#be_like` matcher is not strictly an RSpec matcher, but we have thrown it
207
+ in for good measure.
208
+
209
+ /a/.should be_like('a')
210
+
211
+ expect ::LikeAssay do
212
+ /a/.should be_like('b')
213
+ end
214
+
215
+ /a/.should_not be_like('b')
216
+
217
+
218
+ ### Have
219
+
220
+ The `#have` matchers make it easy to set expectations about the size
221
+ of a collection. In general the term `items` is used if the target
222
+ object is a collection.
223
+
224
+ a = [1, 2, 3]
225
+
226
+ a.should have(3).items
227
+ a.should_not have(2).items
228
+ a.should_not have(4).items
229
+
230
+ a.should have_exactly(3).items
231
+ a.should_not have_exactly(2).items
232
+ a.should_not have_exactly(4).items
233
+
234
+ a.should have_at_least(2).items
235
+ a.should have_at_most(4).items
236
+
237
+ But a method that returns a collection can be used instead.
238
+
239
+ class String
240
+ def words
241
+ split(' ')
242
+ end
243
+ end
244
+
245
+ s = "a sentence with some words"
246
+
247
+ s.should have(5).words
248
+ s.should_not have(4).words
249
+ s.should_not have(6).words
250
+
251
+ s.should have_exactly(5).words
252
+ s.should_not have_exactly(4).words
253
+ s.should_not have_exactly(6).words
254
+
255
+ s.should have_at_least(4).words
256
+ s.should have_at_most(6).words
257
+
258
+ Besides `#have` there is also `#have_at_least` and `#have_at_most`.
259
+
260
+ a = [1, 2, 3]
261
+
262
+ a.should have_at_least(2).items
263
+ a.should have_at_most(4).items
264
+
265
+ a.should have_at_least(3).items
266
+ a.should have_at_most(3).items
267
+
268
+
269
+
@@ -0,0 +1,31 @@
1
+ # HISTORY
2
+
3
+ ## 0.3.0 | 2012-03-16
4
+
5
+ Renamed project from *Assay RSpec* to *RSpecial*, and added
6
+ RSpec's new expect notation.
7
+
8
+ Changes:
9
+
10
+ * Rename project to respecial.
11
+ * Add RSpec's new expect notation.
12
+
13
+
14
+ ## 0.2.0 | 2012-02-26
15
+
16
+ This release adds support for #have matchers.
17
+
18
+ Changes:
19
+
20
+ * Add support for have matchers.
21
+
22
+
23
+ ## 0.1.0 | 2012-01-26
24
+
25
+ This is the initial release of Assay RSpec. Currently the library covers
26
+ every RSpec matcher except the `change` and `have` matchers.
27
+
28
+ Changes:
29
+
30
+ * Happy Birthday!
31
+
@@ -0,0 +1,22 @@
1
+ BSD-2-Clause License
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice,
7
+ this list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
14
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
15
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
16
+ COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
17
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
22
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,76 @@
1
+ # RSpecial
2
+
3
+ [Homepage](http://rubyworks.github.com/rspecial) /
4
+ [Report Issue](http://github.com/rubyworks/rspecial/issues) /
5
+ [Source Code](http://github.com/rubyworks/rspecial)
6
+ ( [![Build Status](https://secure.travis-ci.org/rubyworks/rspecial.png)](http://travis-ci.org/rubyworks/rspecial) )
7
+
8
+ _Well, isn't that special._
9
+
10
+ <br/>
11
+
12
+ RSpecial is an BRASS-compliant *assertions framework*. It defines
13
+ the RSpec's `expect` and `should` handlers and a set of RSpec-compatible matchers
14
+ allowing developers to change test frameworks without having to change
15
+ a slew of previously defined assertions.
16
+
17
+ RSpecial utilizes the [Assay](http://rubyworks.github.com/assay)
18
+ assertions meta-framework on the back-end. Assay defines assertions
19
+ in the same way that Ruby defines exceptions. An assertion is nothing
20
+ more that an extended Exception class. Assay provides a complete set
21
+ of these assertion classes for all common assertion needs.
22
+
23
+
24
+ ## Installation
25
+
26
+ To install with RubyGems simply open a console and type:
27
+
28
+ $ gem install rspecial
29
+
30
+ Old-school site installations via a tarball can be done with [Ruby Setup](http://rubyworks.github.com/setup)
31
+ (`gem install setup`).
32
+
33
+
34
+ ## Basic Usage
35
+
36
+ To use RSpecial, simply require the `rspecial` script, and include the `RSpecial::Matchers`
37
+ or `Test::Matchers` mixin module into your test framework wherever it requires
38
+ it (which may be as simple as the top-level namespace).
39
+
40
+ require 'rspecial'
41
+
42
+ include RSpecial::Matchers
43
+
44
+ Or more generically,
45
+
46
+ include Test::Matchers
47
+
48
+ Now assertions can be made just as if you were using RSpec.
49
+
50
+ expect(10).to be_kind_of(Integer)
51
+
52
+ and the traditional way
53
+
54
+ 10.should be_kind_of(Integer)
55
+
56
+
57
+ ## Limitations
58
+
59
+ Compatibility with RSpec is not 100%, but it is close. Compatibility will improve
60
+ with future releases.
61
+
62
+ Also error messages aren't always as nice, nor always customizable, as they are in RSpec.
63
+ This too will improve with future releases.
64
+
65
+ Please feel _obligated_ to submit a patch if you need a missing a feature ;-)
66
+
67
+
68
+ ## Copyrights
69
+
70
+ RSpecial is copyright open source software
71
+
72
+ Copyright (c) 2012 Rubyworks
73
+
74
+ This program is distributed under the terms of the [BSD-2-Clause](http://spdx.org/licenses/BSD-2-Clause) license.
75
+
76
+ See LICENSE.txt file for details.
@@ -0,0 +1 @@
1
+ require 'rspecial'
@@ -0,0 +1,20 @@
1
+ # RSpecial (http://rubyworks.github.com/rspecial)
2
+ # Copyright (c) 2012 Rubyworks.
3
+ # License (spdx) BSD-2-Clause.
4
+
5
+ require 'assay'
6
+ require 'rspecial/matchers'
7
+ require 'rspecial/have'
8
+ require 'rspecial/should'
9
+ require 'rspecial/expect'
10
+ require 'rspecial/operatics'
11
+
12
+ # This Test::Matchers module holds all matcher methods, which can be mixed into
13
+ # one's testing scope (e.g. World).
14
+ #
15
+ module Test
16
+ module Matchers
17
+ include RSpecial::Matchers
18
+ end
19
+ end
20
+
@@ -0,0 +1,61 @@
1
+ ---
2
+ type: ruby
3
+ revision: 2013
4
+ sources:
5
+ - var
6
+ authors:
7
+ - name: Thomas Sawyer
8
+ email: transfire@gmail.com
9
+ organizations: []
10
+ requirements:
11
+ - name: assay
12
+ - groups:
13
+ - build
14
+ development: true
15
+ name: detroit
16
+ - groups:
17
+ - test
18
+ development: true
19
+ name: qed
20
+ conflicts: []
21
+ alternatives: []
22
+ resources:
23
+ - type: home
24
+ uri: http://rubyworks.github.com/rspecial
25
+ label: Homepage
26
+ - type: docs
27
+ uri: http://rubydoc.info/gems/rspecial
28
+ label: Documentation
29
+ - type: code
30
+ uri: http://github.com/rubyworks/rspecial
31
+ label: Source Code
32
+ - type: mail
33
+ uri: http://groups.google.com/groups/rubyworks-mailinglist
34
+ label: Mailing List
35
+ - type: chat
36
+ uri: http://chat.us.feenode.net/rubyworks
37
+ label: IRC Channel
38
+ repositories:
39
+ - name: upstream
40
+ scm: git
41
+ uri: git@github.com:rubyworks/rspecial.git
42
+ categories: []
43
+ load_path:
44
+ - lib
45
+ copyrights:
46
+ - holder: Rubyworks
47
+ year: '2012'
48
+ license: BSD-2-Clause
49
+ created: '2012-01-18'
50
+ summary: Brass-balled RSpec Expectations
51
+ title: RSpecial
52
+ version: 0.3.0
53
+ name: rspecial
54
+ description: ! 'RSpecial defines a set of RSpec-compatible matcher methods which
55
+
56
+ are BRASS compliant by using Assay as a backend. This allows developers
57
+
58
+ to switch to BRASS compliant test frameworks without having to change
59
+
60
+ a slew of previously written RSpec-based specifications.'
61
+ date: '2012-12-12'
@@ -0,0 +1,151 @@
1
+ module RSpecial
2
+
3
+ # Wraps the target of an expectation.
4
+ #
5
+ # @example
6
+ # expect(something) # => Expect
7
+ #
8
+ # # used with `to`
9
+ # expect(actual).to eq(3)
10
+ #
11
+ # # with `to_not`
12
+ # expect(actual).to_not eq(3)
13
+ #
14
+ class Expect
15
+
16
+ # @api private
17
+ def initialize(target)
18
+ @target = target
19
+ end
20
+
21
+ # Runs the given expectation, passing if `matcher` returns true.
22
+ #
23
+ # @example
24
+ # expect(value).to eq(5)
25
+ # expect { perform }.to raise_error
26
+ #
27
+ # @param [Matcher]
28
+ # matcher
29
+ #
30
+ # @param [String] message optional message to display when the expectation fails
31
+ #
32
+ # @return [Boolean] true if the expectation succeeds (else raises)
33
+ #
34
+ # @see RSpec::Matchers
35
+ #
36
+ def to(matcher=nil, message=nil, &block)
37
+ #prevent_operator_matchers(:to, matcher)
38
+ handle_positive_matcher(@target, matcher, message, &block)
39
+ end
40
+
41
+ # Runs the given expectation, passing if `matcher` returns false.
42
+ #
43
+ # @example
44
+ # expect(value).to_not eq(5)
45
+ # expect(value).not_to eq(5)
46
+ #
47
+ # @param [Matcher]
48
+ # matcher
49
+ #
50
+ # @param [String] message optional message to display when the expectation fails
51
+ #
52
+ # @return [Boolean] false if the negative expectation succeeds (else raises)
53
+ #
54
+ # @see RSpec::Matchers
55
+ #
56
+ def to_not(matcher=nil, message=nil, &block)
57
+ #prevent_operator_matchers(:to_not, matcher)
58
+ handle_negative_matcher(@target, matcher, message, &block)
59
+ end
60
+
61
+ alias :not_to :to_not
62
+
63
+ private
64
+
65
+ #def prevent_operator_matchers(verb, matcher)
66
+ # return if matcher
67
+ #
68
+ # raise ArgumentError, "The expect syntax does not support operator matchers, " +
69
+ # "so you must pass a matcher to `##{verb}`."
70
+ #end
71
+
72
+ #
73
+ # @todo how to customize the message?
74
+ #
75
+ def handle_positive_matcher(actual, matcher, message=nil, &block)
76
+ check_message(message)
77
+
78
+ #::RSpec::Matchers.last_should = :should
79
+ #::RSpec::Matchers.last_matcher = matcher
80
+
81
+ if block
82
+ actual = block.call(actual)
83
+ end
84
+
85
+ #return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) if matcher.nil?
86
+
87
+ return Operatics.new(actual) if matcher.nil?
88
+
89
+ matcher =~ actual
90
+
91
+ #match = matcher.matches?(actual, &block)
92
+ #return match if match
93
+
94
+ #message ||= matcher.respond_to?(:failure_message_for_should) ?
95
+ # matcher.failure_message_for_should :
96
+ # matcher.failure_message
97
+
98
+ #if matcher.respond_to?(:diffable?) && matcher.diffable?
99
+ # ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual
100
+ #else
101
+ # ::RSpec::Expectations.fail_with message
102
+ #end
103
+ end
104
+
105
+ #
106
+ # @todo how to customize the message?
107
+ #
108
+ def handle_negative_matcher(actual, matcher, message=nil, &block)
109
+ check_message(message)
110
+
111
+ #::RSpec::Matchers.last_should = :should_not
112
+ #::RSpec::Matchers.last_matcher = matcher
113
+
114
+ if block
115
+ actual = block.call(actual)
116
+ end
117
+
118
+ #return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) if matcher.nil?
119
+
120
+ return Operatics.new(actual, true) if matcher.nil?
121
+
122
+ matcher !~ actual
123
+
124
+ #match = matcher.respond_to?(:does_not_match?) ?
125
+ # !matcher.does_not_match?(actual, &block) :
126
+ # matcher.matches?(actual, &block)
127
+ #return match unless match
128
+
129
+ #message ||= matcher.respond_to?(:failure_message_for_should_not) ?
130
+ # matcher.failure_message_for_should_not :
131
+ # matcher.negative_failure_message
132
+
133
+ #if matcher.respond_to?(:diffable?) && matcher.diffable?
134
+ # ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual
135
+ #else
136
+ # ::RSpec::Expectations.fail_with message
137
+ #end
138
+ end
139
+
140
+ def message_must_be_string(msg)
141
+ "WARNING: ignoring the provided expectation message argument " +
142
+ "(#{msg.inspect}) since it is not a string."
143
+ end
144
+
145
+ def check_message(msg)
146
+ ::Kernel.warn message_must_be_string(msg) unless msg.nil? || msg.is_a?(String)
147
+ end
148
+
149
+ end
150
+
151
+ end
@@ -0,0 +1,201 @@
1
+ module RSpecial
2
+
3
+ # Delegate to Have Assays.
4
+ #
5
+ class Have
6
+
7
+ attr :expected
8
+
9
+ attr :collection_name
10
+
11
+ attr :relation
12
+
13
+ #
14
+ # Initialize new Have delegator.
15
+ #
16
+ def initialize(expected, relation=:exactly)
17
+ @expected = case expected
18
+ when :no then 0
19
+ when String then expected.to_i
20
+ else expected
21
+ end
22
+ @relation = relation
23
+ @collection_name = nil
24
+ end
25
+
26
+ #
27
+ # @param [#size,#length,#count] collection_or_owner
28
+ #
29
+ def collection(collection_or_owner)
30
+ if collection_or_owner.respond_to?(@collection_name)
31
+ collection_or_owner.__send__(@collection_name, *@args, &@block)
32
+ elsif query_method(collection_or_owner)
33
+ collection_or_owner
34
+ else
35
+ collection_or_owner.__send__(@collection_name, *@args, &@block)
36
+ end
37
+ end
38
+
39
+ #
40
+ #
41
+ #
42
+ def query_method(collection)
43
+ [:size, :length, :count].detect {|m| collection.respond_to?(m)}
44
+ end
45
+
46
+ #
47
+ #
48
+ #
49
+ def method_missing(method, *args, &block)
50
+ @collection_name = method
51
+ @args = args
52
+ @block = block
53
+
54
+ case @relation
55
+ when :at_least
56
+ RSpecial::HaveAtLeastAssay.assertor(self)
57
+ when :at_most
58
+ RSpecial::HaveAtMostAssay.assertor(self)
59
+ else
60
+ RSpecial::HaveExactlyAssay.assertor(self)
61
+ end
62
+ end
63
+
64
+ #
65
+ #
66
+ module Helpers
67
+
68
+ #
69
+ #
70
+ #
71
+ def collection_set(collection_or_owner, have)
72
+ collection = have.collection(collection_or_owner)
73
+ query_method = query_method(collection)
74
+
75
+ raise not_a_collection(have) unless query_method
76
+
77
+ actual = collection.__send__(query_method)
78
+
79
+ return collection, query_method, actual
80
+ end
81
+
82
+ #
83
+ # Return the actual size of the collection.
84
+ #
85
+ def collection_actual(collection_or_owner, have)
86
+ collection_set(collection_or_owner, have).last
87
+ end
88
+
89
+ #
90
+ # Which size method to use: `size`, `length` or `count`.
91
+ #
92
+ def query_method(collection)
93
+ [:size, :length, :count].detect {|m| collection.respond_to?(m)}
94
+ end
95
+
96
+ #
97
+ # Message to use when collection doesn't respond to `size`, `length` or `count`.
98
+ #
99
+ def not_a_collection(have)
100
+ "expected #{have.collection_name} to be a collection but it does not respond to #length, #size or #count"
101
+ end
102
+
103
+ #
104
+ # TODO: use when verbose error message mode
105
+ #
106
+ def self.assert_description(collection_or_owner, have)
107
+ collection, method, actual = collection_set(collection_or_owner, have)
108
+ "expected #{have.relation} #{have.expected} #{have.collection_name}, got #{actual}"
109
+ end
110
+
111
+ #
112
+ #
113
+ #
114
+ def self.refute_descrptipon(collection_or_owner, have)
115
+ collection, method, actual = collection_set(collection_or_owner, have)
116
+ "expected not to have #{have.relation} #{have.expected} #{have.collection_name}, got #{actual}"
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+
123
+ #
124
+ #
125
+ class HaveExactlyAssay < EqualAssay
126
+
127
+ extend Have::Helpers
128
+
129
+ register :have
130
+
131
+ #
132
+ #
133
+ #
134
+ def self.pass?(collection_or_owner, have)
135
+ actual = collection_actual(collection_or_owner, have)
136
+ super(actual, have.expected)
137
+ end
138
+
139
+ #
140
+ # Error message for have equal assertion.
141
+ #
142
+ def self.assert_message(collection_or_owner, have)
143
+ actual = collection_actual(collection_or_owner, have)
144
+ super(actual, have.expected)
145
+ end
146
+
147
+ end
148
+
149
+ #
150
+ #
151
+ class HaveAtLeastAssay < MoreEqualAssay
152
+
153
+ extend Have::Helpers
154
+
155
+ register :have_at_least
156
+
157
+ #
158
+ #
159
+ #
160
+ def self.pass?(collection_or_owner, have)
161
+ actual = collection_actual(collection_or_owner, have)
162
+ super(actual, have.expected)
163
+ end
164
+
165
+ #
166
+ #
167
+ #
168
+ def self.assert_message(collection_or_owner, have)
169
+ actual = collection_actual(collection_or_owner, have)
170
+ super(actual, have.expected)
171
+ end
172
+
173
+ end
174
+
175
+ #
176
+ #
177
+ class HaveAtMostAssay < LessEqualAssay
178
+
179
+ extend Have::Helpers
180
+
181
+ register :have_at_most
182
+
183
+ #
184
+ #
185
+ #
186
+ def self.pass?(collection_or_owner, have)
187
+ actual = collection_actual(collection_or_owner, have)
188
+ super(actual, have.expected)
189
+ end
190
+
191
+ #
192
+ #
193
+ #
194
+ def self.assert_message(collection_or_owner, have)
195
+ actual = collection_actual(collection_or_owner, have)
196
+ super(actual, have.expected)
197
+ end
198
+
199
+ end
200
+
201
+ end
@@ -0,0 +1,258 @@
1
+ module RSpecial
2
+
3
+ # This module provides matchers for RSpec-compatiblity.
4
+ #
5
+ # The set is not fully compataible, but provides most RSpec matchers.
6
+ # The most notable exlusion for the moment is the `have` matchers.
7
+ #
8
+ # Compatability will improve with time. Feel _obligated_ to submit a
9
+ # patch if you really need it. ;)
10
+ #
11
+ # @see https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers
12
+ #
13
+ module Matchers
14
+
15
+ #def self.included(base)
16
+ # @_once ||= require_relative('should').nil?
17
+ #end
18
+
19
+ #def self.extended(base)
20
+ # @_once ||= require_relative('should').nil?
21
+ #end
22
+
23
+ # Passes if the expected and actual are alike.
24
+ #
25
+ # object.should be_like(criterion)
26
+ #
27
+ # There is no equivalant for this in RSpec, we simply add it
28
+ # here to cover all Assays available.
29
+ #
30
+ # @raise LikeAssay
31
+ #
32
+ def be_like(criterion)
33
+ LikeAssay.assertor(criterion)
34
+ end
35
+
36
+ # Passes if expected and actual are nto equal within delta tolerance.
37
+ #
38
+ # value.should be_close(delta, criterion)
39
+ #
40
+ # @raise WithinAssay
41
+ #
42
+ def be_close(delta, criterion)
43
+ WithinAssay.assertor(criterion, delta)
44
+ end
45
+
46
+ # Passes if object is empty.
47
+ #
48
+ # object.should be_empty
49
+ #
50
+ # @raise EmptyAssay
51
+ #
52
+ def be_empty
53
+ EmptyAssay.assertor
54
+ end
55
+
56
+ # Passes if +expected+ == +actual+.
57
+ #
58
+ # 'MY STRING'.should equate_to('my string'.upcase)
59
+ # 'MY STRING'.should_not equate_to('another string')
60
+ #
61
+ # This matcher is not supported by RSpec, but is added so that the
62
+ # EqualityAssay has an explict matcher available.
63
+ #
64
+ # @raise EqualityAssay
65
+ #
66
+ def equate_to(exp)
67
+ EqualityAssay.assertor(exp)
68
+ end
69
+
70
+ #
71
+ # Passes if block is satisfied given target object as argument.
72
+ #
73
+ # 5.should satisfy{ |n| n > 3}
74
+ #
75
+ # @raise ExecutionAssay
76
+ #
77
+ def satisfy(&block)
78
+ ExecutionAssay.assertor(&block)
79
+ end
80
+
81
+ #
82
+ # Passed if object is +false+.
83
+ #
84
+ # value.should be_false
85
+ #
86
+ # @raise FalseAssay
87
+ #
88
+ def be_false
89
+ FalseAssay.assertor
90
+ end
91
+
92
+ #
93
+ # Passes if actual is the same exact object as expected.
94
+ #
95
+ # object.should be_identical_to(object)
96
+ #
97
+ # @raise IdentityAssay
98
+ #
99
+ def equal(obj)
100
+ IdentityAssay.assertor(obj)
101
+ end
102
+
103
+ alias :be_identical_to :equal
104
+
105
+ #
106
+ # Passes if `actual == expected`.
107
+ #
108
+ # object.should eq(object)
109
+ #
110
+ # @raise EqualAssay
111
+ #
112
+ def eq(obj)
113
+ EqualAssay.assertor(obj)
114
+ end
115
+
116
+ #
117
+ # Passes if object is an instance of class.
118
+ #
119
+ # object.should be_instance_of(class)
120
+ #
121
+ # @raise InstanceAssay
122
+ #
123
+ def be_instance_of(cls)
124
+ InstanceAssay.assertor(cls)
125
+ end
126
+
127
+ alias :be_an_instance_of :be_instance_of
128
+
129
+ #
130
+ # Pass if object is a kind of class.
131
+ #
132
+ # object.should be_kind_of(class)
133
+ #
134
+ # @raise KindAssay
135
+ #
136
+ def be_kind_of(cls)
137
+ KindAssay.assertor(cls)
138
+ end
139
+
140
+ alias :be_a_kind_of :be_kind_of
141
+ alias :be_a :be_kind_of
142
+ alias :be_an :be_kind_of
143
+
144
+ #
145
+ # Pass if object matches pattern using `#=~` method.
146
+ #
147
+ # object.should match(regexp)
148
+ #
149
+ # @raise MatchAssay
150
+ #
151
+ def match(regexp)
152
+ MatchAssay.assertor(regexp)
153
+ end
154
+
155
+ #
156
+ # Pass if object is +nil+.
157
+ #
158
+ # value.should be_nil
159
+ #
160
+ # @raise NilAssay
161
+ #
162
+ def be_nil
163
+ NilAssay.assertor
164
+ end
165
+
166
+ #
167
+ # Pass if an exception is raised.
168
+ #
169
+ # lambda { do_something_risky }.should raise_error
170
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError)
171
+ #
172
+ # @raise RaiseAssay
173
+ #
174
+ # @todo Support for message matching ?
175
+ #
176
+ def raise_error(exception=Exception)
177
+ RaiseAssay.assertor(exception)
178
+ end
179
+
180
+ #
181
+ # Pass if object responds to message.
182
+ #
183
+ # object.should respond_to(:method_name)
184
+ #
185
+ # @raise RespondAssay
186
+ #
187
+ def respond_to(method)
188
+ RespondAssay.assertor(method)
189
+ end
190
+
191
+ #
192
+ # Pass if two objects are equal using `#eql?` method.
193
+ #
194
+ # object1.should eql(object2)
195
+ #
196
+ # @raise EqualityAssay
197
+ #
198
+ def eql(exp)
199
+ EqualityAssay.assertor(exp)
200
+ end
201
+
202
+ #
203
+ # Pass if procedure throws a specified symbol.
204
+ #
205
+ # lambda { do_something_risky }.should throw_symbol
206
+ # lambda { do_something_risky }.should throw_symbol(:that_was_risky)
207
+ #
208
+ # @raise ThrowAssay
209
+ #
210
+ # @todo Support for throw argument. (Does RSpec even support this?)
211
+ #
212
+ def throw_symbol(sym=nil) #, arg=nil)
213
+ ThrowAssay.assertor(sym)
214
+ end
215
+
216
+ #
217
+ # Passed if object is +true+.
218
+ #
219
+ # object.should be_true
220
+ #
221
+ # @raise TrueAssay
222
+ #
223
+ def be_true
224
+ TrueAssay.assertor
225
+ end
226
+
227
+ #
228
+ #
229
+ #
230
+ def have(n)
231
+ Have.new(n)
232
+ end
233
+
234
+ alias :have_exactly :have
235
+
236
+ #
237
+ #
238
+ #
239
+ def have_at_least(n)
240
+ Have.new(n, :at_least)
241
+ end
242
+
243
+ #
244
+ #
245
+ #
246
+ def have_at_most(n)
247
+ Have.new(n, :at_most)
248
+ end
249
+
250
+ #
251
+ #
252
+ def expect(target)
253
+ Expect.new(target)
254
+ end
255
+
256
+ end
257
+
258
+ end
@@ -0,0 +1,57 @@
1
+ module RSpecial
2
+
3
+ # Operatics delegates operator based assertions for execpt.rb.
4
+ #
5
+ class Operatics < Object
6
+ instance_methods.each{ |m| undef_method m if m.to_s =~ /^\W/ }
7
+
8
+ #
9
+ def initialize(target, negate=false)
10
+ @target = target
11
+ @negate = negate
12
+ end
13
+
14
+ private
15
+
16
+ #
17
+ def method_missing(op, *a, &b)
18
+ super(op, *a, &b) if op.to_s =~ /^\w/
19
+
20
+ if @negate
21
+ refute!(op, *a, &b)
22
+ else
23
+ assert!(op, *a, &b)
24
+ end
25
+ end
26
+
27
+ #
28
+ def assert!(op, *a, &b)
29
+ if assay = Assertion.by_operator(op)
30
+ return assay.assert!(@target, *a, &b)
31
+ else
32
+ assert! @target.send(op, *a, &b)
33
+ end
34
+ end
35
+
36
+ #
37
+ def refute!(op, *a, &b)
38
+ if assay = Assertion.by_operator(op)
39
+ return assay.refute!(@target, *a, &b)
40
+ else
41
+ refute! @target.send(op, *a, &b)
42
+ end
43
+ end
44
+
45
+ #
46
+ def generic?(op)
47
+ @target.method(op).owner == ::Kernel
48
+ end if ::Method.method_defined?(:owner)
49
+
50
+ #
51
+ def generic?(op)
52
+ @target.method(op).to_s.include?('(Kernel)')
53
+ end unless ::Method.method_defined?(:owner)
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,49 @@
1
+ module RSpecial
2
+
3
+ # The Should module is included into BasicObject to provide
4
+ # the needed assertion interface that RSpec utilizes. Namely, the
5
+ # `should` and `should_not` methods.
6
+ #
7
+ module Should
8
+
9
+ #
10
+ # Use `should` nomenclature for assertions.
11
+ #
12
+ # 10.should be_kind_of(Integer)
13
+ #
14
+ def should(matcher)
15
+ matcher =~ self
16
+ end
17
+
18
+ #
19
+ # Also, `should_not` nomenclature for assertions.
20
+ #
21
+ # 10.should_not be_kind_of?(Integer)
22
+ #
23
+ def should_not(matcher)
24
+ matcher !~ self
25
+ end
26
+
27
+ #
28
+ #
29
+ #
30
+ def should=(value)
31
+ EqualAssay.assert!(self, value)
32
+ end
33
+
34
+ #
35
+ #
36
+ #
37
+ def should_not=(value)
38
+ EqualAssay.refute!(self, value)
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+
46
+ class BasicObject # Object ?
47
+ include ::RSpecial::Should
48
+ end
49
+
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspecial
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Sawyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: assay
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: detroit
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: qed
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: ! 'RSpecial defines a set of RSpec-compatible matcher methods which
63
+
64
+ are BRASS compliant by using Assay as a backend. This allows developers
65
+
66
+ to switch to BRASS compliant test frameworks without having to change
67
+
68
+ a slew of previously written RSpec-based specifications.'
69
+ email:
70
+ - transfire@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files:
74
+ - LICENSE.txt
75
+ - HISTORY.md
76
+ - README.md
77
+ - DEMOS.md
78
+ files:
79
+ - .index
80
+ - .ruby
81
+ - lib/assay/rspec.rb
82
+ - lib/rspecial/expect.rb
83
+ - lib/rspecial/have.rb
84
+ - lib/rspecial/matchers.rb
85
+ - lib/rspecial/operatics.rb
86
+ - lib/rspecial/should.rb
87
+ - lib/rspecial.rb
88
+ - lib/rspecial.yml
89
+ - HISTORY.md
90
+ - README.md
91
+ - DEMOS.md
92
+ - LICENSE.txt
93
+ homepage: http://rubyworks.github.com/rspecial
94
+ licenses:
95
+ - BSD-2-Clause
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 1.8.23
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Brass-balled RSpec Expectations
118
+ test_files: []