Commit 90121b31 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Support for @evented @accessor.

When @cfg has both @accessor and @evented then an event is also
created in addition to get/set methods.
parent 0e51c470
Loading
Loading
Loading
Loading
+52 −5
Original line number Diff line number Diff line
@@ -11,11 +11,9 @@ module JsDuck
      # Grab all configs tagged as @accessor
      accessors = cls[:members][:cfg].find_all {|cfg| cfg[:accessor] }

      # Build lookup table of method names
      methods = {}
      cls[:members][:method].each do |m|
        methods[m[:name]] = m;
      end
      # Build lookup tables of method and event names
      methods = build_lookup_table(cls[:members][:method])
      events = build_lookup_table(cls[:members][:event])

      accessors.each do |cfg|
        # add getter if no method with same name exists
@@ -28,9 +26,23 @@ module JsDuck
        if !methods[set[:name]]
          cls[:members][:method] << set
        end
        # for evented accessors
        if cfg[:evented]
          # add event if no event with same name exists
          ev = create_event(cfg)
          if !events[ev[:name]]
            cls[:members][:event] << ev
          end
        end
      end
    end

    def build_lookup_table(members)
      map = {}
      members.each {|m| map[m[:name]] = m }
      map
    end

    def create_getter(cfg)
      name = "get" + upcase_first(cfg[:name])
      return {
@@ -69,6 +81,41 @@ module JsDuck
      }
    end

    def create_event(cfg)
      name = cfg[:name].downcase + "change"
      setter_name = "set" + upcase_first(cfg[:name]);
      return {
        :tagname => :event,
        :name => name,
        :doc =>
          "Fires when the {@link ##{cfg[:id]}} configuration is changed by {@link #method-#{setter_name}}." +
          "\n\n" +
          "Note that this event is fired *before* the value of {@link ##{cfg[:id]}} has been updated, " +
          "and that you can return false from any listener to the #{name} event " +
          "to cancel the change.",
        :params => [
          {
            :name => "this",
            :type => cfg[:owner],
            :doc => "The #{cfg[:owner]} instance."
          },
          {
            :name => "value",
            :type => cfg[:type],
            :doc => "The new value being set."
          },
          {
            :name => "oldValue",
            :type => cfg[:type],
            :doc => "The existing value."
          },
        ],
        :owner => cfg[:owner],
        :files => cfg[:files],
        :id => "event-" + name,
      }
    end

    def upcase_first(str)
      str[0,1].upcase + str[1..-1]
    end
+2 −0
Original line number Diff line number Diff line
@@ -136,6 +136,8 @@ module JsDuck
          boolean_at_tag(/@protected/, :protected)
        elsif look(/@accessor\b/)
          boolean_at_tag(/@accessor/, :accessor)
        elsif look(/@evented\b/)
          boolean_at_tag(/@evented/, :evented)
        elsif look(/@template\b/)
          boolean_at_tag(/@template/, :template)
        elsif look(/@markdown\b/)
+1 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ module JsDuck
        :default => detect_default(:cfg, doc_map, code),
        :properties => detect_subproperties(docs, :cfg),
        :accessor => !!doc_map[:accessor],
        :evented => !!doc_map[:evented],
      }, doc_map)
    end

+112 −0
Original line number Diff line number Diff line
@@ -119,5 +119,117 @@ describe JsDuck::Aggregator do

  end

  describe "@cfg foo with @evented @accessor" do
    before do
      @docs = parse(<<-EOF)
        /** @class MyClass */
          /**
           * @cfg {String} foo
           * Original comment.
           * @accessor
           * @evented
           */
      EOF
      @events = @docs[0][:members][:event]
    end

    it "creates foochange event" do
      @events[0][:name].should == "foochange"
    end

    it "creates documentation for foochange event" do
      @events[0][:doc].should ==
        "Fires when the {@link #cfg-foo} configuration is changed by {@link #method-setFoo}.\n\n" +
        "Note that this event is fired *before* the value of {@link #cfg-foo} has been updated, " +
        "and that you can return false from any listener to the foochange event " +
        "to cancel the change."
    end

    it "has 3 params" do
      @events[0][:params].length.should == 3
    end

    describe "1st param" do
      before do
        @param = @events[0][:params][0]
      end

      it "is this" do
        @param[:name].should == "this"
      end

      it "is the same type as the class" do
        @param[:type].should == "MyClass"
      end

      it "has documentation" do
        @param[:doc].should == "The MyClass instance."
      end
    end

    describe "2nd param" do
      before do
        @param = @events[0][:params][1]
      end

      it "is value" do
        @param[:name].should == "value"
      end

      it "is the same type as the cfg" do
        @param[:type].should == "String"
      end

      it "has documentation" do
        @param[:doc].should == "The new value being set."
      end
    end

    describe "3rd param" do
      before do
        @param = @events[0][:params][2]
      end

      it "is oldValue" do
        @param[:name].should == "oldValue"
      end

      it "is the same type as the cfg" do
        @param[:type].should == "String"
      end

      it "has documentation" do
        @param[:doc].should == "The existing value."
      end
    end

  end

  describe "@evented @accessor with existing event" do
    before do
      @docs = parse(<<-EOF)
        /** @class MyClass */
          /**
           * @cfg {String} fooBar
           * @accessor
           * @evented
           */
          /**
           * @event foobarchange
           * Event comment.
           */
      EOF
      @events = @docs[0][:members][:event]
    end

    it "doesn't create any additional events" do
      @events.length.should == 1
    end

    it "leaves the existing event as is." do
      @events[0][:doc].should == "Event comment."
    end
  end

end