lemon 0.8.5 → 0.9.0
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/{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
|