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
File without changes
@@ -1,15 +1,16 @@
1
1
  ---
2
+ source:
3
+ - meta
4
+ - VERSION
2
5
  authors:
3
6
  - name: Thomas Sawyer
4
7
  email: transfire@gmail.com
5
8
  copyrights:
6
- - holder: Thomas Sawyer
9
+ - holder: Rubyworks
7
10
  year: '2009'
8
11
  license: BSD-2-Clause
9
- replacements: []
10
- conflicts: []
11
12
  requirements:
12
- - name: test
13
+ - name: rubytest
13
14
  - name: ae
14
15
  - name: ansi
15
16
  version: 1.3+
@@ -25,25 +26,33 @@ requirements:
25
26
  groups:
26
27
  - test
27
28
  development: true
29
+ - name: ripper
30
+ optional: true
31
+ engines:
32
+ - name: ruby
33
+ version: 1.8~
28
34
  dependencies: []
35
+ alternatives: []
36
+ conflicts: []
29
37
  repositories:
30
38
  - uri: git://github.com/proutils/lemon.git
31
39
  scm: git
32
- name: origin
40
+ name: upstream
33
41
  resources:
34
42
  home: http://rubyworks.github.com/lemon
35
43
  code: http://github.com/rubyworks/lemon
44
+ bugs: http://github.com/rubyworks/lemon/issues
45
+ extra: {}
36
46
  load_path:
37
47
  - lib
38
- extra:
39
- manifest: MANIFEST
40
- alternatives: []
41
48
  revision: 0
49
+ created: '2009-10-25'
50
+ summary: Pucker-strength Unit Testing
42
51
  title: Lemon
43
- summary: Pucker-tight Unit Testing
44
- description: Lemon is a unit testing framework that tightly correlates class to test
45
- case and method to test unit.
46
- organization: RubyWorks
47
- version: 0.9.0
48
52
  name: lemon
49
- date: '2011-08-11'
53
+ description: ! 'Lemon is a unit testing framework that tightly correlates
54
+
55
+ class to test case and method to test unit.'
56
+ organization: rubyworks
57
+ version: 0.9.1
58
+ date: '2012-03-09'
@@ -1,11 +1,18 @@
1
- #require 'lemon/cli/test'
1
+ #require 'lemon/cli/runner'
2
2
  require 'lemon/cli/generate'
3
+ require 'lemon/cli/scaffold'
3
4
  require 'lemon/cli/coverage'
5
+ require 'lemon/cli/obrother'
4
6
 
5
7
  module Lemon
6
8
 
9
+ # CLI Interfaces handle all lemon sub-commands.
10
+ #
11
+ module CLI
12
+ end
13
+
7
14
  #--
8
- # TODO: Use Lemon::CLI::Runner and have it delegate to Ruby Test ?
15
+ # TODO: Use Lemon::CLI::Runner and have it delegate to RubyTest ?
9
16
  #++
10
17
 
11
18
  # Command line interface takes the first argument off `argv` to determine
@@ -15,15 +22,19 @@ module Lemon
15
22
  def self.cli(*argv)
16
23
  cmd = argv.shift
17
24
  case cmd
18
- when 'test'
25
+ when 't', 'test', 'run'
19
26
  require 'lemon'
20
- require 'test/cli'
27
+ require 'rubytest'
21
28
  Test::Runner.cli(*ARGV)
22
29
  #Lemon::CLI::Test.new.run(argv)
23
- when /^gen/, /^scaf/
24
- Lemon::CLI::Generate.new.run(argv)
25
- when /^cov/
26
- Lemon::CLI::Coverage.new.run(argv)
30
+ when 'g', 'gen', 'generate', 'generator'
31
+ Lemon::CLI::Generate.run(argv)
32
+ when 's', 'sca', 'scaffold'
33
+ Lemon::CLI::Scaffold.run(argv)
34
+ when 'c', 'cov', 'cover', 'coverage'
35
+ Lemon::CLI::Coverage.run(argv)
36
+ when 'are'
37
+ Lemon::CLI::OBrother.run(argv)
27
38
  else
28
39
  # run tests instead?
29
40
  puts "invalid lemon command -- #{cmd}"
@@ -2,17 +2,14 @@ module Lemon
2
2
 
3
3
  require 'optparse'
4
4
 
5
- # TODO: What about a config file?
6
-
7
- # CLI Interfaces handle all lemon sub-commands.
8
5
  module CLI
9
6
 
10
7
  # Base class for all commands.
11
8
  class Base
12
9
 
13
10
  #
14
- def initialize(argv=ARGV)
15
- @options = {}
11
+ def self.run(argv)
12
+ new.run(argv)
16
13
  end
17
14
 
18
15
  #
