RSpec will also create custom matchers for predicates like has_key?. To
use this feature, just state that the object should have_key(:key) and RSpec will
call has_key?(:key) on the target. For example:

expect(:a=>"A").tohave_key(:a)expect(:a=>"A").tohave_key(:b)# fails

You can use this feature to invoke any predicate that begins with "has_", whether it is
part of the Ruby libraries (like Hash#has_key?) or a method you wrote on your own class.

Note that RSpec does not provide composable aliases for these dynamic predicate
matchers. You can easily define your own aliases, though:

Each of the message-generation methods has access to the block arguments
passed to the create method (in this case, zone). The
failure message methods (failure_message and
failure_message_when_negated) are passed the actual value (the
receiver of expect(..) or expect(..).not_to).

Custom Matcher from scratch

You could also write a custom matcher from scratch, as follows:

classBeInZonedefinitialize(expected)@expected=expectedenddefmatches?(target)@target=target@target.current_zone.eql?(Zone.new(@expected))enddeffailure_message"expected #{@target.inspect} to be in Zone #{@expected}"enddeffailure_message_when_negated"expected #{@target.inspect} not to be in Zone #{@expected}"endend

... and a method like this:

defbe_in_zone(expected)BeInZone.new(expected)end

And then expose the method to your specs. This is normally done
by including the method and the class in a module, which is then
included in your spec:

Making custom matchers composable

Custom matchers can easily participate in composed matcher expressions like these.
Include Composable in your custom matcher to make it support
being composed (matchers defined using the DSL have this included automatically).
Within your matcher's matches? method (or the match block, if using the DSL),
use values_match?(expected, actual) rather than expected == actual.
Under the covers, values_match? is able to match arbitrary
nested data structures containing a mix of both matchers and non-matcher objects.
It uses === and == to perform the matching, considering the values to
match if either returns true. The Composable mixin also provides some helper
methods for surfacing the matcher descriptions within your matcher's description
or failure messages.

RSpec's built-in matchers each have a number of aliases that rephrase the matcher
from a verb phrase (such as be_within) to a noun phrase (such as a_value_within),
which reads better when the matcher is passed as an argument in a composed matcher
expressions, and also uses the noun-phrase wording in the matcher's description,
for readable failure messages. You can alias your custom matchers in similar fashion
using Matchers.alias_matcher.

While the most obvious negated form may be to add a not_ prefix,
the failure messages you get with that form can be confusing (e.g.
"expected [actual] to not [verb], but did not"). We've found it works
best to find a more positive name for the negated form, such as
avoid_changing rather than not_change.

Given a Regexp or String, passes if actual.match(pattern) Given an arbitrary nested data structure (e.g. arrays and hashes), matches if expected === actual || actual == expected for each pair of elements.

Instance Method Details

#aggregate_failures(label = nil, metadata = {}) { ... } ⇒ Object

Note:

The implementation of this feature uses a thread-local variable,
which means that if you have an expectation failure in another thread,
it'll abort like normal.

Allows multiple expectations in the provided block to fail, and then
aggregates them into a single exception, rather than aborting on the
first expectation failure like normal. This allows you to see all
failures from an entire set of expectations without splitting each
off into its own example (which may slow things down if the example
setup is expensive).

label for this aggregation block, which will be
included in the aggregated exception message.

metadata(Hash)(defaults to: {})
—

additional metadata about this failure aggregation
block. If multiple expectations fail, it will be exposed from the
Expectations::MultipleExpectationsNotMetError exception. Mostly
intended for internal RSpec use but you can use it as well.

Yields:

Block containing as many expectation as you want. The block is
simply yielded to, so you can trust that anything that works outside
the block should work within it.

#be(*args) ⇒ ObjectAlso known as:
a_value

Given true, false, or nil, will pass if actual value is true, false or
nil (respectively). Given no args means the caller should satisfy an if
condition (to be or not to be).

Predicates are any Ruby method that ends in a "?" and returns true or
false. Given be_ followed by arbitrary_predicate (without the "?"),
RSpec will match convert that into a query against the target object.

The arbitrary_predicate feature will handle any predicate prefixed with
"be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of) or "be_"
(e.g. be_empty), letting you choose the prefix that best suits the
predicate.

Applied to a proc, specifies that its execution will cause some value to
change.

You can either pass receiver and message, or a block,
but not both.

When passing a block, it must use the { ... } format, not
do/end, as { ... } binds to the change method, whereas do/end
would errantly bind to the expect(..).to or expect(...).not_to method.

You can chain any of the following off of the end to specify details
about the change:

from

to

or any one of:

by

by_at_least

by_at_most

== Notes

Evaluates receiver.message or block before and after it
evaluates the block passed to expect. If the value is the same
object, its before/after hash value is used to see if it has changed.
Therefore, your object needs to properly implement hash to work correctly
with this matcher.

expect( ... ).not_to change supports the form that specifies from
(which specifies what you expect the starting, unchanged value to be)
but does not support forms with subsequent calls to by, by_at_least,
by_at_most or to.

Matches if the actual value ends with the expected value(s). In the case
of a string, matches against the last expected.length characters of the
actual string. In the case of an array, matches against the last
expected.length elements of the actual array.

The match_regex alias is deprecated and is not recommended for use.
It was added in 2.12.1 to facilitate its use from within custom
matchers (due to how the custom matcher DSL was evaluated in 2.x,
match could not be used there), but is no longer needed in 3.x.

Given a Regexp or String, passes if actual.match(pattern)
Given an arbitrary nested data structure (e.g. arrays and hashes),
matches if expected === actual || actual == expected for each
pair of elements.

#output(expected = nil) ⇒ ObjectAlso known as:
a_block_outputting

Note:

to_stdout and to_stderr work by temporarily replacing $stdout or $stderr,
so they're not able to intercept stream output that explicitly uses STDOUT/STDERR
or that uses a reference to $stdout/$stderr that was stored before the
matcher was used.

Note:

to_stdout_from_any_process and to_stderr_from_any_process use Tempfiles, and
are thus significantly (~30x) slower than to_stdout and to_stderr.

With no arg, passes if the block outputs to_stdout or to_stderr.
With a string, passes if the block outputs that specific string to_stdout or to_stderr.
With a regexp or matcher, passes if the block outputs a string to_stdout or to_stderr that matches.

To capture output from any spawned subprocess as well, use to_stdout_from_any_process or
to_stderr_from_any_process. Output from any process that inherits the main process's corresponding
standard stream will be captured.

With no args, matches if any error is raised.
With a named error, matches only if that specific error is raised.
With a named error and messsage specified as a String, matches only if both match.
With a named error and messsage specified as a Regexp, matches only if both match.
Pass an optional block to perform extra verifications on the exception matched

Matches if the actual value starts with the expected value(s). In the
case of a string, matches against the first expected.length characters
of the actual string. In the case of an array, matches against the first
expected.length elements of the actual array.

Your expect block must accept a parameter and pass it on to
the method-under-test as a block.

Note:

This matcher is not designed for use with methods that yield
multiple times.

Passes if the method called in the expect block yields with
no arguments. Fails if it does not yield, or yields with arguments.

Examples:

expect{|b|User.transaction(&b)}.toyield_with_no_argsexpect{|b|5.tap(&b)}.not_toyield_with_no_args# because it yields with `5`
expect{|b|"a".to_sym(&b)}.not_toyield_with_no_args# because it does not yield