- Trollop command-line parser lets you parse any array of tokens, not just ARGV. (todoer)
1b. Bonus: how to have "plug in" options using Trollop - When refactoring, it's often tricky to know where a particular set of changes are going to go. So it pays to look in detail at the code beforehand and not jump into writing specs when you don't even know the subject of the tests yet. But in looking at the code, it doesn't mean you're going in to make changes to it.
- You want to run several implementations, with a different set of fixtures, through the same set of specs. One way. (todoer)
Created
January 9, 2012 15:03
-
-
Save ericgj/1583301 to your computer and use it in GitHub Desktop.
Several things I learned this week: 9 Jan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Trollop command-line parser lets you parse any array of tokens, not just ARGV. | |
opts = Trollop.options( Shellwords.split(str) ) do | |
#... | |
end | |
# and assuming you _don't_ want to exit, display help, etc. in such cases (you're not at the top level of your app): | |
p = Trollop::Parser.new do | |
#... | |
end | |
opts = p.parse(Shellwords.split(str)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Bonus: how to have "plug in" options using Trollop | |
# where 'Plugin' is a module that provides the implementation of a given CLI option | |
# and has module-level accessors for :option_name, :option_desc, :option_type | |
plugins = [ PluginA, PluginB, PluginC ] | |
# parse the command line | |
opts = Trollop.options do | |
plugins.each do |plugin| | |
opt plugin.option_name, plugin.option_desc, :type => plugin.option_type | |
end | |
end | |
# get the command class | |
cmd = CLI::Commands.get(ARGV.shift) | |
# attach the plugin classes | |
cmd.extend *plugins | |
# and run command with the options | |
cmd.run(opts) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# You want to run several implementations, with a different set of fixtures, through the same set of specs. One way. | |
### test_my_adapter.rb | |
module Fixtures | |
def self.adapter_class | |
Adapters::MyAdapter | |
end | |
SIMPLE = #... concrete fixture/dummy/stub for simple case | |
COMPLEX = #... etc. | |
end | |
# run generic tests | |
require File.expand_path('test_adapter_generic',File.dirname(__FILE__)) | |
### test_adapter_generic.rb | |
require 'minitest/spec' | |
MiniTest::Unit.autorun | |
module Fixtures | |
# for example - whatever variables you want to test for each input case | |
Expectation = Struct.new(:count, :categories, :names) | |
# the concrete fixtures have to be set up to match these specs | |
Expectations = { | |
'SIMPLE' => Expectation.new( 6, %w(1 2 3 4 5 6), %w(a b c d e f) ), | |
'COMPLEX' => Expectation.new #... | |
} | |
end | |
describe 'Adapter#method' do | |
def self.get_fixture(fixname) | |
unless fix = Fixtures.const_get(fixname) rescue nil | |
warn "Note: Fixture not found: '#{fixname}', skipping tests" | |
end | |
fix | |
end | |
Fixtures::Expectations.each do |(fixname, expects)| | |
next unless fix = get_fixture(fixname) | |
describe fixname do | |
before do | |
# or however the fixture gets injected into the adapter | |
@subject = Fixtures.adapter_class.new(fix) | |
end | |
# for example, showing how the expectations above are used | |
it 'must return expected count' do | |
assert_equal expects.count, @subject.count | |
end | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment