Recently I added a configuration mechanism to Webrat. It was surprisingly easy, and mainly copied from rails core. I would suggest adding somthing like this to any plugin that has more than a few features or ones that users have asked to have turned off.
First off you’re going to have to create the actual configuration object. There are a few good ways to do this. One is to use a config module, another is to create a configuration object that is accessible via a singleton method.
I’m going to go with the second one, a configuration object.
Toss this one in lib/configuration.rb (A simplification of Code | RDoc)
module Plugin
# Configures Plugin.
def self.configure(configuration = Plugin::Configuration.new)
yield configuration if block_given?
@@configuration = configuration
end
def self.configuration # :nodoc:
@@configuration ||= Plugin::Configuration.new
end
# Plugin can be configured using the Plugin.configure method. For example:
#
# Plugin.configure do |config|
# config.show_whiny_errors = false
# end
class Configuration
# Should whiny error messages be shown?
attr_writer :show_whiny_errors
def initialize # :nodoc:
# set your defaults in here
self.show_whiny_errors = true
# put as much as you want in here
end
# some syntactic sugar for you, the coder
def show_whiny_errors? #:nodoc:
@show_whiny_erorrs ? true : false
end
end
end
Okay, now we need to test the config object itself. This is why it’s nice to make an object just to house the config, it’s easy to test. What do we test? Well defaults and accessors for two!
(The following lifted from Code) (sorry this is in rspec, it’s not hard to do in test::unit)
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe Plugin::Configuration do
# define matchers for testing
predicate_matchers[:show_whiny_errors] = :show_whiny_errors?
it 'should show whiny errors by default' do
config = Plugin::Configuration.new
config.should show_whiny_errors?
end
it 'should be configurable with a block' do
Plugin.configure do |config|
config.show_whiny_errors = false
end
config = Plugin.configuration
config.should_not show_whiny_errors?
end
end
Now we need to do some stuff to make it nicer for our other users to test. Put the following in your test_helper or spec helper. It will allow you to clear your config after each test. Nice to have to to avoid messy test issues.
(The following lifted from Code)
module Plugin
@@previous_config = nil
def self.cache_config_for_test
@@previous_config = Plugin.configuration.clone
end
def self.reset_for_test
@@configuration = @@previous_config if @@previous_config
end
end
# configure your test runner / spec runner to always clear the config
Spec::Runner.configure do |config|
config.before :each do
Plugin.cache_config_for_test
end
config.after :each do
Plugin.reset_for_test
end
end
This last bit is somewhat hard to do in test::unit as it is harder to hook into the setup (you only get one in the call chain). I’m willing to take some help on cleaning this one up for test::unit. Currently I have just been putting it in the setup / teardown for each test file.
Finally you need to make use of this in tests, fortunately that is quite easy. Just:
describe SomeObject do
it 'it shouldn't do it when whiny nils are off' do
Plugin.configure do |config|
config.show_whiny_errors = false
end
object.should_not_receive(:log)
object.do_somthing_that_usually_complains
end
end
Finally, anywhere in your plugin that you think somthing is whiny, just check the config before using it like this:
log("you should really fix this") if Plugin.configuration.show_whiny_errors?
Post a Comment