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.
Files changed (41) hide show
  1. data/Changelog.md +24 -1
  2. data/README.md +36 -2
  3. data/features/built_in_matchers/be.feature +52 -14
  4. data/features/syntax_configuration.feature +68 -0
  5. data/lib/rspec/expectations.rb +2 -0
  6. data/lib/rspec/expectations/expectation_target.rb +52 -0
  7. data/lib/rspec/expectations/extensions.rb +0 -1
  8. data/lib/rspec/expectations/syntax.rb +105 -0
  9. data/lib/rspec/expectations/version.rb +1 -1
  10. data/lib/rspec/matchers.rb +12 -5
  11. data/lib/rspec/matchers/built_in/base_matcher.rb +16 -7
  12. data/lib/rspec/matchers/built_in/be.rb +27 -25
  13. data/lib/rspec/matchers/built_in/be_instance_of.rb +3 -5
  14. data/lib/rspec/matchers/built_in/be_kind_of.rb +3 -5
  15. data/lib/rspec/matchers/built_in/be_within.rb +17 -11
  16. data/lib/rspec/matchers/built_in/cover.rb +5 -6
  17. data/lib/rspec/matchers/built_in/eq.rb +4 -8
  18. data/lib/rspec/matchers/built_in/eql.rb +3 -5
  19. data/lib/rspec/matchers/built_in/equal.rb +6 -10
  20. data/lib/rspec/matchers/built_in/exist.rb +11 -13
  21. data/lib/rspec/matchers/built_in/include.rb +5 -6
  22. data/lib/rspec/matchers/built_in/match.rb +3 -4
  23. data/lib/rspec/matchers/built_in/match_array.rb +7 -14
  24. data/lib/rspec/matchers/built_in/start_and_end_with.rb +1 -3
  25. data/lib/rspec/matchers/built_in/yield.rb +2 -5
  26. data/lib/rspec/matchers/configuration.rb +66 -0
  27. data/spec/rspec/expectations/expectation_target_spec.rb +65 -0
  28. data/spec/rspec/expectations/extensions/kernel_spec.rb +22 -0
  29. data/spec/rspec/matchers/base_matcher_spec.rb +8 -6
  30. data/spec/rspec/matchers/be_spec.rb +2 -2
  31. data/spec/rspec/matchers/be_within_spec.rb +9 -1
  32. data/spec/rspec/matchers/configuration_spec.rb +160 -0
  33. data/spec/rspec/matchers/eq_spec.rb +16 -4
  34. data/spec/rspec/matchers/equal_spec.rb +7 -7
  35. data/spec/rspec/matchers/match_array_spec.rb +12 -0
  36. data/spec/rspec/matchers/yield_spec.rb +3 -3
  37. data/spec/support/in_sub_process.rb +31 -0
  38. metadata +16 -9
  39. data/lib/rspec/expectations/extensions/kernel.rb +0 -26
  40. data/lib/rspec/matchers/block_aliases.rb +0 -21
  41. 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
- module BaseMatcher
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
- return false
34
+ false
33
35
  end
34
- true
35
36
  end
36
37
 
37
38
  def failure_message_for_should
38
- "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"
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
- "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"
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
- include BaseMatcher
6
+ class BeTrue < BaseMatcher
7
+ def match(_, actual)
8
+ !!actual
9
+ end
8
10
 
9
- def matches?(actual)
10
- super(actual)
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
- include BaseMatcher
20
+ class BeFalse < BaseMatcher
21
+ def match(_, actual)
22
+ !actual
23
+ end
16
24
 
17
- def matches?(actual)
18
- !super(actual)
25
+ def failure_message_for_should
26
+ "expected: false value\n got: #{actual.inspect}"
19
27
  end
20
- end
21
28
 
22
- class BeNil
23
- include BaseMatcher
29
+ def failure_message_for_should_not
30
+ "expected: non-false value\n got: #{actual.inspect}"
31
+ end
32
+ end
24
33
 
25
- def matches?(actual)
26
- super(actual).nil?
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 matches?(actual)
46
- @actual = actual
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.__send__(@operator, @expected)
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
- include BaseMatcher
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
- include BaseMatcher
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
- 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
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
- super(expected)
6
+ @expected = expected
9
7
  end
10
8
 
11
9
  def matches?(range)
12
- expected.all? {|e| super(range).cover?(e)}
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
- include BaseMatcher
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
- include BaseMatcher
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
- include BaseMatcher
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 == expected' if you don't care about
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
- private
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
- include BaseMatcher
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
- super(actual)
13
- predicates = [:exist?, :exists?].select { |p| actual.respond_to?(p) }
14
- existance_values = predicates.map { |p| actual.send(p, *expected) }
15
- uniq_truthy_values = existance_values.map { |v| !!v }.uniq
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; existance_values.first
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?: #{existance_values.first}\n" +
22
- "exists?: #{existance_values.last}"
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
- super(expected)
6
+ @expected = expected
9
7
  end
10
8
 
11
9
  def matches?(actual)
12
- perform_match(:all?, :all?, super(actual), expected)
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,11 +1,10 @@
1
1
  module RSpec
2
2
  module Matchers
3
3
  module BuiltIn
4
- class Match
5
- include BaseMatcher
4
+ class Match < BaseMatcher
6
5
 
7
- def matches?(actual)
8
- super(actual).match(expected)
6
+ def match(expected, actual)
7
+ actual.match expected
9
8
  end
10
9
  end
11
10
  end
@@ -1,23 +1,16 @@
1
1
  module RSpec
2
2
  module Matchers
3
3
  module BuiltIn
4
- class MatchArray
5
- include RSpec::Matchers::Pretty
6
-
7
- def initialize(expected)
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(@expected).inspect}\n"
20
- message += "actual collection contained: #{safe_sort(@actual).inspect}\n"
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(@expected)}"
24
+ "contain exactly #{_pretty_print(expected)}"
32
25
  end
33
26
 
34
27
  private