We earlier moved to duplicating Action objects in the Faces subsystem to
ensure they had the correct binding context during execution and introspection.

This was correct, but introduced a bug where we would report both the parent
and child binding as separate entries with duplicate names, in the list of
actions.

This flowed on to the help output, where it would cause every inherited action
to be listed twice: once on the parent, once on the child.  (This was actually
worse if the inheritance was deeper: we would duplicate once for every level
between the instance and the origin of the action.)
---
 lib/puppet/interface/action_manager.rb     |    5 ++-
 spec/unit/interface/action_manager_spec.rb |   50 +++++++++++++++++++++-------
 2 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/lib/puppet/interface/action_manager.rb 
b/lib/puppet/interface/action_manager.rb
index c5eb8e0..fbf588d 100644
--- a/lib/puppet/interface/action_manager.rb
+++ b/lib/puppet/interface/action_manager.rb
@@ -34,7 +34,10 @@ module Puppet::Interface::ActionManager
     elsif self.class.respond_to?(:actions)
       result += self.class.actions
     end
-    result.sort
+    # We need to uniq the result, because we duplicate actions when they are
+    # fetched to ensure that they have the correct bindings; they shadow the
+    # parent, and uniq implements that. --daniel 2011-06-01
+    result.uniq.sort
   end
 
   def get_action(name)
diff --git a/spec/unit/interface/action_manager_spec.rb 
b/spec/unit/interface/action_manager_spec.rb
index e357a5f..3a84e4f 100755
--- a/spec/unit/interface/action_manager_spec.rb
+++ b/spec/unit/interface/action_manager_spec.rb
@@ -186,23 +186,49 @@ describe Puppet::Interface::ActionManager do
       @instance.should be_action(:foo)
     end
 
-    it "should list actions defined in superclasses" do
-      @subclass = Class.new(@klass)
-      @instance = @subclass.new
+    context "with actions defined in superclass" do
+      before :each do
+        @subclass = Class.new(@klass)
+        @instance = @subclass.new
+
+        @klass.action(:parent) do
+          when_invoked { |options| "a" }
+        end
+        @subclass.action(:sub) do
+          when_invoked { |options| "a" }
+        end
+        @instance.action(:instance) do
+          when_invoked { |options| "a" }
+        end
+      end
+
+      it "should list actions defined in superclasses" do
+        @instance.should be_action(:parent)
+        @instance.should be_action(:sub)
+        @instance.should be_action(:instance)
+      end
 
-      @klass.action(:parent) do
-        when_invoked { |options| "a" }
+      it "should list inherited actions" do
+        @instance.actions.should =~ [:instance, :parent, :sub]
       end
-      @subclass.action(:sub) do
-        when_invoked { |options| "a" }
+
+      it "should not duplicate instance actions after fetching them (#7699)" do
+        @instance.actions.should =~ [:instance, :parent, :sub]
+        @instance.get_action(:instance)
+        @instance.actions.should =~ [:instance, :parent, :sub]
       end
-      @instance.action(:instance) do
-        when_invoked { |options| "a" }
+
+      it "should not duplicate subclass actions after fetching them (#7699)" do
+        @instance.actions.should =~ [:instance, :parent, :sub]
+        @instance.get_action(:sub)
+        @instance.actions.should =~ [:instance, :parent, :sub]
       end
 
-      @instance.should be_action(:parent)
-      @instance.should be_action(:sub)
-      @instance.should be_action(:instance)
+      it "should not duplicate superclass actions after fetching them (#7699)" 
do
+        @instance.actions.should =~ [:instance, :parent, :sub]
+        @instance.get_action(:parent)
+        @instance.actions.should =~ [:instance, :parent, :sub]
+      end
     end
 
     it "should create an instance method when an action is defined in a 
superclass" do
-- 
1.7.5.2

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to