Saturday, March 13, 2010

Tough Time Spec'ing Exit

‹prev | My Chain | next›

Dang.

I really wanted to move on, but I think I need to add a code generator for new map, reduces and libraries. I think it would be helpful to be able to generate a map-reduce for recipes by date with this command:
couch-docs generate map-reduce recipes by_date
After some searching, I came across the rubygen gem which seems like it might do the trick. I install with:
cstrom@whitefall:~/repos/couch_docs$ gem install rubigen
WARNING: Installing to ~/.gem since /var/lib/gems/1.8 and
/var/lib/gems/1.8/bin aren't both writable.
Successfully installed rubigen-1.5.4
1 gem installed
Hrm. It looks like rubigen requires activesupport:
$:.unshift(File.dirname(__FILE__)) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))

begin
# if you are using rubygems, fix to 2.3.5
gem 'activesupport', '2.3.5'
rescue
end

require 'active_support'

module RubiGen
VERSION = '1.5.4'
end
...
ActiveSupport seems a bit much. RubiGen is something intended more for rolling your own framework.

So, even though it will mean a less awesome generator, I will roll my own. I start with an RSpec example over the command line:
  context "generate" do
it "should fail with unknown generators" do
@it = CommandLine.new(['generate', 'foo'])
Kernel.should_receive(:exit)
@it.run
end
That fails with:
1)
SystemExit in 'CouchDocs::CommandLine generate should fail with unknown generators'
exit
./spec/couch_docs_spec.rb:439:in `new'
./spec/couch_docs_spec.rb:439:
Ugh. SystemExit? What's that all about? Ah, there is some output in my spec run:
.......invalid command: "generate".  Must be one of push, dump.

Usage: couch-docs push|dump [OPTIONS] couchdb_url [target_dir]

Try --help for more options.
F
Ah, I really am in the normal change-the-message or make-it-pass cycle. In this case, I need to add to the list of know commands:

And then handle the new generate command:
...
if @command == "generate"
puts "Invalid generator #{args.first}"
exit
else
# handle push/dump
...
Running the examples, I get:
1)
SystemExit in 'CouchDocs::CommandLine generate should fail with unknown generators'
exit
./spec/couch_docs_spec.rb:439:in `new'
./spec/couch_docs_spec.rb:439:
Hunh? Shouldn't that should_receive exit prevent that error?

Sadly, it takes me a loooong time to realize that exit is occurring in the new, not the run so I have to rearrange when I set my expectation for an exit:
    it "should fail with unknown generators" do
Kernel.should_receive(:exit)
@it = CommandLine.new(['generate', 'foo'])
end
Running the example, I now find... the exact same thing:
1)
SystemExit in 'CouchDocs::CommandLine generate should fail with unknown generators'
exit
./spec/couch_docs_spec.rb:440:in `new'
./spec/couch_docs_spec.rb:440:
Gah!

At this point, I have to resort to catching exceptions on lambdas:
    it "should fail with unknown generators" do
lambda {
CommandLine.new(['generate', 'foo'])
}.should raise_error SystemExit
end
That finally gets the example passing.

Rather than stumble any further, I will call it a night at this point and hope for better fortune tomorrow.

Day #41

No comments:

Post a Comment