methadone 1.0.0.rc5 → 1.0.0.rc6

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 (44) hide show
  1. data/lib/methadone/cli.rb +2 -0
  2. data/lib/methadone/cli_logging.rb +3 -0
  3. data/lib/methadone/cucumber.rb +1 -1
  4. data/lib/methadone/error.rb +8 -1
  5. data/lib/methadone/execution_strategy/jvm.rb +2 -0
  6. data/lib/methadone/execution_strategy/mri.rb +2 -0
  7. data/lib/methadone/execution_strategy/open_3.rb +2 -0
  8. data/lib/methadone/execution_strategy/open_4.rb +2 -0
  9. data/lib/methadone/execution_strategy/rbx_open_4.rb +2 -0
  10. data/lib/methadone/exit_now.rb +18 -3
  11. data/lib/methadone/main.rb +34 -6
  12. data/lib/methadone/process_status.rb +45 -0
  13. data/lib/methadone/sh.rb +52 -29
  14. data/lib/methadone/version.rb +1 -1
  15. data/methadone.gemspec +10 -0
  16. data/test/test_main.rb +20 -0
  17. data/test/test_sh.rb +104 -3
  18. metadata +23 -47
  19. data/tutorial/.vimrc +0 -6
  20. data/tutorial/1_intro.md +0 -52
  21. data/tutorial/2_bootstrap.md +0 -174
  22. data/tutorial/3_ui.md +0 -336
  23. data/tutorial/4_happy_path.md +0 -405
  24. data/tutorial/5_more_features.md +0 -693
  25. data/tutorial/6_refactor.md +0 -220
  26. data/tutorial/7_logging_debugging.md +0 -274
  27. data/tutorial/8_conclusion.md +0 -11
  28. data/tutorial/code/.rvmrc +0 -1
  29. data/tutorial/code/fullstop/.gitignore +0 -5
  30. data/tutorial/code/fullstop/Gemfile +0 -4
  31. data/tutorial/code/fullstop/LICENSE.txt +0 -202
  32. data/tutorial/code/fullstop/README.rdoc +0 -23
  33. data/tutorial/code/fullstop/Rakefile +0 -31
  34. data/tutorial/code/fullstop/bin/fullstop +0 -43
  35. data/tutorial/code/fullstop/features/fullstop.feature +0 -40
  36. data/tutorial/code/fullstop/features/step_definitions/fullstop_steps.rb +0 -64
  37. data/tutorial/code/fullstop/features/support/env.rb +0 -22
  38. data/tutorial/code/fullstop/fullstop.gemspec +0 -28
  39. data/tutorial/code/fullstop/lib/fullstop.rb +0 -2
  40. data/tutorial/code/fullstop/lib/fullstop/repo.rb +0 -38
  41. data/tutorial/code/fullstop/lib/fullstop/version.rb +0 -3
  42. data/tutorial/code/fullstop/test/tc_something.rb +0 -7
  43. data/tutorial/en.utf-8.add +0 -18
  44. data/tutorial/toc.md +0 -27
data/methadone.gemspec CHANGED
@@ -11,6 +11,16 @@ Gem::Specification.new do |s|
11
11
  s.homepage = "http://github.com/davetron5000/methadone"
12
12
  s.summary = %q{Kick the bash habit and start your command-line apps off right}
13
13
  s.description = %q{Methadone provides a lot of small but useful features for developing a command-line app, including an opinionated bootstrapping process, some helpful cucumber steps, and some classes to bridge logging and output into a simple, unified, interface}
14
+ s.post_install_message = "
15
+
16
+ !!!!!!!!!!!!!!!!!!!!!!
17
+
18
+ If you are on Ruby 1.8 or REE, you MUST
19
+
20
+ gem install open4
21
+
22
+ !!!!!!!!!!!!!!!!!!!!!!
23
+ "
14
24
 
15
25
  s.rubyforge_project = "methadone"
16
26
 
data/test/test_main.rb CHANGED
@@ -209,6 +209,26 @@ class TestMain < BaseTest
209
209
  }
210
210
  end
211
211
 
