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

Initial @inheritdoc restructuring work.

Splitted up the tests into three files.

Changed around the rules of how inheritance works:

- Only inheriting x when item itself doesn't define it.
- No more combining local docs with inherited doc.
- Recursive inheritance now resolves the parent, then inherits from
  it directly, not going to the bottom of inheritance chain and
  inheriting from it.
parent 6fa10c57
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -30,12 +30,16 @@ module JsDuck
      # Copy over doc/params/return from parent member.
      def resolve(m, new_cfgs)
        parent = find_parent(m)
        if parent && parent[:inheritdoc]
          resolve(parent, new_cfgs)
        end

        if m[:inheritdoc] && parent
          m[:doc] = (m[:doc] + "\n\n" + parent[:doc]).strip
          m[:params] = parent[:params] if parent[:params]
          m[:return] = parent[:return] if parent[:return]
          m[:type] = parent[:type] if parent[:type]
          m[:doc] = parent[:doc] if m[:doc].empty?
          m[:params] = parent[:params] unless m[:params] && m[:params].length > 0
          m[:return] = parent[:return] unless m[:return]
          m[:throws] = parent[:throws] unless m[:throws] && m[:throws].length > 0
          m[:type] = parent[:type] unless m[:type] && m[:type] != "Object"

          if m[:autodetected]
            m[:deprecated] = parent[:deprecated] if parent[:deprecated] && !m[:deprecated]
@@ -48,6 +52,8 @@ module JsDuck
        end

        resolve_visibility(m, parent)

        m[:inheritdoc] = nil
      end

      # Changes given properties into configs within class
@@ -122,7 +128,7 @@ module JsDuck
          end
        end

        return parent[:inheritdoc] ? find_parent(parent) : parent
        return parent
      end

      def lookup_member(cls, m)
@@ -161,10 +167,15 @@ module JsDuck
      # Copy over doc from parent class.
      def resolve_class(cls)
        parent = find_class_parent(cls)
        if parent && parent[:inheritdoc]
          resolve_class(parent)
        end

        if parent
          cls[:doc] = (cls[:doc] + "\n\n" + parent[:doc]).strip
          cls[:doc] = parent[:doc] if cls[:doc].empty?
        end

        cls[:inheritdoc] = nil
      end

      def find_class_parent(cls)
@@ -178,7 +189,7 @@ module JsDuck
          return warn("parent class not found", cls) unless parent
        end

        return parent[:inheritdoc] ? find_class_parent(parent) : parent
        return parent
      end

      def warn(msg, item)
+286 −0
Original line number Diff line number Diff line
require "mini_parser"