@@ -25,12 +22,28 @@ module Lemon
25
22
  begin
26
23
  command_parse(argv)
27
24
  command_run(argv)
28
- rescue => err
29
- raise err if $DEBUG
30
- $stderr.puts('ERROR: ' + err.to_s)
25
+ #rescue => err
26
+ # raise err if $DEBUG
27
+ # $stderr.puts('ERROR: ' + err.to_s)
31
28
  end
32
29
  end
33
30
 
31
+ private
32
+
33
+ #
34
+ # Initialize new command instance. This will be overriden in subclasses.
35
+ #
36
+ def initialize(argv=ARGV)
37
+ @options = {}
38
+ end
39
+
40
+ #
41
+ # Parse command line argument. This is a no-op as it will be overridden
42
+ # in subclasses.
43
+ #
44
+ def command_parse(argv)
45
+ end
46
+
34
47
  #
35
48
  def option_parser
36
49
  @option_parser ||= (
@@ -54,7 +67,7 @@ module Lemon
54
67
  )
55
68
  end
56
69
 
57
- #
70
+ # -n --namespace
58
71
  def option_namespaces
59
72
  option_parser.on('-n', '--namespace NAME', 'add a namespace to output') do |name|
60
73
  options[:namespaces] ||= []
@@ -68,54 +81,63 @@ module Lemon
68
81
  # end
69
82
  #end
70
83
 
84
+ # -f --format
71
85
  def option_format
72
86
  option_parser.on('-f', '--format NAME', 'output format') do |name|
73
87
  options[:format] = name
74
88
  end
75
89
  end
76
90
 
91
+ # -v --verbose
77
92
  def option_verbose
78
93
  option_parser.on('-v', '--verbose', 'shortcut for `-f verbose`') do |name|
79
94
  options[:format] = 'verbose'
80
95
  end
81
96
  end
82
97
 
83
- def option_covered
98
+ # -c --covered, -u --uncovered and -a --all
99
+ def option_coverage
84
100
  option_parser.on('-c', '--covered', 'include covered units') do
85
- options[:covered] = true
101
+ if options[:coverage] == :uncovered
102
+ options[:coverage] = :all
103
+ else
104
+ options[:coverage] = :covered
105
+ end
86
106
  end
87
- end
88
-
89
- def option_uncovered
90
107
  option_parser.on('-u', '--uncovered', 'include only uncovered units') do
91
- options[:uncovered] = true
108
+ if options[:coverage] == :covered
109
+ options[:coverage] = :all
110
+ else
111
+ options[:coverage] = :uncovered
112
+ end
92
113
  end
93
- end
94
-
95
- def option_all
96
114
  option_parser.on('-a', '--all', 'include all namespaces and units') do
97
- options[:all] = true
115
+ options[:coverage] = :all
98
116
  end
99
117
  end
100
118
 
119
+ # -p --private
101
120
  def option_private
102
121
  option_parser.on('-p', '--private', 'include private and protected methods') do
103
122
  options[:private] = true
104
123
  end
105
124
  end
106
125
 
126
+ # -z --zealous
107
127
  def option_zealous
108
128
  option_parser.on('-z', '--zealous', 'include undefined case methods') do
109
129
  options[:zealous] = true
110
130
  end
111
131
  end
112
132
 
133
+ # -o --output
113
134
  def option_output
114
- option_parser.on('-o', '--output DIRECTORY', 'log directory') do |dir|
135
+ option_parser.on('-o', '--output DIRECTORY', 'output directory') do |dir|
115
136
  options[:output] = dir
116
137
  end
117
138
  end
118
139
 
140
+ # -I
119
141
  def option_loadpath
120
142
  option_parser.on("-I PATH" , 'add directory to $LOAD_PATH') do |path|
121
143
  paths = path.split(/[:;]/)
@@ -124,6 +146,7 @@ module Lemon
124
146
  end
125
147
  end
126
148
 
149
+ # -r
127
150
  def option_requires
128
151
  option_parser.on("-r FILE" , 'require file(s) (before doing anything else)') do |files|
129
152
  files = files.split(/[:;]/)
@@ -132,6 +155,13 @@ module Lemon
132
155
  end
133
156
  end
134
157
 
158
+ # --dryrun
159
+ def option_dryrun
160
+ option_parser.on('--dryrun', 'no disk writes') do
161
+ options[:dryrun] = true
162
+ end
163
+ end
164
+
135
165
  end
136
166
 
137
167
  end
@@ -5,11 +5,20 @@ module Lemon
5
5
  require 'lemon/cli/base'
6
6
 
7
7
  # Generate Command
8
+ #
8
9
  class Generate < Base
9
10
 
10
11
  # Generate test templates.
