lemon 0.8.4 → 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.config/cucumber.yml +3 -0
  2. data/.gitignore +8 -0
  3. data/.reap/digest +678 -0
  4. data/.reap/test.reap +7 -0
  5. data/.ruby +42 -45
  6. data/Assembly +43 -0
  7. data/HISTORY.rdoc +10 -0
  8. data/MANIFEST +65 -0
  9. data/PROFILE +9 -6
  10. data/Rakefile +14 -0
  11. data/VERSION +1 -1
  12. data/lemon.gemspec +152 -0
  13. data/lib/lemon.yml +42 -45
  14. data/lib/lemon/cli.rb +4 -2
  15. data/lib/lemon/controller/test_runner.rb +4 -0
  16. data/lib/lemon/model/test_case.rb +122 -40
  17. data/notes/2010-05-05-coverage.rdoc +47 -0
  18. data/notes/2010-05-06-files_not_classes.rdoc +19 -0
  19. data/notes/2010-07-11-acid_testing.rdoc +52 -0
  20. data/notes/2010-08-02-enforcing-the-unit.md +68 -0
  21. data/notes/2010-08-03-new-api.md +37 -0
  22. data/site/.rsync-filter +8 -0
  23. data/site/assets/images/cut-lemon.png +0 -0
  24. data/site/assets/images/forkme.png +0 -0
  25. data/site/assets/images/github-logo.png +0 -0
  26. data/site/assets/images/lemon.jpg +0 -0
  27. data/site/assets/images/lemon.svg +39 -0
  28. data/site/assets/images/lemons-are-good.png +0 -0
  29. data/site/assets/images/opensource.png +0 -0
  30. data/site/assets/images/ruby-logo.png +0 -0
  31. data/site/assets/images/skin.jpg +0 -0
  32. data/site/assets/images/skin1.jpg +0 -0
  33. data/site/assets/images/tap.png +0 -0
  34. data/site/assets/images/title.png +0 -0
  35. data/site/assets/styles/class.css +6 -0
  36. data/site/assets/styles/reset.css +17 -0
  37. data/site/assets/styles/site.css +33 -0
  38. data/site/index.html +217 -0
  39. data/work/deprecated/command/abstract.rb +29 -0
  40. data/work/deprecated/command/coverage.rb +115 -0
  41. data/work/deprecated/command/generate.rb +124 -0
  42. data/work/deprecated/command/test.rb +112 -0
  43. data/work/reference/dsl2.rb +136 -0
  44. data/work/reference/dynamic_constant_lookup.rb +76 -0
  45. data/work/sandbox/lib/sample.rb +13 -0
  46. data/work/sandbox/test/sample_case.rb +12 -0
  47. data/work/trash/example-cover.rb +5 -0
  48. data/work/trash/example.rb +16 -0
  49. metadata +134 -101
  50. data/.yardopts +0 -7
  51. data/QED.rdoc +0 -1
