Please review pull request #703: usability improvements to resource_type API opened by (cprice-puppet)

Description:

These commits do the following:

  • Allow you to filter the output of a "resource_type" search by "kind" (defined_type, class, node)
  • Change the output to use terminology that is more consistent with our documentation

  • Opened: Tue Apr 24 00:46:03 UTC 2012
  • Based on: puppetlabs:master (54e1c83afde1b721e5433adea17a4dd0caffbc63)
  • Requested merge: cprice-puppet:feature/master/filter_resource_type_by_type (0e41832a8045c0784544284f0089ec5ba08d8495)

Diff follows:

diff --git a/lib/puppet/indirector/resource_type/parser.rb b/lib/puppet/indirector/resource_type/parser.rb
index 4bcaf3f..6afb554 100644
--- a/lib/puppet/indirector/resource_type/parser.rb
+++ b/lib/puppet/indirector/resource_type/parser.rb
@@ -20,11 +20,44 @@ def find(request)
     nil
   end
 
+  # This is the "search" indirection method for resource types.  It searches
+  #  through a specified environment for all custom declared classes
+  #  (a.k.a 'hostclasses'), defined types (a.k.a. 'definitions'), and nodes.
+  #
+  # @param [Puppet::Indirector::Request] request
+  #   Important properties of the request parameter:
+  #   1. request.environment : The environment in which to look for types.
+  #   2. request.key : A String that will be treated as a regular _expression_ to
+  #         be matched against the names of the available types.  You may also
+  #         pass a "*", which will match all available types.
+  #   3. request.options[:kind] : a String that can be used to filter the output
+  #         to only return the desired kinds.  The current supported values are
+  #         'class', 'defined_type', and 'node'.
   def search(request)
     krt = request.environment.known_resource_types
     # Make sure we've got all of the types loaded.
     krt.loader.import_all
-    result = [krt.hostclasses.values, krt.definitions.values, krt.nodes.values].flatten.reject { |t| t.name == "" }
+
+    result_candidates = []
+    # We need to check and see if the request contains a 'kind' filter, and, if so, filter accordingly.s
+    if request.options.has_key?(:kind)
+      case request.options[:kind]
+        when "class"
+          result_candidates = krt.hostclasses.values
+        when "defined_type"
+          result_candidates = krt.definitions.values
+        when "node"
+          result_candidates = krt.nodes.values
+        else
+          raise ArgumentError, "Unrecognized kind filter: " +
+                    "'#{request.options[:kind]}', expected one " +
+                    " of 'class', 'defined_type', or 'node'."
+      end
+    else
+      result_candidates = [krt.hostclasses.values, krt.definitions.values, krt.nodes.values]
+    end
+
+    result = result_candidates.flatten.reject { |t| t.name == "" }
     return nil if result.empty?
     return result if request.key == "*"
 
diff --git a/lib/puppet/network/format.rb b/lib/puppet/network/format.rb
index 69895c3..940ec09 100644
--- a/lib/puppet/network/format.rb
+++ b/lib/puppet/network/format.rb
@@ -68,9 +68,9 @@ def render(instance)
     raise NotImplementedError, "#{instance.class} does not respond to #{render_method}; can not render instances to #{mime}"
   end
 
-  def render_multiple(instances)
+  def render_multiple(instances, options = {})
     # This method implicitly assumes that all instances are of the same type.
-    return instances[0].class.send(render_multiple_method, instances) if instances[0].class.respond_to?(render_multiple_method)
+    return instances[0].class.send(render_multiple_method, instances, options) if instances[0].class.respond_to?(render_multiple_method)
     raise NotImplementedError, "#{instances[0].class} does not respond to #{render_multiple_method}; can not intern multiple instances to #{mime}"
   end
 
diff --git a/lib/puppet/network/format_handler.rb b/lib/puppet/network/format_handler.rb
index b94a4f9..1c8e3f0 100644
--- a/lib/puppet/network/format_handler.rb
+++ b/lib/puppet/network/format_handler.rb
@@ -112,8 +112,16 @@ def convert_from_multiple(format, data)
       format_handler.protected_format(format).intern_multiple(self, data)
     end
 
