Commit d4801167 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Generate @since data also for parameters.

Only add the @since annotation for params that were introduced after the
method itself was added.  When doing so, only consider the positions of
parameters, as they might be renamed between versions.

When method has explicit @since tag, then no param since tags are added.

Also implement #respond_to? on NullObject.
parent 040d7d5a
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -23,7 +23,10 @@ module JsDuck
      private

      def current_version
        Util::NullObject.new(:[] => Util::NullObject.new(:[] => true))
        JsDuck::Util::NullObject.new(
          :[] => JsDuck::Util::NullObject.new( # class
            :[] => JsDuck::Util::NullObject.new( # member
              :length => 1.0 / 0))) # params count == Infinity
      end

      # Reads in data from all .json files in directory
@@ -61,7 +64,7 @@ module JsDuck
      def members_id_index(json)
        index = {}
        json["members"].each do |m|
          index[m["id"]] = true
          index[m["id"]] = m["params"] ? m["params"].map {|p| p["name"] } : true
        end
        index
      end
+32 −4
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ module JsDuck
      end

      # Using the imported versions data, adds @since tags to all
      # classes/members.
      # classes/members/params.
      def generate_since_tags(versions)
        new_versions = build_new_versions_map(versions)

@@ -49,9 +49,20 @@ module JsDuck
          cls[:new] = true if new_versions[v]

          cls.all_local_members.each do |m|
            v = m[:since] || member_since(versions, cls, m)
            m[:since] = v
            m[:new] = true if new_versions[v]
            member_version = m[:since] || member_since(versions, cls, m)

            if !m[:since]
              Array(m[:params]).each_with_index do |p, i|
                v = param_since(versions, cls, m, i)
                if v != member_version
                  p[:since] = v
                  p[:new] = true if new_versions[v]
                end
              end
            end

            m[:since] = member_version
            m[:new] = true if new_versions[member_version]
          end
        end
      end
@@ -75,6 +86,23 @@ module JsDuck
        new_versions
      end

      def param_since(versions, cls, m, i)
        versions.each do |ver|
          c = ver[:classes][cls[:name]]
          return ver[:version] if c && has_param?(c[m[:id]], i)
          cls[:alternateClassNames].each do |name|
            c = ver[:classes][name]
            return ver[:version] if c && has_param?(c[m[:id]], i)
          end
        end
      end

      # Because parameters can be renamed between versions, only
      # consider parameter count.
      def has_param?(member, param_index)
        member && member.respond_to?(:length) && member.length > param_index
      end

      def member_since(versions, cls, m)
        versions.each do |ver|
          c = ver[:classes][cls[:name]]
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ module JsDuck
            "<div class='sub-desc'>",
              p[:doc],
              p[:default] ? "<p>Defaults to: <code>#{Util::HTML.escape(p[:default])}</code></p>" : "",
              p[:since] ? "<p>Available since: <b>#{Util::HTML.escape(p[:since])}</b></p>" : "",
              p[:properties] && p[:properties].length > 0 ? render(p) : "",
            "</div>",
          "</li>",
+4 −0
Original line number Diff line number Diff line
@@ -17,6 +17,10 @@ module JsDuck
      def method_missing(meth, *args, &block)
        @methods.has_key?(meth) ? @methods[meth] : self
      end

      def respond_to?(meth)
        @methods.has_key?(meth)
      end
    end

  end
+84 −1
Original line number Diff line number Diff line
@@ -5,7 +5,10 @@ require "jsduck/class"
describe JsDuck::Process::Versions do

  def current_version
    JsDuck::Util::NullObject.new(:[] => JsDuck::Util::NullObject.new(:[] => true))
    JsDuck::Util::NullObject.new(
      :[] => JsDuck::Util::NullObject.new( # class
        :[] => JsDuck::Util::NullObject.new( # member
          :length => 1.0 / 0))) # params count == Infinity
  end

  describe "without :new_since option" do
@@ -190,4 +193,84 @@ describe JsDuck::Process::Versions do
    end
  end

  describe "method parameters" do
    let(:relations) do
      versions = [
        {
          :version => "1.0", :classes => {
            "MyClass" => {"method-foo" => ["x"]},
          },
        },
        {
          :version => "2.0", :classes => {
            "MyClass" => {"method-foo" => ["x", "oldY"]},
          },
        },
        {
          :version => "3.0", :classes => current_version
        }
      ]
      importer = JsDuck::Util::NullObject.new(:import => versions)

      relations = [
        {:name => "MyClass", :alternateClassNames => [], :members => [
            {:tagname => :method, :id => "method-foo", :params => [
                {:name => "x"},
                {:name => "y"},
                {:name => "z"},
              ]},
            {:tagname => :method, :id => "method-bar", :since => "0.1", :params => [
                {:name => "x"},
              ]},
          ]},
      ].map {|cfg| JsDuck::Class.new(cfg) }

      opts = {:imports => versions, :new_since => "3.0"}
      JsDuck::Process::Versions.new(relations, opts, importer).process_all!

      relations
    end

    describe "method #foo" do
      let(:method) do
        relations[0][:members][0]
      end

      it "adds @since 1.0 to our method" do
        method[:since].should == "1.0"
      end

      it "adds no @since to 1st param, because it's also from 1.0" do
        method[:params][0][:since].should == nil
      end

      it "adds @since 2.0 to 2nd param (although it was named differently in 2.0)" do
        method[:params][1][:since].should == "2.0"
      end

      it "adds @since 3.0 to 3rd param" do
        method[:params][2][:since].should == "3.0"
      end

      it "adds @new to 3rd param" do
        method[:params][2][:new].should == true
      end
    end

    describe "method with explicit @since 0.1" do
      let(:method) do
        relations[0][:members][1]
      end

      it "adds @since 0.1 to our method" do
        method[:since].should == "0.1"
      end

      it "doesn't add a @since to parameter" do
        method[:params][0][:since].should == nil
      end
    end

  end

end