rspec-expectations 2.8.0 → 2.9.0.rc2

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.
Files changed (68) hide show
  1. data/.document +5 -0
  2. data/.yardopts +3 -0
  3. data/Changelog.md +176 -0
  4. data/README.md +2 -13
  5. data/features/custom_matchers/access_running_example.feature +1 -1
  6. data/features/step_definitions/additional_cli_steps.rb +4 -4
  7. data/lib/rspec/expectations/fail_with.rb +3 -3
  8. data/lib/rspec/expectations/handler.rb +3 -5
  9. data/lib/rspec/expectations/version.rb +1 -1
  10. data/lib/rspec/matchers.rb +387 -21
  11. data/lib/rspec/matchers/built_in.rb +33 -0
  12. data/lib/rspec/matchers/built_in/base_matcher.rb +58 -0
  13. data/lib/rspec/matchers/built_in/be.rb +183 -0
  14. data/lib/rspec/matchers/built_in/be_instance_of.rb +13 -0
  15. data/lib/rspec/matchers/built_in/be_kind_of.rb +13 -0
  16. data/lib/rspec/matchers/built_in/be_within.rb +39 -0
  17. data/lib/rspec/matchers/built_in/change.rb +132 -0
  18. data/lib/rspec/matchers/built_in/cover.rb +22 -0
  19. data/lib/rspec/matchers/built_in/eq.rb +26 -0
  20. data/lib/rspec/matchers/built_in/eql.rb +25 -0
  21. data/lib/rspec/matchers/built_in/equal.rb +48 -0
  22. data/lib/rspec/matchers/built_in/exist.rb +28 -0
  23. data/lib/rspec/matchers/built_in/has.rb +47 -0
  24. data/lib/rspec/matchers/built_in/have.rb +107 -0
  25. data/lib/rspec/matchers/built_in/include.rb +52 -0
  26. data/lib/rspec/matchers/built_in/match.rb +13 -0
  27. data/lib/rspec/matchers/built_in/match_array.rb +52 -0
  28. data/lib/rspec/matchers/built_in/raise_error.rb +96 -0
  29. data/lib/rspec/matchers/built_in/respond_to.rb +73 -0
  30. data/lib/rspec/matchers/built_in/satisfy.rb +29 -0
  31. data/lib/rspec/matchers/built_in/throw_symbol.rb +93 -0
  32. data/lib/rspec/matchers/dsl.rb +1 -1
  33. data/lib/rspec/matchers/matcher.rb +263 -233
  34. data/lib/rspec/matchers/method_missing.rb +2 -2
  35. data/lib/rspec/matchers/operator_matcher.rb +19 -20
  36. data/spec/rspec/expectations/handler_spec.rb +1 -1
  37. data/spec/rspec/matchers/base_matcher_spec.rb +1 -2
  38. data/spec/rspec/matchers/change_spec.rb +3 -3
  39. data/spec/rspec/matchers/cover_spec.rb +46 -46
  40. data/spec/rspec/matchers/dsl_spec.rb +36 -3
  41. data/spec/rspec/matchers/have_spec.rb +2 -2
  42. data/spec/rspec/matchers/include_spec.rb +1 -1
  43. data/spec/rspec/matchers/matcher_spec.rb +319 -305
  44. data/spec/rspec/matchers/method_missing_spec.rb +1 -0
  45. data/spec/rspec/matchers/operator_matcher_spec.rb +2 -2
  46. data/spec/rspec/matchers/throw_symbol_spec.rb +103 -105
  47. metadata +93 -39
  48. data/lib/rspec/matchers/base_matcher.rb +0 -56
  49. data/lib/rspec/matchers/be.rb +0 -232
  50. data/lib/rspec/matchers/be_instance_of.rb +0 -24
  51. data/lib/rspec/matchers/be_kind_of.rb +0 -24
  52. data/lib/rspec/matchers/be_within.rb +0 -47
  53. data/lib/rspec/matchers/change.rb +0 -197
  54. data/lib/rspec/matchers/cover.rb +0 -36
  55. data/lib/rspec/matchers/eq.rb +0 -36
  56. data/lib/rspec/matchers/eql.rb +0 -35
  57. data/lib/rspec/matchers/equal.rb +0 -58
  58. data/lib/rspec/matchers/errors.rb +0 -5
  59. data/lib/rspec/matchers/exist.rb +0 -34
  60. data/lib/rspec/matchers/has.rb +0 -44
  61. data/lib/rspec/matchers/have.rb +0 -162
  62. data/lib/rspec/matchers/include.rb +0 -66
  63. data/lib/rspec/matchers/match.rb +0 -21
  64. data/lib/rspec/matchers/match_array.rb +0 -65
  65. data/lib/rspec/matchers/raise_error.rb +0 -116
  66. data/lib/rspec/matchers/respond_to.rb +0 -80
  67. data/lib/rspec/matchers/satisfy.rb +0 -46
  68. data/lib/rspec/matchers/throw_symbol.rb +0 -112