11
- def command_run(test_files)
12
- require 'lemon/generator'
12
+ def command_run(files)
13
+ if i = files.index('-')
14
+ options[:files] = files[0...i]
15
+ options[:tests] = files[i+1..-1]
16
+ else
17
+ options[:files] = files
18
+ options[:tests] = []
19
+ end
20
+
21
+ require 'lemon/coverage/generator'
13
22
 
14
23
  loadpath = options[:loadpath] || []
15
24
  requires = options[:requires] || []
@@ -17,31 +26,57 @@ module Lemon
17
26
  loadpath.each{ |path| $LOAD_PATH.unshift(path) }
18
27
  requires.each{ |path| require(path) }
19
28
 
20
- #cover = options[:uncovered]
21
- #suite = Lemon::TestSuite.new(test_files, :cover=>cover) #, :cover_all=>true)
22
- generator = Lemon::Generator.new(test_files, options)
29
+ generator = Lemon::Generator.new(options)
23
30
 
24
- #if uncovered
25
- # puts cover.generate_uncovered #(output)
26
- #else
27
- puts generator.generate #(output)
28
- #end
31
+ render_map = generator.generate
32
+
33
+ generate_output(render_map)
34
+ end
35
+
36
+ #
37
+ def generate_output(render_map)
38
+ render_map.each do |group, test|
39
+ puts "# --- #{group} ---"
40
+ puts
41
+ puts test
42
+ puts
43
+ end
29
44
  end
30
45
 
31
46
  #
32
47
  def command_parse(argv)
33
- option_parser.banner = "Usage: lemonade generate [options] [files ...]"
34
- #option_parser.separator("Generate test scaffolding.")
48
+ option_parser.banner = "Usage: lemons generate [options] [files ...]"
49
+
50
+ setup_options
51
+
52
+ option_parser.parse!(argv)
53
+ end
35
54
 
55
+ #
56
+ def setup_options
57
+ option_group
36
58
  option_namespaces
37
- option_covered
38
- option_uncovered
39
- option_all
40
59
  option_private
60
+ option_caps
41
61
  option_loadpath
42
62
  option_requires
63
+ end
43
64
 
44
- option_parser.parse!(argv)
65
+ # -f --file
66
+ def option_group
67
+ option_parser.on('-f', '--file', 'group tests by file') do
68
+ options[:group] = :file
69
+ end
70
+ #option_parser.on('-c', '--case', 'group tests by case') do
71
+ # options[:group] = :case
72
+ #end
73
+ end
74
+
75
+ # -C --caps
76
+ def option_caps
77
+ option_parser.on('-C', '--caps', 'use capitalized test terms') do
78
+ options[:caps] = true
79
+ end
45
80
  end
46
81
 
47
82
  end