-    def render_multiple(format, instances)
-      format_handler.protected_format(format).render_multiple(instances)
+    # render an array of objects
+    #
+    # @param [Puppet::Netork::Format] - the formatter to use to render with
+    # @param [Array] instances - the list of objects to render
+    # @param [Hash] options - an optional hash of rendering hints / options to use to
+    #   control formatting.  Options/hints may not be supported by all renderers.
+    #   Example options are:
+    #    * :pp - "pretty print".  request for output to be formatted in a more human-readable fashion.
+    def render_multiple(format, instances, options = {})
+      format_handler.protected_format(format).render_multiple(instances, options)
     end
 
     def default_format
diff --git a/lib/puppet/network/formats.rb b/lib/puppet/network/formats.rb
index c5af288..c29ae77 100644
--- a/lib/puppet/network/formats.rb
+++ b/lib/puppet/network/formats.rb
@@ -16,7 +16,7 @@ def render(instance)
   end
 
   # Yaml monkey-patches Array, so this works.
-  def render_multiple(instances)
+  def render_multiple(instances, options = {})
     instances.to_yaml
   end
 
@@ -56,7 +56,7 @@ def render(instance)
     encode(instance.to_yaml)
   end
 
-  def render_multiple(instances)
+  def render_multiple(instances, options = {})
     encode(instances.to_yaml)
   end
 
@@ -85,7 +85,7 @@ def intern_multiple(klass, text)
     raise NotImplementedError
   end
 
-  def render_multiple(instances)
+  def render_multiple(instances, options = {})
     raise NotImplementedError
   end
 
@@ -113,9 +113,19 @@ def intern_multiple(klass, text)
     end
   end
 
-  # PSON monkey-patches Array, so this works.
-  def render_multiple(instances)
-    instances.to_pson
+  # render an array of objects as PSON.
+  #
+  # @param [Array] instances - the list of objects to render
+  # @param [Hash] options - an optional hash of rendering hints / options to use to
+  #   control formatting.  Currently supported options are:
+  #    * :pp - "pretty print".  output will be formatted in a more human-readable fashion.
+  def render_multiple(instances, options = {})
+    if (options.has_key?(:pp) and options[:pp] != false)
+      PSON::pretty_generate(instances)
+    else
+      # PSON monkey-patches Array, so this works.
+      instances.to_pson
+    end
   end
 
   # If they pass class information, we want to ignore it.  By default,
@@ -165,7 +175,7 @@ def render(datum)
     return json.render(datum)
   end
 
-  def render_multiple(data)
+  def render_multiple(data, options = {})
     data.collect(&:render).join("\n")
   end
 end
diff --git a/lib/puppet/network/http/api/v1.rb b/lib/puppet/network/http/api/v1.rb
index ef19fe4..29146ff 100644
--- a/lib/puppet/network/http/api/v1.rb
+++ b/lib/puppet/network/http/api/v1.rb
@@ -54,7 +54,7 @@ def indirection_method(http_method, indirection)
     raise ArgumentError, "No support for http method #{http_method}" unless METHOD_MAP[http_method]
 
     unless method = METHOD_MAP[http_method][plurality(indirection)]
-      raise ArgumentError, "No support for plural #{http_method} operations"
+      raise ArgumentError, "No support for plurality #{plurality(indirection)} for #{http_method} operations"
     end
 
     method
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index c25798d..b97091c 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -143,7 +143,12 @@ def do_search(indirection_name, key, params, request, response)
     format = format_to_use(request)
     set_content_type(response, format)
 
-    set_response(response, model.render_multiple(format, result))
+    render_options = {}
+    if (params.has_key?(:pp))
+      render_options[:pp] = true
+    end
+
+    set_response(response, model.render_multiple(format, result, render_options))
   end
 
   # Execute our destroy.
diff --git a/lib/puppet/resource/type.rb b/lib/puppet/resource/type.rb
index 72dbf22..abd2853 100644
--- a/lib/puppet/resource/type.rb
+++ b/lib/puppet/resource/type.rb
@@ -11,12 +11,35 @@ class Puppet::Resource::Type
   include Puppet::Util::Warnings
   include Puppet::Util::Errors
 