@@ -0,0 +1,33 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ require 'rspec/matchers/built_in/base_matcher'
5
+ autoload :BeAnInstanceOf, 'rspec/matchers/built_in/be_instance_of'
6
+ autoload :Be, 'rspec/matchers/built_in/be'
7
+ autoload :BeTrue, 'rspec/matchers/built_in/be'
8
+ autoload :BeFalse, 'rspec/matchers/built_in/be'
9
+ autoload :BeNil, 'rspec/matchers/built_in/be'
10
+ autoload :BeComparedTo, 'rspec/matchers/built_in/be'
11
+ autoload :BePredicate, 'rspec/matchers/built_in/be'
12
+ autoload :BeAKindOf, 'rspec/matchers/built_in/be_kind_of'
13
+ autoload :BeWithin, 'rspec/matchers/built_in/be_within'
14
+ autoload :Change, 'rspec/matchers/built_in/change'
15
+ autoload :Cover, 'rspec/matchers/built_in/cover' if (1..2).respond_to?(:cover?)
16
+ autoload :Eq, 'rspec/matchers/built_in/eq'
17
+ autoload :Eql, 'rspec/matchers/built_in/eql'
18
+ autoload :Equal, 'rspec/matchers/built_in/equal'
19
+ autoload :Exist, 'rspec/matchers/built_in/exist'
20
+ autoload :Has, 'rspec/matchers/built_in/has'
21
+ autoload :Have, 'rspec/matchers/built_in/have'
22
+ autoload :Include, 'rspec/matchers/built_in/include'
23
+ autoload :Match, 'rspec/matchers/built_in/match'
24
+ autoload :MatchArray, 'rspec/matchers/built_in/match_array'
25
+ autoload :RaiseError, 'rspec/matchers/built_in/raise_error'
26
+ autoload :RespondTo, 'rspec/matchers/built_in/respond_to'
27
+ autoload :Satisfy, 'rspec/matchers/built_in/satisfy'
28
+ autoload :ThrowSymbol, 'rspec/matchers/built_in/throw_symbol'
29
+ end
30
+ end
31
+ end
32
+
33
+
@@ -0,0 +1,58 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ # @api private
5
+ #
6
+ # Used _internally_ as a base class for matchers that ship with
7
+ # rspec-expectations.
8
+ #
9
+ # ### Warning:
10
+ #
11
+ # This class is for internal use, and subject to change without notice. We
12
+ # strongly recommend that you do not base your custom matchers on this
13
+ # class. If/when this changes, we will announce it and remove this warning.
14
+ module BaseMatcher
15
+ include RSpec::Matchers::Pretty
16
+
17
+ attr_reader :actual, :expected, :rescued_exception
18
+
19
+ def initialize(expected=nil)
20
+ @expected = expected
21
+ end
22
+
23
+ def matches?(actual)
24
+ @actual = actual
25
+ end
26
+
27
+ def match_unless_raises(exception=Exception)
28
+ begin
29
+ yield
30
+ true
31
+ rescue exception => @rescued_exception
32
+ false
33
+ end
34
+ end
35
+
36
+ def failure_message_for_should
37
+ "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"
38
+ end
39
+
40
+ def failure_message_for_should_not
41
+ "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"
42
+ end
43
+
44
+ def description
45
+ expected ? "#{name_to_sentence} #{expected.inspect}" : name_to_sentence
46
+ end
47
+
48
+ def diffable?
49
+ false
50
+ end
51
+
52
+ def ==(other)
53
+ matches?(other)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,183 @@
1
+ require 'rspec/matchers/dsl'
2
+
3
+ module RSpec
4
+ module Matchers
5
+ module BuiltIn
6
+ class BeTrue
7
+ include BaseMatcher
8
+
9
+ def matches?(actual)
10
+ super(actual)
11
+ end
12
+ end
13
+
14
+ class BeFalse
15
+ include BaseMatcher
16
+
17
+ def matches?(actual)
18
+ !super(actual)
19
+ end
20
+ end
21
+
22
+ class BeNil
23
+ include BaseMatcher
24
+
25
+ def matches?(actual)
26
+ super(actual).nil?
27
+ end
28
+
29
+ def failure_message_for_should
30
+ "expected: nil\n got: #{actual.inspect}"
31
+ end
32
+
33
+ def failure_message_for_should_not
34
+ "expected: not nil\n got: nil"
35
+ end
36
+ end
37
+
38
+ class Be
39
+ include RSpec::Matchers::Pretty
40
+
41
+ def initialize(*args, &block)
42
+ @args = args
43
+ end
44
+
45
+ def matches?(actual)
46
+ @actual = actual
47
+ !!@actual
48
+ end
49
+
50
+ def failure_message_for_should
51
+ "expected #{@actual.inspect} to evaluate to true"
52
+ end
53
+
54
+ def failure_message_for_should_not
55
+ "expected #{@actual.inspect} to evaluate to false"
56
+ end
57
+
58
+ def description
59
+ "be"
60
+ end
61
+
62
+ [:==, :<, :<=, :>=, :>, :===].each do |operator|
63
+ define_method operator do |operand|
64
+ BeComparedTo.new(operand, operator)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def args_to_s
71
+ @args.empty? ? "" : parenthesize(inspected_args.join(', '))
72
+ end
73
+
74
+ def parenthesize(string)
75
+ "(#{string})"
76
+ end
77
+
78
+ def inspected_args
79
+ @args.collect{|a| a.inspect}
80
+ end
81
+
82
+ def expected_to_sentence
83
+ split_words(@expected)
84
+ end
85
+
86
+ def args_to_sentence
87
+ to_sentence(@args)
88
+ end
89
+ end
90
+
91
+ class BeComparedTo < Be
92
+ def initialize(operand, operator)
93
+ @expected, @operator = operand, operator
94
+ @args = []
95
+ end
96
+
97
+ def matches?(actual)
98
+ @actual = actual
99
+ @actual.__send__(@operator, @expected)
100
+ end
101
+
102
+ def failure_message_for_should
103
+ "expected: #{@operator} #{@expected.inspect}\n got: #{@operator.to_s.gsub(/./, ' ')} #{@actual.inspect}"
104
+ end
105
+
106
+ def failure_message_for_should_not
107
+ message = <<-MESSAGE
108
+ 'should_not be #{@operator} #{@expected}' not only FAILED,
109
+ it is a bit confusing.
110
+ MESSAGE
111
+
112
+ raise message << ([:===,:==].include?(@operator) ?
113
+ "It might be more clearly expressed without the \"be\"?" :
114
+ "It might be more clearly expressed in the positive?")
115
+ end
116
+
117
+ def description
118
+ "be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
119
+ end
120
+ end
121
+
122
+ class BePredicate < Be
123
+ def initialize(*args, &block)
124
+ @expected = parse_expected(args.shift)
125
+ @args = args
126
+ @block = block
127
+ end
128
+
129
+ def matches?(actual)
130
+ @actual = actual
131
+ begin
132
+ return @result = actual.__send__(predicate, *@args, &@block)
133
+ rescue NameError => predicate_missing_error
134
+ "this needs to be here or rcov will not count this branch even though it's executed in a code example"
135
+ end
136
+
137
+ begin
138
+ return @result = actual.__send__(present_tense_predicate, *@args, &@block)
139
+ rescue NameError
140
+ raise predicate_missing_error
141
+ end
142
+ end
143
+
144
+ def failure_message_for_should
145
+ "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
146
+ end
147
+
148
+ def failure_message_for_should_not
149
+ "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
150
+ end
151
+
152
+ def description
153
+ "#{prefix_to_sentence}#{expected_to_sentence}#{args_to_sentence}"
154
+ end
155
+
156
+ private
157
+
158
+ def predicate
159
+ "#{@expected}?".to_sym
160
+ end
161
+
162
+ def present_tense_predicate
163
+ "#{@expected}s?".to_sym
164
+ end
165
+
166
+ def parse_expected(expected)
167
+ @prefix, expected = prefix_and_expected(expected)
168
+ expected
169
+ end
170
+
171
+ def prefix_and_expected(symbol)
172
+ symbol.to_s =~ /^(be_(an?_)?)(.*)/
173
+ return $1, $3
174
+ end
175
+
176
+ def prefix_to_sentence
177
+ split_words(@prefix)
178
+ end
179
+ end
180
+ end
181
+
182
+ end
183
+ end
@@ -0,0 +1,13 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class BeAnInstanceOf
5
+ include BaseMatcher
6
+
7
+ def matches?(actual)
8
+ super(actual).instance_of?(expected)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class BeAKindOf
5
+ include BaseMatcher
6
+
7
+ def matches?(actual)
8
+ super(actual).kind_of?(expected)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class BeWithin
5
+ include BaseMatcher
6
+
7
+ attr_reader :delta
8
+
9
+ def initialize(delta)
10
+ @delta = delta
11
+ end
12
+
13
+ def matches?(actual)
14
+ unless defined?(@expected)
15
+ raise ArgumentError.new("You must set an expected value using #of: be_within(#{delta}).of(expected_value)")
16
+ end
17
+ (super(actual) - expected).abs < delta
18
+ end
19
+
20
+ def of(expected)
21
+ @expected = expected
22
+ self
23
+ end
24
+
25
+ def failure_message_for_should
26
+ "expected #{actual} to #{description}"
27
+ end
28
+
29
+ def failure_message_for_should_not
30
+ "expected #{actual} not to #{description}"
31
+ end
32
+
33
+ def description
34
+ "be within #{delta} of #{expected}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,132 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class Change
5
+ def initialize(receiver=nil, message=nil, &block)
6
+ @message = message
7
+ @value_proc = block || lambda {receiver.__send__(message)}
8
+ @expected_after = @expected_before = @minimum = @maximum = @expected_delta = nil
9
+ @eval_before = @eval_after = false
10
+ end
11
+
12
+ def matches?(event_proc)
13
+ raise_block_syntax_error if block_given?
14
+
15
+ @actual_before = evaluate_value_proc
16
+ event_proc.call
17
+ @actual_after = evaluate_value_proc
18
+
19
+ (!change_expected? || changed?) && matches_before? && matches_after? && matches_expected_delta? && matches_min? && matches_max?
20
+ end
21
+
22
+ def raise_block_syntax_error
23
+ raise SyntaxError.new(<<-MESSAGE)
24
+ block passed to should or should_not change must use {} instead of do/end
25
+ MESSAGE
26
+ end
27
+
28
+ def evaluate_value_proc
29
+ case val = @value_proc.call
30
+ when Enumerable
31
+ val.dup
32
+ else
33
+ val
34
+ end
35
+ end
36
+
37
+ def failure_message_for_should
38
+ if @eval_before && !expected_matches_actual?(@expected_before, @actual_before)
39
+ "#{message} should have initially been #{@expected_before.inspect}, but was #{@actual_before.inspect}"
40
+ elsif @eval_after && !expected_matches_actual?(@expected_after, @actual_after)
41
+ "#{message} should have been changed to #{@expected_after.inspect}, but is now #{@actual_after.inspect}"
42
+ elsif @expected_delta
43
+ "#{message} should have been changed by #{@expected_delta.inspect}, but was changed by #{actual_delta.inspect}"
44
+ elsif @minimum
45
+ "#{message} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}"
46
+ elsif @maximum
47
+ "#{message} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}"
48
+ else
49
+ "#{message} should have changed, but is still #{@actual_before.inspect}"
50
+ end
51
+ end
52
+
53
+ def actual_delta
54
+ @actual_after - @actual_before
55
+ end
56
+
57
+ def failure_message_for_should_not
58
+ "#{message} should not have changed, but did change from #{@actual_before.inspect} to #{@actual_after.inspect}"
59
+ end
60
+
61
+ def by(expected_delta)
62
+ @expected_delta = expected_delta
63
+ self
64
+ end
65
+
66
+ def by_at_least(minimum)
67
+ @minimum = minimum
68
+ self
69
+ end
70
+
71
+ def by_at_most(maximum)
72
+ @maximum = maximum
73
+ self
74
+ end
75
+
76
+ def to(to)
77
+ @eval_after = true
78
+ @expected_after = to
79
+ self
80
+ end
81
+
82
+ def from (before)
83
+ @eval_before = true
84
+ @expected_before = before
85
+ self
86
+ end
87
+
88
+ def description
89
+ "change ##{message}"
90
+ end
91
+
92
+ private
93
+
94
+ def message
95
+ @message || "result"
96
+ end
97
+
98
+ def change_expected?
99
+ @expected_delta != 0
100
+ end
101
+
102
+ def changed?
103
+ @actual_before != @actual_after
104
+ end
105
+
106
+ def matches_before?
107
+ @eval_before ? expected_matches_actual?(@expected_before, @actual_before) : true
108
+ end
109
+
110
+ def matches_after?
111
+ @eval_after ? expected_matches_actual?(@expected_after, @actual_after) : true
112
+ end
113
+
114
+ def matches_expected_delta?
115
+ @expected_delta ? (@actual_before + @expected_delta == @actual_after) : true
116
+ end
117
+
118
+ def matches_min?
119
+ @minimum ? (@actual_after - @actual_before >= @minimum) : true
120
+ end
121
+
122
+ def matches_max?
123
+ @maximum ? (@actual_after - @actual_before <= @maximum) : true
124
+ end
125
+
126
+ def expected_matches_actual?(expected, actual)
127
+ expected === actual
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end