Class: RSpec::Matchers::DSL::Matcher

Inherits:
Object
  • Object
show all
Includes:
RSpec::Matchers, Pretty
Defined in:
lib/rspec/matchers/matcher.rb

Overview

Provides the context in which the block passed to RSpec::Matchers.define will be evaluated.

Constant Summary

PERSISTENT_INSTANCE_VARIABLES =
[
  :@name, :@declarations, :@diffable,
  :@match_block, :@match_for_should_not_block,
  :@expected_exception
].to_set

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Methods included from RSpec::Matchers

#be, #be_a, #be_a_kind_of, #be_an_instance_of, #be_close, #be_false, #be_nil, #be_true, #be_within, #change, clear_generated_description, configuration, #cover, #end_with, #eq, #eql, #equal, #exist, generated_description, #have, #have_at_least, #have_at_most, is_a_matcher?, #match_array, #raise_error, #respond_to, #satisfy, #start_with, #throw_symbol, #yield_control, #yield_successive_args, #yield_with_args, #yield_with_no_args

Methods included from Pretty

#_pretty_print, #expected_to_sentence, #name, #name_to_sentence, #split_words, #to_sentence, #to_word, #underscore

Constructor Details

- (Matcher) initialize(name, &declarations)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A new instance of Matcher



16
17
18
19
20
21
22
23
24
# File 'lib/rspec/matchers/matcher.rb', line 16

def initialize(name, &declarations)
  @name         = name
  @declarations = declarations
  @actual       = nil
  @diffable     = false
  @expected_exception, @rescued_exception = nil, nil
  @match_for_should_not_block = nil
  @messages = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(method, *args, &block) (private)



229
230
231
232
233
234
235
# File 'lib/rspec/matchers/matcher.rb', line 229

def method_missing(method, *args, &block)
  if matcher_execution_context.respond_to?(method)
    matcher_execution_context.__send__ method, *args, &block
  else
    super(method, *args, &block)
  end
end

Instance Attribute Details

- (Object) actual (readonly)

Returns the value of attribute actual



12
13
14
# File 'lib/rspec/matchers/matcher.rb', line 12

def actual
  @actual
end

- (Object) expected (readonly)

Returns the value of attribute expected



12
13
14
# File 'lib/rspec/matchers/matcher.rb', line 12

def expected
  @expected
end

- (Object) matcher_execution_context

Returns the value of attribute matcher_execution_context



13
14
15
# File 'lib/rspec/matchers/matcher.rb', line 13

def matcher_execution_context
  @matcher_execution_context
end

- (Object) rescued_exception (readonly)

Returns the value of attribute rescued_exception



12
13
14
# File 'lib/rspec/matchers/matcher.rb', line 12

def rescued_exception
  @rescued_exception
end

Instance Method Details

- (Object) chain(method, &block)

Convenience for defining methods on this matcher to create a fluent interface. The trick about fluent interfaces is that each method must return self in order to chain methods together. chain handles that for you.

Examples:


RSpec::Matchers.define :have_errors_on do |key|
  chain :with do |message|
    @message = message
  end

  match do |actual|
    actual.errors[key] == @message
  end
end

minor.should have_errors_on(:age).with("Not old enough to participate")


201
202
203
204
205
206
# File 'lib/rspec/matchers/matcher.rb', line 201

def chain(method, &block)
  define_method method do |*args|
    block.call(*args)
    self
  end
end

- (Object) description(&block)

Customize the description to use for one-liners. Only use this when the description generated by default doesn't suit your needs.

Examples:


RSpec::Matchers.define :qualify_for do |expected|
  match { ... }

  description do
    "qualify for #{expected}"
  end
end


173
174
175
# File 'lib/rspec/matchers/matcher.rb', line 173

def description(&block)
  cache_or_call_cached(:description, &block)
end

- (Object) diffable

Tells the matcher to diff the actual and expected values in the failure message.



179
180
181
# File 'lib/rspec/matchers/matcher.rb', line 179

def diffable
  @diffable = true
end

- (Boolean) diffable?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Used internally by objects returns by +should+ and +should_not+.

Returns:

  • (Boolean)


210
211
212
# File 'lib/rspec/matchers/matcher.rb', line 210

def diffable?
  @diffable
end

- (Boolean) does_not_match?(actual)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Used internally by +should_not+

Returns:

  • (Boolean)


216
217
218
219
220
221
# File 'lib/rspec/matchers/matcher.rb', line 216

