From 5f881ee7867ec7a3984b5124ac6e192c610fbac2 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Thu, 30 Mar 2017 21:21:26 +0900 Subject: [PATCH] Give ChangeDetectorAgent access to `last_property` This allows user to detect a new lowest value or a new high by comparing a new value with the existing value. --- app/models/agents/change_detector_agent.rb | 7 ++- .../agents/change_detector_agent_spec.rb | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/app/models/agents/change_detector_agent.rb b/app/models/agents/change_detector_agent.rb index 9a605ee1..3f5d718a 100644 --- a/app/models/agents/change_detector_agent.rb +++ b/app/models/agents/change_detector_agent.rb @@ -5,7 +5,7 @@ module Agents description <<-MD The Change Detector Agent receives a stream of events and emits a new event when a property of the received event changes. - `property` specifies the property to be watched. + `property` specifies a Liquid template that expands to the property to be watched, where you can use a variable `last_property` for the last property value. If you want to detect a new lowest price, try this: `{% assign drop = last_property | minus: price %}{% if last_property == blank or drop > 0 %}{{ price | default: last_property }}{% else %}{{ last_property }}{% endif %}` `expected_update_period_in_days` is used to determine if the Agent is working. @@ -43,7 +43,10 @@ module Agents def receive(incoming_events) incoming_events.each do |event| - handle(interpolated(event), event) + interpolation_context.stack do + interpolation_context['last_property'] = last_property + handle(interpolated(event), event) + end end end diff --git a/spec/models/agents/change_detector_agent_spec.rb b/spec/models/agents/change_detector_agent_spec.rb index 151fc31e..bd543887 100644 --- a/spec/models/agents/change_detector_agent_spec.rb +++ b/spec/models/agents/change_detector_agent_spec.rb @@ -95,4 +95,62 @@ describe Agents::ChangeDetectorAgent do }.to change(Event, :count).by(0) end end + + describe "#receive using last_property to track lowest value" do + before :each do + @event = create_event("100") + end + + before do + # Evaluate the output as number and detect a new lowest value + @checker.options['property'] = '{% assign drop = last_property | minus: output %}{% if last_property == blank or drop > 0 %}{{ output | default: last_property }}{% else %}{{ last_property }}{% endif %}' + end + + it "creates events when the value drops" do + @checker.receive([@event]) + + event = create_event("90") + expect { + @checker.receive([event]) + }.to change(Event, :count).by(1) + expect(@checker.memory['last_property']).to eq "90" + end + + it "does not create event when the value does not change" do + @checker.receive([@event]) + + event = create_event("100") + expect { + @checker.receive([event]) + }.not_to change(Event, :count) + expect(@checker.memory['last_property']).to eq "100" + end + + it "does not create event when the value rises" do + @checker.receive([@event]) + + event = create_event("110") + expect { + @checker.receive([event]) + }.not_to change(Event, :count) + expect(@checker.memory['last_property']).to eq "100" + end + + it "does not create event when the value is blank" do + @checker.receive([@event]) + + event = create_event("") + expect { + @checker.receive([event]) + }.not_to change(Event, :count) + expect(@checker.memory['last_property']).to eq "100" + end + + it "creates events when memory is empty" do + expect { + @checker.receive([@event]) + }.to change(Event, :count).by(1) + expect(@checker.memory['last_property']).to eq "100" + end + end end