@@ -0,0 +1,124 @@
1
+ module Lemon
2
+ module Command
3
+ require 'lemon/command/abstract'
4
+
5
+ # Lemon Generate Command-line tool.
6
+ class Generate < Abstract
7
+ require 'lemon/coverage'
8
+
9
+ #
10
+ def self.subcommand
11
+ 'generate' #['-g', '--generate']
12
+ end
13
+
14
+ # Initialize and run.
15
+ def self.run
16
+ new.run
17
+ end
18
+
19
+ # New Command instance.
20
+ def initialize
21
+ @requires = []
22
+ @includes = []
23
+ @namespaces = []
24
+ @public_only = false
25
+ @uncovered = false
26
+ end
27
+
28
+ # TODO: Support output ? perhaps complex scaffolding
29
+ #attr_accessor :output
30
+
31
+ #
32
+ attr_accessor :public_only
33
+
34
+ #
35
+ attr_accessor :uncovered
36
+
37
+ #
38
+ def public_only?
39
+ @public_only
40
+ end
41
+
42
+ #
43
+ def uncovered_only?
44
+ @uncovered
45
+ end
46
+
47
+ # Get or set librarires to pre-require.
48
+ def requires(*paths)
49
+ @requires.concat(paths) unless paths.empty?
50
+ @requires
51
+ end
52
+
53
+ # Get or set paths to include in $LOAD_PATH.
54
+ def includes(*paths)
55
+ @includes.concat(paths) unless paths.empty?
56
+ @includes
57
+ end
58
+
59
+ #
60
+ def namespaces(*names)
61
+ @namespaces.concat(names) unless names.empty?
62
+ @namespaces
63
+ end
64
+
65
+ # Instance of OptionParser.
66
+ def parser
67
+ @parser ||= OptionParser.new do |opt|
68
+ opt.banner = "lemon generate [OPTIONS]"
69
+ opt.separator("Generate unit test scaffolding.")
70
+ opt.on("--namespace", "-n [NAME]", "limit tests to this namespace") do |name|
71
+ namespaces(name)
72
+ end
73
+ opt.on("--public", "-p", "only include public methods") do
74
+ self.public_only = true
75
+ end
76
+ opt.on("--uncovered", "-u", "only include uncovered methods") do
77
+ self.uncovered = true
78
+ end
79
+ #opt.on("--output", "-o [PATH]", "output directory") do |path|
80
+ # self.output = path
81
+ #end
82
+ opt.on("-r [FILES]" , "library files to require") do |files|
83
+ files = files.split(/[:;]/)
84
+ requires(*files)
85
+ end
86
+ opt.on("-I [PATH]" , "include in $LOAD_PATH") do |path|
87
+ path = path.split(/[:;]/)
88
+ includes(*path)
89
+ end
90
+ opt.on("--debug" , "turn on debugging mode") do
91
+ $DEBUG = true
92
+ end
93
+ opt.on_tail("--help", "-h", "show this help message") do
94
+ puts opt
95
+ exit
96
+ end
97
+ end
98
+ end
99
+
100
+ # Generate test skeletons.
101
+ def run
102
+ parser.parse!
103
+
104
+ test_files = ARGV.dup
105
+
106
+ includes.each{ |path| $LOAD_PATH.unshift(path) }
107
+ requires.each{ |path| require(path) }
108
+
109
+ suite = Lemon::Test::Suite.new(test_files, :cover=>true)
110
+ cover = Lemon::Coverage.new(suite, namespaces, :public=>public_only?)
111
+ #cover = Lemon::Coverage.new([], namespaces, :public=>public_only?, :uncovered=>uncovered_only?)
112
+
113
+ if uncovered_only?
114
+ puts cover.generate_uncovered #(output)
115
+ else
116
+ puts cover.generate #(output)
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+ end
124
+
@@ -0,0 +1,112 @@
1
+ module Lemon
2
+ module Command
3
+ require 'lemon/command/abstract'
4
+
5
+ # Lemon Test Command-line tool.
6
+ class Test < Abstract
7
+ require 'lemon/runner'
8
+
9
+ def self.subcommand
10
+ 'test'
11
+ end
12
+
13
+ # Initialize and run.
14
+ def self.run
15
+ new.run
16
+ end
17
+
18
+ # New Command instance.
19
+ def initialize
20
+ @format = nil
21
+ @cover = false
22
+ @requires = []
23
+ @includes = []
24
+ @namespaces = []
25
+ end
26
+
27
+ #
28
+ attr_accessor :format
29
+
30
+ #
31
+ attr_accessor :cover
32
+
33
+ # Get or set librarires to pre-require.
34
+ def requires(*paths)
35
+ @requires.concat(paths) unless paths.empty?
36
+ @requires
37
+ end
38
+
39
+ # Get or set paths to include in $LOAD_PATH.
40
+ def includes(*paths)
41
+ @includes.concat(paths) unless paths.empty?
42
+ @includes
43
+ end
44
+
45
+ #
46
+ def namespaces(*names)
47
+ @namespaces.concat(names) unless names.empty?
48
+ @namespaces
49
+ end
50
+
51
+ # Instance of OptionParser.
52
+ def parser
53
+ @parser ||= OptionParser.new do |opt|
54
+ opt.banner = "lemon [options] [test-files ...]"
55
+ opt.separator("Run unit tests.")
56
+ opt.separator("OPTIONS:")
57
+ #opt.on('--coverage', '-c', "include coverage informarton") do
58
+ # self.cover = true
59
+ #end
60
+ opt.on('--verbose', '-v', "select verbose report format") do |type|
61
+ self.format = :verbose
62
+ end
63
+ opt.on('--outline', '-o', "select outline report format") do |type|
64
+ self.format = :outline
65
+ end
66
+ opt.on('--format', '-f [TYPE]', "select report format") do |type|
67
+ self.format = type
68
+ end
69
+ opt.on("--namespace", "-n [NAME]", "limit testing to this namespace") do |name|
70
+ namespaces(name)
71
+ end
72
+ opt.on("-r [FILES]" , 'library files to require') do |files|
73
+ files = files.split(/[:;]/)
74
+ requires(*files)
75
+ end
76
+ opt.on("-I [PATH]" , 'include in $LOAD_PATH') do |path|
77
+ paths = path.split(/[:;]/)
78
+ includes(*paths)
79
+ end
80
+ opt.on("--debug" , 'turn on debugging mode') do
81
+ $DEBUG = true
82
+ end
83
+ opt.on_tail('--help', '-h', 'show this help message') do
84
+ puts opt
85
+ exit
86
+ end
87
+ end
88
+ end
89
+
90
+ # Run unit tests.
91
+ def run
92
+ parser.parse!
93
+
94
+ files = ARGV.dup
95
+
96
+ includes.each{ |path| $LOAD_PATH.unshift(path) }
97
+ requires.each{ |path| require(path) }
98
+
99
+ #suite = Lemon::Test::Suite.new(files, :cover=>cover)
100
+ #runner = Lemon::Runner.new(suite, :format=>format, :cover=>cover, :namespaces=>namespaces)
101
+
102
+ suite = Lemon::Test::Suite.new(files)
103
+ runner = Lemon::Runner.new(suite, :format=>format, :namespaces=>namespaces)
104
+
105
+ runner.run
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+ end
112
+
@@ -0,0 +1,136 @@
1
+ require 'ae'
2
+
3
+ module Lemon
4
+
5
+ def self.suite
6
+ @suite ||= Suite.new(Runner.new(Reporter.new))
7
+ end
8
+
9
+ def self.suite=(suite)
10
+ @suite = suite
11
+ end
12
+
13
+ class Context
14
+ def initialize(desc=nil)
15
+ @desc = desc
16
+ @before = {}
17
+ @after = {}
18
+ end
19
+
20
+ def description
21
+ @desc
22
+ end
23
+
24
+ def before(which, &block)
25
+ @before[which] = block if block
26
+ @before[which]
27
+ end
28
+
29
+ def after(which, &block)
30
+ @after[which] = block if block
31
+ @after[which]
32
+ end
33
+ end
34
+
35
+ class Suite
36
+ def initialize(runner)
37
+ @runner = runner
38
+ end
39
+
40
+ def before(which, &block)
41
+ @runner.before(which, &block)
42
+ end
43
+
44
+ def after(which, &block)
45
+ @runner.after(which, &block)
46
+ end
47
+
48
+ def unit(mod, meth, desc=nil, &block)
49
+ @runner.unit(mod, meth, desc, &block)
50
+ end
51
+
52
+ def context(desc, &block)
53
+ @runner.context(desc, &block)
54
+ end
55
+ end
56
+
57
+ # Runner is a listner.
58
+ class Runner
59
+ #
60
+ def initialize(*reporters)
61
+ @reporters = reporters
62
+ #@before = {} #Hash.new{|h,k| h[k]=[]}
63
+ #@after = {} #Hash.new{|h,k| h[k]=[]}
64
+ @context_stack = [Context.new]
65
+ end
66
+
67
+ def before(which, &block)
68
+ @context_stack.last.before(which, &block)
69
+ @reporters.each do |reporter|
70
+ reporter.before(which, &block)
71
+ end
72
+ end
73
+
74
+ def after(which, &block)
75
+ @context_stack.last.after(which, &block)
76
+ @reporters.each do |reporter|
77
+ reporter.after(which, &block)
78
+ end
79
+ end
80
+
81
+ def instance(desc, &block)
82
+ @instance = Context.new(desc, &block)
83
+ end
84
+
85
+ def unit(mod, meth, desc=nil, &block)
86
+ @reporters.each do |reporter|
87
+ reporter.unit(mod, meth, desc, &block)
88
+ end
89
+
90
+ if @instance && block.arity != 0
91
+ block.call(@instance.call)
92
+ else
93
+ block.call
94
+ end
95
+
96
+ end
97
+ end
98
+
99
+ class Reporter
100
+ #
101
+ def initialize
102
+ end
103
+
104
+ def before(which, &block)
105
+ end
106
+
107
+ def after(which, &block)
108
+ end
109
+
110
+ def unit(mod, meth, desc=nil, &block)
111
+ puts "%s#%s %s" % [mod.name, meth.to_s, desc]
112
+ end
113
+ end
114
+
115
+ end
116
+
117
+
118
+ #
119
+ def before(which, &block)
120
+ Lemon.suite.before(which, &block)
121
+ end
122
+
123
+ #
124
+ def after(which, &block)
125
+ Lemon.suite.after(which, &block)
126
+ end
127
+
128
+ #
129
+ def unit(mod, meth, desc=nil, &blk)
130
+ Lemon.suite.unit(mod, meth, desc, &blk)
131
+ end
132
+
133
+ def context(desc, &block)
134
+ Lemon.suite.context(desc, &block)
135
+ end
136
+
@@ -0,0 +1,76 @@
1
+ #
2
+ module M
3
+ def m1; "m1"; end
4
+ module N
5
+ def self.n1; "n1"; end
6
+ end
7
+ end
8
+
9
+ class X
10
+ class << self
11
+ alias _new new
12
+ def new(&block)
13
+ klass = Class.new(self)
14
+ klass.module_eval(&block)
15
+ klass._new
16
+ end
17
+ end
18
+
19
+ def m ; m1 ; end
20
+ def n ; N.n1 ; end
21
+ end
22
+
23
+ x = X.new do
24
+ include M
25
+ end
26
+
27
+ p x.m
28
+ p x.n
29
+
30
+
31
+ exit
32
+
33
+ class X
34
+ attr :set
35
+ def initialize(&block)
36
+ @set = {}
37
+ instance_eval(&block)
38
+ end
39
+ def defset(name, &block)
40
+ @set[name] = block
41
+ end
42
+ def include(*mods)
43
+ (class << self; self; end).class_eval do
44
+ include *mods
45
+ end
46
+ end
47
+ end
48
+
49
+ #
50
+ module M
51
+ def m1; "m1"; end
52
+ module N
53
+ def self.n1; "n1"; end
54
+ end
55
+ end
56
+
57
+ x = X.new do
58
+
59
+ include M
60
+
61
+ #Before /returns/ do |unit|
62
+ # puts "returns something"
63
+ #end
64
+
65
+ defset :m do
66
+ m1 == "m1"
67
+ end
68
+
69
+ defset :n do
70
+ N.n1 == "n1"
71
+ end
72
+
73
+ end
74
+
75
+ x.set[:m].call
76
+ x.set[:n].call