def does_not_match?(actual)
  @actual = actual
  @match_for_should_not_block ?
    instance_exec(actual, &@match_for_should_not_block) :
    !matches?(actual)
end

- (Object) failure_message_for_should {|Object| ... }

Customize the failure messsage to use when this matcher is invoked with should. Only use this when the message generated by default doesn't suit your needs.

Examples:


RSpec::Matchers.define :have_strength do |expected|
  match { ... }

  failure_message_for_should do |actual|
    "Expected strength of #{expected}, but had #{actual.strength}"
  end
end

Yields:

  • (Object)

    actual the actual object



136
137
138
# File 'lib/rspec/matchers/matcher.rb', line 136

def failure_message_for_should(&block)
  cache_or_call_cached(:failure_message_for_should, &block)
end

- (Object) failure_message_for_should_not {|Object| ... }

Customize the failure messsage to use when this matcher is invoked with should_not. Only use this when the message generated by default doesn't suit your needs.

Examples:


RSpec::Matchers.define :have_strength do |expected|
  match { ... }

  failure_message_for_should_not do |actual|
    "Expected not to have strength of #{expected}, but did"
  end
end

Yields:

  • (Object)

    actual the actual object

  • (Object)

    actual the actual object



156
157
158
# File 'lib/rspec/matchers/matcher.rb', line 156

def failure_message_for_should_not(&block)
  cache_or_call_cached(:failure_message_for_should_not, &block)
end

- (Object) for_expected(*expected)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rspec/matchers/matcher.rb', line 33

def for_expected(*expected)
  @expected = expected
  dup.instance_eval do
    instance_variables.map {|ivar| ivar.intern}.each do |ivar|
      instance_variable_set(ivar, nil) unless (PERSISTENT_INSTANCE_VARIABLES + [:@expected]).include?(ivar)
    end
    @messages = {}
    instance_exec(*@expected, &@declarations)
    self
  end
end

- (Object) match {|Object| ... } Also known as: match_for_should

Stores the block that is used to determine whether this matcher passes or fails. The block should return a boolean value. When the matcher is passed to should and the block returns true, then the expectation passes. Similarly, when the matcher is passed to should_not and the block returns false, then the expectation passes.

Use match_for_should when used in conjuntion with match_for_should_not.

Examples:


RSpec::Matchers.define :be_even do
  match do |actual|
    actual.even?
  end
end

4.should be_even     # passes
3.should_not be_even # passes
3.should be_even     # fails
4.should_not be_even # fails

Yields:

  • (Object)

    actual the actual value (or receiver of should)



88
89
90
# File 'lib/rspec/matchers/matcher.rb', line 88

def match(&block)
  @match_block = block
end

- (Object) match_for_should_not {|Object| ... }

Use this to define the block for a negative expectation (should_not) when the positive and negative forms require different handling. This is rarely necessary, but can be helpful, for example, when specifying asynchronous processes that require different timeouts.

Yields:

  • (Object)

    actual the actual value (or receiver of should)



100
101
102
# File 'lib/rspec/matchers/matcher.rb', line 100

def match_for_should_not(&block)
  @match_for_should_not_block = block
end

- (Object) match_unless_raises(exception = Exception, &block)

Use this instead of match when the block will raise an exception rather than returning false to indicate a failure.

Examples:


RSpec::Matchers.define :accept_as_valid do |candidate_address|
  match_unless_raises ValidationException do |validator|
    validator.validate(candidate_address)
  end
end

email_validator.should accept_as_valid("person@company.com")


116
117
118
119
# File 'lib/rspec/matchers/matcher.rb', line 116

def match_unless_raises(exception=Exception, &block)
  @expected_exception = exception
  match(&block)
end

- (Boolean) matches?(actual)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Used internally by +should+ and +should_not+.

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rspec/matchers/matcher.rb', line 47

def matches?(actual)
  @actual = actual
  if @expected_exception
    begin
      instance_exec(actual, &@match_block)
      true
    rescue @expected_exception => @rescued_exception
      false
    end
  else
    begin
      instance_exec(actual, &@match_block)
    rescue RSpec::Expectations::ExpectationNotMetError
      false
    end
  end
end

- (Boolean) respond_to?(method, include_private = false)

Returns:

  • (Boolean)


223
224
225
# File 'lib/rspec/matchers/matcher.rb', line 223

def respond_to?(method, include_private=false)
  super || matcher_execution_context.respond_to?(method, include_private)
end