-  RESOURCE_SUPERTYPES = [:hostclass, :node, :definition]
+  RESOURCE_KINDS = [:hostclass, :node, :definition]
+
+  # We have reached a point where we've established some naming conventions
+  #  in our documentation that don't entirely match up with our internal names
+  #  for things.  Ideally we'd change the internal representation to match the
+  #  conventions expressed in our docs, but that would be a fairly far-reaching
+  #  and risky change.  For the time being, we're settling for mapping the
+  #  internal names to the external ones (and vice-versa) during serialization
+  #  and deserialization.  These two hashes is here to help with that mapping.
+  RESOURCE_KINDS_TO_EXTERNAL_NAMES = {
+      :hostclass => "class",
+      :node => "node",
+      :definition => "defined_type",
+  }
+  RESOURCE_EXTERNAL_NAMES_TO_KINDS = {
+      "class" => :hostclass,
+      "node" => :node,
+      "defined_type" => :definition,
+  }
 
   attr_accessor :file, :line, :doc, :code, :ruby_code, :parent, :resource_type_collection
-  attr_reader :type, :namespace, :arguments, :behaves_like, :module_name
+  attr_reader :namespace, :arguments, :behaves_like, :module_name
 
-  RESOURCE_SUPERTYPES.each do |t|
+  # This should probably be renamed to 'kind' eventually, in accordance with the changes
+  #  made for serialization and API usability (#14137).  At the moment that seems like
+  #  it would touch a whole lot of places in the code, though.  --cprice 2012-04-23
+  attr_reader :type
+
+  RESOURCE_KINDS.each do |t|
     define_method("#{t}?") { self.type == t }
   end
 
@@ -26,13 +49,36 @@ class Puppet::Resource::Type
 
   def self.from_pson(data)
     name = data.delete('name') or raise ArgumentError, "Resource Type names must be specified"
-    type = data.delete('type') || "definition"
+    kind = data.delete('kind') || "definition"
+
+    unless RESOURCE_EXTERNAL_NAMES_TO_KINDS.has_key?(kind)
+      raise ArgumentError, "Unsupported resource kind '#{kind}'"
+    end
+
+    type = RESOURCE_EXTERNAL_NAMES_TO_KINDS[kind]
 
     data = "" { |result, ary| result[ary[0].intern] = ary[1]; result }
 
+    # This is a bit of a hack; when we serialize, we use the term "parameters" because that
+    #  is the terminology that we use in our documentation.  However, internally to this
+    #  class we use the term "arguments".  Ideally we'd change the implementation to be consistent
+    #  with the documentation, but that would be challenging right now because it could potentially
+    #  touch a lot of places in the code, not to mention that we already have another meaning for
+    #  "parameters" internally.  So, for now, we will simply transform the internal "arguments"
+    #  value to "parameters" when serializing, and the opposite when deserializing.
+    #     --cprice 2012-04-23
+    data[:arguments] = data.delete(:parameters)
+
     new(type, name, data)
   end
 
+  # This method doesn't seem like it has anything to do with PSON in particular, and it shouldn't.
+  #  It's just transforming to a simple object that can be serialized and de-serialized via
+  #  any transport format.  Should probably be renamed if we get a chance to clean up our
+  #  serialization / deserialization, and there are probably many other similar methods in
+  #  other classes.
+  #  --cprice 2012-04-23
+
   def to_pson_data_hash
     data = "" :line, :file, :parent].inject({}) do |hash, param|
       next hash unless (value = self.send(param)) and (value != "")
@@ -40,14 +86,34 @@ def to_pson_data_hash
       hash
     end
 
-    data['arguments'] = arguments.dup unless arguments.empty?
+    # This is a bit of a hack; when we serialize, we use the term "parameters" because that
+    #  is the terminology that we use in our documentation.  However, internally to this
+    #  class we use the term "arguments".  Ideally we'd change the implementation to be consistent
+    #  with the documentation, but that would be challenging right now because it could potentially
+    #  touch a lot of places in the code, not to mention that we already have another meaning for
+    #  "parameters" internally.  So, for now, we will simply transform the internal "arguments"
+    #  value to "parameters" when serializing, and the opposite when deserializing.
+    #     --cprice 2012-04-23
+    data['parameters'] = arguments.dup unless arguments.empty?
 
     data['name'] = name
-    data['type'] = type
 
