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
|
module Spec
module Runner
class Specification
class << self
attr_accessor :current, :generated_description
protected :current=
callback_events :before_setup, :after_teardown
end
attr_reader :spec_block
callback_events :before_setup, :after_teardown
def initialize(name, opts={}, &spec_block)
@from = caller(0)[3]
@description = name
@options = opts
@spec_block = spec_block
@description_generated_callback = lambda { |desc| @generated_description = desc }
end
def run(reporter, setup_block, teardown_block, dry_run, execution_context)
reporter.spec_started(name) if reporter
return reporter.spec_finished(name) if dry_run
errors = []
begin
set_current
setup_ok = setup_spec(execution_context, errors, &setup_block)
spec_ok = execute_spec(execution_context, errors) if setup_ok
teardown_ok = teardown_spec(execution_context, errors, &teardown_block)
ensure
clear_current
end
SpecShouldRaiseHandler.new(@from, @options).handle(errors)
reporter.spec_finished(name, errors.first, failure_location(setup_ok, spec_ok, teardown_ok)) if reporter
end
def matches?(matcher, description)
matcher.spec_desc = name
matcher.matches?(description)
end
private
def name
@description == :__generate_description ? generated_description : @description
end
def generated_description
@generated_description || "NAME NOT GENERATED"
end
def setup_spec(execution_context, errors, &setup_block)
notify_before_setup(errors)
execution_context.instance_eval(&setup_block) if setup_block
return errors.empty?
rescue => e
errors << e
return false
end
def execute_spec(execution_context, errors)
begin
execution_context.instance_eval(&spec_block)
return true
rescue Exception => e
errors << e
return false
end
end
def teardown_spec(execution_context, errors, &teardown_block)
execution_context.instance_eval(&teardown_block) if teardown_block
notify_after_teardown(errors)
return errors.empty?
rescue => e
errors << e
return false
end
def notify_before_setup(errors)
notify_class_callbacks(:before_setup, self, &append_errors(errors))
notify_callbacks(:before_setup, self, &append_errors(errors))
end
def notify_after_teardown(errors)
notify_callbacks(:after_teardown, self, &append_errors(errors))
notify_class_callbacks(:after_teardown, self, &append_errors(errors))
end
def append_errors(errors)
proc {|error| errors << error}
end
def set_current
Spec::Matchers.description_generated(&@description_generated_callback)
self.class.send(:current=, self)
end
def clear_current
Spec::Matchers.unregister_callback(:description_generated, @description_generated_callback)
self.class.send(:current=, nil)
end
def failure_location(setup_ok, spec_ok, teardown_ok)
return 'setup' unless setup_ok
return name unless spec_ok
return 'teardown' unless teardown_ok
end
end
end
end
|