lemon 0.8.5 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{lemon.gemspec → .gemspec} +0 -0
- data/.ruby +4 -11
- data/Assembly +5 -11
- data/HISTORY.rdoc +31 -0
- data/MANIFEST +45 -55
- data/PROFILE +6 -6
- data/README.md +113 -0
- data/Rakefile +12 -3
- data/VERSION +1 -1
- data/bin/lemonade +8 -0
- data/lib/lemon.rb +52 -2
- data/lib/lemon.yml +4 -11
- data/lib/lemon/{model/ae.rb → ae.rb} +0 -0
- data/lib/lemon/cli.rb +28 -279
- data/lib/lemon/cli/base.rb +139 -0
- data/lib/lemon/cli/coverage.rb +52 -0
- data/lib/lemon/cli/generate.rb +51 -0
- data/lib/lemon/cli/test.rb +50 -0
- data/lib/lemon/core_ext.rb +7 -0
- data/lib/lemon/core_ext/kernel.rb +20 -0
- data/lib/lemon/core_ext/omission.rb +18 -0
- data/lib/lemon/{controller/coverage_analyzer.rb → coverage/analyzer.rb} +41 -19
- data/lib/lemon/{model → coverage}/cover_unit.rb +0 -0
- data/lib/lemon/{view/cover_reports → coverage/formats}/abstract.rb +0 -0
- data/lib/lemon/{view/cover_reports → coverage/formats}/compact.rb +1 -1
- data/lib/lemon/{view/cover_reports → coverage/formats}/outline.rb +1 -1
- data/lib/lemon/{view/cover_reports → coverage/formats}/verbose.rb +1 -1
- data/lib/lemon/{view/cover_reports → coverage/formats}/yaml.rb +1 -1
- data/lib/lemon/{model → coverage}/snapshot.rb +0 -0
- data/lib/lemon/{model → coverage}/source_parser.rb +0 -0
- data/lib/lemon/{controller/scaffold_generator.rb → generator.rb} +53 -14
- data/lib/lemon/test_advice.rb +63 -0
- data/lib/lemon/test_case.rb +270 -0
- data/lib/lemon/test_class.rb +28 -0
- data/lib/lemon/test_method.rb +207 -0
- data/lib/lemon/test_module.rb +114 -0
- data/lib/lemon/test_proc.rb +140 -0
- data/lib/lemon/test_setup.rb +54 -0
- data/lib/lemon/test_world.rb +9 -0
- data/notes/{2010-05-06-files_not_classes.rdoc → 2010-05-06-files-not-classes.rdoc} +0 -0
- data/notes/{2010-07-11-acid_testing.rdoc → 2010-07-11-acid-testing.rdoc} +0 -0
- data/notes/2011-07-07-nailing-down-the-nomenclature.md +6 -0
- data/site/index.html +7 -6
- data/{qed → spec}/applique/fs.rb +0 -0
- data/{qed → spec}/coverage/01_complete.rdoc +26 -16
- data/{qed → spec}/coverage/02_incomplete.rdoc +10 -7
- data/{qed → spec}/coverage/03_extensions.rdoc +10 -6
- data/spec/coverage/applique/lemon.rb +1 -0
- data/try/.test +8 -0
- data/try/case_error.rb +18 -0
- data/try/case_fail.rb +19 -0
- data/try/case_pass.rb +42 -0
- data/try/case_pending.rb +18 -0
- data/try/case_singleton.rb +18 -0
- data/try/case_untested.rb +14 -0
- data/try/fixtures/calculator.rb +15 -0
- data/{demo/fixture → try/fixtures}/example-use.rb +0 -0
- data/{demo/fixture → try/fixtures}/example.rb +0 -0
- data/try/helpers/loadpath.rb +1 -0
- data/{.config → work/deprecated}/cucumber.yml +0 -0
- data/{features → work/deprecated/features}/coverage.feature +0 -0
- data/{features → work/deprecated/features}/generate.feature +0 -0
- data/{features → work/deprecated/features}/step_definitions/coverage_steps.rb +0 -0
- data/{features → work/deprecated/features}/support/ae.rb +0 -0
- data/{features → work/deprecated/features}/support/aruba.rb +0 -0
- data/{features → work/deprecated/features}/test.feature +0 -0
- data/work/deprecated/model/dsl/advice.rb +78 -0
- data/work/deprecated/model/dsl/subject.rb +40 -0
- data/{lib/lemon → work/deprecated}/model/main.rb +40 -29
- data/work/deprecated/model/test.rb +54 -0
- data/work/deprecated/model/test_base_dsl.rb +88 -0
- data/work/deprecated/model/test_clause.rb +112 -0
- data/{lib/lemon → work/deprecated}/model/test_context.rb +24 -24
- data/work/deprecated/model/test_feature.rb +128 -0
- data/work/deprecated/model/test_scenario.rb +137 -0
- data/{lib/lemon → work/deprecated}/model/test_suite.rb +113 -32
- data/work/deprecated/rake.rb +103 -0
- data/{test → work/deprecated/test}/case_coverage_analyzer.rb +0 -0
- data/{test → work/deprecated/test}/case_test_case_dsl.rb +2 -2
- data/{test → work/deprecated/test}/fixtures/case_complete.rb +0 -0
- data/{test → work/deprecated/test}/fixtures/case_inclusion.rb +0 -0
- data/{test → work/deprecated/test}/fixtures/case_incomplete.rb +0 -0
- data/{test → work/deprecated/test}/fixtures/example.rb +0 -0
- data/{test → work/deprecated/test}/fixtures/helper.rb +0 -0
- data/{test → work/deprecated/test}/runner +0 -0
- data/work/old-tests/case_example.rb +15 -0
- data/work/old-tests/feature_example.rb +40 -0
- data/work/reference/dsl2.rb +4 -0
- metadata +101 -98
- data/README.rdoc +0 -103
- data/bin/lemon +0 -4
- data/demo/case_example_error.rb +0 -10
- data/demo/case_example_fail.rb +0 -15
- data/demo/case_example_pass.rb +0 -32
- data/demo/case_example_pending.rb +0 -14
- data/demo/case_example_untested.rb +0 -10
- data/lib/lemon/controller/test_runner.rb +0 -299
- data/lib/lemon/model/pending.rb +0 -10
- data/lib/lemon/model/test_case.rb +0 -305
- data/lib/lemon/model/test_unit.rb +0 -147
- data/lib/lemon/view/test_reports/abstract.rb +0 -256
- data/lib/lemon/view/test_reports/dotprogress.rb +0 -73
- data/lib/lemon/view/test_reports/html.rb +0 -146
- data/lib/lemon/view/test_reports/outline.rb +0 -118
- data/lib/lemon/view/test_reports/summary.rb +0 -131
- data/lib/lemon/view/test_reports/tap.rb +0 -49
- data/lib/lemon/view/test_reports/tapj.rb +0 -130
- data/lib/lemon/view/test_reports/tapy.rb +0 -141
- data/lib/lemon/view/test_reports/verbose.rb +0 -197
- data/work/sandbox/lib/sample.rb +0 -13
- data/work/sandbox/test/sample_case.rb +0 -12
- data/work/trash/example-cover.rb +0 -5
- data/work/trash/example.rb +0 -16
@@ -0,0 +1,63 @@
|
|
1
|
+
module Lemon
|
2
|
+
|
3
|
+
#--
|
4
|
+
# TODO: Probably can replace advice with simple hash.
|
5
|
+
#++
|
6
|
+
|
7
|
+
# Test Advice
|
8
|
+
class TestAdvice
|
9
|
+
|
10
|
+
# The test case to which this advice belongs.
|
11
|
+
#attr :context
|
12
|
+
|
13
|
+
#
|
14
|
+
attr :table
|
15
|
+
|
16
|
+
# New case instance.
|
17
|
+
def initialize
|
18
|
+
@table = Hash.new{ |h,k| h[k] = {} }
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
def initialize_copy(original)
|
23
|
+
@table = original.table.clone
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
def [](type)
|
28
|
+
@table[type.to_sym]
|
29
|
+
end
|
30
|
+
|
31
|
+
=begin
|
32
|
+
#
|
33
|
+
#def teardown=(procedure)
|
34
|
+
# @teardown = procedure
|
35
|
+
#end
|
36
|
+
|
37
|
+
# Setup.
|
38
|
+
def setup(scope=nil)
|
39
|
+
if scope
|
40
|
+
scope.instance_eval(&@setup)
|
41
|
+
else
|
42
|
+
@setup
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Teardown.
|
47
|
+
def teardown(scope=nil)
|
48
|
+
if scope
|
49
|
+
scope.instance_eval(&@teardown) if @teardown
|
50
|
+
else
|
51
|
+
@teardown
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the description with newlines removed.
|
56
|
+
def to_s
|
57
|
+
description.gsub(/\n/, ' ')
|
58
|
+
end
|
59
|
+
=end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'lemon/core_ext'
|
2
|
+
require 'lemon/test_advice'
|
3
|
+
require 'lemon/test_setup'
|
4
|
+
require 'lemon/test_world'
|
5
|
+
|
6
|
+
module Lemon
|
7
|
+
|
8
|
+
# Test Case serves as the base class for Lemon's
|
9
|
+
# specialized test case classes.
|
10
|
+
#
|
11
|
+
class TestCase
|
12
|
+
|
13
|
+
# The parent context in which this case resides.
|
14
|
+
attr :context
|
15
|
+
|
16
|
+
# Brief description of the test case.
|
17
|
+
attr :label
|
18
|
+
|
19
|
+
# Target component.
|
20
|
+
attr :target
|
21
|
+
|
22
|
+
# The setup and teardown advice.
|
23
|
+
attr :setup
|
24
|
+
|
25
|
+
# Advice are labeled procedures, such as before
|
26
|
+
# and after advice.
|
27
|
+
attr :advice
|
28
|
+
|
29
|
+
# List of tests and sub-contexts.
|
30
|
+
attr :tests
|
31
|
+
|
32
|
+
# Skip execution of test case?
|
33
|
+
attr :skip
|
34
|
+
|
35
|
+
# A test case +target+ is a class or module.
|
36
|
+
#
|
37
|
+
# @param [Hash] settings
|
38
|
+
# The settings used to define the test case.
|
39
|
+
#
|
40
|
+
# @option settings [TestCase] :context
|
41
|
+
# Parent test case.
|
42
|
+
#
|
43
|
+
# @option settings [Module,Class,Symbol] :target
|
44
|
+
# The testcase's target.
|
45
|
+
#
|
46
|
+
# @option settings [String] :label
|
47
|
+
# Breif description of testcase.
|
48
|
+
# (NOTE: this might not be used)
|
49
|
+
#
|
50
|
+
# @option settings [TestSetup] :setup
|
51
|
+
# Test setup.
|
52
|
+
#
|
53
|
+
# @option settings [Boolean] :skip
|
54
|
+
# If runner should skip test.
|
55
|
+
#
|
56
|
+
def initialize(settings={}, &block)
|
57
|
+
@context = settings[:context]
|
58
|
+
@target = settings[:target]
|
59
|
+
@label = settings[:label]
|
60
|
+
@setup = settings[:setup]
|
61
|
+
@skip = settings[:skip]
|
62
|
+
|
63
|
+
@advice = @context ? @context.advice.dup : TestAdvice.new
|
64
|
+
|
65
|
+
@tests = []
|
66
|
+
@scope = scope_class.new(self)
|
67
|
+
|
68
|
+
validate_settings
|
69
|
+
|
70
|
+
evaluate(&block)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Subclasses can override this methof to validate settings.
|
74
|
+
# It is run just before evaluation of scope block.
|
75
|
+
def validate_settings
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
def evaluate(&block)
|
80
|
+
@scope.module_eval(&block)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Iterate over each test and subcase.
|
84
|
+
def each(&block)
|
85
|
+
tests.each(&block)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Number of tests and subcases.
|
89
|
+
def size
|
90
|
+
tests.size
|
91
|
+
end
|
92
|
+
|
93
|
+
# Subclasses of TestCase can override this to describe
|
94
|
+
# the type of test case they define.
|
95
|
+
def type
|
96
|
+
'Case'
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
def to_s
|
101
|
+
@label.to_s
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
def skip?
|
106
|
+
@skip
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
def skip!(reason=true)
|
111
|
+
@skip = reason
|
112
|
+
end
|
113
|
+
|
114
|
+
# Run test in the context of this case.
|
115
|
+
#
|
116
|
+
# @param [TestProc] test
|
117
|
+
# The test unit to run.
|
118
|
+
#
|
119
|
+
def run(test, &block)
|
120
|
+
advice[:before].each do |matches, block|
|
121
|
+
if matches.all?{ |match| test.match?(match) }
|
122
|
+
scope.instance_exec(test, &block) #block.call(unit)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
block.call
|
127
|
+
|
128
|
+
advice[:after].each do |matches, block|
|
129
|
+
if matches.all?{ |match| test.match?(match) }
|
130
|
+
scope.instance_exec(test, &block) #block.call(unit)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Module for evaluating test case script.
|
136
|
+
#
|
137
|
+
# @return [Scope] evaluation scope
|
138
|
+
def scope
|
139
|
+
@scope
|
140
|
+
end
|
141
|
+
|
142
|
+
# Get the scope class dynamically so that each subclass
|
143
|
+
# of TestCase will retrieve it's own.
|
144
|
+
def scope_class
|
145
|
+
self.class.const_get(:Scope)
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
class Scope < World
|
150
|
+
|
151
|
+
#
|
152
|
+
def initialize(testcase) #, &code)
|
153
|
+
@_testcase = testcase
|
154
|
+
@_setup = testcase.setup
|
155
|
+
@_skip = nil
|
156
|
+
|
157
|
+
extend testcase.context.scope if testcase.context
|
158
|
+
|
159
|
+
#module_eval(&code)
|
160
|
+
end
|
161
|
+
|
162
|
+
#--
|
163
|
+
# THINK: Instead of resuing TestCase can we have a TestContext
|
164
|
+
# or other way to more generically mimics the parent context?
|
165
|
+
#++
|
166
|
+
|
167
|
+
##
|
168
|
+
#def context(label, &block)
|
169
|
+
# @_testcase.tests << TestCase.new(
|
170
|
+
# :testcase => @testcase,
|
171
|
+
# :label => label,
|
172
|
+
# &block
|
173
|
+
# )
|
174
|
+
#end
|
175
|
+
#alias :Context :context
|
176
|
+
|
177
|
+
# Setup is used to set things up for each unit test.
|
178
|
+
# The setup procedure is run before each unit.
|
179
|
+
#
|
180
|
+
# @param [String] description
|
181
|
+
# A brief description of what the setup procedure sets-up.
|
182
|
+
#
|
183
|
+
def setup(description=nil, &procedure)
|
184
|
+
if procedure
|
185
|
+
@_setup = TestSetup.new(@test_case, description, &procedure)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
alias :Setup :setup
|
189
|
+
|
190
|
+
# Original Lemon nomenclature for `#setup`.
|
191
|
+
alias :concern :setup
|
192
|
+
alias :Concern :setup
|
193
|
+
|
194
|
+
# Teardown procedure is used to clean-up after each unit test.
|
195
|
+
#
|
196
|
+
def teardown(&procedure)
|
197
|
+
@_setup.teardown = procedure
|
198
|
+
end
|
199
|
+
alias :Teardown :teardown
|
200
|
+
|
201
|
+
#--
|
202
|
+
# TODO: Allow Before and After to handle setup and teardown?
|
203
|
+
# But that would only allow one setup per case.
|
204
|
+
#++
|
205
|
+
|
206
|
+
# Define a _complex_ before procedure. The #before method allows
|
207
|
+
# before procedures to be defined that are triggered by a match
|
208
|
+
# against the unit's target method name or _aspect_ description.
|
209
|
+
# This allows groups of tests to be defined that share special
|
210
|
+
# setup code.
|
211
|
+
#
|
212
|
+
# @example
|
213
|
+
# Method :puts do
|
214
|
+
# Test "standard output (@stdout)" do
|
215
|
+
# puts "Hello"
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
# Before /@stdout/ do
|
219
|
+
# $stdout = StringIO.new
|
220
|
+
# end
|
221
|
+
#
|
222
|
+
# After /@stdout/ do
|
223
|
+
# $stdout = STDOUT
|
224
|
+
# end
|
225
|
+
# end
|
226
|
+
#
|
227
|
+
# @param [Array<Symbol,Regexp>] matches
|
228
|
+
# List of match critera that must _all_ be matched
|
229
|
+
# to trigger the before procedure.
|
230
|
+
#
|
231
|
+
def before(*matches, &procedure)
|
232
|
+
@_testcase.advice[:before][matches] = procedure
|
233
|
+
end
|
234
|
+
alias :Before :before
|
235
|
+
|
236
|
+
# Define a _complex_ after procedure. The #before method allows
|
237
|
+
# before procedures to be defined that are triggered by a match
|
238
|
+
# against the unit's target method name or _aspect_ description.
|
239
|
+
# This allows groups of tests to be defined that share special
|
240
|
+
# teardown code.
|
241
|
+
#
|
242
|
+
# @example
|
243
|
+
# Method :puts do
|
244
|
+
# Test "standard output (@stdout)" do
|
245
|
+
# puts "Hello"
|
246
|
+
# end
|
247
|
+
#
|
248
|
+
# Before /@stdout/ do
|
249
|
+
# $stdout = StringIO.new
|
250
|
+
# end
|
251
|
+
#
|
252
|
+
# After /@stdout/ do
|
253
|
+
# $stdout = STDOUT
|
254
|
+
# end
|
255
|
+
# end
|
256
|
+
#
|
257
|
+
# @param [Array<Symbol,Regexp>] matches
|
258
|
+
# List of match critera that must _all_ be matched
|
259
|
+
# to trigger the after procedure.
|
260
|
+
#
|
261
|
+
def after(*matches, &procedure)
|
262
|
+
@_testcase.advice[:after][matches] = procedure
|
263
|
+
end
|
264
|
+
alias :After :after
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Lemon
|
2
|
+
|
3
|
+
require 'lemon/test_module'
|
4
|
+
|
5
|
+
# Subclass of TestModule used for classes.
|
6
|
+
# It's basically the same class.
|
7
|
+
#
|
8
|
+
class TestClass < TestModule
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Make sure the target is a class.
|
13
|
+
def validate_target
|
14
|
+
raise unless Class === @target
|
15
|
+
end
|
16
|
+
|
17
|
+
# The type of testcase.
|
18
|
+
def type
|
19
|
+
'Class'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Evaluation scope for {TestClass}.
|
23
|
+
class Scope < TestModule::Scope
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module Lemon
|
2
|
+
|
3
|
+
require 'lemon/test_case'
|
4
|
+
require 'lemon/test_proc'
|
5
|
+
|
6
|
+
# The TestMethod class is a special TestCase that requires
|
7
|
+
# a particular target method be tested.
|
8
|
+
#
|
9
|
+
class TestMethod < TestCase
|
10
|
+
|
11
|
+
# New unit test.
|
12
|
+
#
|
13
|
+
# @option settings [Boolean] :function
|
14
|
+
# Is the target method a class method, or not.
|
15
|
+
#
|
16
|
+
def initialize(settings={}, &block)
|
17
|
+
@tested = false
|
18
|
+
@function = settings[:function]
|
19
|
+
super(settings)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Validate that a context and target method have been supplied.
|
23
|
+
def validate_settings
|
24
|
+
raise "method test has no module or class context" unless @context
|
25
|
+
raise "#{@target} is not a method name" unless Symbol === @target
|
26
|
+
end
|
27
|
+
|
28
|
+
# Type is either `Method` or `Function` (a function is a class method).
|
29
|
+
def type
|
30
|
+
if function?
|
31
|
+
'Function'
|
32
|
+
else
|
33
|
+
'Method'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Used to make sure the the method has been tested, or not.
|
38
|
+
attr_accessor :tested
|
39
|
+
|
40
|
+
# Is this method a class method?
|
41
|
+
def function?
|
42
|
+
@function
|
43
|
+
end
|
44
|
+
|
45
|
+
# A function is also known as a "class method".
|
46
|
+
alias :class_method? :function?
|
47
|
+
|
48
|
+
# If class method, returns target method's name prefixed with double colons.
|
49
|
+
# If instance method, then returns target method's name prefixed with hash
|
50
|
+
# character.
|
51
|
+
def name
|
52
|
+
function? ? "::#{target}" : "##{target}"
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: If sub-cases are to be supported than we need to incorporate
|
56
|
+
# the label into to_s.
|
57
|
+
|
58
|
+
# Returns the prefixed method name.
|
59
|
+
def to_s
|
60
|
+
function? ? "::#{target}" : "##{target}"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the fully qulaified name of the target method. This is
|
64
|
+
# the standard interface used by Ruby Test.
|
65
|
+
def unit
|
66
|
+
function? ? "#{context}.#{target}" : "#{context}##{target}"
|
67
|
+
end
|
68
|
+
|
69
|
+
# Run test in the context of this case. Notice that #run for
|
70
|
+
# TestMethod is more complex than a general TestCase. This is
|
71
|
+
# to ensure that the target method is invoked during the course
|
72
|
+
# of the test.
|
73
|
+
#
|
74
|
+
# @param [TestProc] test
|
75
|
+
# The test procedure instance to run.
|
76
|
+
#
|
77
|
+
# @yield
|
78
|
+
# The procedure for running the test.
|
79
|
+
#
|
80
|
+
def run(test, &block)
|
81
|
+
target = self.target
|
82
|
+
|
83
|
+
raise_pending(test.procedure) unless test.procedure
|
84
|
+
|
85
|
+
begin
|
86
|
+
target_class.class_eval do
|
87
|
+
alias_method "_lemon_#{target}", target
|
88
|
+
define_method(target) do |*a,&b|
|
89
|
+
test.tested = true
|
90
|
+
__send__("_lemon_#{target}",*a,&b)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
rescue => error
|
94
|
+
Kernel.eval <<-END, test.to_proc.binding
|
95
|
+
raise #{error.class}, "#{target} not tested"
|
96
|
+
END
|
97
|
+
end
|
98
|
+
|
99
|
+
begin
|
100
|
+
super(test, &block)
|
101
|
+
#block.call
|
102
|
+
|
103
|
+
ensure
|
104
|
+
target_class.class_eval %{
|
105
|
+
alias_method "#{target}", "_lemon_#{target}"
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
raise_pending(test.procedure) unless test.tested
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
def raise_pending(procedure)
|
114
|
+
if RUBY_VERSION < '1.9'
|
115
|
+
Kernel.eval %[raise NotImplementedError, "#{target} not tested"], procedure
|
116
|
+
else
|
117
|
+
Kernel.eval %[raise NotImplementedError, "#{target} not tested"], procedure.binding
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# If the target method is a class method, then the target class is the
|
122
|
+
# meta-class, otherwise just the class itself.
|
123
|
+
def target_class
|
124
|
+
@target_class ||= (
|
125
|
+
if function?
|
126
|
+
(class << context.target; self; end)
|
127
|
+
else
|
128
|
+
context.target
|
129
|
+
end
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Scope for evaluating method test definitions.
|
134
|
+
#
|
135
|
+
class Scope < TestCase::Scope
|
136
|
+
|
137
|
+
# Define a unit test for this case.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# test "print message with new line to stdout" do
|
141
|
+
# puts "Hello"
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
def test(label=nil, &block)
|
145
|
+
block = Omission.new(@_omit).to_proc if @_omit
|
146
|
+
test = TestProc.new(
|
147
|
+
:context => @_testcase,
|
148
|
+
:setup => @_setup,
|
149
|
+
:skip => @_skip,
|
150
|
+
:label => label,
|
151
|
+
&block
|
152
|
+
)
|
153
|
+
@_testcase.tests << test
|
154
|
+
test
|
155
|
+
end
|
156
|
+
alias :Test :test
|
157
|
+
|
158
|
+
# Create a sub-case ofr the method case.
|
159
|
+
def context(label, &block)
|
160
|
+
@_testcase.tests << TestMethod.new(
|
161
|
+
:context => @_testcase,
|
162
|
+
:target => @_testcase.target,
|
163
|
+
:setup => @_setup,
|
164
|
+
:skip => @_skip,
|
165
|
+
:label => label,
|
166
|
+
&block
|
167
|
+
)
|
168
|
+
end
|
169
|
+
alias :Context :context
|
170
|
+
|
171
|
+
# Omit tests.
|
172
|
+
#
|
173
|
+
# @example
|
174
|
+
# omit "reason" do
|
175
|
+
# test do
|
176
|
+
# ...
|
177
|
+
# end
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
def omit(label=true, &block)
|
181
|
+
@_omit = label
|
182
|
+
block.call
|
183
|
+
@_omit = nil
|
184
|
+
end
|
185
|
+
alias :Omit :omit
|
186
|
+
|
187
|
+
# Skip tests. Unlike omit, skipped tests are not executed at all.
|
188
|
+
#
|
189
|
+
# @example
|
190
|
+
# skip "reason" do
|
191
|
+
# test do
|
192
|
+
# ...
|
193
|
+
# end
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
def skip(label=true, &block)
|
197
|
+
@_skip = label
|
198
|
+
block.call
|
199
|
+
@_skip = nil
|
200
|
+
end
|
201
|
+
alias :Skip :skip
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|