+    unless RESOURCE_KINDS_TO_EXTERNAL_NAMES.has_key?(type)
+      raise ArgumentError, "Unsupported resource kind '#{type}'"
+    end
+    data['kind'] = RESOURCE_KINDS_TO_EXTERNAL_NAMES[type]
     data
   end
 
+  # It seems wrong that we have a 'to_pson' method on this class, but not a 'to_yaml'.
+  #  As a result, if you use the REST API to retrieve one or more objects of this type,
+  #  you will receive different data if you use 'Accept: yaml' vs 'Accept: pson'.  That
+  #  seems really, really wrong.  The "Accept" header should never affect what data is
+  #  being returned--only the format of the data.  If the data itself is going to differ,
+  #  then there should be a different request URL.  Documenting the REST API becomes
+  #  a much more complex problem when the "Accept" header can change the semantics
+  #  of the response.  --cprice 2012-04-23
+
   def to_pson(*args)
     to_pson_data_hash.to_pson(*args)
   end
@@ -80,7 +146,7 @@ def evaluate_code(resource)
 
   def initialize(type, name, options = {})
     @type = type.to_s.downcase.to_sym
-    raise ArgumentError, "Invalid resource supertype '#{type}'" unless RESOURCE_SUPERTYPES.include?(@type)
+    raise ArgumentError, "Invalid resource supertype '#{type}'" unless RESOURCE_KINDS.include?(@type)
 
     name = convert_from_ast(name) if name.is_a?(Puppet::Parser::AST::HostName)
 
diff --git a/spec/unit/indirector/resource_type/parser_spec.rb b/spec/unit/indirector/resource_type/parser_spec.rb
index fa2aa10..734faf8 100755
--- a/spec/unit/indirector/resource_type/parser_spec.rb
+++ b/spec/unit/indirector/resource_type/parser_spec.rb
@@ -56,94 +56,158 @@
   end
 
   describe "when searching" do
-    before do
-      @request.key = "*"
+    describe "when the search key is a wildcard" do
+      before do
+        @request.key = "*"
+      end
+
+      it "should use the request's environment's list of known resource types" do
+        @request.environment.known_resource_types.expects(:hostclasses).returns({})
+
+        @terminus.search(@request)
+      end
+
+      it "should return all results if '*' is provided as the search string" do
+        type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+        node = @krt.add(Puppet::Resource::Type.new(:node, "bar"))
+        define = @krt.add(Puppet::Resource::Type.new(:definition, "baz"))
+
+        result = @terminus.search(@request)
+        result.should be_include(type)
+        result.should be_include(node)
+        result.should be_include(define)
+      end
+
+      it "should return all known types" do
+        type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+        node = @krt.add(Puppet::Resource::Type.new(:node, "bar"))
+        define = @krt.add(Puppet::Resource::Type.new(:definition, "baz"))
+
+        result = @terminus.search(@request)
+        result.should be_include(type)
+        result.should be_include(node)
+        result.should be_include(define)
+      end
+
+      it "should not return the 'main' class" do
+        main = @krt.add(Puppet::Resource::Type.new(:hostclass, ""))
+
+        # So there is a return value
+        foo = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+
+        @terminus.search(@request).should_not be_include(main)
+      end
+
+      it "should return nil if no types can be found" do
+        @terminus.search(@request).should be_nil
+      end
+
+      it "should load all resource types from all search paths" do
+        dir = tmpdir("searching_in_all")
+        first = File.join(dir, "first")
+        second = File.join(dir, "second")
+        FileUtils.mkdir_p(first)
+        FileUtils.mkdir_p(second)
+        Puppet[:modulepath] = "#{first}#{File::PATH_SEPARATOR}#{second}"
+
+        # Make a new request, since we've reset the env
+        @request = Puppet::Indirector::Request.new(:resource_type, :search, "*")
+
+        _onepath_ = File.join(first, "one", "manifests")
+        FileUtils.mkdir_p(onepath)
+        twopath = File.join(first, "two", "manifests")
+        FileUtils.mkdir_p(twopath)
+
+        File.open(File.join(onepath, "oneklass.pp"), "w") { |f| f.puts "class one::oneklass {}" }
+        File.open(File.join(twopath, "twoklass.pp"), "w") { |f| f.puts "class two::twoklass {}" }
+
+        result = @terminus.search(@request)
+        result.find { |t| t.name == "one::oneklass" }.should be_instance_of(Puppet::Resource::Type)
+        result.find { |t| t.name == "two::twoklass" }.should be_instance_of(Puppet::Resource::Type)
+      end
+
+      context "when specifying a 'kind' parameter" do
+        before :each do
+          @klass = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+          @node = @krt.add(Puppet::Resource::Type.new(:node, "bar"))
+          @define = @krt.add(Puppet::Resource::Type.new(:definition, "baz"))
+        end
+
+        it "should raise an error if you pass an invalid kind filter" do
+          @request.options[:kind] = "i bet you don't have a kind called this"
+          expect {
+            @terminus.search(@request)
+          }.to raise_error(ArgumentError, /Unrecognized kind filter/)
+
+        end
+
+        it "should support filtering for only hostclass results" do
+          @request.options[:kind] = "class"
+
+          result = @terminus.search(@request)
+          result.should be_include(@klass)
+          result.should_not be_include(@node)
+          result.should_not be_include(@define)
+        end
+
+        it "should support filtering for only node results" do
+          @request.options[:kind] = "node"
+
+          result = @terminus.search(@request)
+          result.should_not be_include(@klass)
+          result.should be_include(@node)
+          result.should_not be_include(@define)
+        end
+
+        it "should support filtering for only definition results" do
+          @request.options[:kind] = "defined_type"
+
+          result = @terminus.search(@request)
+          result.should_not be_include(@klass)
+          result.should_not be_include(@node)
+          result.should be_include(@define)
+        end
+      end
     end
 
