lemon 0.9.0 → 0.9.1

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.
Files changed (107) hide show
  1. data/.ruby +23 -14
  2. data/.yardopts +6 -0
  3. data/Config.rb +14 -0
  4. data/{HISTORY.rdoc → HISTORY.md} +26 -11
  5. data/LICENSE.txt +27 -0
  6. data/README.md +42 -28
  7. data/SPECSHEET.md +314 -0
  8. data/bin/{lemonade → lemons} +0 -0
  9. data/lib/lemon.yml +23 -14
  10. data/lib/lemon/cli.rb +19 -8
  11. data/lib/lemon/cli/base.rb +50 -20
  12. data/lib/lemon/cli/generate.rb +51 -16
  13. data/lib/lemon/cli/lemon.ascii +84 -0
  14. data/lib/lemon/cli/obrother.rb +35 -0
  15. data/lib/lemon/cli/scaffold.rb +116 -0
  16. data/lib/lemon/core_ext.rb +2 -2
  17. data/lib/lemon/core_ext/module.rb +9 -0
  18. data/lib/lemon/coverage/analyzer.rb +76 -5
  19. data/lib/lemon/coverage/cover_unit.rb +38 -14
  20. data/lib/lemon/coverage/formats/verbose.rb +1 -1
  21. data/lib/lemon/coverage/generator.rb +196 -0
  22. data/lib/lemon/coverage/snapshot.rb +16 -16
  23. data/lib/lemon/coverage/source_parser.rb +103 -37
  24. data/lib/lemon/ignore_callers.rb +19 -0
  25. data/lib/lemon/test_case.rb +135 -26
  26. data/lib/lemon/test_class.rb +16 -3
  27. data/lib/lemon/test_class_method.rb +58 -0
  28. data/lib/lemon/test_method.rb +57 -68
  29. data/lib/lemon/test_module.rb +47 -44
  30. data/lib/lemon/test_proc.rb +28 -2
  31. data/lib/lemon/test_scope.rb +14 -0
  32. data/lib/lemon/test_setup.rb +1 -1
  33. data/lib/lemon/test_world.rb +7 -0
  34. data/{work/deprecated/features/support → spec/applique}/ae.rb +0 -0
  35. data/spec/coverage/{01_complete.rdoc → 01_complete.md} +3 -3
  36. data/spec/coverage/{02_incomplete.rdoc → 02_incomplete.md} +2 -2
  37. data/spec/coverage/{03_extensions.rdoc → 03_extensions.md} +2 -2
  38. data/try/case_scope.rb +19 -0
  39. metadata +50 -102
  40. data/.gemspec +0 -152
  41. data/.gitignore +0 -8
  42. data/.reap/digest +0 -678
  43. data/.reap/test.reap +0 -7
  44. data/Assembly +0 -37
  45. data/COPYING.rdoc +0 -33
  46. data/MANIFEST +0 -55
  47. data/PROFILE +0 -30
  48. data/Rakefile +0 -23
  49. data/VERSION +0 -1
  50. data/lib/lemon/core_ext/omission.rb +0 -18
  51. data/lib/lemon/generator.rb +0 -149
  52. data/notes/2010-05-05-coverage.rdoc +0 -47
  53. data/notes/2010-05-06-files-not-classes.rdoc +0 -19
  54. data/notes/2010-07-11-acid-testing.rdoc +0 -52
  55. data/notes/2010-08-02-enforcing-the-unit.md +0 -68
  56. data/notes/2010-08-03-new-api.md +0 -37
  57. data/notes/2011-07-07-nailing-down-the-nomenclature.md +0 -6
  58. data/site/.rsync-filter +0 -8
  59. data/site/assets/images/cut-lemon.png +0 -0
  60. data/site/assets/images/forkme.png +0 -0
  61. data/site/assets/images/github-logo.png +0 -0
  62. data/site/assets/images/lemon.jpg +0 -0
  63. data/site/assets/images/lemon.svg +0 -39
  64. data/site/assets/images/lemons-are-good.png +0 -0
  65. data/site/assets/images/opensource.png +0 -0
  66. data/site/assets/images/ruby-logo.png +0 -0
  67. data/site/assets/images/skin.jpg +0 -0
  68. data/site/assets/images/skin1.jpg +0 -0
  69. data/site/assets/images/tap.png +0 -0
  70. data/site/assets/images/title.png +0 -0
  71. data/site/assets/styles/class.css +0 -6
  72. data/site/assets/styles/reset.css +0 -17
  73. data/site/assets/styles/site.css +0 -33
  74. data/site/index.html +0 -218
  75. data/work/deprecated/command/abstract.rb +0 -29
  76. data/work/deprecated/command/coverage.rb +0 -115
  77. data/work/deprecated/command/generate.rb +0 -124
  78. data/work/deprecated/command/test.rb +0 -112
  79. data/work/deprecated/cucumber.yml +0 -3
  80. data/work/deprecated/features/coverage.feature +0 -65
  81. data/work/deprecated/features/generate.feature +0 -66
  82. data/work/deprecated/features/step_definitions/coverage_steps.rb +0 -1
  83. data/work/deprecated/features/support/aruba.rb +0 -1
  84. data/work/deprecated/features/test.feature +0 -67
  85. data/work/deprecated/model/dsl/advice.rb +0 -78
  86. data/work/deprecated/model/dsl/subject.rb +0 -40
  87. data/work/deprecated/model/main.rb +0 -87
  88. data/work/deprecated/model/test.rb +0 -54
  89. data/work/deprecated/model/test_base_dsl.rb +0 -88
  90. data/work/deprecated/model/test_clause.rb +0 -112
  91. data/work/deprecated/model/test_context.rb +0 -90
  92. data/work/deprecated/model/test_feature.rb +0 -128
  93. data/work/deprecated/model/test_scenario.rb +0 -137
  94. data/work/deprecated/model/test_suite.rb +0 -297
  95. data/work/deprecated/rake.rb +0 -103
  96. data/work/deprecated/test/case_coverage_analyzer.rb +0 -25
  97. data/work/deprecated/test/case_test_case_dsl.rb +0 -46
  98. data/work/deprecated/test/fixtures/case_complete.rb +0 -25
  99. data/work/deprecated/test/fixtures/case_inclusion.rb +0 -18
  100. data/work/deprecated/test/fixtures/case_incomplete.rb +0 -12
  101. data/work/deprecated/test/fixtures/example.rb +0 -13
  102. data/work/deprecated/test/fixtures/helper.rb +0 -13
  103. data/work/deprecated/test/runner +0 -2
  104. data/work/old-tests/case_example.rb +0 -15
  105. data/work/old-tests/feature_example.rb +0 -40
  106. data/work/reference/dsl2.rb +0 -140
  107. data/work/reference/dynamic_constant_lookup.rb +0 -76
