diff options
author | Chris Roberts <chrisroberts.code@gmail.com> | 2013-04-18 10:49:32 -0700 |
---|---|---|
committer | Chris Roberts <chrisroberts.code@gmail.com> | 2013-04-18 10:49:32 -0700 |
commit | 47a51f58bf8f84718e6cc2dbeaf21028b4d711d3 (patch) | |
tree | 169983c67b80364221b821c59a86401adb2f440e | |
parent | 83e161811cbe483759790d737229efbca2f93021 (diff) | |
download | mixlib-cli-47a51f58bf8f84718e6cc2dbeaf21028b4d711d3.tar.gz |
Properly pass options during inheritance. Full dup to ensure proper option isolation.
-rw-r--r-- | lib/mixlib/cli.rb | 27 | ||||
-rw-r--r-- | spec/mixlib/cli_spec.rb | 36 |
2 files changed, 62 insertions, 1 deletions
diff --git a/lib/mixlib/cli.rb b/lib/mixlib/cli.rb index bdaabdb..23fcb9e 100644 --- a/lib/mixlib/cli.rb +++ b/lib/mixlib/cli.rb @@ -38,8 +38,32 @@ module Mixlib # #parse_options. After calling this method, the attribute #config will # contain a hash of `:option_name => value` pairs. module CLI - module ClassMethods + + module InheritMethods + def inherited(receiver) + receiver.options = deep_dup(self.options) + receiver.extend(Mixlib::CLI::InheritMethods) + end + def deep_dup(thing) + new_thing = thing.respond_to?(:dup) ? thing.dup : thing + if(new_thing.kind_of?(Enumerable)) + if(new_thing.kind_of?(Hash)) + duped = new_thing.map do |key, value| + [deep_dup(key), deep_dup(value)] + end + new_thing = new_thing.class[*duped.flatten] + else + new_thing.map!{|value| deep_dup(value)} + end + end + new_thing + rescue TypeError + thing + end + end + + module ClassMethods # When this setting is set to +true+, default values supplied to the # mixlib-cli DSL will be stored in a separate Hash def use_separate_default_options(true_or_false) @@ -255,6 +279,7 @@ module Mixlib def self.included(receiver) receiver.extend(Mixlib::CLI::ClassMethods) + receiver.extend(Mixlib::CLI::InheritMethods) end end diff --git a/spec/mixlib/cli_spec.rb b/spec/mixlib/cli_spec.rb index 39740b4..9175506 100644 --- a/spec/mixlib/cli_spec.rb +++ b/spec/mixlib/cli_spec.rb @@ -235,6 +235,42 @@ describe Mixlib::CLI do end + context "when subclassed" do + before do + TestCLI.options = {:arg1 => {:boolean => true}} + end + + it "should retain previously defined options from parent" do + class T1 < TestCLI + option :arg2, :boolean => true + end + T1.options[:arg1].should be_a(Hash) + T1.options[:arg2].should be_a(Hash) + TestCLI.options[:arg2].should be_nil + end + + it "should not be able to modify parent classes options" do + class T2 < TestCLI + option :arg2, :boolean => true + end + T2.options[:arg1][:boolean] = false + T2.options[:arg1][:boolean].should be_false + T1.options[:arg1][:boolean].should be_true + end + + it "should pass its options onto child" do + class T3 < TestCLI + option :arg2, :boolean => true + end + class T4 < T3 + option :arg3, :boolean => true + end + 3.times do |i| + T4.options["arg#{i + 1}".to_sym].should be_a(Hash) + end + end + end + end |