-
-
Notifications
You must be signed in to change notification settings - Fork 397
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #119 from rspec/expect_syntax
Add support for `expect(value)` syntax.
- Loading branch information
Showing
12 changed files
with
459 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
module RSpec | ||
module Expectations | ||
# Wraps the target of an expectation. | ||
# @example | ||
# expect(something) # => ExpectationTarget wrapping something | ||
class ExpectationTarget | ||
# @api private | ||
def initialize(target) | ||
@target = target | ||
end | ||
|
||
# Runs the given expectation, passing if `matcher` returns true. | ||
# @example | ||
# expect(value).to eq(5) | ||
# expect { perform }.to raise_error | ||
# @param [Matcher] | ||
# matcher | ||
# @param [String] message optional message to display when the expectation fails | ||
# @return [Boolean] true if the expectation succeeds (else raises) | ||
# @see RSpec::Matchers | ||
def to(matcher=nil, message=nil, &block) | ||
prevent_operator_matchers(:to, matcher) | ||
RSpec::Expectations::PositiveExpectationHandler.handle_matcher(@target, matcher, message, &block) | ||
end | ||
|
||
# Runs the given expectation, passing if `matcher` returns false. | ||
# @example | ||
# expect(value).to_not eq(5) | ||
# expect(value).not_to eq(5) | ||
# @param [Matcher] | ||
# matcher | ||
# @param [String] message optional message to display when the expectation fails | ||
# @return [Boolean] false if the negative expectation succeeds (else raises) | ||
# @see RSpec::Matchers | ||
def to_not(matcher=nil, message=nil, &block) | ||
prevent_operator_matchers(:to_not, matcher) | ||
RSpec::Expectations::NegativeExpectationHandler.handle_matcher(@target, matcher, message, &block) | ||
end | ||
alias not_to to_not | ||
|
||
private | ||
|
||
def prevent_operator_matchers(verb, matcher) | ||
return if matcher | ||
|
||
raise ArgumentError, "The expect syntax does not support operator matchers, " + | ||
"so you must pass a matcher to `##{verb}`." | ||
end | ||
end | ||
end | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,2 @@ | ||
require 'rspec/expectations/extensions/kernel' | ||
require 'rspec/expectations/extensions/array' | ||
require 'rspec/expectations/extensions/object' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
module RSpec | ||
module Expectations | ||
# @api private | ||
# Provides methods for enabling and disabling the available | ||
# syntaxes provided by rspec-expectations. | ||
module Syntax | ||
extend self | ||
|
||
# @api private | ||
# Enables the `should` syntax. | ||
def enable_should(syntax_host = ::Kernel) | ||
return if should_enabled?(syntax_host) | ||
|
||
syntax_host.module_eval do | ||
# Passes if +matcher+ returns true. Available on every +Object+. | ||
# @example | ||
# actual.should eq(expected) | ||
# actual.should be > 4 | ||
# @param [Matcher] | ||
# matcher | ||
# @param [String] message optional message to display when the expectation fails | ||
# @return [Boolean] true if the expectation succeeds (else raises) | ||
# @see RSpec::Matchers | ||
def should(matcher=nil, message=nil, &block) | ||
RSpec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block) | ||
end | ||
|
||
# Passes if +matcher+ returns false. Available on every +Object+. | ||
# @example | ||
# actual.should_not eq(expected) | ||
# @param [Matcher] | ||
# matcher | ||
# @param [String] message optional message to display when the expectation fails | ||
# @return [Boolean] false if the negative expectation succeeds (else raises) | ||
# @see RSpec::Matchers | ||
def should_not(matcher=nil, message=nil, &block) | ||
RSpec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block) | ||
end | ||
end | ||
end | ||
|
||
# @api private | ||
# Disables the `should` syntax. | ||
def disable_should(syntax_host = ::Kernel) | ||
return unless should_enabled?(syntax_host) | ||
|
||
syntax_host.module_eval do | ||
undef should | ||
undef should_not | ||
end | ||
end | ||
|
||
# @api private | ||
# Enables the `expect` syntax. | ||
def enable_expect(syntax_host = ::RSpec::Matchers) | ||
return if expect_enabled?(syntax_host) | ||
|
||
syntax_host.module_eval do | ||
def expect(*target, &target_block) | ||
target << target_block if block_given? | ||
raise ArgumentError.new("You must pass an argument or a block to #expect but not both.") unless target.size == 1 | ||
::RSpec::Expectations::ExpectationTarget.new(target.first) | ||
end | ||
end | ||
end | ||
|
||
# @api private | ||
# Disables the `expect` syntax. | ||
def disable_expect(syntax_host = ::RSpec::Matchers) | ||
return unless expect_enabled?(syntax_host) | ||
|
||
syntax_host.module_eval do | ||
undef expect | ||
end | ||
end | ||
|
||
# @api private | ||
# Indicates whether or not the `should` syntax is enabled. | ||
def should_enabled?(syntax_host = ::Kernel) | ||
syntax_host.method_defined?(:should) | ||
end | ||
|
||
# @api private | ||
# Indicates whether or not the `expect` syntax is enabled. | ||
def expect_enabled?(syntax_host = ::RSpec::Matchers) | ||
syntax_host.method_defined?(:expect) | ||
end | ||
end | ||
end | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require 'rspec/expectations/syntax' | ||
|
||
module RSpec | ||
module Matchers | ||
# Provides configuration options for rspec-expectations. | ||
class Configuration | ||
# Configures the supported syntax. | ||
# @param [Array<Symbol>, Symbol] values the syntaxes to enable | ||
# @example | ||
# RSpec.configure do |rspec| | ||
# rspec.expect_with :rspec do |c| | ||
# c.syntax = :should | ||
# # or | ||
# c.syntax = :expect | ||
# # or | ||
# c.syntax = [:should, :expect] | ||
# end | ||
# end | ||
def syntax=(values) | ||
if Array(values).include?(:expect) | ||
Expectations::Syntax.enable_expect | ||
else | ||
Expectations::Syntax.disable_expect | ||
end | ||
|
||
if Array(values).include?(:should) | ||
Expectations::Syntax.enable_should | ||
else | ||
Expectations::Syntax.disable_should | ||
end | ||
end | ||
|
||
# The list of configured syntaxes. | ||
# @return [Array<Symbol>] the list of configured syntaxes. | ||
def syntax | ||
syntaxes = [] | ||
syntaxes << :should if Expectations::Syntax.should_enabled? | ||
syntaxes << :expect if Expectations::Syntax.expect_enabled? | ||
syntaxes | ||
end | ||
end | ||
|
||
# The configuration object | ||
# @return [RSpec::Matchers::Configuration] the configuration object | ||
def self.configuration | ||
@configuration ||= Configuration.new | ||
end | ||
|
||
# set default syntax | ||
configuration.syntax = [:expect, :should] | ||
end | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
require 'spec_helper' | ||
|
||
module RSpec | ||
module Expectations | ||
# so our examples below can set expectations about the target | ||
ExpectationTarget.send(:attr_reader, :target) | ||
|
||
describe ExpectationTarget do | ||
context 'when constructed via #expect' do | ||
it 'constructs a new instance targetting the given argument' do | ||
expect(7).target.should eq(7) | ||
end | ||
|
||
it 'constructs a new instance targetting the given block' do | ||
block = lambda {} | ||
expect(&block).target.should be(block) | ||
end | ||
|
||
it 'raises an ArgumentError when given an argument and a block' do | ||
lambda { expect(7) { } }.should raise_error(ArgumentError) | ||
end | ||
|
||
it 'raises an ArgumentError when given neither an argument nor a block' do | ||
lambda { expect }.should raise_error(ArgumentError) | ||
end | ||
|
||
it 'can be passed nil' do | ||
expect(nil).target.should be_nil | ||
end | ||
|
||
it 'passes a valid positive expectation' do | ||
expect(5).to eq(5) | ||
end | ||
|
||
it 'passes a valid negative expectation' do | ||
expect(5).to_not eq(4) | ||
expect(5).not_to eq(4) | ||
end | ||
|
||
it 'fails an invalid positive expectation' do | ||
lambda { expect(5).to eq(4) }.should fail_with(/expected: 4.*got: 5/m) | ||
end | ||
|
||
it 'fails an invalid negative expectation' do | ||
message = /expected 5 not to be a kind of Fixnum/ | ||
lambda { expect(5).to_not be_a(Fixnum) }.should fail_with(message) | ||
lambda { expect(5).not_to be_a(Fixnum) }.should fail_with(message) | ||
end | ||
|
||
it 'does not support operator matchers from #to' do | ||
expect { | ||
expect(3).to == 3 | ||
}.to raise_error(ArgumentError) | ||
end | ||
|
||
it 'does not support operator matchers from #not_to' do | ||
expect { | ||
expect(3).not_to == 4 | ||
}.to raise_error(ArgumentError) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
Oops, something went wrong.