@@ -1,297 +0,0 @@
1
- require 'lemon/model/test_case'
2
- require 'lemon/model/test_method'
3
- require 'lemon/model/test_module'
4
- require 'lemon/model/test_feature'
5
- require 'lemon/model/snapshot'
6
- #require 'lemon/model/main'
7
- require 'lemon/core_ext/kernel'
8
-
9
- module Lemon
10
-
11
- # Current suite being defined. This is used
12
- # to define a Suite object via the toplevel DSL.
13
- def self.suite
14
- $lemon_suite #@suite ||= Lemon::TestSuite.new([])
15
- end
16
-
17
- #
18
- def self.suite=(suite)
19
- $lemon_suite = suite
20
- end
21
-
22
- # Test Suites encapsulate a set of test cases.
23
- #
24
- class TestSuite
25
-
26
- # Files from which the suite is loaded.
27
- attr :files
28
-
29
- # Test cases in this suite.
30
- attr :cases
31
-
32
- # List of pre-test procedures that apply suite-wide.
33
- attr :before
34
-
35
- # List of post-test procedures that apply suite-wide.
36
- attr :after
37
-
38
- # A snapshot of the system before the suite is loaded.
39
- # Only set if +cover+ option is true.
40
- #attr :canonical
41
-
42
- # List of files to be covered. This primarily serves
43
- # as a means for allowing one test to load another
44
- # and ensuring converage remains accurate.
45
- #attr :subtest
46
-
47
- #attr :current_file
48
-
49
- #def coverage
50
- # @final_coveage ||= @coverage - @canonical
51
- #end
52
-
53
- #
54
- attr :options
55
-
56
- attr :stack
57
-
58
- attr :dsl
59
-
60
- #
61
- def initialize(files, options={})
62
- @files = files.flatten
63
- @options = options
64
-
65
- @cases = []
66
- @helpers = []
67
-
68
- @before = {}
69
- @after = {}
70
-
71
- load_helpers
72
-
73
- #if cover? or cover_all?
74
- # @coverage = Snapshot.new
75
- # @canonical = Snapshot.capture
76
- #end
77
-
78
- @dsl = DSL.new(self) #, files)
79
-
80
- load_files
81
- end
82
-
83
- #
84
- def cover?
85
- @options[:cover]
86
- end
87
-
88
- #
89
- def cover_all?
90
- @options[:cover_all]
91
- end
92
-
93
- #
94
- #class Scope < Module
95
- # def initialize
96
- # extend self
97
- # end
98
- #end
99
-
100
- def to_a
101
- @cases
102
- end
103
-
104
- # Iterate through this suite's test cases.
105
- def each(&block)
106
- @cases.each(&block)
107
- end
108
-
109
- #
110
- def advice
111
- @advice ||= TestAdvice.new
112
- end
113
-
114
- #
115
- def subject
116
- @subject
117
- end
118
-
119
- =begin
120
- #
121
- def start_suite
122
- end
123
-
124
- #
125
- def finish_suite
126
- end
127
- =end
128
-
129
- #
130
- def scope
131
- s = Object.new
132
- s.extend(dsl)
133
- s
134
- end
135
-
136
- # Automatically load helpers. Helpers are any *.rb script in
137
- # a `helpers` directory, relative to a test script.
138
- #
139
- # TODO: You can change the file pattern used to automatically
140
- # load helper scripts in `.lemon`.
141
- #
142
- def load_helpers
143
- helpers = []
144
- filelist.each do |file|
145
- dir = File.dirname(file)
146
- hlp = Dir[File.join(dir, 'helper{s,}/*.rb')]
147
- helpers.concat(hlp)
148
- end
149
- helpers.uniq!
150
- helpers.each do |hlp|
151
- require File.expand_path(hlp)
152
- end
153
- @helpers = helpers
154
- end
155
-
156
- #
157
- def load_files #(*files)
158
- s = Lemon.suite || self
159
- Lemon.suite = self
160
-
161
- filelist.each do |file|
162
- #load_file(file)
163
- load file #require file
164
- end
165
-
166
- Lemon.suite = s
167
-
168
- #if cover?
169
- # $stdout << "\n"
170
- # $stdout.flush
171
- #end
172
-
173
- self #return Lemon.suite
174
- end
175
-
176
- #
177
- #def load_file(file)
178
- # #@current_file = file
179
- # #if cover_all?
180
- # # Covers(file)
181
- # #else
182
- # file = File.expand_path(file)
183
- # @dsl.module_eval(File.read(file), file)
184
- # #require(file) #load(file)
185
- # #end
186
- #end
187
-
188
- # Directories glob *.rb files.
189
- def filelist
190
- @filelist ||= (
191
- files = @files
192
- files = files.map{ |f| Dir[f] }.flatten
193
- files = files.map do |file|
194
- if File.directory?(file)
195
- Dir[File.join(file, '**', '*.rb')]
196
- else
197
- file
198
- end
199
- end.flatten
200
- #files = files.map{ |f| File.expand_path(f) }
201
- files.uniq
202
- files.reject{ |f| /fixture(|s)\/(.*?)\.rb$/ =~ f }
203
- files.reject{ |f| /helper(|s)\/(.*?)\.rb$/ =~ f }
204
- )
205
- end
206
-
207
- # TODO: Note sure about scope creation here
208
- def scope
209
- @scope ||= (
210
- scope = Object.new
211
- scope.extend(dsl)
212
- )
213
- end
214
-
215
- class DSL < Module
216
- #
217
- def initialize(suite)
218
- @suite = suite
219
- #module_eval(&code)
220
- end
221
-
222
- # TODO: need require_find() to avoid first snapshot ?
223
- def covers(file)
224
- #if @test_suite.cover?
225
- # #return if $".include?(file)
226
- # s = Snapshot.capture
227
- # if require(file)
228
- # z = Snapshot.capture
229
- # @test_suite.coverage << (z - s)
230
- # end
231
- #else
232
- require file
233
- #end
234
- end
235
- alias_method :Covers, :covers
236
-
237
- # Define a test case belonging to this suite.
238
- def test_case(description, &block)
239
- options = {
240
- :description => description
241
- }
242
- @suite.cases << TestCase.new(@suite, options, &block)
243
- end
244
-
245
- #
246
- alias_method :TestCase, :test_case
247
-
248
- # Define a module test case belonging to this suite.
249
- def test_module(target_module, &block)
250
- raise "lemon: target must be a module" unless Module === target_module
251
- options = {
252
- :target => target_module
253
- }
254
- @suite.cases << TestModule.new(@suite, optios, &block)
255
- end
256
-
257
- # Define a class test case belonging to this suite.
258
- def test_class(target_class, &block)
259
- raise "lemon: case target must be a class" unless Class === target_class
260
- options = {
261
- :target => target_class
262
- }
263
- @suite.cases << TestModule.new(@suite, options, &block)
264
- end
265
-
266
- # Define a test feature.
267
- def test_feature(target, &block)
268
- options = {
269
- :target => target
270
- }
271
- @suite.cases << TestFeature.new(@suite, options, &block)
272
- end
273
-
274
- # Define a pre-test procedure to apply suite-wide.
275
- def before(*matches, &block)
276
- @suite.before[matches] = block #<< Advice.new(match, &block)
277
- end
278
- alias_method :Before, :before
279
-
280
- # Define a post-test procedure to apply suite-wide.
281
- def after(*matches, &block)
282
- @suite.after[matches] = block #<< Advice.new(match, &block)
283
- end
284
- alias_method :After, :after
285
-
286
- # Includes at the suite level are routed to the toplevel.
287
- #def include(*mods)
288
- # TOPLEVEL_BINDING.eval('self').instance_eval do
289
- # include(*mods)
290
- # end
291
- #end
292
-
293
- end
294
-
295
- end
296
-
297
- end
@@ -1,103 +0,0 @@
1
- require 'rake/tasklib'
2
-
3
- module Lemon
4
-
5
- module Rake
6
-
7
- # Define a lemon test rake task.
8
- #
9
- # The `TEST` environment variable can be used to select tests
10
- # when using the task.
11
- #
12
- # TODO: The test task uses #fork. Maybe it should shell out instead?
13
- class TestTask < ::Rake::TaskLib
14
-
15
- #
16
- DEFAULT_TESTS = [
17
- 'test/**/case_*.rb',
18
- 'test/**/*_case.rb',
19
- 'test/**/test_*.rb',
20
- 'test/**/*_test.rb'
21
- ]
22
-
23
- #
24
- attr_accessor :tests
25
-
26
- #
27
- attr_accessor :loadpath
28
-
29
- #
30
- attr_accessor :requires
31
-
32
- #
33
- attr_accessor :namespaces
34
-
35
- #
36
- attr_accessor :format
37
-
38
- #
39
- def initialize(name='lemon:test', desc="run lemon tests", &block)
40
- @name = name
41
- @desc = desc
42
-
43
- @loadpath = ['lib']
44
- @requires = []
45
- @tests = [ENV['TEST']] || DEFAULT_TESTS
46
- @format = nil
47
- @namespaces = []
48
-
49
- block.call(self)
50
-
51
- define_task
52
- end
53
-
54
- #
55
- def define_task
56
- desc @desc
57
- task @name do
58
- require 'open3'
59
-
60
- @tests ||= (
61
- if ENV['tests']
62
- ENV['tests'].split(/[:;]/)
63
- else
64
- DEFAULT_TESTS
65
- end
66
- )
67
-
68
- run
69
- end
70
- end
71
-
72
- #
73
- def run
74
- fork {
75
- #require 'lemon'
76
- require 'lemon/controller/test_runner'
77
- loadpath.each do |path|
78
- $LOAD_PATH.unshift(path)
79
- end
80
- requires.each do |file|
81
- require file
82
- end
83
- runner = Lemon::TestRunner.new(
84
- tests,
85
- :format => format,
86
- :namespaces => namespaces
87
- )
88
- success = runner.run
89
- exit -1 unless success
90
- }
91
- Process.wait
92
- end
93
-
94
- #
95
- #def ruby_command
96
- # File.join(RbConfig::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
97
- #end
98
-
99
- end
100
-
101
- end
102
-
103
- end
@@ -1,25 +0,0 @@
1
- covers 'lemon/controller/coverage_analyzer'
2
-
3
- testcase Lemon::CoverageAnalyzer do
4
-
5
- setup "Coverage of public units of an incomplete test" do
6
- @memo_instance ||= (
7
- files = ['test/fixtures/case_incomplete.rb']
8
- Lemon::CoverageAnalyzer.new(files)
9
- )
10
- end
11
-
12
- unit :covered => 'returns a list of covered units' do |ca|
13
- ca.covered.assert.is_a?(Array)
14
- end
15
-
16
- unit :uncovered => 'returns a list of uncovered units' do |ca|
17
- ca.uncovered.assert.is_a?(Array)
18
- end
19
-
20
- unit :current => 'returns a current Snapshot of all units in the system' do |ca|
21
- ca.current.assert.is_a?(Lemon::Snapshot)
22
- end
23
-
24
- end
25
-
@@ -1,46 +0,0 @@
1
- testcase Lemon::TestCase::DSL do
2
-
3
- before do
4
- @files = ['test/fixtures/case_inclusion.rb']
5
- end
6
-
7
- setup "Modules included in a test case are accessible by the unit tests" do
8
- ts = Lemon::TestSuite.new(@files)
9
- tc = ts.test_cases.first # the only one
10
- tc.dsl
11
- end
12
-
13
- unit :include, "allows access to module methods" do |dsl|
14
- mod = Module.new{ def x; "x"; end }
15
- dsl.include(mod)
16
- # how to test?
17
- end
18
-
19
- # I do not think it is possible to make this work using dyanmic module
20
- # construction. Please correct me if you know otherwise. To fix
21
- # would mean turning test cases into classes instead of objects. Maybe
22
- # we will do this in the future.
23
- omit unit :include, "allows access to nested modules" do |dsl|
24
- mod = Module.new{ N = 1 }
25
- dsl.include(mod)
26
- dsl::N == 1
27
- end
28
-
29
- setup "Test cases are augmented by before and afters procedures" do
30
- ts = Lemon::TestSuite.new(@files)
31
- tc = ts.test_cases.first # the only one
32
- tc.dsl
33
- end
34
-
35
- unit :before => "setup a pre-testcase procedure" do |dsl|
36
- dsl.before{ }
37
- # how to test?
38
- end
39
-
40
- unit :after => "setup a post-testcase procedure" do |dsl|
41
- dsl.after{ }
42
- # how to test?
43
- end
44
-
45
- end
46
-