rspec-expectations 2.99.2 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +14 -6
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/Changelog.md +63 -104
  5. data/License.txt +1 -0
  6. data/README.md +14 -8
  7. data/features/README.md +1 -2
  8. data/features/built_in_matchers/README.md +3 -0
  9. data/features/built_in_matchers/be.feature +44 -44
  10. data/features/built_in_matchers/be_within.feature +1 -1
  11. data/features/built_in_matchers/comparisons.feature +97 -0
  12. data/features/built_in_matchers/cover.feature +3 -3
  13. data/features/built_in_matchers/end_with.feature +3 -3
  14. data/features/built_in_matchers/equality.feature +20 -23
  15. data/features/built_in_matchers/exist.feature +5 -5
  16. data/features/built_in_matchers/expect_error.feature +14 -14
  17. data/features/built_in_matchers/include.feature +15 -15
  18. data/features/built_in_matchers/match.feature +4 -5
  19. data/features/built_in_matchers/match_array.feature +37 -0
  20. data/features/built_in_matchers/predicates.feature +30 -6
  21. data/features/built_in_matchers/respond_to.feature +4 -4
  22. data/features/built_in_matchers/satisfy.feature +2 -2
  23. data/features/built_in_matchers/start_with.feature +3 -3
  24. data/features/built_in_matchers/types.feature +6 -6
  25. data/features/custom_matchers/access_running_example.feature +3 -3
  26. data/features/custom_matchers/define_matcher.feature +6 -34
  27. data/features/custom_matchers/define_matcher_outside_rspec.feature +2 -2
  28. data/features/custom_matchers/define_matcher_with_fluent_interface.feature +1 -1
  29. data/features/customized_message.feature +18 -1
  30. data/features/diffing.feature +3 -3
  31. data/features/implicit_docstrings.feature +9 -9
  32. data/features/step_definitions/additional_cli_steps.rb +0 -10
  33. data/features/support/env.rb +10 -3
  34. data/features/test_frameworks/test_unit.feature +0 -40
  35. data/lib/rspec-expectations.rb +0 -5
  36. data/lib/rspec/expectations.rb +4 -18
  37. data/lib/rspec/expectations/expectation_target.rb +10 -77
  38. data/lib/rspec/expectations/extensions.rb +0 -1
  39. data/lib/rspec/expectations/handler.rb +1 -5
  40. data/lib/rspec/expectations/syntax.rb +25 -5
  41. data/lib/rspec/expectations/version.rb +1 -1
  42. data/lib/rspec/matchers.rb +7 -102
  43. data/lib/rspec/matchers/built_in/base_matcher.rb +10 -17
  44. data/lib/rspec/matchers/built_in/be.rb +5 -18
  45. data/lib/rspec/matchers/built_in/be_within.rb +2 -8
  46. data/lib/rspec/matchers/built_in/change.rb +1 -39
  47. data/lib/rspec/matchers/built_in/has.rb +7 -40
  48. data/lib/rspec/matchers/built_in/include.rb +1 -1
  49. data/lib/rspec/matchers/built_in/match_array.rb +1 -1
  50. data/lib/rspec/matchers/built_in/raise_error.rb +44 -23
  51. data/lib/rspec/matchers/built_in/respond_to.rb +1 -7
  52. data/lib/rspec/matchers/built_in/satisfy.rb +1 -7
  53. data/lib/rspec/matchers/built_in/throw_symbol.rb +2 -10
  54. data/lib/rspec/matchers/built_in/yield.rb +4 -25
  55. data/lib/rspec/matchers/compatibility.rb +2 -2
  56. data/lib/rspec/{expectations → matchers}/configuration.rb +9 -6
  57. data/lib/rspec/matchers/dsl.rb +2 -4
  58. data/lib/rspec/matchers/matcher.rb +163 -283
  59. data/lib/rspec/matchers/operator_matcher.rb +57 -71
  60. data/lib/rspec/matchers/pretty.rb +0 -4
  61. data/lib/rspec/matchers/test_unit_integration.rb +5 -22
  62. data/spec/rspec/expectations/expectation_target_spec.rb +0 -62
  63. data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -4
  64. data/spec/rspec/expectations_spec.rb +2 -43
  65. data/spec/rspec/matchers/base_matcher_spec.rb +12 -27
  66. data/spec/rspec/matchers/be_spec.rb +2 -71
  67. data/spec/rspec/matchers/change_spec.rb +1 -76
  68. data/spec/rspec/{expectations → matchers}/configuration_spec.rb +41 -21
  69. data/spec/rspec/matchers/description_generation_spec.rb +2 -21
  70. data/spec/rspec/matchers/equal_spec.rb +0 -26
  71. data/spec/rspec/matchers/has_spec.rb +0 -24
  72. data/spec/rspec/matchers/match_array_spec.rb +0 -13
  73. data/spec/rspec/matchers/matcher_spec.rb +325 -279
  74. data/spec/rspec/matchers/matchers_spec.rb +36 -0
  75. data/spec/rspec/matchers/operator_matcher_spec.rb +8 -27
  76. data/spec/rspec/matchers/raise_error_spec.rb +65 -209
  77. data/spec/rspec/matchers/yield_spec.rb +32 -9
  78. data/spec/spec_helper.rb +21 -6
  79. data/spec/support/classes.rb +7 -7
  80. data/spec/support/in_sub_process.rb +7 -8
  81. data/spec/support/shared_examples.rb +0 -42
  82. metadata +113 -84
  83. metadata.gz.sig +4 -0
  84. data/features/built_in_matchers/have.feature +0 -109
  85. data/features/built_in_matchers/operators.feature +0 -227
  86. data/lib/rspec/expectations/caller_filter.rb +0 -60
  87. data/lib/rspec/expectations/deprecation.rb +0 -27
  88. data/lib/rspec/expectations/extensions/array.rb +0 -9
  89. data/lib/rspec/matchers/be_close.rb +0 -12
  90. data/lib/rspec/matchers/built_in/have.rb +0 -273
  91. data/lib/rspec/matchers/differentiate_block_method_types.rb +0 -55
  92. data/lib/rspec/matchers/extensions/instance_eval_with_args.rb +0 -39
  93. data/lib/rspec/matchers/match_aliases.rb +0 -22
  94. data/spec/rspec/matchers/be_close_spec.rb +0 -25
  95. data/spec/rspec/matchers/differentiate_block_method_types_spec.rb +0 -39
  96. data/spec/rspec/matchers/have_spec.rb +0 -853
  97. data/spec/rspec/matchers/pretty_spec.rb +0 -23
  98. data/spec/support/helper_methods.rb +0 -42
