remarkable 3.1.8 → 3.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +58 -58
- data/LICENSE +20 -20
- data/README +197 -197
- data/lib/remarkable.rb +18 -18
- data/lib/remarkable/base.rb +55 -56
- data/lib/remarkable/core_ext/array.rb +19 -19
- data/lib/remarkable/dsl.rb +35 -35
- data/lib/remarkable/dsl/assertions.rb +384 -384
- data/lib/remarkable/dsl/callbacks.rb +52 -52
- data/lib/remarkable/dsl/optionals.rb +122 -122
- data/lib/remarkable/i18n.rb +53 -53
- data/lib/remarkable/macros.rb +48 -48
- data/lib/remarkable/matchers.rb +17 -17
- data/lib/remarkable/messages.rb +103 -103
- data/lib/remarkable/pending.rb +66 -66
- data/lib/remarkable/rspec.rb +24 -24
- data/lib/remarkable/version.rb +3 -3
- data/locale/en.yml +14 -14
- data/spec/base_spec.rb +41 -41
- data/spec/dsl/assertions_spec.rb +54 -54
- data/spec/dsl/optionals_spec.rb +237 -237
- data/spec/i18n_spec.rb +41 -41
- data/spec/locale/en.yml +20 -20
- data/spec/locale/pt-BR.yml +21 -21
- data/spec/macros_spec.rb +26 -26
- data/spec/matchers/be_a_person_matcher.rb +25 -25
- data/spec/matchers/collection_contain_matcher.rb +32 -32
- data/spec/matchers/contain_matcher.rb +31 -31
- data/spec/matchers/single_contain_matcher.rb +49 -49
- data/spec/matchers_spec.rb +5 -5
- data/spec/messages_spec.rb +66 -66
- data/spec/pending_spec.rb +7 -7
- data/spec/spec.opts +4 -4
- data/spec/spec_helper.rb +15 -15
- metadata +3 -3
data/lib/remarkable/macros.rb
CHANGED
@@ -1,58 +1,58 @@
|
|
1
1
|
module Remarkable
|
2
2
|
# This class is responsable for converting matchers to macros. You shouldn't
|
3
3
|
# worry with what happens here, because it happens automatically.
|
4
|
-
#
|
5
|
-
module Macros
|
6
|
-
|
7
|
-
protected
|
8
|
-
|
9
|
-
def method_missing(method_id, *args, &block) #:nodoc:
|
10
|
-
if method_id.to_s =~ /^(should_not|should)_(.+)/
|
11
|
-
should_or_should_not_method_missing($1, $2, caller, *args, &block)
|
12
|
-
elsif method_id.to_s =~ /^x(should_not|should)_(.+)/
|
13
|
-
disabled_method_missing($1, $2, *args, &block)
|
14
|
-
else
|
15
|
-
super(method_id, *args, &block)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
4
|
+
#
|
5
|
+
module Macros
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def method_missing(method_id, *args, &block) #:nodoc:
|
10
|
+
if method_id.to_s =~ /^(should_not|should)_(.+)/
|
11
|
+
should_or_should_not_method_missing($1, $2, caller, *args, &block)
|
12
|
+
elsif method_id.to_s =~ /^x(should_not|should)_(.+)/
|
13
|
+
disabled_method_missing($1, $2, *args, &block)
|
14
|
+
else
|
15
|
+
super(method_id, *args, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
19
|
def should_or_should_not_method_missing(should_or_should_not, method, calltrace, *args, &block) #:nodoc:
|
20
20
|
description = if @_pending_group
|
21
21
|
get_description_from_matcher(should_or_should_not, method, *args, &block)
|
22
22
|
else
|
23
23
|
nil
|
24
24
|
end
|
25
|
-
|
26
|
-
example(description){
|
27
|
-
begin
|
28
|
-
send(should_or_should_not, send(method, *args, &block))
|
25
|
+
|
26
|
+
example(description){
|
27
|
+
begin
|
28
|
+
send(should_or_should_not, send(method, *args, &block))
|
29
29
|
rescue Exception => e
|
30
|
-
trace = e.backtrace.to_a + calltrace.to_a
|
31
|
-
e.set_backtrace(trace)
|
32
|
-
raise e
|
33
|
-
end
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
def disabled_method_missing(should_or_should_not, method, *args, &block) #:nodoc:
|
38
|
-
description = get_description_from_matcher(should_or_should_not, method, *args, &block)
|
39
|
-
xexample(description)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Try to get the description from the matcher. If an error is raised, we
|
43
|
-
# deduct the description from the matcher name, but it will be shown in
|
44
|
-
# english.
|
45
|
-
#
|
46
|
-
def get_description_from_matcher(should_or_should_not, method, *args, &block) #:nodoc:
|
47
|
-
verb = should_or_should_not.to_s.gsub('_', ' ')
|
48
|
-
|
49
|
-
desc = Remarkable::Matchers.send(method, *args, &block).spec(self).description
|
50
|
-
verb = Remarkable.t("remarkable.core.#{should_or_should_not}", :default => verb)
|
51
|
-
rescue
|
52
|
-
desc = method.to_s.gsub('_', ' ')
|
53
|
-
ensure
|
54
|
-
verb << ' ' << desc
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
30
|
+
trace = e.backtrace.to_a + calltrace.to_a
|
31
|
+
e.set_backtrace(trace)
|
32
|
+
raise e
|
33
|
+
end
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def disabled_method_missing(should_or_should_not, method, *args, &block) #:nodoc:
|
38
|
+
description = get_description_from_matcher(should_or_should_not, method, *args, &block)
|
39
|
+
xexample(description)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Try to get the description from the matcher. If an error is raised, we
|
43
|
+
# deduct the description from the matcher name, but it will be shown in
|
44
|
+
# english.
|
45
|
+
#
|
46
|
+
def get_description_from_matcher(should_or_should_not, method, *args, &block) #:nodoc:
|
47
|
+
verb = should_or_should_not.to_s.gsub('_', ' ')
|
48
|
+
|
49
|
+
desc = Remarkable::Matchers.send(method, *args, &block).spec(self).description
|
50
|
+
verb = Remarkable.t("remarkable.core.#{should_or_should_not}", :default => verb)
|
51
|
+
rescue
|
52
|
+
desc = method.to_s.gsub('_', ' ')
|
53
|
+
ensure
|
54
|
+
verb << ' ' << desc
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/remarkable/matchers.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
# Remarkable core module
|
2
|
-
module Remarkable
|
3
|
-
# A module that keeps all matchers added. This is useful because it allows
|
4
|
-
# to include matchers in Test::Unit as well.
|
5
|
-
module Matchers; end
|
6
|
-
|
1
|
+
# Remarkable core module
|
2
|
+
module Remarkable
|
3
|
+
# A module that keeps all matchers added. This is useful because it allows
|
4
|
+
# to include matchers in Test::Unit as well.
|
5
|
+
module Matchers; end
|
6
|
+
|
7
7
|
# Helper that includes required Remarkable modules into the given klass.
|
8
8
|
#
|
9
9
|
# If the module to be included responds to :after_include, it's called with the
|
10
10
|
# target as argument.
|
11
|
-
#
|
11
|
+
#
|
12
12
|
def self.include_matchers!(base, target=nil)
|
13
13
|
if target.nil?
|
14
14
|
if rspec_defined?
|
@@ -19,22 +19,22 @@ module Remarkable
|
|
19
19
|
end
|
20
20
|
|
21
21
|
metaclass = (class << target; self; end)
|
22
|
-
target.send :extend, Remarkable::Pending unless metaclass.ancestors.include?(Remarkable::Pending)
|
22
|
+
target.send :extend, Remarkable::Pending unless metaclass.ancestors.include?(Remarkable::Pending)
|
23
23
|
target.send :extend, Remarkable::Macros unless metaclass.ancestors.include?(Remarkable::Macros)
|
24
|
-
|
25
|
-
if defined?(base::Matchers)
|
26
|
-
target.send :include, base::Matchers
|
27
|
-
|
28
|
-
Remarkable::Matchers.send :extend, base::Matchers
|
29
|
-
Remarkable::Matchers.send :include, base::Matchers
|
24
|
+
|
25
|
+
if defined?(base::Matchers)
|
26
|
+
target.send :include, base::Matchers
|
27
|
+
|
28
|
+
Remarkable::Matchers.send :extend, base::Matchers
|
29
|
+
Remarkable::Matchers.send :include, base::Matchers
|
30
30
|
end
|
31
31
|
|
32
32
|
if base.respond_to?(:after_include)
|
33
33
|
base.after_include(target)
|
34
|
-
end
|
34
|
+
end
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.rspec_defined? #:nodoc:
|
38
38
|
defined?(Spec)
|
39
|
-
end
|
40
|
-
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/remarkable/messages.rb
CHANGED
@@ -1,103 +1,103 @@
|
|
1
|
-
module Remarkable
|
2
|
-
# Holds the methods required by rspec for each matcher plus a collection of
|
3
|
-
# helpers to deal with I18n.
|
4
|
-
#
|
5
|
-
module Messages
|
6
|
-
|
7
|
-
# Provides a default description message. Overwrite it if needed.
|
8
|
-
# By default it uses default i18n options, but without the subjects, which
|
9
|
-
# usually are not available when description is called.
|
10
|
-
#
|
11
|
-
def description(options={})
|
12
|
-
options = default_i18n_options.merge(options)
|
13
|
-
|
14
|
-
# Remove subject keys
|
15
|
-
options.delete(:subject_name)
|
16
|
-
options.delete(:subject_inspect)
|
17
|
-
|
18
|
-
Remarkable.t 'description', options
|
19
|
-
end
|
20
|
-
|
21
|
-
# Provides a default failure message. Overwrite it if needed.
|
22
|
-
#
|
23
|
-
def failure_message_for_should
|
24
|
-
Remarkable.t 'remarkable.core.failure_message_for_should', :expectation => @expectation
|
25
|
-
end
|
26
|
-
alias :failure_message :failure_message_for_should
|
27
|
-
|
28
|
-
# Provides a default negative failure message. Overwrite it if needed.
|
29
|
-
#
|
30
|
-
def failure_message_for_should_not
|
31
|
-
Remarkable.t 'remarkable.core.failure_message_for_should_not', :expectation => @expectation
|
32
|
-
end
|
33
|
-
alias :negative_failure_message :failure_message_for_should_not
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
# Returns the matcher scope in I18n.
|
38
|
-
#
|
39
|
-
# If the matcher is Remarkable::ActiveRecord::Matchers::ValidatePresenceOfMatcher
|
40
|
-
# the default scope will be:
|
41
|
-
#
|
42
|
-
# 'remarkable.active_record.validate_presence_of'
|
43
|
-
#
|
44
|
-
def matcher_i18n_scope
|
45
|
-
@matcher_i18n_scope ||= self.class.name.to_s.
|
46
|
-
gsub(/::Matchers::/, '::').
|
47
|
-
gsub(/::/, '.').
|
48
|
-
gsub(/Matcher$/, '').
|
49
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
50
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
51
|
-
tr("-", "_").
|
52
|
-
downcase
|
53
|
-
end
|
54
|
-
|
55
|
-
# Matcher i18n options used in description, failure_message and
|
56
|
-
# negative_failure_message. It provides by default the subject_name and
|
57
|
-
# the subject_inspect value. But when used with DSL, it provides a whole
|
58
|
-
# bunch of options (check dsl/matches.rb for more information).
|
59
|
-
#
|
60
|
-
def default_i18n_options
|
61
|
-
interpolation_options.update(
|
62
|
-
:scope => matcher_i18n_scope,
|
63
|
-
:subject_name => subject_name,
|
64
|
-
:subject_inspect => @subject.inspect
|
65
|
-
)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Method to be overwritten if user wants to provide more interpolation
|
69
|
-
# options to I18n.
|
70
|
-
#
|
71
|
-
def interpolation_options
|
72
|
-
{}
|
73
|
-
end
|
74
|
-
|
75
|
-
# Returns the not word from I18n API.
|
76
|
-
#
|
77
|
-
def not_word
|
78
|
-
Remarkable.t('remarkable.core.not', :default => 'not') + " "
|
79
|
-
end
|
80
|
-
|
81
|
-
# Converts an array to a sentence
|
82
|
-
#
|
83
|
-
def array_to_sentence(array, inspect=false, empty_default='')
|
84
|
-
words_connector = Remarkable.t 'remarkable.core.helpers.words_connector'
|
85
|
-
two_words_connector = Remarkable.t 'remarkable.core.helpers.two_words_connector'
|
86
|
-
last_word_connector = Remarkable.t 'remarkable.core.helpers.last_word_connector'
|
87
|
-
|
88
|
-
array = array.map { |i| i.inspect } if inspect
|
89
|
-
|
90
|
-
case array.length
|
91
|
-
when 0
|
92
|
-
empty_default
|
93
|
-
when 1
|
94
|
-
array[0].to_s
|
95
|
-
when 2
|
96
|
-
"#{array[0]}#{two_words_connector}#{array[1]}"
|
97
|
-
else
|
98
|
-
"#{array[0...-1].join(words_connector)}#{last_word_connector}#{array[-1]}"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
end
|
1
|
+
module Remarkable
|
2
|
+
# Holds the methods required by rspec for each matcher plus a collection of
|
3
|
+
# helpers to deal with I18n.
|
4
|
+
#
|
5
|
+
module Messages
|
6
|
+
|
7
|
+
# Provides a default description message. Overwrite it if needed.
|
8
|
+
# By default it uses default i18n options, but without the subjects, which
|
9
|
+
# usually are not available when description is called.
|
10
|
+
#
|
11
|
+
def description(options={})
|
12
|
+
options = default_i18n_options.merge(options)
|
13
|
+
|
14
|
+
# Remove subject keys
|
15
|
+
options.delete(:subject_name)
|
16
|
+
options.delete(:subject_inspect)
|
17
|
+
|
18
|
+
Remarkable.t 'description', options
|
19
|
+
end
|
20
|
+
|
21
|
+
# Provides a default failure message. Overwrite it if needed.
|
22
|
+
#
|
23
|
+
def failure_message_for_should
|
24
|
+
Remarkable.t 'remarkable.core.failure_message_for_should', :expectation => @expectation
|
25
|
+
end
|
26
|
+
alias :failure_message :failure_message_for_should
|
27
|
+
|
28
|
+
# Provides a default negative failure message. Overwrite it if needed.
|
29
|
+
#
|
30
|
+
def failure_message_for_should_not
|
31
|
+
Remarkable.t 'remarkable.core.failure_message_for_should_not', :expectation => @expectation
|
32
|
+
end
|
33
|
+
alias :negative_failure_message :failure_message_for_should_not
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Returns the matcher scope in I18n.
|
38
|
+
#
|
39
|
+
# If the matcher is Remarkable::ActiveRecord::Matchers::ValidatePresenceOfMatcher
|
40
|
+
# the default scope will be:
|
41
|
+
#
|
42
|
+
# 'remarkable.active_record.validate_presence_of'
|
43
|
+
#
|
44
|
+
def matcher_i18n_scope
|
45
|
+
@matcher_i18n_scope ||= self.class.name.to_s.
|
46
|
+
gsub(/::Matchers::/, '::').
|
47
|
+
gsub(/::/, '.').
|
48
|
+
gsub(/Matcher$/, '').
|
49
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
50
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
51
|
+
tr("-", "_").
|
52
|
+
downcase
|
53
|
+
end
|
54
|
+
|
55
|
+
# Matcher i18n options used in description, failure_message and
|
56
|
+
# negative_failure_message. It provides by default the subject_name and
|
57
|
+
# the subject_inspect value. But when used with DSL, it provides a whole
|
58
|
+
# bunch of options (check dsl/matches.rb for more information).
|
59
|
+
#
|
60
|
+
def default_i18n_options
|
61
|
+
interpolation_options.update(
|
62
|
+
:scope => matcher_i18n_scope,
|
63
|
+
:subject_name => subject_name,
|
64
|
+
:subject_inspect => @subject.inspect
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Method to be overwritten if user wants to provide more interpolation
|
69
|
+
# options to I18n.
|
70
|
+
#
|
71
|
+
def interpolation_options
|
72
|
+
{}
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the not word from I18n API.
|
76
|
+
#
|
77
|
+
def not_word
|
78
|
+
Remarkable.t('remarkable.core.not', :default => 'not') + " "
|
79
|
+
end
|
80
|
+
|
81
|
+
# Converts an array to a sentence
|
82
|
+
#
|
83
|
+
def array_to_sentence(array, inspect=false, empty_default='')
|
84
|
+
words_connector = Remarkable.t 'remarkable.core.helpers.words_connector'
|
85
|
+
two_words_connector = Remarkable.t 'remarkable.core.helpers.two_words_connector'
|
86
|
+
last_word_connector = Remarkable.t 'remarkable.core.helpers.last_word_connector'
|
87
|
+
|
88
|
+
array = array.map { |i| i.inspect } if inspect
|
89
|
+
|
90
|
+
case array.length
|
91
|
+
when 0
|
92
|
+
empty_default
|
93
|
+
when 1
|
94
|
+
array[0].to_s
|
95
|
+
when 2
|
96
|
+
"#{array[0]}#{two_words_connector}#{array[1]}"
|
97
|
+
else
|
98
|
+
"#{array[0...-1].join(words_connector)}#{last_word_connector}#{array[-1]}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
data/lib/remarkable/pending.rb
CHANGED
@@ -1,68 +1,68 @@
|
|
1
|
-
module Remarkable
|
2
|
-
|
3
|
-
module Pending
|
4
|
-
|
5
|
-
# We cannot put the alias method in the module because it's a Ruby 1.8 bug
|
6
|
-
# http://coderrr.wordpress.com/2008/03/28/alias_methodmodule-bug-in-ruby-18/
|
7
|
-
#
|
1
|
+
module Remarkable
|
2
|
+
|
3
|
+
module Pending
|
4
|
+
|
5
|
+
# We cannot put the alias method in the module because it's a Ruby 1.8 bug
|
6
|
+
# http://coderrr.wordpress.com/2008/03/28/alias_methodmodule-bug-in-ruby-18/
|
7
|
+
#
|
8
8
|
def self.extended(base) #:nodoc:
|
9
|
-
if base.respond_to?(:example)
|
10
|
-
class << base
|
11
|
-
alias_method :example_without_pending, :example
|
12
|
-
alias_method :example, :example_with_pending
|
13
|
-
alias :it :example
|
14
|
-
alias :specify :example
|
9
|
+
if base.respond_to?(:example)
|
10
|
+
class << base
|
11
|
+
alias_method :example_without_pending, :example
|
12
|
+
alias_method :example, :example_with_pending
|
13
|
+
alias :it :example
|
14
|
+
alias :specify :example
|
15
15
|
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Adds a pending block to your specs.
|
20
|
-
#
|
21
|
-
# == Examples
|
22
|
-
#
|
23
|
-
# pending 'create manager resource' do
|
24
|
-
# should_have_one :manager
|
25
|
-
# should_validate_associated :manager
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# By default, it executes the examples inside the pending block. So as soon
|
29
|
-
# as you add the has_one :manager relationship to your model, your specs
|
30
|
-
# will say that this was already fixed and there is no need to be treated
|
31
|
-
# as pending. To disable this behavior, you can give :execute => false:
|
32
|
-
#
|
33
|
-
# pending 'create manager resource', :execute => false
|
34
|
-
#
|
35
|
-
def pending(*args, &block)
|
36
|
-
options = { :execute => true }.merge(args.extract_options!)
|
37
|
-
|
38
|
-
@_pending_group = true
|
39
|
-
@_pending_group_description = args.first || "TODO"
|
40
|
-
@_pending_group_execute = options.delete(:execute)
|
41
|
-
|
42
|
-
self.instance_eval(&block)
|
43
|
-
|
44
|
-
@_pending_group = false
|
45
|
-
@_pending_group_description = nil
|
46
|
-
@_pending_group_execute = nil
|
47
|
-
end
|
48
|
-
|
49
|
-
def example_with_pending(description=nil, options={}, backtrace=nil, &implementation) #:nodoc:
|
50
|
-
if block_given? && @_pending_group
|
51
|
-
pending_caller = caller.detect{ |c| c !~ /method_missing'/ }
|
52
|
-
pending_description = @_pending_group_description
|
53
|
-
|
54
|
-
pending_block = if @_pending_group_execute
|
55
|
-
proc{ pending(pending_description){ self.instance_eval(&implementation) } }
|
56
|
-
else
|
57
|
-
proc{ pending(pending_description) }
|
58
|
-
end
|
59
|
-
|
60
|
-
example_without_pending(description, options, backtrace || pending_caller, &pending_block)
|
61
|
-
else
|
62
|
-
example_without_pending(description, options, backtrace || caller(0)[1], &implementation)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds a pending block to your specs.
|
20
|
+
#
|
21
|
+
# == Examples
|
22
|
+
#
|
23
|
+
# pending 'create manager resource' do
|
24
|
+
# should_have_one :manager
|
25
|
+
# should_validate_associated :manager
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# By default, it executes the examples inside the pending block. So as soon
|
29
|
+
# as you add the has_one :manager relationship to your model, your specs
|
30
|
+
# will say that this was already fixed and there is no need to be treated
|
31
|
+
# as pending. To disable this behavior, you can give :execute => false:
|
32
|
+
#
|
33
|
+
# pending 'create manager resource', :execute => false
|
34
|
+
#
|
35
|
+
def pending(*args, &block)
|
36
|
+
options = { :execute => true }.merge(args.extract_options!)
|
37
|
+
|
38
|
+
@_pending_group = true
|
39
|
+
@_pending_group_description = args.first || "TODO"
|
40
|
+
@_pending_group_execute = options.delete(:execute)
|
41
|
+
|
42
|
+
self.instance_eval(&block)
|
43
|
+
|
44
|
+
@_pending_group = false
|
45
|
+
@_pending_group_description = nil
|
46
|
+
@_pending_group_execute = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def example_with_pending(description=nil, options={}, backtrace=nil, &implementation) #:nodoc:
|
50
|
+
if block_given? && @_pending_group
|
51
|
+
pending_caller = caller.detect{ |c| c !~ /method_missing'/ }
|
52
|
+
pending_description = @_pending_group_description
|
53
|
+
|
54
|
+
pending_block = if @_pending_group_execute
|
55
|
+
proc{ pending(pending_description){ self.instance_eval(&implementation) } }
|
56
|
+
else
|
57
|
+
proc{ pending(pending_description) }
|
58
|
+
end
|
59
|
+
|
60
|
+
example_without_pending(description, options, backtrace || pending_caller, &pending_block)
|
61
|
+
else
|
62
|
+
example_without_pending(description, options, backtrace || caller(0)[1], &implementation)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|