describe JsDuck::Aggregator do
  def parse(string)
    Helper::MiniParser.parse(string, {:inherit_doc => true})
  end

  describe "autoinherit with config:{}" do
    before do
      @docs = parse(<<-EOF)
        /** */
        Ext.define("Parent", {
            config: {
                /**
                 * My config.
                 */
                foo: 5
            }
        });
        /** */
        Ext.define("Child", {
            extend: "Parent",
            config: {
                foo: 10
            }
        });
      EOF
      @cls = @docs["Child"]
      @cfg = @cls[:members][0]
    end

    it "inherits docs from parent" do
      @cfg[:doc].should == "My config."
    end

    it "inherits being public from parent" do
      @cfg[:private].should == nil
    end
  end

  describe "autoinherit with config:{} through two parents" do
    before do
      @docs = parse(<<-EOF)
        /** */
        Ext.define("Parent", {
            config: {
                /**
                 * My config.
                 */
                foo: 5
            }
        });
        /** */
        Ext.define("Middle", {
            extend: "Parent",
            config: {
                foo: 7
            }
        });
        /** */
        Ext.define("Child", {
            extend: "Middle",
            config: {
                foo: 10
            }
        });
      EOF
      @cls = @docs["Child"]
      @cfg = @cls[:members][0]
    end

    it "inherits docs from parent" do
      @cfg[:doc].should == "My config."
    end

    it "inherits being public from parent" do
      @cfg[:private].should == nil
    end
  end

  describe "autoinherit with config:{} and no parent" do
    before do
      @docs = parse(<<-EOF)
        /** */
        Ext.define("Child", {
            config: {
                foo: 10
            }
        });
      EOF
      @cls = @docs["Child"]
      @cfg = @cls[:members][0]
    end

    it "becomes private" do
      @cfg[:private].should == true
    end
  end

  describe "autoinherit with several tags" do
    before do
      @docs = parse(<<-EOF)
        /** */
        Ext.define("Parent", {
            /**
             * My property.
             * @protected
             * @deprecated 4.0 Use something else.
             */
            foo: 5
        });
        /** */
        Ext.define("Child", {
            extend: "Parent",
            foo: 10
        });
      EOF
      @cls = @docs["Child"]
      @property = @cls[:members][0]
    end

    it "inherits @protected" do
      @property[:protected].should == true
    end

    it "inherits @deprecated" do
      @property[:deprecated][:version].should == "4.0"
      @property[:deprecated][:text].should == "Use something else."
    end
  end

  describe "autoinherit with his own and parent tags" do
    before do
      @docs = parse(<<-EOF)
        /** */
        Ext.define("Parent", {
            /**
             * My property.
             * @protected
             * @deprecated 3.0
             */
            foo: 5
        });
        /** */
        Ext.define("Child", {
            extend: "Parent",
            // @readonly
            // @deprecated 4.0
            foo: 10
        });
      EOF
      @cls = @docs["Child"]
      @property = @cls[:members][0]
    end

    it "inherits @protected" do
      @property[:protected].should == true
    end

    it "keeps @readonly" do
      @property[:readonly].should == true
    end

    it "overrides @deprecated of parent with its own @deprecated" do
      @property[:deprecated][:version].should == "4.0"
    end
  end

  describe "inheriting cfg/property type" do
    let(:members) do
      ms = parse(<<-EOF)["Child"][:members]
        /** */
        Ext.define("Parent", {
            /**
             * @property {String/Number}
             */
            foo: 42,
            /**
             * @property {String/Number}
             */
            bar: 5,
            baz: 15,
            /**
             * @property {String/Number}
             * @private
             */
            zap: 7
        });
        /** */
        Ext.define("Child", {
            extend: "Parent",
            /**
             * @inheritdoc
             */
            foo: "blah",
            bar: "blah",
            baz: "blah",
            zap: "blah"
        });
      EOF
      hash = {}
      ms.each {|p| hash[p[:name]] = p }
      hash
    end

    it "explicit inherit from public parent keeps the type of parent" do
      members["foo"][:type].should == "String/Number"
    end

    it "autoinherit from public parent keeps the type of parent" do
      members["bar"][:type].should == "String/Number"
    end

    it "autoinherit from private parent overrides parent type" do
      members["baz"][:type].should == "String"
    end

    it "autoinherit from explicitly documented private parent keeps parent type" do
      members["zap"][:type].should == "String/Number"
    end
  end

  describe "instance members autoinherit with parent containing statics" do
    before do
      @docs = parse(<<-EOF)
        /** */
        Ext.define("Parent", {
            inheritableStatics: {
                /** My method. */
                foo: function() {},
                /** My property. */
                bar: 10
            }
        });
        /** */
        Ext.define("Child", {
            extend: "Parent",
            foo: function(){},
            bar: 11
        });
      EOF
      @cls = @docs["Child"]
    end

    it "doesn't inherit from parent static method" do
      @cls[:members][0][:doc].should_not == "My method."
    end

    it "doesn't inherit from parent static property" do
      @cls[:members][1][:doc].should_not == "My property."
    end
  end

  describe "static members autoinherit with parent containing statics" do
    before do
      @docs = parse(<<-EOF)
        /** */
        Ext.define("Parent", {
            inheritableStatics: {
                /** My method. */
                foo: function() {},
                /** My property. */
                bar: 10
            }
        });
        /** */
        Ext.define("Child", {
            extend: "Parent",
            inheritableStatics: {
                foo: function(){},
                bar: 11
            }
        });
      EOF
      @cls = @docs["Child"]
    end

    it "inherits from parent static method" do
      @cls[:members][0][:doc].should == "My method."
    end

    it "inherits from parent static property" do
      @cls[:members][1][:doc].should == "My property."
    end
  end
end
+52 −0
Original line number Diff line number Diff line
require "mini_parser"

describe JsDuck::Aggregator do
  def parse(string)
    Helper::MiniParser.parse(string, {:inherit_doc => true})
  end

  shared_examples_for "basic docs inheritance" do
    before do
      @docs = parse(<<-EOF)
        /**
         * @class Foo
         */
            /**
             * @method foo
             * Comment for class Foo.
             */
        /**
         * @class Bar
         */
            /**
             * @method bar
             * #{@tag_name} Foo#foo
             */
      EOF
      @bar = @docs["Bar"][:members][0]
    end

    it "inherits docs from the referenced member" do
      @bar[:doc].should == "Comment for class Foo."
    end
  end

  describe "@inheritdoc" do
    before { @tag_name = "@inheritdoc" }

    it_behaves_like "basic docs inheritance"
  end

  describe "@inheritDoc" do
    before { @tag_name = "@inheritDoc" }

    it_behaves_like "basic docs inheritance"
  end

  describe "@alias" do
    before { @tag_name = "@alias" }

    it_behaves_like "basic docs inheritance"
  end

end
+162 −592

File changed.

Preview size limit exceeded, changes collapsed.