rspec-expectations 2.10.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +24 -1
- data/README.md +36 -2
- data/features/built_in_matchers/be.feature +52 -14
- data/features/syntax_configuration.feature +68 -0
- data/lib/rspec/expectations.rb +2 -0
- data/lib/rspec/expectations/expectation_target.rb +52 -0
- data/lib/rspec/expectations/extensions.rb +0 -1
- data/lib/rspec/expectations/syntax.rb +105 -0
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +12 -5
- data/lib/rspec/matchers/built_in/base_matcher.rb +16 -7
- data/lib/rspec/matchers/built_in/be.rb +27 -25
- data/lib/rspec/matchers/built_in/be_instance_of.rb +3 -5
- data/lib/rspec/matchers/built_in/be_kind_of.rb +3 -5
- data/lib/rspec/matchers/built_in/be_within.rb +17 -11
- data/lib/rspec/matchers/built_in/cover.rb +5 -6
- data/lib/rspec/matchers/built_in/eq.rb +4 -8
- data/lib/rspec/matchers/built_in/eql.rb +3 -5
- data/lib/rspec/matchers/built_in/equal.rb +6 -10
- data/lib/rspec/matchers/built_in/exist.rb +11 -13
- data/lib/rspec/matchers/built_in/include.rb +5 -6
- data/lib/rspec/matchers/built_in/match.rb +3 -4
- data/lib/rspec/matchers/built_in/match_array.rb +7 -14
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +1 -3
- data/lib/rspec/matchers/built_in/yield.rb +2 -5
- data/lib/rspec/matchers/configuration.rb +66 -0
- data/spec/rspec/expectations/expectation_target_spec.rb +65 -0
- data/spec/rspec/expectations/extensions/kernel_spec.rb +22 -0
- data/spec/rspec/matchers/base_matcher_spec.rb +8 -6
- data/spec/rspec/matchers/be_spec.rb +2 -2
- data/spec/rspec/matchers/be_within_spec.rb +9 -1
- data/spec/rspec/matchers/configuration_spec.rb +160 -0
- data/spec/rspec/matchers/eq_spec.rb +16 -4
- data/spec/rspec/matchers/equal_spec.rb +7 -7
- data/spec/rspec/matchers/match_array_spec.rb +12 -0
- data/spec/rspec/matchers/yield_spec.rb +3 -3
- data/spec/support/in_sub_process.rb +31 -0
- metadata +16 -9
- data/lib/rspec/expectations/extensions/kernel.rb +0 -26
- data/lib/rspec/matchers/block_aliases.rb +0 -21
- data/spec/rspec/matchers/compatibility_spec.rb +0 -28
@@ -11,39 +11,42 @@ module RSpec
|
|
11
11
|
# This class is for internal use, and subject to change without notice. We
|
12
12
|
# strongly recommend that you do not base your custom matchers on this
|
13
13
|
# class. If/when this changes, we will announce it and remove this warning.
|
14
|
-
|
14
|
+
class BaseMatcher
|
15
15
|
include RSpec::Matchers::Pretty
|
16
16
|
|
17
17
|
attr_reader :actual, :expected, :rescued_exception
|
18
18
|
|
19
|
-
def initialize(expected=nil)
|
19
|
+
def initialize(expected = nil)
|
20
20
|
@expected = expected
|
21
21
|
end
|
22
22
|
|
23
23
|
def matches?(actual)
|
24
24
|
@actual = actual
|
25
|
+
match(expected, actual)
|
25
26
|
end
|
26
27
|
|
27
28
|
def match_unless_raises(*exceptions)
|
28
29
|
exceptions.unshift Exception if exceptions.empty?
|
29
30
|
begin
|
30
31
|
yield
|
32
|
+
true
|
31
33
|
rescue *exceptions => @rescued_exception
|
32
|
-
|
34
|
+
false
|
33
35
|
end
|
34
|
-
true
|
35
36
|
end
|
36
37
|
|
37
38
|
def failure_message_for_should
|
38
|
-
|
39
|
+
assert_ivars :@actual, :@expected
|
40
|
+
"expected #{@actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"
|
39
41
|
end
|
40
42
|
|
41
43
|
def failure_message_for_should_not
|
42
|
-
|
44
|
+
assert_ivars :@actual, :@expected
|
45
|
+
"expected #{@actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"
|
43
46
|
end
|
44
47
|
|
45
48
|
def description
|
46
|
-
expected ? "#{name_to_sentence} #{expected.inspect}" : name_to_sentence
|
49
|
+
expected ? "#{name_to_sentence} #{@expected.inspect}" : name_to_sentence
|
47
50
|
end
|
48
51
|
|
49
52
|
def diffable?
|
@@ -53,6 +56,12 @@ module RSpec
|
|
53
56
|
def ==(other)
|
54
57
|
matches?(other)
|
55
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def assert_ivars *ivars
|
63
|
+
raise "#{self.class.name} needs to supply #{to_sentence ivars}" unless ivars.all? { |v| instance_variables.map(&:intern).include? v }
|
64
|
+
end
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
@@ -3,27 +3,37 @@ require 'rspec/matchers/dsl'
|
|
3
3
|
module RSpec
|
4
4
|
module Matchers
|
5
5
|
module BuiltIn
|
6
|
-
class BeTrue
|
7
|
-
|
6
|
+
class BeTrue < BaseMatcher
|
7
|
+
def match(_, actual)
|
8
|
+
!!actual
|
9
|
+
end
|
8
10
|
|
9
|
-
def
|
10
|
-
|
11
|
+
def failure_message_for_should
|
12
|
+
"expected: true value\n got: #{actual.inspect}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def failure_message_for_should_not
|
16
|
+
"expected: non-true value\n got: #{actual.inspect}"
|
11
17
|
end
|
12
18
|
end
|
13
19
|
|
14
|
-
class BeFalse
|
15
|
-
|
20
|
+
class BeFalse < BaseMatcher
|
21
|
+
def match(_, actual)
|
22
|
+
!actual
|
23
|
+
end
|
16
24
|
|
17
|
-
def
|
18
|
-
|
25
|
+
def failure_message_for_should
|
26
|
+
"expected: false value\n got: #{actual.inspect}"
|
19
27
|
end
|
20
|
-
end
|
21
28
|
|
22
|
-
|
23
|
-
|
29
|
+
def failure_message_for_should_not
|
30
|
+
"expected: non-false value\n got: #{actual.inspect}"
|
31
|
+
end
|
32
|
+
end
|
24
33
|
|
25
|
-
|
26
|
-
|
34
|
+
class BeNil < BaseMatcher
|
35
|
+
def match(_, actual)
|
36
|
+
actual.nil?
|
27
37
|
end
|
28
38
|
|
29
39
|
def failure_message_for_should
|
@@ -35,16 +45,13 @@ module RSpec
|
|
35
45
|
end
|
36
46
|
end
|
37
47
|
|
38
|
-
class Be
|
39
|
-
include RSpec::Matchers::Pretty
|
40
|
-
|
48
|
+
class Be < BaseMatcher
|
41
49
|
def initialize(*args, &block)
|
42
50
|
@args = args
|
43
51
|
end
|
44
52
|
|
45
|
-
def
|
46
|
-
|
47
|
-
!!@actual
|
53
|
+
def match(_, actual)
|
54
|
+
!!actual
|
48
55
|
end
|
49
56
|
|
50
57
|
def failure_message_for_should
|
@@ -55,10 +62,6 @@ module RSpec
|
|
55
62
|
"expected #{@actual.inspect} to evaluate to false"
|
56
63
|
end
|
57
64
|
|
58
|
-
def description
|
59
|
-
"be"
|
60
|
-
end
|
61
|
-
|
62
65
|
[:==, :<, :<=, :>=, :>, :===].each do |operator|
|
63
66
|
define_method operator do |operand|
|
64
67
|
BeComparedTo.new(operand, operator)
|
@@ -96,7 +99,7 @@ module RSpec
|
|
96
99
|
|
97
100
|
def matches?(actual)
|
98
101
|
@actual = actual
|
99
|
-
@actual.
|
102
|
+
@actual.send @operator, @expected
|
100
103
|
end
|
101
104
|
|
102
105
|
def failure_message_for_should
|
@@ -178,6 +181,5 @@ it is a bit confusing.
|
|
178
181
|
end
|
179
182
|
end
|
180
183
|
end
|
181
|
-
|
182
184
|
end
|
183
185
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class BeAnInstanceOf
|
5
|
-
|
6
|
-
|
7
|
-
def matches?(actual)
|
8
|
-
super(actual).instance_of?(expected)
|
4
|
+
class BeAnInstanceOf < BaseMatcher
|
5
|
+
def match(expected, actual)
|
6
|
+
actual.instance_of? expected
|
9
7
|
end
|
10
8
|
end
|
11
9
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class BeAKindOf
|
5
|
-
|
6
|
-
|
7
|
-
def matches?(actual)
|
8
|
-
super(actual).kind_of?(expected)
|
4
|
+
class BeAKindOf < BaseMatcher
|
5
|
+
def match(expected, actual)
|
6
|
+
actual.kind_of? expected
|
9
7
|
end
|
10
8
|
end
|
11
9
|
end
|
@@ -2,19 +2,15 @@ module RSpec
|
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
4
|
class BeWithin
|
5
|
-
include BaseMatcher
|
6
|
-
|
7
|
-
attr_reader :delta
|
8
|
-
|
9
5
|
def initialize(delta)
|
10
6
|
@delta = delta
|
11
7
|
end
|
12
8
|
|
13
9
|
def matches?(actual)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
(
|
10
|
+
@actual = actual
|
11
|
+
raise needs_expected unless defined? @expected
|
12
|
+
raise needs_numeric unless @actual.is_a? Numeric
|
13
|
+
(@actual - @expected).abs <= @delta
|
18
14
|
end
|
19
15
|
|
20
16
|
def of(expected)
|
@@ -23,15 +19,25 @@ module RSpec
|
|
23
19
|
end
|
24
20
|
|
25
21
|
def failure_message_for_should
|
26
|
-
"expected #{actual} to #{description}"
|
22
|
+
"expected #{@actual} to #{description}"
|
27
23
|
end
|
28
24
|
|
29
25
|
def failure_message_for_should_not
|
30
|
-
"expected #{actual} not to #{description}"
|
26
|
+
"expected #{@actual} not to #{description}"
|
31
27
|
end
|
32
28
|
|
33
29
|
def description
|
34
|
-
"be within #{delta} of #{expected}"
|
30
|
+
"be within #{@delta} of #{@expected}"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def needs_numeric
|
36
|
+
ArgumentError.new "The actual value (#{@actual.inspect}) must be of a `Numeric` type"
|
37
|
+
end
|
38
|
+
|
39
|
+
def needs_expected
|
40
|
+
ArgumentError.new "You must set an expected value using #of: be_within(#{@delta}).of(expected_value)"
|
35
41
|
end
|
36
42
|
end
|
37
43
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class Cover
|
5
|
-
include BaseMatcher
|
6
|
-
|
4
|
+
class Cover < BaseMatcher
|
7
5
|
def initialize(*expected)
|
8
|
-
|
6
|
+
@expected = expected
|
9
7
|
end
|
10
8
|
|
11
9
|
def matches?(range)
|
12
|
-
|
10
|
+
@actual = range
|
11
|
+
@expected.all? { |e| range.cover?(e) }
|
13
12
|
end
|
14
13
|
|
15
14
|
def does_not_match?(range)
|
16
15
|
@actual = range
|
17
|
-
expected.none? {|e| range.cover?(e)}
|
16
|
+
expected.none? { |e| range.cover?(e) }
|
18
17
|
end
|
19
18
|
end
|
20
19
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class Eq
|
5
|
-
|
6
|
-
|
7
|
-
def matches?(actual)
|
8
|
-
super(actual) == expected
|
4
|
+
class Eq < BaseMatcher
|
5
|
+
def match(expected, actual)
|
6
|
+
actual == expected
|
9
7
|
end
|
10
8
|
|
11
9
|
def failure_message_for_should
|
@@ -16,9 +14,7 @@ module RSpec
|
|
16
14
|
"\nexpected: value != #{expected.inspect}\n got: #{actual.inspect}\n\n(compared using ==)\n"
|
17
15
|
end
|
18
16
|
|
19
|
-
def diffable
|
20
|
-
true
|
21
|
-
end
|
17
|
+
def diffable?; true; end
|
22
18
|
end
|
23
19
|
end
|
24
20
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class Eql
|
5
|
-
|
6
|
-
|
7
|
-
def matches?(actual)
|
8
|
-
super(actual).eql?(expected)
|
4
|
+
class Eql < BaseMatcher
|
5
|
+
def match(expected, actual)
|
6
|
+
actual.eql? expected
|
9
7
|
end
|
10
8
|
|
11
9
|
def failure_message_for_should
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class Equal
|
5
|
-
|
6
|
-
|
7
|
-
def matches?(actual)
|
8
|
-
super(actual).equal?(expected)
|
4
|
+
class Equal < BaseMatcher
|
5
|
+
def match(expected, actual)
|
6
|
+
actual.equal? expected
|
9
7
|
end
|
10
8
|
|
11
9
|
def failure_message_for_should
|
@@ -16,7 +14,7 @@ expected #{inspect_object(expected)}
|
|
16
14
|
|
17
15
|
Compared using equal?, which compares object identity,
|
18
16
|
but expected and actual are not the same object. Use
|
19
|
-
'actual.should
|
17
|
+
'actual.should eq(expected)' if you don't care about
|
20
18
|
object identity in this example.
|
21
19
|
|
22
20
|
MESSAGE
|
@@ -33,11 +31,9 @@ Compared using equal?, which compares object identity.
|
|
33
31
|
MESSAGE
|
34
32
|
end
|
35
33
|
|
36
|
-
def diffable
|
37
|
-
true
|
38
|
-
end
|
34
|
+
def diffable?; true; end
|
39
35
|
|
40
|
-
|
36
|
+
private
|
41
37
|
|
42
38
|
def inspect_object(o)
|
43
39
|
"#<#{o.class}:#{o.object_id}> => #{o.inspect}"
|
@@ -1,25 +1,23 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class Exist
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(*args)
|
8
|
-
super(args)
|
4
|
+
class Exist < BaseMatcher
|
5
|
+
def initialize(*expected)
|
6
|
+
@expected = expected
|
9
7
|
end
|
10
8
|
|
11
9
|
def matches?(actual)
|
12
|
-
|
13
|
-
predicates = [:exist?, :exists?].select { |p| actual.respond_to?(p) }
|
14
|
-
|
15
|
-
uniq_truthy_values =
|
10
|
+
@actual = actual
|
11
|
+
predicates = [:exist?, :exists?].select { |p| @actual.respond_to?(p) }
|
12
|
+
existence_values = predicates.map { |p| @actual.send(p, *@expected) }
|
13
|
+
uniq_truthy_values = existence_values.map { |v| !!v }.uniq
|
16
14
|
|
17
15
|
case uniq_truthy_values.size
|
18
|
-
when 0; raise NoMethodError.new("#{actual.inspect} does not respond to either #exist? or #exists?")
|
19
|
-
when 1;
|
16
|
+
when 0; raise NoMethodError.new("#{@actual.inspect} does not respond to either #exist? or #exists?")
|
17
|
+
when 1; existence_values.first
|
20
18
|
else raise "#exist? and #exists? returned different values:\n\n" +
|
21
|
-
" exist?: #{
|
22
|
-
"exists?: #{
|
19
|
+
" exist?: #{existence_values.first}\n" +
|
20
|
+
"exists?: #{existence_values.last}"
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class Include
|
5
|
-
include BaseMatcher
|
6
|
-
|
4
|
+
class Include < BaseMatcher
|
7
5
|
def initialize(*expected)
|
8
|
-
|
6
|
+
@expected = expected
|
9
7
|
end
|
10
8
|
|
11
9
|
def matches?(actual)
|
12
|
-
|
10
|
+
@actual = actual
|
11
|
+
perform_match(:all?, :all?, @actual, @expected)
|
13
12
|
end
|
14
13
|
|
15
14
|
def does_not_match?(actual)
|
16
15
|
@actual = actual
|
17
|
-
perform_match(:none?, :any?, actual, expected)
|
16
|
+
perform_match(:none?, :any?, @actual, @expected)
|
18
17
|
end
|
19
18
|
|
20
19
|
def description
|
@@ -1,23 +1,16 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
module BuiltIn
|
4
|
-
class MatchArray
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@expected = expected
|
9
|
-
end
|
10
|
-
|
11
|
-
def matches?(actual)
|
12
|
-
@actual = actual
|
13
|
-
@extra_items = difference_between_arrays(@actual, @expected)
|
14
|
-
@missing_items = difference_between_arrays(@expected, @actual)
|
4
|
+
class MatchArray < BaseMatcher
|
5
|
+
def match(expected, actual)
|
6
|
+
@extra_items = difference_between_arrays(actual, expected)
|
7
|
+
@missing_items = difference_between_arrays(expected, actual)
|
15
8
|
@extra_items.empty? & @missing_items.empty?
|
16
9
|
end
|
17
10
|
|
18
11
|
def failure_message_for_should
|
19
|
-
message = "expected collection contained: #{safe_sort(
|
20
|
-
message += "actual collection contained: #{safe_sort(
|
12
|
+
message = "expected collection contained: #{safe_sort(expected).inspect}\n"
|
13
|
+
message += "actual collection contained: #{safe_sort(actual).inspect}\n"
|
21
14
|
message += "the missing elements were: #{safe_sort(@missing_items).inspect}\n" unless @missing_items.empty?
|
22
15
|
message += "the extra elements were: #{safe_sort(@extra_items).inspect}\n" unless @extra_items.empty?
|
23
16
|
message
|
@@ -28,7 +21,7 @@ module RSpec
|
|
28
21
|
end
|
29
22
|
|
30
23
|
def description
|
31
|
-
"contain exactly #{_pretty_print(
|
24
|
+
"contain exactly #{_pretty_print(expected)}"
|
32
25
|
end
|
33
26
|
|
34
27
|
private
|