1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
module RSpec
module Core
# Provides methods to mark examples as pending. These methods are available
# to be called from within any example or hook.
module Pending
# Raised in the middle of an example to indicate that it should be marked
# as skipped.
class SkipDeclaredInExample < StandardError
attr_reader :argument
def initialize(argument)
@argument = argument
end
end
# If Test::Unit is loaded, we'll use its error as baseclass, so that
# Test::Unit will report unmet RSpec expectations as failures rather than
# errors.
begin
class PendingExampleFixedError < Test::Unit::AssertionFailedError; end
rescue
class PendingExampleFixedError < StandardError; end
end
# @private
NO_REASON_GIVEN = 'No reason given'
# @private
NOT_YET_IMPLEMENTED = 'Not yet implemented'
# @overload pending()
# @overload pending(message)
#
# Marks an example as pending. The rest of the example will still be
# executed, and if it passes the example will fail to indicate that the
# pending can be removed.
#
# @param message [String] optional message to add to the summary report.
#
# @example
# describe "some behaviour" do
# # reported as "Pending: no reason given"
# it "is pending with no message" do
# pending
# raise "broken"
# end
#
# # reported as "Pending: something else getting finished"
# it "is pending with a custom message" do
# pending("something else getting finished")
# raise "broken"
# end
# end
#
# @note When using `pending` inside an example body using this method
# hooks, such as `before(:example)`, have already be run. This means that
# a failure from the code in the `before` hook will prevent the example
# from being considered pending, as the example body would not be
# executed. If you need to consider hooks as pending as well you can use
# the pending metadata as an alternative, e.g.
# `it "does something", pending: "message"`.
def pending(message=nil)
current_example = RSpec.current_example
if block_given?
raise ArgumentError, <<-EOS.gsub(/^\s+\|/, '')
|The semantics of `RSpec::Core::Pending#pending` have changed in
|RSpec 3. In RSpec 2.x, it caused the example to be skipped. In
|RSpec 3, the rest of the example is still run but is expected to
|fail, and will be marked as a failure (rather than as pending) if
|the example passes.
|
|Passing a block within an example is now deprecated. Marking the
|example as pending provides the same behavior in RSpec 3 which was
|provided only by the block in RSpec 2.x.
|
|Move the code in the block provided to `pending` into the rest of
|the example body.
|
|Called from #{CallerFilter.first_non_rspec_line}.
|
EOS
elsif current_example
Pending.mark_pending! current_example, message
else
raise "`pending` may not be used outside of examples, such as in " \
"before(:context). Maybe you want `skip`?"
end
end
# @overload skip()
# @overload skip(message)
#
# Marks an example as pending and skips execution.
#
# @param message [String] optional message to add to the summary report.
#
# @example
# describe "an example" do
# # reported as "Pending: no reason given"
# it "is skipped with no message" do
# skip
# end
#
# # reported as "Pending: something else getting finished"
# it "is skipped with a custom message" do
# skip "something else getting finished"
# end
# end
def skip(message=nil)
current_example = RSpec.current_example
Pending.mark_skipped!(current_example, message) if current_example
raise SkipDeclaredInExample.new(message)
end
# @private
#
# Mark example as skipped.
#
# @param example [RSpec::Core::Example] the example to mark as skipped
# @param message_or_bool [Boolean, String] the message to use, or true
def self.mark_skipped!(example, message_or_bool)
Pending.mark_pending! example, message_or_bool
example.metadata[:skip] = true
end
# @private
#
# Mark example as pending.
#
# @param example [RSpec::Core::Example] the example to mark as pending
# @param message_or_bool [Boolean, String] the message to use, or true
def self.mark_pending!(example, message_or_bool)
message = if !message_or_bool || !(String === message_or_bool)
NO_REASON_GIVEN
else
message_or_bool
end
example.metadata[:pending] = true
example.execution_result.pending_message = message
example.execution_result.pending_fixed = false
end
# @private
#
# Mark example as fixed.
#
# @param example [RSpec::Core::Example] the example to mark as fixed
def self.mark_fixed!(example)
example.execution_result.pending_fixed = true
end
end
end
end
|