@@ -1,273 +0,0 @@
1
- module RSpec
2
- module Matchers
3
- module BuiltIn
4
- class Have
5
- include MatchAliases
6
-
7
- QUERY_METHODS = [:size, :length, :count].freeze
8
-
9
- def initialize(expected, relativity=:exactly)
10
- @expected = case expected
11
- when :no then 0
12
- when String then expected.to_i
13
- else expected
14
- end
15
- @relativity = relativity
16
-
17
- @actual = @collection_name = @plural_collection_name = nil
18
- @target_owns_a_collection = false
19
- @negative_expectation = false
20
- @expectation_format_method = "to"
21
- end
22
-
23
- def relativities
24
- @relativities ||= {
25
- :exactly => "",
26
- :at_least => "at least ",
27
- :at_most => "at most "
28
- }
29
- end
30
-
31
- def matches?(collection_or_owner)
32
- collection = determine_collection(collection_or_owner)
33
- case collection
34
- when enumerator_class
35
- for query_method in QUERY_METHODS
36
- next unless collection.respond_to?(query_method)
37
- @actual = collection.__send__(query_method)
38
-
39
- if @actual
40
- print_deprecation_message(query_method)
41
- break
42
- end
43
- end
44
-
45
- raise not_a_collection if @actual.nil?
46
- else
47
- query_method = determine_query_method(collection)
48
- raise not_a_collection unless query_method
49
- @actual = collection.__send__(query_method)
50
-
51
- print_deprecation_message(query_method)
52
- end
53
- case @relativity
54
- when :at_least then @actual >= @expected
55
- when :at_most then @actual <= @expected
56
- else @actual == @expected
57
- end
58
- end
59
-
60
- def does_not_match?(collection_or_owner)
61
- @negative_expectation = true
62
- @expectation_format_method = "to_not"
63
- !matches?(collection_or_owner)
64
- end
65
-
66
- def determine_collection(collection_or_owner)
67
- if collection_or_owner.respond_to?(@collection_name)
68
- @target_owns_a_collection = true
69
- collection_or_owner.__send__(@collection_name, *@args, &@block)
70
- elsif (@plural_collection_name && collection_or_owner.respond_to?(@plural_collection_name))
71
- @target_owns_a_collection = true
72
- collection_or_owner.__send__(@plural_collection_name, *@args, &@block)
73
- elsif determine_query_method(collection_or_owner)
74
- collection_or_owner
75
- else
76
- collection_or_owner.__send__(@collection_name, *@args, &@block)
77
- end
78
- end
79
-
80
- def determine_query_method(collection)
81
- QUERY_METHODS.detect {|m| collection.respond_to?(m)}
82
- end
83
-
84
- def not_a_collection
85
- "expected #{@collection_name} to be a collection but it does not respond to #length, #size or #count"
86
- end
87
-
88
- def failure_message_for_should
89
- "expected #{relative_expectation} #{@collection_name}, got #{@actual}"
90
- end
91
-
92
- def failure_message_for_should_not
93
- if @relativity == :exactly
94
- return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}"
95
- elsif @relativity == :at_most
96
- return <<-EOF
97
- Isn't life confusing enough?
98
- Instead of having to figure out the meaning of this:
99
- #{Expectations::Syntax.negative_expression("actual", "have_at_most(#{@expected}).#{@collection_name}")}
100
- We recommend that you use this instead:
101
- #{Expectations::Syntax.positive_expression("actual", "have_at_least(#{@expected + 1}).#{@collection_name}")}
102
- EOF
103
- elsif @relativity == :at_least
104
- return <<-EOF
105
- Isn't life confusing enough?
106
- Instead of having to figure out the meaning of this:
107
- #{Expectations::Syntax.negative_expression("actual", "have_at_least(#{@expected}).#{@collection_name}")}
108
- We recommend that you use this instead:
109
- #{Expectations::Syntax.positive_expression("actual", "have_at_most(#{@expected - 1}).#{@collection_name}")}
110
- EOF
111
- end
112
- end
113
-
114
- def description
115
- "have #{relative_expectation} #{@collection_name}"
116
- end
117
-
118
- def respond_to?(m)
119
- @expected.respond_to?(m) || super
120
- end
121
-
122
- private
123
-
124
- def method_missing(method, *args, &block)
125
- @collection_name = method
126
- if inflector = (defined?(ActiveSupport::Inflector) && ActiveSupport::Inflector.respond_to?(:pluralize) ? ActiveSupport::Inflector : (defined?(Inflector) ? Inflector : nil))
127
- @plural_collection_name = inflector.pluralize(method.to_s)
128
- end
129
- @args = args
130
- @block = block
131
- self
132
- end
133
-
134
- def relative_expectation
135
- "#{relativities[@relativity]}#{@expected}"
136
- end
137
-
138
- def enumerator_class
139
- RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator
140
- end
141
-
142
- def print_deprecation_message(query_method)
143
- deprecation_message = "the rspec-collection_matchers gem "
144
- deprecation_message << "or replace your expectation with something like "
145
- if for_rspec_rails_error_on?
146
- # It is supposed to be safe to be able to convert the args array to
147
- # a string. This is because the `errors_on` method only takes two
148
- # valid arguments: attribute name (symbol/string) and a hash
149
- deprecated_call = expectation_expression(query_method, "record")
150
- deprecated_call << "(#{errors_on_args_list})" unless @args.empty?
151
-
152
- deprecation_message << <<-EOS.gsub(/^\s+\|/, '')
153
- |
154
- |
155
- | #{record_valid_expression}
156
- | expect(#{record_errors_expression(query_method)}).#{expectation_format_method} #{suggested_matcher_expression}
157
- |
158
- EOS
159
- else
160
- deprecated_call = expectation_expression(query_method)
161
- deprecation_message << "`expect(#{cardinality_expression(query_method)}).#{expectation_format_method} #{suggested_matcher_expression}`"
162
- end
163
-
164
- RSpec.deprecate("`#{deprecated_call}`",
165
- :replacement => deprecation_message,
166
- :type => "the have matcher"
167
- )
168
- end
169
-
170
- def expectation_expression(query_method, target = nil)
171
- target ||= target_expression
172
- if @negative_expectation
173
- RSpec::Expectations::Syntax.negative_expression(target, original_matcher_expression)
174
- else
175
- RSpec::Expectations::Syntax.positive_expression(target, original_matcher_expression)
176
- end
177
- end
178
-
179
- def target_expression
180
- if @target_owns_a_collection
181
- 'collection_owner'
182
- else
183
- 'collection'
184
- end
185
- end
186
-
187
- def original_matcher_expression
188
- "#{matcher_method}(#{@expected}).#{@collection_name}"
189
- end
190
-
191
- def expectation_format_method
192
- if @relativity == :exactly
193
- @expectation_format_method
194
- else
195
- "to"
196
- end
197
- end
198
-
199
- def cardinality_expression(query_method)
200
- expression = "#{target_expression}."
201
- expression << "#{@collection_name}." if @target_owns_a_collection
202
- expression << String(query_method)
203
- end
204
-
205
- def suggested_matcher_expression
206
- send("suggested_matcher_expression_for_#{@relativity}")
207
- end
208
-
209
- def suggested_matcher_expression_for_exactly
210
- "eq(#{@expected})"
211
- end
212
-
213
- def suggested_matcher_expression_for_at_most
214
- if @negative_expectation
215
- "be > #{@expected}"
216
- else
217
- "be <= #{@expected}"
218
- end
219
- end
220
-
221
- def suggested_matcher_expression_for_at_least
222
- if @negative_expectation
223
- "be < #{@expected}"
224
- else
225
- "be >= #{@expected}"
226
- end
227
- end
228
-
229
- def matcher_method
230
- case @relativity
231
- when :exactly
232
- "have"
233
- when :at_most
234
- "have_at_most"
235
- when :at_least
236
- "have_at_least"
237
- end
238
- end
239
-
240
- # RSpec Rails `errors_on` specific helpers
241
- def for_rspec_rails_error_on?
242
- defined?(RSpec::Rails) &&
243
- /\.errors?_on\b/ =~ original_matcher_expression
244
- end
245
-
246
- def errors_on_args_list
247
- list = @args.first.inspect
248
- context = validation_context
249
- list << ", :context => #{context}" if context
250
- list
251
- end
252
-
253
- def record_valid_expression
254
- expression = "record.valid?"
255
- if on_context = validation_context
256
- expression << "(#{on_context})"
257
- end
258
- expression
259
- end
260
-
261
- def validation_context
262
- return unless Hash === @args.last
263
- @args.last[:context].inspect
264
- end
265
-
266
- def record_errors_expression(query_method)
267
- attribute = (@args.first || :attr)
268
- "record.errors[#{attribute.inspect}].#{String(query_method)}"
269
- end
270
- end
271
- end
272
- end
273
- end
@@ -1,55 +0,0 @@
1
- module RSpec
2
- module Matchers
3
- # Evaluates a block in order to determine what methods, if any,
4
- # it defines as instance methods (using `def foo`) vs singleton
5
- # methods (using `def self.foo`).
6
- #
7
- # @api private
8
- class DifferentiateBlockMethodTypes
9
- def initialize(*block_args, &block)
10
- @block_args = block_args
11
- @block = block
12
-
13
- ignore_macro_methods
14
-
15
- capture_added_methods(singletons_singleton_class, singleton_methods)
16
- capture_added_methods(singleton_class, instance_methods)
17
-
18
- singleton_class.class_exec(*block_args, &block)
19
- end
20
-
21
- def singleton_methods
22
- @singleton_methods ||= []
23
- end
24
-
25
- def instance_methods
26
- @instance_methods ||= []
27
- end
28
-
29
- private
30
-
31
- def capture_added_methods(object, method_list)
32
- object.__send__(:define_method, :singleton_method_added) do |method_name|
33
- method_list << method_name
34
- end
35
-
36
- method_list.delete(:singleton_method_added)
37
- end
38
-
39
- unless method_defined?(:singleton_class)
40
- def singleton_class
41
- class << self; self; end
42
- end
43
- end
44
-
45
- def singletons_singleton_class
46
- class << singleton_class; self; end
47
- end
48
-
49
- def ignore_macro_methods
50
- def singleton_class.method_missing(*); self; end
51
- end
52
- end
53
- end
54
- end
55
-
@@ -1,39 +0,0 @@
1
- module RSpec
2
- module Matchers
3
- module Extensions
4
- module InstanceEvalWithArgs
5
- # based on Bounded Spec InstanceExec (Mauricio Fernandez)
6
- # http://eigenclass.org/hiki/bounded+space+instance_exec
7
- # - uses singleton_class instead of global InstanceExecHelper module
8
- # - this keeps it scoped to classes/modules that include this module
9
- # - only necessary for ruby 1.8.6
10
- def instance_eval_with_args(*args, &block)
11
- return instance_exec(*args, &block) if respond_to?(:instance_exec)
12
-
13
- # If there are no args and the block doesn't expect any, there's no
14
- # need to fake instance_exec with our hack below.
15
- # Notes:
16
- # * lambda { }.arity # => -1
17
- # * lambda { || }.arity # => 0
18
- # * lambda { |*a| }.arity # -1
19
- return instance_eval(&block) if block.arity < 1 && args.empty?
20
-
21
- singleton_class = (class << self; self; end)
22
- begin
23
- orig_critical, Thread.critical = Thread.critical, true
24
- n = 0
25
- n += 1 while respond_to?(method_name="__instance_exec#{n}")
26
- singleton_class.module_eval{ define_method(method_name, &block) }
27
- ensure
28
- Thread.critical = orig_critical
29
- end
30
- begin
31
- return __send__(method_name, *args)
32
- ensure
33
- singleton_class.module_eval{ remove_method(method_name) } rescue nil
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,22 +0,0 @@
1
- module RSpec
2
- module Matchers
3
- module MatchAliases
4
- def ==(other)
5
- return true if equal?(other)
6
-
7
- matched = matches?(other)
8
-
9
- if matched
10
- RSpec.deprecate("Using `matcher == value` as an alias for `#matches?`", :replacement => "`matcher === value`")
11
- end
12
-
13
- matched
14
- end
15
-
16
- def ===(other)
17
- matches?(other)
18
- end
19
- end
20
- end
21
- end
22
-
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RSpec
4
- module Matchers
5
- describe "expect(actual).to be_close(expected, delta)" do
6
- before(:each) do
7
- allow(RSpec).to receive(:deprecate)
8
- end
9
-
10
- it "is deprecated" do
11
- expect_deprecation_with_type('be_close(3.0, 0.5)',
12
- 'be_within(0.5).of(3.0)',
13
- 'the be_close matcher'
14
- )
15
- be_close(3.0, 0.5)
16
- end
17
-
18
- it "delegates to be_within(delta).of(expected)" do
19
- should_receive(:be_within).with(0.5).and_return( be_within_matcher = double )
20
- be_within_matcher.should_receive(:of).with(3.0)
21
- be_close(3.0, 0.5)
22
- end
23
- end
24
- end
25
- end
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RSpec
4
- module Matchers
5
- describe DifferentiateBlockMethodTypes do
6
- let(:differentiator) do
7
- DifferentiateBlockMethodTypes.new do
8
- def some_instance_method_1; end
9
- def self.some_singleton_method_1; end
10
- define_method(:some_instance_method_2) { }
11
-
12
- if RUBY_VERSION.to_f > 1.8
13
- define_singleton_method(:some_singleton_method_2) { }
14
- else
15
- def self.some_singleton_method_2; end
16
- end
17
- end
18
- end
19
-
20
- it 'differentiates singleton method defs from instance method defs' do
21
- expect(differentiator.instance_methods).to eq([:some_instance_method_1, :some_instance_method_2])
22
- expect(differentiator.singleton_methods).to eq([:some_singleton_method_1, :some_singleton_method_2])
23
- end
24
-
25
- it 'passes the given args through to the block' do
26
- expect { |b|
27
- DifferentiateBlockMethodTypes.new(1, 2, &b)
28
- }.to yield_with_args(1, 2)
29
- end
30
-
31
- it 'ignores unrecognized DSL methods called in the block' do
32
- expect {
33
- DifferentiateBlockMethodTypes.new { foo.bar; some_dsl { nested } }
34
- }.not_to raise_error
35
- end
36
- end
37
- end
38
- end
39
-