212
+ test_that "when we help_now! we exit and show help" do
213
+ Given {
214
+ @message = any_sentence
215
+ main do
216
+ help_now!(@message)
217
+ end
218
+
219
+ opts.on("--switch") { options[:switch] = true }
220
+ opts.on("--flag FLAG") { |value| options[:flag] = value }
221
+
222
+ set_argv []
223
+ }
224
+
225
+ Then {
226
+ assert_exits(64) { When run_go! }
227
+ assert $stdout.string.include?(opts.to_s),"Expected #{$stdout.string} to contain #{opts.to_s}"
228
+ assert_logged_at_error @message
229
+ }
230
+ end
231
+
212
232
  test_that "opts allows us to more expediently set up OptionParser" do
213
233
  Given {
214
234
  @switch = nil
data/test/test_sh.rb CHANGED
@@ -108,6 +108,30 @@ class TestSH < Clean::Test::TestCase
108
108
  assert_successful_command_execution(@exit_code,@logger,@command,test_command_stdout)
109
109
  }
110
110
  end
111
+
112
+ test_that "#{method}, when the command succeeds and given a block of three arguments, calls the block with the stdout, stderr, and exit code" do
113
+ Given {
114
+ use_capturing_logger
115
+ @command = test_command
116
+ @block_called = false
117
+ @stdout_received = nil
118
+ @stderr_received = nil
119
+ @exitstatus_received = nil
120
+ }
121
+ When {
122
+ @exit_code = self.send(method,@command) do |stdout,stderr,exitstatus|
123
+ @stdout_received = stdout
124
+ @stderr_received = stderr
125
+ @exitstatus_received = exitstatus
126
+ end
127
+ }
128
+ Then {
129
+ @stdout_received.should == test_command_stdout
130
+ @stderr_received.length.should == 0
131
+ @exitstatus_received.should == 0
132
+ assert_successful_command_execution(@exit_code,@logger,@command,test_command_stdout)
133
+ }
134
+ end
111
135
  end
112
136
 
113
137
  test_that "sh, when the command fails and given a block, doesn't call the block" do
@@ -115,7 +139,7 @@ class TestSH < Clean::Test::TestCase
115
139
  use_capturing_logger
116
140
  @command = test_command("foo")
117
141
  @block_called = false
118
- }
142
+ }
119
143
  When {
120
144
  @exit_code = sh @command do
121
145
  @block_called = true
@@ -127,6 +151,50 @@ class TestSH < Clean::Test::TestCase
127
151
  }
128
152
  end
129
153
 
154
+ test_that "sh, when the command fails with an unexpected status, and given a block, doesn't call the block" do
155
+ Given {
156
+ use_capturing_logger
157
+ @command = test_command("foo")
158
+ @block_called = false
159
+ }
160
+ When {
161
+ @exit_code = sh @command, :expected => [2] do
162
+ @block_called = true
163
+ end
164
+ }
165
+ Then {
166
+ @exit_code.should == 1
167
+ assert_logger_output_for_failure(@logger,@command,test_command_stdout,test_command_stderr)
168
+ }
169
+ end
170
+
171
+ [1,[1],[1,2]].each do |expected|
172
+ [:sh,:sh!].each do |method|
173
+ test_that "#{method}, when the command fails with an expected error code (using syntax #{expected}/#{expected.class}), treats it as success" do
174
+ Given {
175
+ use_capturing_logger
176
+ @command = test_command("foo")
177
+ @block_called = false
178
+ @exitstatus_received = nil
179
+ }
180
+ When {
181
+ @exit_code = self.send(method,@command,:expected => expected) do |_,_,exitstatus|
182
+ @block_called = true
183
+ @exitstatus_received = exitstatus
184
+ end
185
+ }
186
+ Then {
187
+ @exit_code.should == 1
188
+ @block_called.should == true
189
+ @exitstatus_received.should == 1
190
+ @logger.debugs[0].should == "Executing '#{test_command}foo'"
191
+ @logger.debugs[1].should == "Output of '#{test_command}foo': #{test_command_stdout}"
192
+ @logger.warns[0].should == "Error output of '#{test_command}foo': #{test_command_stderr}"
193
+ }
194
+ end
195
+ end
196
+ end
197
+
130
198
  test_that "sh runs a command that will fail and logs about it" do
131
199
  Given {
132
200
  use_capturing_logger
@@ -219,7 +287,11 @@ class TestSH < Clean::Test::TestCase
219
287
 
220
288
  def run_command(command)
221
289
  @command = command
222
- [any_string,any_string,OpenStruct.new(:exitstatus => @exit_code)]
290
+ if @exitcode.kind_of? Fixnum
291
+ [any_string,any_string,OpenStruct.new(:exitstatus => @exitcode)]
292
+ else
293
+ [any_string,any_string,@exitcode]
294
+ end
223
295
  end
224
296
 
225
297
  def exception_meaning_command_not_found
@@ -251,7 +323,35 @@ class TestSH < Clean::Test::TestCase
251
323
  }
