Prechádzať zdrojové kódy

Refactor Drop classes.

Not alone EventDrop but all subclasses now take a hash of "locals" which
could be referenced in interpolation.  This will make it easier for
Agent classes to add custom "locals" for use in interpolation.
Akinori MUSHA 10 rokov pred
rodič
commit
a93bb2674e

+ 42 - 1
app/concerns/liquid_droppable.rb

@@ -1,9 +1,50 @@
 module LiquidDroppable
 module LiquidDroppable
   extend ActiveSupport::Concern
   extend ActiveSupport::Concern
 
 
+  # In subclasses of this base class, "locals" take precedence over
+  # methods.
   class Drop < Liquid::Drop
   class Drop < Liquid::Drop
-    def initialize(object)
+    class << self
+      def inherited(subclass)
+        class << subclass
+          attr_reader :drop_methods
+
+          # Make all public methods private so that #before_method
+          # catches everything.
+          def drop_methods!
+            return if @drop_methods
+
+            @drop_methods = Set.new
+
+            (public_instance_methods - Drop.public_instance_methods).each { |name|
+              @drop_methods << name.to_s
+              private name
+            }
+          end
+        end
+      end
+    end
+
+    def initialize(object, locals = nil)
+      self.class.drop_methods!
+
       @object = object
       @object = object
+      @locals = locals || {}
+    end
+
+    def before_method(name)
+      if @locals.include?(name)
+        @locals[name]
+      elsif self.class.drop_methods.include?(name)
+        __send__(name)
+      end
+    end
+
+    def each
+      return to_enum(__method__) unless block_given?
+      self.class.drop_methods.each { |name|
+        yield [name, __send__(name)]
+      }
     end
     end
   end
   end
 
 

+ 2 - 12
app/models/agent.rb

@@ -391,7 +391,7 @@ class AgentDrop
     @object.short_type
     @object.short_type
   end
   end
 
 
-  METHODS = [
+  [
     :name,
     :name,
     :type,
     :type,
     :options,
     :options,
@@ -402,19 +402,9 @@ class AgentDrop
     :disabled,
     :disabled,
     :keep_events_for,
     :keep_events_for,
     :propagate_immediately,
     :propagate_immediately,
-  ]
-
-  METHODS.each { |attr|
+  ].each { |attr|
     define_method(attr) {
     define_method(attr) {
       @object.__send__(attr)
       @object.__send__(attr)
     } unless method_defined?(attr)
     } unless method_defined?(attr)
   }
   }
-
-  def each(&block)
-    return to_enum(__method__) unless block
-
-    METHODS.each { |attr|
-      yield [attr, __sent__(attr)]
-    }
-  end
 end
 end

+ 12 - 17
app/models/event.rb

@@ -44,26 +44,21 @@ class Event < ActiveRecord::Base
 end
 end
 
 
 class EventDrop
 class EventDrop
-  def initialize(event, payload = event.payload)
-    super(event)
-    @payload = payload
-  end
-
-  def before_method(key)
-    if @payload.key?(key)
-      @payload[key]
-    else
-      case key
-      when 'agent'
-        @object.agent
-      when 'created_at'
-        @object.created_at
-      end
-    end
+  def initialize(object, locals = nil)
+    locals ||= object.payload
+    super
   end
   end
 
 
   def each(&block)
   def each(&block)
     return to_enum(__method__) unless block
     return to_enum(__method__) unless block
-    @payload.each(&block)
+    @locals.each(&block)
+  end
+
+  def agent
+    @object.agent
+  end
+
+  def created_at
+    @object.created_at
   end
   end
 end
 end

+ 9 - 0
spec/models/event_spec.rb

@@ -102,6 +102,15 @@ describe EventDrop do
     interpolate(t, @event).should eq('some title: http://some.site.example.org/')
     interpolate(t, @event).should eq('some title: http://some.site.example.org/')
   end
   end
 
 
+  it 'should use created_at from the payload if it exists' do
+    created_at = @event.created_at - 86400
+    # Avoid timezone issue by using %s
+    @event.payload['created_at'] = created_at.strftime("%s")
+    @event.save!
+    t = '{{created_at | date:"%s" }}'
+    interpolate(t, @event).should eq(created_at.strftime("%s"))
+  end
+
   it 'should be iteratable' do
   it 'should be iteratable' do
     # to_liquid returns self
     # to_liquid returns self
     t = "{% for pair in to_liquid %}{{pair | join:':' }}\n{% endfor %}"
     t = "{% for pair in to_liquid %}{{pair | join:':' }}\n{% endfor %}"