@@ -0,0 +1,84 @@
1
+
2
+
3
+
4
+ ;.
5
+ : @. @'@@ @# .`
6
+ @@' +@@ @, :@ @@ #.
7
+ ;@@@ @.@@ @ @ @ +: @@ @
8
+ @' #: ##@` @ '; @ :',# :# ,@@:
9
+ '+ ` ;# @+ :+ @ @ +. @ @ #@ @;
10
+ ` @ .#@@ `@ @ @ `@ @ @. @ @
11
+ +@ @@#, @ @ +; @` @ `@ @` @
12
+ @` @ @ @ @` ,@' @ @ @ '@
13
+ @ '' ,; . @@# ` #@` .@@
14
+ +' @@@+ + ;@
15
+ @ `@ ; @
16
+ ,@ @@` +.
17
+ @@@ +; '@`
18
+ :: .@@@@@@@@@@@@@@@'` #@@'
19
+ `@@@@@@@#''#@@@@@@@@@@@;
20
+ @@@@@':,,,,,,,,,,,,,,,,'@@@#
21
+ @@@@',,,,,,,,,,,,,,,,,,,,,,:@@@@@.
22
+ .@@@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,#@@@@+
23
+ @@@#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;@@@'
24
+ +@@#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:@@@
25
+ @@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'@@,
26
+ @@#,,,,,,.........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@
27
+ .@#,,,,,............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#@`
28
+ @@,,,,,..............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@
29
+ @@,,,,,.................,,,,,,,,,,,,,,,,,,,,,,:,,,,,@@
30
+ @@:,,,,...................,,,,,,,,,,,,,,,,,,,,,,,,,,,:@@
31
+ @@,,,,,...................,,,,,,,,,,,,,,,,,,,,,,,,,,,,#@'
32
+ @@,,,,,.....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@.
33
+ @@;,,,,,.....................,,,,,,,,,,,,,,,,,,,,,,,,,,:,,@@;
34
+ '@@,,,,,,.....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:@@@@`
35
+ .@@,,,,,,......................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'@@@@
36
+ @@@,,,,,,,.......................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:,#@@
37
+ :@@@,,,,,,,,......................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;@+
38
+ @@,,,,,,,,,,......................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@
39
+ @@,,,:,,,,,,,,.....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:;@
40
+ @@,,,,,,,,,,,,.....................,,,,,,,,,,,,,,,,;',,,,,,,,,,,,,,,,,,:@,
41
+ '@@@+:,,,,,,,,,.....................,,,,,,,,,,,,,,,,@@,,,,,,,,,,,,,,,,,,'@
42
+ @@@@@,,,,,,,,,,,...................,,,,,,,,,,,,,,,,,++,,,,,,,,,,,,,,,,,,@@
43
+ @@@@#@,,,,,,,,,,,...,@+...........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'@;
44
+ @@#@#@:,,,,,,,,,,...@@@...........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@
45
+ @@@@#,,,,,,,,,,,,,...@'.........,,,,,,,,,,,,,,,,,,,,,,,,@,,,,,,,,,,,,,@@.
46
+ @@@@,,,,,,,,,,,,,,,,..........,,,,,,,,,,,,,,,,,,,,,,,,,@@;,,,,,,,,,,,+@@
47
+ `@',,,,,,,,,,,,,,,,,,,......,,,,,,,,,,,,,,,,,,,,,,,,,,@@#,,,,,,,,,,,,@@
48
+ @@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@+,,,,,,,,,,,,#@'
49
+ :@@;,,,,,,,,,,,,,,@+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#@@;,,,,,,,,,,,,,@@
50
+ +@@#,,,,,,,,,,,,,@@@+,,,,,,,,,,,,,,,,,,,,,,,,,,:@@@,,,,,,,,,,,,,,'@;
51
+ @@',:,,,,,,,,,,,:@@@@,,,,,,,,,,,,,,,,,,,,,,'@@@+,,,,,,,,,,,,,,:@@
52
+ @@,,,,,,,,,,,,,,,:@@@@@',,,,,,,,,,,,,,,'@@@@+,,,,,,,,,,,,,,,,#@,
53
+ '@@,,,,,,,,,,,,,,,,,+@@@@@@@@@@@@@@@@@@@@@:,,,,,,,,,,,,,,,,,,@@
54
+ @@,,,,,,,,,,,,,,,,,,,,,;#@@@@@@@@@@@+;,,,,,,,,,,,,,,,,,,,,,@@`
55
+ #@#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#@#
56
+ @@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@@
57
+ @@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#@#
58
+ '@#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+@@
59
+ @@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@@
60
+ @@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;@@'
61
+ ,@@',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@@
62
+ @@@',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;@@@
63
+ ;@@@@:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:+@@@@.
64
+ .@@@@@+:,,,,,,,,,,,,,,,,,,,,,,,,;@@@@@@'
65
+ `@@@@@@@@##;;;:,,,,,,;####@@@@@@:
66
+ `;@@@@@@@@@@@@@@@@@@@@@@@`
67
+ ```,;@#:::`
68
+ @
69
+ @,
70
+ `@; `@
71
+ @`@ `@. #@`
72
+ @ @ @ @@ @@@ @+@`@.@@
73
+ .@ ' @ @ @ @` @+@`,' ,#@ @@ @@
74
+ '@@# .'@ @`@ ;@# #@; @@' +@. @@:,@@`# @ @ ,+@;`@##@@. @
75
+ @ @#`@ .@@@ @ @`#@ @;#:;@ @ `@@ @ @@@ @@ . . .
76
+ @ @@ +@ @ @ @ @ @@ '+ ,# @ @+@ .
77
+ @'#@#; # :@. @@ ++ @. @ @ @ .
78
+ '; , .+ @ @#+ @ ' @
79
+ @# . @
80
+ @
81
+
82
+
83
+
84
+
@@ -0,0 +1,35 @@
1
+ module Lemon
2
+
3
+ module CLI
4
+
5
+ require 'lemon/cli/base'
6
+
7
+ # The ol' "Sing it, Brother" Command.
8
+ #
9
+ class OBrother < Base
10
+
11
+ #
12
+ def command_run(argv)
13
+ if argv.any?{ |a| a.downcase == 'good' }
14
+ show_ascii_art
15
+ else
16
+ puts "No, they are GOOD!"
17
+ end
18
+ end
19
+
20
+ #
21
+ def show_ascii_art
22
+ string = File.read(File.dirname(__FILE__) + '/lemon.ascii')
23
+ begin
24
+ require 'ansi'
25
+ puts string.ansi(:yellow)
26
+ rescue LoadError
27
+ puts string
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end