scope 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|