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.
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?