/
example.rb
178 lines (148 loc) · 5.07 KB
/
example.rb
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
module RSpec
module Core
class Example
attr_reader :metadata, :options, :example_group_instance
# Returns the first exception raised, if any, in the context of running
# this example.
attr_reader :exception
def self.delegate_to_metadata(*keys)
keys.each do |key|
define_method(key) {@metadata[key]}
end
end
delegate_to_metadata :description, :full_description, :execution_result, :file_path, :pending, :location
def initialize(example_group_class, desc, options, example_block=nil)
@example_group_class, @options, @example_block = example_group_class, options, example_block
@metadata = @example_group_class.metadata.for_example(desc, options)
@exception = nil
@pending_declared_in_example = false
end
def example_group
@example_group_class
end
def around_hooks
@around_hooks ||= example_group.around_hooks_for(self)
end
def all_apply?(filters)
@metadata.all_apply?(filters) || @example_group_class.all_apply?(filters)
end
alias_method :pending?, :pending
def run(example_group_instance, reporter)
@example_group_instance = example_group_instance
@example_group_instance.example = self
start(reporter)
begin
unless pending
with_around_hooks do
begin
run_before_each
@example_group_instance.instance_eval(&@example_block)
rescue Pending::PendingDeclaredInExample => e
@pending_declared_in_example = e.message
rescue Exception => e
set_exception(e)
ensure
run_after_each
end
end
end
rescue Exception => e
set_exception(e)
ensure
@example_group_instance.instance_variables.each do |ivar|
@example_group_instance.instance_variable_set(ivar, nil)
end
@example_group_instance = nil
begin
assign_auto_description
rescue Exception => e
set_exception(e)
end
end
finish(reporter)
end
def set_exception(exception)
@exception ||= exception
end
def fail_fast(reporter, exception)
start(reporter)
set_exception(exception)
finish(reporter)
end
def self.procsy(metadata, &block)
Proc.new(&block).extend(Procsy).with(metadata)
end
module Procsy
attr_reader :metadata
def self.extended(object)
def object.run; call; end
end
def with(metadata)
@metadata = metadata
self
end
end
private
def with_around_hooks(&block)
if around_hooks.empty?
yield
else
@example_group_class.run_around_each_hooks(self, Example.procsy(metadata, &block)).call
end
end
def start(reporter)
reporter.example_started(self)
record :started_at => Time.now
end
def finish(reporter)
if @exception
record_finished 'failed', :exception => @exception
reporter.example_failed self
false
elsif @pending_declared_in_example
record_finished 'pending', :pending_message => @pending_declared_in_example
reporter.example_pending self
true
elsif pending
record_finished 'pending', :pending_message => 'Not Yet Implemented'
reporter.example_pending self
true
else
record_finished 'passed'
reporter.example_passed self
true
end
end
def record_finished(status, results={})
finished_at = Time.now
record results.merge(:status => status, :finished_at => finished_at, :run_time => (finished_at - execution_result[:started_at]))
end
def run_before_each
@example_group_instance.setup_mocks_for_rspec if @example_group_instance.respond_to?(:setup_mocks_for_rspec)
@example_group_class.run_before_each_hooks(self)
end
def run_after_each
@example_group_class.run_after_each_hooks(self)
@example_group_instance.verify_mocks_for_rspec if @example_group_instance.respond_to?(:verify_mocks_for_rspec)
ensure
@example_group_instance.teardown_mocks_for_rspec if @example_group_instance.respond_to?(:teardown_mocks_for_rspec)
end
def assign_auto_description
if description.empty? and !pending?
if RSpec.configuration.expecting_with_rspec?
metadata[:description] = RSpec::Matchers.generated_description
RSpec::Matchers.clear_generated_description
else
raise NotImplementedError.new(
"Generated descriptions are only supported when you use rspec-expectations. " +
"You must give every example an explicit description."
)
end
end
end
def record(results={})
execution_result.update(results)
end
end
end
end