rspecial 0.3.0

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/.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: []