252
324
  Then {
253
325
  @app.strategy.command.should == @command
254
- @results.should == @exitstatus
326
+ @results.should == @exit_code
327
+ }
328
+ end
329
+
330
+ test_that "when the execution strategy returns a non-int, but truthy value, it gets coerced into a 0" do
331
+ Given {
332
+ @app = MyExecutionStrategyApp.new(true)
333
+ @command = "ls"
334
+ }
335
+ When {
336
+ @results = @app.sh(@command)
337
+ }
338
+ Then {
339
+ @app.strategy.command.should == @command
340
+ @results.should == 0
341
+ }
342
+ end
343
+
344
+ test_that "when the execution strategy returns a non-int, but falsey value, it gets coerced into a 1" do
345
+ Given {
346
+ @app = MyExecutionStrategyApp.new(false)
347
+ @command = "ls"
348
+ }
349
+ When {
350
+ @results = @app.sh(@command)
351
+ }
352
+ Then {
353
+ @app.strategy.command.should == @command
354
+ @results.should == 1
255
355
  }
256
356
  end
257
357
 
@@ -276,6 +376,7 @@ private
276
376
  change_logger(@logger)
277
377
  end
278
378
 
379
+ # Runs the test command which exits with the length of ARGV/args
279
380
  def test_command(args='')
280
381
  File.join(File.dirname(__FILE__),'command_for_tests.rb') + ' ' + args
281
382
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: methadone
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc5
4
+ version: 1.0.0.rc6
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-28 00:00:00.000000000Z
12
+ date: 2012-03-29 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
- requirement: &70123273030540 !ruby/object:Gem::Requirement
16
+ requirement: &70347550918840 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70123273030540
24
+ version_requirements: *70347550918840
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec-expectations
27
- requirement: &70123273030040 !ruby/object:Gem::Requirement
27
+ requirement: &70347550918300 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.6'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70123273030040
35
+ version_requirements: *70347550918300
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70123273029560 !ruby/object:Gem::Requirement
38
+ requirement: &70347550917880 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70123273029560
46
+ version_requirements: *70347550917880
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rdoc
49
- requirement: &70123273028900 !ruby/object:Gem::Requirement
49
+ requirement: &70347550917340 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '3.9'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70123273028900
57
+ version_requirements: *70347550917340
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: cucumber
60
- requirement: &70123273028320 !ruby/object:Gem::Requirement
60
+ requirement: &70347550916840 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.1.1
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70123273028320
68
+ version_requirements: *70347550916840
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: aruba
71
- requirement: &70123273027800 !ruby/object:Gem::Requirement
71
+ requirement: &70347550916460 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70123273027800
79
+ version_requirements: *70347550916460
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: simplecov
82
- requirement: &70123273027220 !ruby/object:Gem::Requirement
82
+ requirement: &70347550915860 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0.5'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70123273027220
90
+ version_requirements: *70347550915860
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: clean_test
93
- requirement: &70123273026680 !ruby/object:Gem::Requirement
93
+ requirement: &70347550915300 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0.10'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70123273026680
101
+ version_requirements: *70347550915300
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: mocha
104
- requirement: &70123273026220 !ruby/object:Gem::Requirement
104
+ requirement: &70347550914780 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70123273026220
112
+ version_requirements: *70347550914780
113
113
  description: Methadone provides a lot of small but useful features for developing
114
114
  a command-line app, including an opinionated bootstrapping process, some helpful
115
115
  cucumber steps, and some classes to bridge logging and output into a simple, unified,
@@ -152,6 +152,7 @@ files:
152
152
  - lib/methadone/execution_strategy/rbx_open_4.rb
153
153
  - lib/methadone/exit_now.rb
154
154
  - lib/methadone/main.rb
155
+ - lib/methadone/process_status.rb
155
156
  - lib/methadone/sh.rb
156
157
  - lib/methadone/version.rb
157
158
  - methadone.gemspec
@@ -179,35 +180,10 @@ files:
179
180
  - test/test_exit_now.rb
180
181
  - test/test_main.rb
181
182
  - test/test_sh.rb
