lemon 0.8.1 → 0.8.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/HISTORY.rdoc +15 -0
- data/README.rdoc +32 -14
- data/bin/lemon +3 -2
- data/demo/case_example_fail.rb +15 -0
- data/demo/case_example_pass.rb +32 -0
- data/demo/case_example_pending.rb +14 -0
- data/demo/case_example_untested.rb +10 -0
- data/demo/fixture/example-use.rb +5 -0
- data/demo/fixture/example.rb +20 -0
- data/lib/lemon.rb +2 -2
- data/lib/lemon/cli.rb +281 -0
- data/lib/lemon/controller/coverage_analyzer.rb +343 -0
- data/lib/lemon/controller/scaffold_generator.rb +110 -0
- data/lib/lemon/controller/test_runner.rb +284 -0
- data/lib/lemon/meta/data.rb +29 -0
- data/lib/lemon/meta/gemfile +24 -0
- data/{PROFILE → lib/lemon/meta/profile} +6 -5
- data/lib/lemon/model/ae.rb +4 -0
- data/lib/lemon/model/cover_unit.rb +75 -0
- data/lib/lemon/{dsl.rb → model/main.rb} +22 -28
- data/lib/lemon/model/pending.rb +10 -0
- data/lib/lemon/model/snapshot.rb +203 -0
- data/lib/lemon/model/source_parser.rb +198 -0
- data/lib/lemon/model/test_case.rb +221 -0
- data/lib/lemon/model/test_context.rb +90 -0
- data/lib/lemon/model/test_suite.rb +216 -0
- data/lib/lemon/{test/unit.rb → model/test_unit.rb} +40 -28
- data/lib/lemon/{coversheet → view/cover_reports}/abstract.rb +19 -20
- data/lib/lemon/view/cover_reports/compact.rb +37 -0
- data/lib/lemon/view/cover_reports/outline.rb +45 -0
- data/lib/lemon/view/cover_reports/verbose.rb +51 -0
- data/lib/lemon/view/cover_reports/yaml.rb +15 -0
- data/lib/lemon/view/test_reports/abstract.rb +149 -0
- data/lib/lemon/view/test_reports/dotprogress.rb +73 -0
- data/lib/lemon/view/test_reports/html.rb +146 -0
- data/lib/lemon/view/test_reports/outline.rb +118 -0
- data/lib/lemon/view/test_reports/summary.rb +131 -0
- data/lib/lemon/view/test_reports/tap.rb +49 -0
- data/lib/lemon/view/test_reports/verbose.rb +197 -0
- data/meta/data.rb +29 -0
- data/meta/gemfile +24 -0
- data/meta/profile +17 -0
- data/test/api/applique/fs.rb +18 -0
- data/test/api/coverage/complete.rdoc +136 -0
- data/test/api/coverage/extensions.rdoc +61 -0
- data/test/api/coverage/incomplete.rdoc +97 -0
- data/{features → test/cli}/coverage.feature +4 -4
- data/{features → test/cli}/generate.feature +2 -2
- data/{features → test/cli}/step_definitions/coverage_steps.rb +0 -0
- data/{features → test/cli}/support/ae.rb +0 -0
- data/{features → test/cli}/support/aruba.rb +0 -0
- data/{features → test/cli}/test.feature +0 -0
- data/test/fixtures/case_complete.rb +17 -4
- data/test/fixtures/case_inclusion.rb +18 -0
- data/test/fixtures/case_incomplete.rb +4 -4
- data/test/fixtures/example.rb +5 -0
- data/test/fixtures/helper.rb +13 -0
- data/test/runner +3 -0
- data/test/unit/case_coverage_analyzer.rb +25 -0
- data/test/unit/case_test_case_dsl.rb +46 -0
- metadata +87 -42
- data/REQUIRE +0 -9
- data/VERSION +0 -6
- data/lib/lemon/command.rb +0 -184
- data/lib/lemon/coverage.rb +0 -260
- data/lib/lemon/coversheet/outline.rb +0 -47
- data/lib/lemon/kernel.rb +0 -24
- data/lib/lemon/reporter.rb +0 -22
- data/lib/lemon/reporter/abstract.rb +0 -97
- data/lib/lemon/reporter/dotprogress.rb +0 -68
- data/lib/lemon/reporter/outline.rb +0 -105
- data/lib/lemon/reporter/verbose.rb +0 -143
- data/lib/lemon/runner.rb +0 -308
- data/lib/lemon/snapshot.rb +0 -185
- data/lib/lemon/test/case.rb +0 -139
- data/lib/lemon/test/concern.rb +0 -52
- data/lib/lemon/test/suite.rb +0 -229
- data/test/case_coverage.rb +0 -26
- data/test/case_testcase.rb +0 -58
data/lib/lemon/coverage.rb
DELETED
@@ -1,260 +0,0 @@
|
|
1
|
-
require 'lemon/snapshot'
|
2
|
-
require 'lemon/coversheet/outline'
|
3
|
-
|
4
|
-
module Lemon
|
5
|
-
|
6
|
-
#
|
7
|
-
class Coverage
|
8
|
-
|
9
|
-
#
|
10
|
-
attr :suite
|
11
|
-
|
12
|
-
# Paths of lemon tests and/or ruby scripts to be compared and covered.
|
13
|
-
# This can include directories too, in which case all .rb scripts below
|
14
|
-
# then directory will be included.
|
15
|
-
attr :files
|
16
|
-
|
17
|
-
## Conical snapshot of system (before loading libraries to be covered).
|
18
|
-
#attr :canonical
|
19
|
-
|
20
|
-
#
|
21
|
-
attr :namespaces
|
22
|
-
|
23
|
-
## New Coverage object.
|
24
|
-
##
|
25
|
-
## Coverage.new('lib/', :MyApp, :public => true)
|
26
|
-
##
|
27
|
-
#def initialize(suite_or_files, namespaces=nil, options={})
|
28
|
-
# @namespaces = namespaces || []
|
29
|
-
# case suite_or_files
|
30
|
-
# when Test::Suite
|
31
|
-
# @suite = suite_or_files
|
32
|
-
# @files = suite_or_files.files
|
33
|
-
# else
|
34
|
-
# @suite = Test::Suite.new(suite_or_files)
|
35
|
-
# @files = suite_or_files
|
36
|
-
# end
|
37
|
-
# #@canonical = @suite.canonical
|
38
|
-
# @public = options[:public]
|
39
|
-
#end
|
40
|
-
|
41
|
-
# New Coverage object.
|
42
|
-
#
|
43
|
-
# Coverage.new('lib/', :MyApp, :public => true)
|
44
|
-
#
|
45
|
-
def initialize(suite, namespaces=nil, options={})
|
46
|
-
@namespaces = [namespaces].flatten.compact
|
47
|
-
@suite = suite
|
48
|
-
@files = suite.files
|
49
|
-
#@canonical = @suite.canonical
|
50
|
-
@public = options[:public]
|
51
|
-
end
|
52
|
-
|
53
|
-
##
|
54
|
-
#def canonical!
|
55
|
-
# @canonical = Snapshot.capture
|
56
|
-
#end
|
57
|
-
|
58
|
-
#
|
59
|
-
def suite=(suite)
|
60
|
-
raise ArgumentError unless Test::Suite === suite
|
61
|
-
@suite = suite
|
62
|
-
end
|
63
|
-
|
64
|
-
# Over use public methods for coverage.
|
65
|
-
def public_only?
|
66
|
-
@public
|
67
|
-
end
|
68
|
-
|
69
|
-
#
|
70
|
-
def each(&block)
|
71
|
-
checklist.each(&block)
|
72
|
-
end
|
73
|
-
|
74
|
-
# Produce a coverage map.
|
75
|
-
#def checklist
|
76
|
-
# list = system.checklist
|
77
|
-
# suite.each do |testcase|
|
78
|
-
# testcase.testunits.each do |testunit|
|
79
|
-
# list[testcase.target.name][testunit.key] = true
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
# list
|
83
|
-
#end
|
84
|
-
|
85
|
-
# Produce a coverage checklist.
|
86
|
-
def checklist
|
87
|
-
list = system.checklist
|
88
|
-
suite.each do |testcase|
|
89
|
-
testcase.testunits.each do |testunit|
|
90
|
-
list[testcase.target.name][testunit.key] = true
|
91
|
-
end
|
92
|
-
end
|
93
|
-
list
|
94
|
-
end
|
95
|
-
|
96
|
-
#
|
97
|
-
def format(type)
|
98
|
-
coversheet = nil
|
99
|
-
case type
|
100
|
-
when :verbose
|
101
|
-
puts checklist.to_yaml
|
102
|
-
else
|
103
|
-
coversheet = CoverSheet::Outline.new(self)
|
104
|
-
coversheet.coverage_finished
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
#def load_covered_files
|
109
|
-
# suite.load_covered_files
|
110
|
-
#end
|
111
|
-
|
112
|
-
# Iterate over +paths+ and use #load to bring in all +.rb+ scripts.
|
113
|
-
#def load_system
|
114
|
-
# files = []
|
115
|
-
# paths.map do |path|
|
116
|
-
# if File.directory?(path)
|
117
|
-
# files.concat(Dir[File.join(path, '**', '*.rb')])
|
118
|
-
# else
|
119
|
-
# files.concat(Dir[path])
|
120
|
-
# end
|
121
|
-
# end
|
122
|
-
# files.each{ |file| load(file) }
|
123
|
-
#end
|
124
|
-
|
125
|
-
# # Snapshot of System to be covered. This takes a current snapshot
|
126
|
-
# # of the system and removes the canonical snapshot or filters out
|
127
|
-
# # everything but the selected namespace.
|
128
|
-
# def system
|
129
|
-
# if namespaces.empty?
|
130
|
-
# snapshot - canonical
|
131
|
-
# else
|
132
|
-
# (snapshot - canonical).filter do |ofmod|
|
133
|
-
# namespaces.any?{ |n| ofmod.name.start_with?(n.to_s) }
|
134
|
-
# end
|
135
|
-
# end
|
136
|
-
# end
|
137
|
-
|
138
|
-
# List of modules/classes not covered.
|
139
|
-
def uncovered_cases
|
140
|
-
c = suite.coverage.map{ |ofmod| ofmod.base }
|
141
|
-
a = suite.testcases.map{ |tc| tc.target }
|
142
|
-
c - a
|
143
|
-
end
|
144
|
-
|
145
|
-
# List of methods not covered by covered cases.
|
146
|
-
def uncovered_units
|
147
|
-
@calculated ||= calculate_coverage
|
148
|
-
@uncovered_units
|
149
|
-
end
|
150
|
-
|
151
|
-
#
|
152
|
-
def undefined_units
|
153
|
-
@calculated ||= calculate_coverage
|
154
|
-
@undefined_units
|
155
|
-
end
|
156
|
-
|
157
|
-
#
|
158
|
-
def calculate_coverage
|
159
|
-
clist = []
|
160
|
-
tlist = []
|
161
|
-
suite.testcases.each do |tc|
|
162
|
-
mod = tc.target
|
163
|
-
|
164
|
-
metaunits, units = *tc.testunits.partition{ |u| u.meta? }
|
165
|
-
|
166
|
-
units.map!{ |u| u.fullname }
|
167
|
-
metaunits.map!{ |u| u.fullname }
|
168
|
-
|
169
|
-
tlist = tlist | units
|
170
|
-
tlist = tlist | metaunits
|
171
|
-
|
172
|
-
if system[mod]
|
173
|
-
meths = system[mod].instance_methods.map{ |m| "#{mod}##{m}" }
|
174
|
-
metameths = system[mod].class_methods.map{ |m| "#{mod}.#{m}" }
|
175
|
-
|
176
|
-
clist = clist | meths
|
177
|
-
clist = clist | metameths
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
@uncovered_units = clist - tlist
|
182
|
-
@undefined_units = tlist - clist
|
183
|
-
end
|
184
|
-
|
185
|
-
#
|
186
|
-
def system
|
187
|
-
if namespaces.empty?
|
188
|
-
suite.coverage
|
189
|
-
else
|
190
|
-
suite.coverage.filter do |ofmod|
|
191
|
-
namespaces.any?{ |n| ofmod.name.start_with?(n.to_s) }
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
# Generate code template.
|
197
|
-
#
|
198
|
-
# TODO: support output
|
199
|
-
def generate(output=nil)
|
200
|
-
code = []
|
201
|
-
|
202
|
-
system.each do |ofmod|
|
203
|
-
next if ofmod.base.is_a?(Lemon::Test::Suite)
|
204
|
-
|
205
|
-
code << "TestCase #{ofmod.base} do"
|
206
|
-
|
207
|
-
ofmod.class_methods(public_only?).each do |meth|
|
208
|
-
code << "\n MetaUnit :#{meth} => '' do\n raise Pending\n end"
|
209
|
-
end
|
210
|
-
|
211
|
-
ofmod.instance_methods(public_only?).each do |meth|
|
212
|
-
code << "\n Unit :#{meth} => '' do\n raise Pending\n end"
|
213
|
-
end
|
214
|
-
|
215
|
-
code << "\nend\n"
|
216
|
-
end
|
217
|
-
|
218
|
-
code.join("\n")
|
219
|
-
end
|
220
|
-
|
221
|
-
#
|
222
|
-
def generate_uncovered(output=nil)
|
223
|
-
code = []
|
224
|
-
checklist.each do |base, methods|
|
225
|
-
next if /Lemon::Test::Suite/ =~ base.to_s
|
226
|
-
code << "TestCase #{base} do"
|
227
|
-
methods.each do |meth, covered|
|
228
|
-
next if covered
|
229
|
-
if meth.to_s =~ /^\:\:/
|
230
|
-
meth = meth.sub('::','')
|
231
|
-
code << "\n MetaUnit :#{meth} => '' do\n raise Pending\n end"
|
232
|
-
else
|
233
|
-
code << "\n Unit :#{meth} => '' do\n raise Pending\n end"
|
234
|
-
end
|
235
|
-
end
|
236
|
-
#base.public_instance_methods(false).each do |meth|
|
237
|
-
# code << "\n Unit :#{meth} => '' do\n Pending\n end"
|
238
|
-
#end
|
239
|
-
#unless public_only?
|
240
|
-
# base.private_instance_methods(false).each do |meth|
|
241
|
-
# code << "\n Unit :#{meth} => '' do\n Pending\n end"
|
242
|
-
# end
|
243
|
-
# base.protected_instance_methods(false).each do |meth|
|
244
|
-
# code << "\n Unit :#{meth} => '' do\n Pending\n end"
|
245
|
-
# end
|
246
|
-
#end
|
247
|
-
code << "\nend\n"
|
248
|
-
end
|
249
|
-
code.join("\n")
|
250
|
-
end
|
251
|
-
|
252
|
-
# Get a snapshot of the system.
|
253
|
-
def snapshot
|
254
|
-
Snapshot.capture
|
255
|
-
end
|
256
|
-
|
257
|
-
end#class Coverage
|
258
|
-
|
259
|
-
end#module Lemon
|
260
|
-
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'lemon/coversheet/abstract'
|
2
|
-
|
3
|
-
module Lemon
|
4
|
-
module CoverSheet
|
5
|
-
|
6
|
-
class Outline < Abstract
|
7
|
-
|
8
|
-
#
|
9
|
-
def coverage_finished
|
10
|
-
|
11
|
-
unless uncovered_cases.empty?
|
12
|
-
unc = uncovered_cases.map do |mod|
|
13
|
-
yellow(mod.name)
|
14
|
-
end.join(", ")
|
15
|
-
puts "\nUncovered Cases: " + unc
|
16
|
-
end
|
17
|
-
|
18
|
-
unless uncovered_units.empty?
|
19
|
-
unc = uncovered_units.map do |unit|
|
20
|
-
yellow(unit)
|
21
|
-
end.join(", ")
|
22
|
-
puts "\nUncovered Units: " + unc
|
23
|
-
end
|
24
|
-
|
25
|
-
#unless uncovered.empty?
|
26
|
-
# unc = uncovered.map do |unit|
|
27
|
-
# yellow(unit)
|
28
|
-
# end.join(", ")
|
29
|
-
# puts "\nUncovered: " + unc
|
30
|
-
#end
|
31
|
-
|
32
|
-
unless undefined_units.empty?
|
33
|
-
unc = undefined_units.map do |unit|
|
34
|
-
yellow(unit)
|
35
|
-
end.join(", ")
|
36
|
-
puts "\nUndefined Units: " + unc
|
37
|
-
end
|
38
|
-
|
39
|
-
puts
|
40
|
-
puts tally
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
data/lib/lemon/kernel.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'facets/functor'
|
2
|
-
|
3
|
-
$PRY_TABLE = {} #Hash.new{|h,k| h[k]=nil}
|
4
|
-
|
5
|
-
module Kernel
|
6
|
-
|
7
|
-
# Pry allows you to test private and protected methods,
|
8
|
-
# via a public-only interface.
|
9
|
-
#
|
10
|
-
# Generally one should avoid testing private and protected
|
11
|
-
# method directly, instead relying on tests of public methods to
|
12
|
-
# indirectly test them, because private and protected methods are
|
13
|
-
# considered implementation details. But sometimes is necessary
|
14
|
-
# to test them directly, or if you wish to achieve *absolute
|
15
|
-
# coverage*, say in mission critical systems.
|
16
|
-
|
17
|
-
def pry
|
18
|
-
$PRY_TABLE[self] ||= Functor.new do |op, *a, &b|
|
19
|
-
__send__(op, *a, &b)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
data/lib/lemon/reporter.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'lemon/reporter/dotprogress'
|
2
|
-
require 'lemon/reporter/outline'
|
3
|
-
require 'lemon/reporter/verbose'
|
4
|
-
|
5
|
-
module Lemon
|
6
|
-
module Reporter
|
7
|
-
|
8
|
-
# TODO: make Reporter#factory more dynamic
|
9
|
-
def self.factory(format, runner)
|
10
|
-
format = format.to_s if format
|
11
|
-
case format
|
12
|
-
when 'v', 'verb', 'verbose'
|
13
|
-
Reporter::Verbose.new(runner)
|
14
|
-
when 'o', 'out', 'outline'
|
15
|
-
Reporter::Outline.new(runner)
|
16
|
-
else
|
17
|
-
Reporter::DotProgress.new(runner)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
module Lemon
|
2
|
-
module Reporter
|
3
|
-
|
4
|
-
# = Reporter Base Class
|
5
|
-
class Abstract
|
6
|
-
|
7
|
-
# Supports ANSI Codes?
|
8
|
-
ANSI_SUPPORT = (
|
9
|
-
begin
|
10
|
-
require 'ansi/code'
|
11
|
-
true
|
12
|
-
rescue LoadError
|
13
|
-
false
|
14
|
-
end
|
15
|
-
)
|
16
|
-
|
17
|
-
def initialize(runner)
|
18
|
-
@runner = runner
|
19
|
-
@ansicolor = ANSI_SUPPORT
|
20
|
-
end
|
21
|
-
|
22
|
-
#
|
23
|
-
attr :runner
|
24
|
-
|
25
|
-
#
|
26
|
-
def report_start(suite)
|
27
|
-
end
|
28
|
-
|
29
|
-
def report_concern(concern)
|
30
|
-
end
|
31
|
-
|
32
|
-
def report_success(testunit)
|
33
|
-
end
|
34
|
-
|
35
|
-
def report_failure(testunit, exception)
|
36
|
-
end
|
37
|
-
|
38
|
-
def report_error(testunit, exception)
|
39
|
-
end
|
40
|
-
|
41
|
-
def report_finish
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def successes ; runner.successes ; end
|
47
|
-
def failures ; runner.failures ; end
|
48
|
-
def errors ; runner.errors ; end
|
49
|
-
def pendings ; runner.pendings ; end
|
50
|
-
|
51
|
-
#def uncovered_cases ; runner.uncovered_cases ; end
|
52
|
-
#def uncovered_units ; runner.uncovered_units ; end
|
53
|
-
#def undefined_units ; runner.undefined_units ; end
|
54
|
-
|
55
|
-
#def uncovered ; runner.uncovered ; end
|
56
|
-
#def undefined ; runner.undefined ; end
|
57
|
-
|
58
|
-
## Is coverage information requested?
|
59
|
-
#def cover? ; runner.cover? ; end
|
60
|
-
|
61
|
-
#
|
62
|
-
def red(string)
|
63
|
-
@ansicolor ? ANSI::Code.red{ string } : string
|
64
|
-
end
|
65
|
-
|
66
|
-
#
|
67
|
-
def yellow(string)
|
68
|
-
@ansicolor ? ANSI::Code.yellow{ string } : string
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
def green(string)
|
73
|
-
@ansicolor ? ANSI::Code.green{ string } : string
|
74
|
-
end
|
75
|
-
|
76
|
-
#
|
77
|
-
def cyan(string)
|
78
|
-
@ansicolor ? ANSI::Code.cyan{ string } : string
|
79
|
-
end
|
80
|
-
|
81
|
-
#
|
82
|
-
def total
|
83
|
-
successes.size + failures.size + errors.size + pendings.size
|
84
|
-
end
|
85
|
-
|
86
|
-
#
|
87
|
-
def tally
|
88
|
-
s = "#{total} tests: #{successes.size} pass, #{failures.size} fail, #{errors.size} err, #{pendings.size} pending "
|
89
|
-
#s += "(#{uncovered_units.size} uncovered, #{undefined_units.size} undefined)" if cover?
|
90
|
-
s
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|