-    it "should use the request's environment's list of known resource types" do
-      @request.environment.known_resource_types.expects(:hostclasses).returns({})
-
-      @terminus.search(@request)
-    end
-
-    it "should return all results if '*' is provided as the search string" do
-      @request.key = "*"
-      type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
-      node = @krt.add(Puppet::Resource::Type.new(:node, "bar"))
-      define = @krt.add(Puppet::Resource::Type.new(:definition, "baz"))
-
-      result = @terminus.search(@request)
-      result.should be_include(type)
-      result.should be_include(node)
-      result.should be_include(define)
-    end
-
-    it "should treat any search string not '*' as a regex" do
-      @request.key = "a"
-      foo = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
-      bar = @krt.add(Puppet::Resource::Type.new(:hostclass, "bar"))
-      baz = @krt.add(Puppet::Resource::Type.new(:hostclass, "baz"))
-
-      result = @terminus.search(@request)
-      result.should be_include(bar)
-      result.should be_include(baz)
-      result.should_not be_include(foo)
-    end
-
-    it "should fail if a provided search string is not '*' and is not a valid regex" do
-      @request.key = "*foo*"
-
-      # Add one instance so we don't just get an empty array"
-      @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
-      lambda { @terminus.search(@request) }.should raise_error(ArgumentError)
+    context "when the search string is not a wildcard" do
+
+      it "should treat any search string as a regex" do
+        @request.key = "a"
+        foo = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+        bar = @krt.add(Puppet::Resource::Type.new(:hostclass, "bar"))
+        baz = @krt.add(Puppet::Resource::Type.new(:hostclass, "baz"))
+
+        result = @terminus.search(@request)
+        result.should be_include(bar)
+        result.should be_include(baz)
+        result.should_not be_include(foo)
+      end
+
+      it "should support kind filtering with a regex" do
+        @request.key = "foo"
+        @request.options[:kind] = "class"
+
+        foobar = @krt.add(Puppet::Resource::Type.new(:hostclass, "foobar"))
+        foobaz = @krt.add(Puppet::Resource::Type.new(:hostclass, "foobaz"))
+        foobam = @krt.add(Puppet::Resource::Type.new(:definition, "foobam"))
+        fooball = @krt.add(Puppet::Resource::Type.new(:node, "fooball"))
+
+        result = @terminus.search(@request)
+        result.should be_include(foobar)
+        result.should be_include(foobaz)
+        result.should_not be_include(foobam)
+        result.should_not be_include(fooball)
+      end
+
+      it "should fail if a provided search string is not a valid regex" do
+        @request.key = "*foo*"
+
+        # Add one instance so we don't just get an empty array"
+        @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
+        lambda { @terminus.search(@request) }.should raise_error(ArgumentError)
+      end
     end
 
