From 36c5564d87ae9780f40af4ecc9326ea763a9ba9d Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 25 Oct 2019 10:01:31 -0400 Subject: [PATCH 1/4] NotificationCenter learns to accept blocks as the callback --- lib/optimizely/notification_center.rb | 6 ++++-- spec/notification_center_spec.rb | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/optimizely/notification_center.rb b/lib/optimizely/notification_center.rb index 4a3b0169..6c175b9b 100644 --- a/lib/optimizely/notification_center.rb +++ b/lib/optimizely/notification_center.rb @@ -44,15 +44,17 @@ def initialize(logger, error_handler) # # @return [notification ID] Used to remove the notification - def add_notification_listener(notification_type, notification_callback) + def add_notification_listener(notification_type, notification_callback = nil, &block) return nil unless notification_type_valid?(notification_type) + notification_callback ||= block + unless notification_callback @logger.log Logger::ERROR, 'Callback can not be empty.' return nil end - unless notification_callback.is_a? Method + unless notification_callback.respond_to? :call @logger.log Logger::ERROR, 'Invalid notification callback given.' return nil end diff --git a/spec/notification_center_spec.rb b/spec/notification_center_spec.rb index be3a4b8e..25425eeb 100644 --- a/spec/notification_center_spec.rb +++ b/spec/notification_center_spec.rb @@ -484,6 +484,18 @@ def deliver_three; end expect(spy_logger).to_not have_received(:log) .with(Logger::INFO, 'delivered three.') end + + it 'should send notifications to blocks' do + actual_args = [] + notification_center.add_notification_listener(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:TRACK]) do |*args| + actual_args = args + end + + notification_center.send_notifications(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:TRACK], + :arg1, "arg2", arg3: 4) + + expect(actual_args).to eq([:arg1, "arg2", arg3: 4]) + end end describe '.notification_count' do From 3c9a3e44a70b54dfddc62e83e66365009bd29176 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 25 Oct 2019 10:02:08 -0400 Subject: [PATCH 2/4] NotificationCenter guards against receiving both callback and block If given both a callback and a block, it would not be clear which would be invoked for the notification. --- lib/optimizely/notification_center.rb | 5 +++++ spec/notification_center_spec.rb | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/optimizely/notification_center.rb b/lib/optimizely/notification_center.rb index 6c175b9b..9b2c3869 100644 --- a/lib/optimizely/notification_center.rb +++ b/lib/optimizely/notification_center.rb @@ -47,6 +47,11 @@ def initialize(logger, error_handler) def add_notification_listener(notification_type, notification_callback = nil, &block) return nil unless notification_type_valid?(notification_type) + if notification_callback && block_given? + @logger.log Logger::ERROR, 'Callback and block are mutually exclusive.' + return nil + end + notification_callback ||= block unless notification_callback diff --git a/spec/notification_center_spec.rb b/spec/notification_center_spec.rb index 25425eeb..b45f1c60 100644 --- a/spec/notification_center_spec.rb +++ b/spec/notification_center_spec.rb @@ -73,6 +73,15 @@ def call; end expect(spy_logger).to have_received(:log).once .with(Logger::ERROR, 'Invalid notification callback given.') end + + it 'should log and return nil if given both callback and block' do + result = notification_center.add_notification_listener(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:ACTIVATE], + @callback_reference) { } + + expect(result).to be_nil + expect(spy_logger).to have_received(:log).once + .with(Logger::ERROR, 'Callback and block are mutually exclusive.') + end end describe 'test add notification with valid type and callback' do From 07e2d31e84eaf37b672881ec143b0c16025b4c2a Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 25 Oct 2019 09:48:37 -0400 Subject: [PATCH 3/4] NotificationCenter accepts lambdas and general Callables as well --- spec/notification_center_spec.rb | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/spec/notification_center_spec.rb b/spec/notification_center_spec.rb index b45f1c60..880a7ed6 100644 --- a/spec/notification_center_spec.rb +++ b/spec/notification_center_spec.rb @@ -30,7 +30,11 @@ before(:context) do class CallBack - def call; end + attr_reader :args + + def call(*args) + @args = args + end end @callback = CallBack.new @@ -505,6 +509,27 @@ def deliver_three; end expect(actual_args).to eq([:arg1, "arg2", arg3: 4]) end + + it 'should send notifications to lambdas' do + actual_args = [] + notification_center.add_notification_listener(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:TRACK], + ->(*args) { actual_args = args }) + + notification_center.send_notifications(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:TRACK], + :arg1, "arg2", arg3: 4) + + expect(actual_args).to eq([:arg1, "arg2", arg3: 4]) + end + + it 'should send notifications to callables' do + callback = CallBack.new + notification_center.add_notification_listener(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:TRACK], callback) + + notification_center.send_notifications(Optimizely::NotificationCenter::NOTIFICATION_TYPES[:TRACK], + :arg1, "arg2", arg3: 4) + + expect(callback.args).to eq([:arg1, "arg2", arg3: 4]) + end end describe '.notification_count' do From d8c654d0a5bd08cce4968d7ef7b5765875a1a9a4 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 25 Oct 2019 09:59:40 -0400 Subject: [PATCH 4/4] Document the expanded callable param --- lib/optimizely/notification_center.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/optimizely/notification_center.rb b/lib/optimizely/notification_center.rb index 9b2c3869..6f4eda99 100644 --- a/lib/optimizely/notification_center.rb +++ b/lib/optimizely/notification_center.rb @@ -39,8 +39,9 @@ def initialize(logger, error_handler) # Adds notification callback to the notification center # - # @param notification_type - One of the constants in NOTIFICATION_TYPES - # @param notification_callback - Function to call when the event is sent + # @param notification_type - One of the constants in NOTIFICATION_TYPES + # @param notification_callback [lambda, Method, Callable] (default: block) - Called when the event is sent + # @yield Block to be used as callback if callback omitted. # # @return [notification ID] Used to remove the notification @@ -77,7 +78,7 @@ def add_notification_listener(notification_type, notification_callback = nil, &b # # @param notification_id # - # @return [Boolean] The function returns true if found and removed, false otherwise + # @return [Boolean] true if found and removed, false otherwise def remove_notification_listener(notification_id) unless notification_id