182
- - tutorial/.vimrc
183
- - tutorial/1_intro.md
184
- - tutorial/2_bootstrap.md
185
- - tutorial/3_ui.md
186
- - tutorial/4_happy_path.md
187
- - tutorial/5_more_features.md
188
- - tutorial/6_refactor.md
189
- - tutorial/7_logging_debugging.md
190
- - tutorial/8_conclusion.md
191
- - tutorial/code/.rvmrc
192
- - tutorial/code/fullstop/.gitignore
193
- - tutorial/code/fullstop/Gemfile
194
- - tutorial/code/fullstop/LICENSE.txt
195
- - tutorial/code/fullstop/README.rdoc
196
- - tutorial/code/fullstop/Rakefile
197
- - tutorial/code/fullstop/bin/fullstop
198
- - tutorial/code/fullstop/features/fullstop.feature
199
- - tutorial/code/fullstop/features/step_definitions/fullstop_steps.rb
200
- - tutorial/code/fullstop/features/support/env.rb
201
- - tutorial/code/fullstop/fullstop.gemspec
202
- - tutorial/code/fullstop/lib/fullstop.rb
203
- - tutorial/code/fullstop/lib/fullstop/repo.rb
204
- - tutorial/code/fullstop/lib/fullstop/version.rb
205
- - tutorial/code/fullstop/test/tc_something.rb
206
- - tutorial/en.utf-8.add
207
- - tutorial/toc.md
208
183
  homepage: http://github.com/davetron5000/methadone
209
184
  licenses: []
210
- post_install_message:
185
+ post_install_message: ! "\n\n!!!!!!!!!!!!!!!!!!!!!!\n\nIf you are on Ruby 1.8 or REE,
186
+ you MUST\n\ngem install open4\n\n!!!!!!!!!!!!!!!!!!!!!!\n "
211
187
  rdoc_options: []
212
188
  require_paths:
213
189
  - lib