-    it "should return all known types" do
-      type = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
-      node = @krt.add(Puppet::Resource::Type.new(:node, "bar"))
-      define = @krt.add(Puppet::Resource::Type.new(:definition, "baz"))
-
-      result = @terminus.search(@request)
-      result.should be_include(type)
-      result.should be_include(node)
-      result.should be_include(define)
-    end
-
-    it "should not return the 'main' class" do
-      main = @krt.add(Puppet::Resource::Type.new(:hostclass, ""))
-
-      # So there is a return value
-      foo = @krt.add(Puppet::Resource::Type.new(:hostclass, "foo"))
-
-      @terminus.search(@request).should_not be_include(main)
-    end
-
-    it "should return nil if no types can be found" do
-      @terminus.search(@request).should be_nil
-    end
-
-    it "should load all resource types from all search paths" do
-      dir = tmpdir("searching_in_all")
-      first = File.join(dir, "first")
-      second = File.join(dir, "second")
-      FileUtils.mkdir_p(first)
-      FileUtils.mkdir_p(second)
-      Puppet[:modulepath] = "#{first}#{File::PATH_SEPARATOR}#{second}"
-
-      # Make a new request, since we've reset the env
-      @request = Puppet::Indirector::Request.new(:resource_type, :search, "*")
-
-      _onepath_ = File.join(first, "one", "manifests")
-      FileUtils.mkdir_p(onepath)
-      twopath = File.join(first, "two", "manifests")
-      FileUtils.mkdir_p(twopath)
-
-      File.open(File.join(onepath, "oneklass.pp"), "w") { |f| f.puts "class one::oneklass {}" }
-      File.open(File.join(twopath, "twoklass.pp"), "w") { |f| f.puts "class two::twoklass {}" }
-
-      result = @terminus.search(@request)
-      result.find { |t| t.name == "one::oneklass" }.should be_instance_of(Puppet::Resource::Type)
-      result.find { |t| t.name == "two::twoklass" }.should be_instance_of(Puppet::Resource::Type)
-    end
   end
 end
diff --git a/spec/unit/network/format_handler_spec.rb b/spec/unit/network/format_handler_spec.rb
index 8b535c3..e4ed2e6 100755
--- a/spec/unit/network/format_handler_spec.rb
+++ b/spec/unit/network/format_handler_spec.rb
@@ -168,13 +168,13 @@ class FormatTester
     end
 
     it "should be able to use a specific hook for rendering multiple instances" do
-      @format.expects(:render_multiple).with("mydata")
+      @format.expects(:render_multiple).with("mydata", {})
 
       FormatTester.render_multiple(:my_format, "mydata")
     end
 
     it "should raise a FormatError when an exception is encountered when rendering multiple items into a format" do
-      @format.expects(:render_multiple).with("mydata").raises "foo"
+      @format.expects(:render_multiple).with("mydata", {}).raises "foo"
       lambda { FormatTester.render_multiple(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
     end
   end
diff --git a/spec/unit/network/http/handler_spec.rb b/spec/unit/network/http/handler_spec.rb
index c709d82..871a011 100755
--- a/spec/unit/network/http/handler_spec.rb
+++ b/spec/unit/network/http/handler_spec.rb
@@ -313,7 +313,7 @@ def stub_server_interface
 
         @indirection.stubs(:search).returns(@result)
 
-        @model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances"
+        @model_class.expects(:render_multiple).with(@oneformat, @result, {}).returns "my rendered instances"
 
         @handler.expects(:set_response).with { |response, data| data == "my rendered instances" }
         @handler.do_search("my_handler", "my_result", {}, @request, @response)
@@ -322,7 +322,7 @@ def stub_server_interface
       it "should return [] when searching returns an empty array" do
         @handler.expects(:accept_header).with(@request).returns "one,two"
         @indirection.stubs(:search).returns([])
-        @model_class.expects(:render_multiple).with(@oneformat, []).returns "[]"
+        @model_class.expects(:render_multiple).with(@oneformat, [], {}).returns "[]"
 
 
         @handler.expects(:set_response).with { |response, data| data == "[]" }

    

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