scope 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/scope.rb +63 -29
- data/scope.gemspec +1 -1
- metadata +4 -4
data/lib/scope.rb
CHANGED
@@ -32,19 +32,26 @@ module Scope
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.context(name, &block)
|
35
|
+
context_focused = false
|
36
|
+
if @focus_enabled && @focus_next_test_or_context
|
37
|
+
@focus_next_test_or_context = false
|
38
|
+
@inside_focused_context = true
|
39
|
+
context_focused = true
|
40
|
+
end
|
35
41
|
parent = @contexts.last
|
36
42
|
new_context = Context.new(name, parent)
|
37
43
|
parent.tests_and_subcontexts << new_context
|
38
44
|
@contexts << new_context
|
39
45
|
block.call
|
40
46
|
@contexts.pop
|
47
|
+
@inside_focused_context = false if context_focused
|
41
48
|
end
|
42
49
|
|
43
50
|
def self.should(name, &block)
|
44
51
|
# When focus_enabled is true, we'll only be running the next should() block that gets defined.
|
45
52
|
if @focus_enabled
|
46
|
-
return unless @
|
47
|
-
@
|
53
|
+
return unless @focus_next_test_or_context || @inside_focused_context
|
54
|
+
@focus_next_test_or_context &&= false
|
48
55
|
end
|
49
56
|
|
50
57
|
context_name = @contexts[1..-1].map { |context| context.name }.join(" ")
|
@@ -63,14 +70,16 @@ module Scope
|
|
63
70
|
def self.setup_once(&block) @contexts.last.setup_once = block end
|
64
71
|
def self.teardown_once(&block) @contexts.last.teardown_once = block end
|
65
72
|
|
66
|
-
# "Focuses" the next test that's defined after this method is called, ensuring that only that
|
73
|
+
# "Focuses" the next test or context that's defined after this method is called, ensuring that only that
|
74
|
+
# test/context is run.
|
67
75
|
def self.focus
|
68
|
-
# Since we're focusing only the next test, remove any tests which were already defined.
|
76
|
+
# Since we're focusing only the next test/context, remove any tests which were already defined.
|
69
77
|
context_for_test.values.uniq.each do |context|
|
70
78
|
context.tests_and_subcontexts.reject! { |test| test.is_a?(String) }
|
71
79
|
end
|
72
80
|
@focus_enabled = true
|
73
|
-
@
|
81
|
+
@focus_next_test_or_context = true
|
82
|
+
@inside_focused_context = false
|
74
83
|
end
|
75
84
|
|
76
85
|
# run() is called by the MiniTest framework. This TestCase class is instantiated once per test method
|
@@ -81,7 +90,7 @@ module Scope
|
|
81
90
|
result = nil
|
82
91
|
begin
|
83
92
|
# Unit::TestCase's implementation of run() invokes the test method with exception handling.
|
84
|
-
context.run_setup_and_teardown(self, test_name) { result = super }
|
93
|
+
context.run_setup_and_teardown(self, test_name) { result = super(test_runner) }
|
85
94
|
rescue *MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
|
86
95
|
raise
|
87
96
|
rescue Exception => error
|
@@ -107,27 +116,42 @@ module Scope
|
|
107
116
|
|
108
117
|
# Runs the setup work for this context and any parent contexts, yields to the block (which should invoke
|
109
118
|
# the actual test method), and then completes the teardown work.
|
110
|
-
def run_setup_and_teardown(test_case_instance, test_name)
|
119
|
+
def run_setup_and_teardown(test_case_instance, test_name, &runner_proc)
|
111
120
|
contexts = ([self] + ancestor_contexts).reverse
|
121
|
+
recursively_run_setup_and_teardown(test_case_instance, test_name, contexts, runner_proc)
|
122
|
+
end
|
123
|
+
|
124
|
+
def teardown_once=(block) @teardown_once = run_only_once(block) end
|
125
|
+
def setup_once=(block) @setup_once = run_only_once(block) end
|
126
|
+
|
127
|
+
private
|
128
|
+
def recursively_run_setup_and_teardown(test_case_instance, test_name, contexts, runner_proc)
|
129
|
+
outer_context = contexts.slice! 0
|
112
130
|
# We're using instance_eval so that instance vars set by the block are created on the test_case_instance
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
131
|
+
test_case_instance.instance_eval(&outer_context.setup_once) if outer_context.setup_once
|
132
|
+
test_case_instance.instance_eval(&outer_context.setup) if outer_context.setup
|
133
|
+
begin
|
134
|
+
if contexts.empty?
|
135
|
+
runner_proc.call
|
136
|
+
else
|
137
|
+
recursively_run_setup_and_teardown(test_case_instance, test_name, contexts, runner_proc)
|
138
|
+
end
|
139
|
+
ensure
|
140
|
+
# The ensure block guarantees that this context's teardown blocks will be run, even in an exception
|
141
|
+
# is thrown in a descendant context or in the test itself.
|
142
|
+
test_case_instance.instance_eval(&outer_context.teardown) if outer_context.teardown
|
143
|
+
if outer_context.name_of_last_test == test_name
|
144
|
+
test_case_instance.instance_eval(&outer_context.teardown_once) if outer_context.teardown_once
|
127
145
|
end
|
128
146
|
end
|
129
147
|
end
|
130
148
|
|
149
|
+
def run_only_once(block)
|
150
|
+
has_run = false
|
151
|
+
Proc.new { instance_eval(&block) unless has_run; has_run = true }
|
152
|
+
end
|
153
|
+
|
154
|
+
protected
|
131
155
|
def ancestor_contexts
|
132
156
|
ancestors = []
|
133
157
|
parent = self
|
@@ -135,13 +159,23 @@ module Scope
|
|
135
159
|
ancestors
|
136
160
|
end
|
137
161
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
162
|
+
# Returns the name of the last actual test within this context (including within its descendant contexts),
|
163
|
+
# or nil if none exists.
|
164
|
+
def name_of_last_test
|
165
|
+
unless defined? @name_of_last_test
|
166
|
+
@name_of_last_test = nil
|
167
|
+
tests_and_subcontexts.reverse.each do |test_or_context|
|
168
|
+
if test_or_context.is_a? String
|
169
|
+
@name_of_last_test = test_or_context
|
170
|
+
break
|
171
|
+
end
|
172
|
+
unless test_or_context.name_of_last_test.nil?
|
173
|
+
@name_of_last_test = test_or_context.name_of_last_test
|
174
|
+
break
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
@name_of_last_test
|
145
179
|
end
|
146
180
|
end
|
147
|
-
end
|
181
|
+
end
|
data/scope.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "scope"
|
3
|
-
s.version = "0.2.
|
3
|
+
s.version = "0.2.2"
|
4
4
|
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new(">=0") if s.respond_to? :required_rubygems_version=
|
6
6
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Phil Crosby
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-06-27 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|