data/tutorial/.vimrc DELETED
@@ -1,6 +0,0 @@
1
- set spell spelllang=en_us
2
- syn spell toplevel
3
- set spf=~/Projects/methadone/tutorial/en.utf-8.add
4
- ab taht that
5
- ab builting built-in
6
- ab builtin built-in
data/tutorial/1_intro.md DELETED
@@ -1,52 +0,0 @@
1
- # Awesome Ruby Command Line Apps with Methadone
2
-
3
- Kick the bash habit, and make all your command-line apps with Ruby.
4
-
5
- In [Build Awesome Command-Line Applications in Ruby][clibook], I lay out how to make an awesome command-line application using
6
- Ruby. The book focuses on tools like `OptionParser` to create the app. As I wrote and researched, it became clear that there
7
- was a gap between `OptionParser`, which is very powerful, yet verbose, and other command line tools like [trollop][trollop],
8
- [main][main], and [thor][thor], which have simple APIs, but aren't very powerful.
9
-
10
- [clibook]: http://www.awesomecommandlineapps.com
11
- [main]: http://github.com/ahoward/main
12
- [trollop]: http://trollop.rubyforge.org
13
- [thor]: http://www.github.com/wycats/thor
14
-
15
- I created Methadone to bridge that gap. Methadone provides all the power of `OptionParser`, but has a simple, clean API.
16
- Methadone also includes additional tools and classes to make your command-line apps even better.
17
-
18
- This tutorial will show you how to make a simple command-line app using Methadone that will be easy-to-use, easy-to-maintain, and
19
- fully tested.
20
-
21
- ## What you'll need
22
-
23
- You'll need an installation of Ruby and the ability to install Ruby gems. I would recommend that you use rvm and a gemset to
24
- work through these, but they aren't required. There's a decent [walkthrough][setup] on my book's website of setting this up the
25
- way I work. Although Methadone works on most versions of Ruby, I would recommend you use Ruby
26
- 1.9.3, if you can. If not, try to use an MRI Ruby as those versions (1.8.7, REE, 1.9.2, or 1.9.3) have the highest compatibility
27
- with other gems.
28
-
29
- [setup]: http://www.awesomecommandlineapps.com/setup.html
30
-
31
- ## How this is organized
32
-
33
- This is a tutorial for making a simple command-line app. Unlike some tutorials and books, we will be working through this using
34
- a "test-first" approach. One thing that Methadone tries to enable is using [TDD][tdd] for creating and writing your command-line
35
- app. As such, we'll write tests as much as possible to drive our work.
36
-
37
- [tdd]: http://en.wikipedia.org/wiki/Test-driven_development
38
-
39
- ## The tutorial app
40
-
41
- The app we'll build is going to manage "dot files". These are the files that live in your home directory and configure your
42
- shell, editor, and various other programs. For example, `~/.bashrc` is the file to configure `bash`. Many developers keep these
43
- files on [Github][github] so that they can maintain the same files across multiple computers.
44
-
45
- [github]: http://www.github.com
46
-
47
- To set this up on a new computer, you have to checkout the repo, and symlink all the files to your home directory. To update the
48
- files you have to update the repo and then check if any new files were added. This is the sort of tedious manual process that is
49
- ripe for automation via a command-line app.
50
-
51
- We'll develop a simplified version to demonstrate how to use Methadone.
52
-
@@ -1,174 +0,0 @@
1
- # Bootstrapping our app
2
-
3
- One thing that's great about writing a webapp with Ruby on Rails is that, with one command, you have a skeleton app, including
4
- a fully functional test framework set up. You can start writing tests immediately. There's no common equivalent for a
5
- command-line app, which is what Methadone aims to provide.
6
-
7
- Methadone will also bootstrap other aspects of your app, such a `Rakefile`, a gemspec, a shell of an executable, a license, and a
8
- README. First, let's install Methadone via RubyGems (note that if your aren't using rvm, you may need to use `sudo` to install
9
- gems):
10
-
11
- ```sh
12
- $ gem install methadone
13
- Fetching: methadone-1.0.0.gem (100%)
14
- Successfully installed methadone-1.0.0
15
- 1 gem installed
16
- Installing ri documentation for methadone-1.0.0...
17
- Installing RDoc documentation for methadone-1.0.0...
18
- ```
19
-
20
- Methadone comes bundled with a command-line app that will do the bootstrapping:
21
-
22
- ```sh
23
- $ methadone --help
24
- Usage: methadone [options] app_name
25
-
26
- Kick the bash habit by bootstrapping your Ruby command-line apps
27
-
28
- v1.0.0
29
-
30
- Options:
31
- --force Overwrite files if they exist
32
- --[no-]readme [Do not ]produce a README file
33
- -l, --license LICENSE Specify the license for your project (mit|apache|custom|NONE)
34
- --log-level LEVEL Set the logging level (debug|info|warn|error|fatal)
35
- (Default: info)
36
- --version Show help/version info
37
-
38
- Default values can be placed in the METHODONE_OPTS environment variable
39
- ```
40
-
41
- The app that we'll be building in this tutorial is be called `fullstop`, which is derived from the [British name][fullstop] for a period, which is the character used as a prefix to our dotfiles, and, is the reason they are called "dot" files in the first place. Based on the command-line syntax for `methadone`, we can create our app right now with one simple command. We'll use the Apache license as well as a README.
42
-
43
- [fullstop]: http://en.wikipedia.org/wiki/Full_stop
44
-
45
- ```sh
46
- $ methadone --readme --license apache fullstop
47
- $ ls fullstop
48
- Gemfile README.rdoc bin/
49
- fullstop.gemspec test/ LICENSE.txt
50
- Rakefile features/ lib/
51
- ```
52
-
53
- As you can see, we've got a generic gemified project. Before we can start developing, we'll need to install a few gems using Bundler first:
54
-
55
- ```sh
56
- $ cd fullstop
57
- $ bundle install
58
- Fetching source index for http://rubygems.org/
59
- Installing rake (0.9.2.2)
60
- Installing ffi (1.0.11) with native extensions
61
- Installing childprocess (0.3.1)
62
- Installing builder (3.0.0)
63
- Installing diff-lcs (1.1.3)
64
- Installing json (1.6.5) with native extensions
65
- Installing gherkin (2.7.6) with native extensions
66
- Installing term-ansicolor (1.0.7)
67
- Installing cucumber (1.1.4)
68
- Installing rspec-core (2.8.0)
69
- Installing rspec-expectations (2.8.0)
70
- Installing rspec-mocks (2.8.0)
71
- Installing rspec (2.8.0)
72
- Installing aruba (0.4.11)
73
- Using bundler (1.0.21)
74
- Installing methadone (0.5.1)
75
- Using fullstop (0.0.1) from source at /Users/davec/Projects/methadone/tutorial/code/fullstop
76
- Installing rdoc (3.12)
77
- Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
78
- ```
79
-
80
- Your versions might not match up, but this should be more or less what you see. The first thing you'll notice is that this seems
81
- like a *lot* of gems! Most of them are brought in by our acceptance testing framework, [aruba][aruba], which is a library on top
82
- of [cucumber][cucumber] tailor-made for testing command-line apps. Methadone also assumes you'll be unit
83
- testing with `Test::Unit`, which is a fine default. In fact, both unit and acceptance tests are set up for you and available
84
- via `rake` tasks. Let's see them in action.
85
-
86
- [aruba]: http://www.github.com/cucumber/aruba
87
- [cucumber]: http://cukes.info
88
-
89
- ```sh
90
- $ rake
91
- Run options:
92
-
93
- # Running tests:
94
-
95
- .
96
-
97
- Finished tests in 0.000623s, 1605.1364 tests/s, 1605.1364 assertions/s.
98
-
99
- 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
100
- ......
101
-
102
- 1 scenario (1 passed)
103
- 6 steps (6 passed)
104
- 0m0.136s
105
- ```
106
-
107
- As you can see, we ran one unit test and one cucumber scenario. These were provided by Methadone as placeholders for your tests.
108
- Just like what Ruby on Rails does when you create an app, Methadone has reduced the friction between your need to write software
109
- and your ability to do so.
110
-
111
- Methadone also generated a very basic scaffold of the command-line app itself. It's in `bin` and is called `fullstop` (the
112
- argument we gave to `methadone`). Let's run it now:
113
-
114
- ```sh
115
- $ bin/fullstop
116
- /Users/davec/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- fullstop (LoadError)
117
- from /Users/davec/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
118
- from bin/fullstop:5:in `<main>'
119
- ```
120
-
121
- Oops! What happened?
122
-
123
- Methadone is encouraging you to develop your app with best practices, and one such practice is to not have your executables mess with the load path. In many Ruby command-line applications, you'll see code like this at the top of the file:
124
-
125
- ```ruby
126
- $: << File.join(File.dirname(__FILE__),'..','lib')
127
- ```
128
-
129
- This puts the `lib` directory, that is relative to the `bin` directory (where our executable lives), into Ruby's load path. This will allow *us* to run the app easily, but for your users, it's not necessary if you distribute your app with RubyGems (which you should do) and it's generally not a good idea to modify the load path. In order to run the app directly during development, we'll need to use `bundle exec`, like so (note that we won't be running our app a lot in development, but scripting it using Aruba so we can test its behavior in an automated way):
130
-
131
- ```sh
132
- $ bundle exec bin/fullstop --help
133
- Usage: fullstop [options]
134
-
135
- v0.0.1
136
-
137
- Options:
138
- --version Show help/version info
139
- --log-level LEVEL Set the logging level (debug|info|warn|error|fatal)
140
- (Default: info)
141
- ```
142
-
143
-
144
- Not too bad! We've got the makings of a reasonable help system, versioning support, a usage statement and a working executable.
145
- Just remember to run the app with `bundle exec` while you're developing. Remember, your users won't have to worry about as long
146
- as they installed it with RubyGems.
147
-
148
- Before we move on, let's look at the cucumber scenario that Methadone generated for us. We're going to work "outside in" on our
149
- app, so this will be a sneak peek at what we'll be doing next.
150
-
151
- ```sh
152
- $ cat features/fullstop.feature
153
- ```
154
- ```cucumber
155
- Feature: My bootstrapped app kinda works
156
- In order to get going on coding my awesome app
157
- I want to have aruba and cucumber setup
158
- So I don't have to do it myself
159
-
160
- Scenario: App just runs
161
- When I get help for "fullstop"
162
- Then the exit status should be 0
163
- And the banner should be present
164
- And the banner should document that this app takes options
165
- And the following options should be documented:
166
- |--version|
167
- And the banner should document that this app takes no arguments
168
- ```
169
-
170
- We probably won't keep this exactly scenario around, but it's a good demonstration of Aruba and Cucumber, and will help to get us
171
- going. Since this scenario passes, that means that we already have the cucumber steps defined somewhere. As we'll see, the
172
- combination of Aruba and Methadone results in a lot of pre-defined steps that make acceptance testing a snap.
173
-
174
- In the next section, we'll expand this scenario to create the user interface we'll need to get our app going.