rspec-expectations 2.10.0 → 2.11.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/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
|