Skip to content

Commit 32e618e

Browse files
committed
ruby doc configuration
1 parent 1d88c92 commit 32e618e

10 files changed

+253
-194
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Gemfile.lock
66
/_yardoc/
77
/coverage/
88
/doc/
9+
!/doc/README.md
910
/spec/reports/
1011
/tmp/
1112
*.DS_Store

.yardopts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--query '@api.text != "no-doc"'
2+
lib/optimizely/error_handler.rb
3+
lib/optimizely/exceptions.rb
4+
lib/optimizely/event_dispatcher.rb
5+
lib/optimizely/logger.rb
6+
lib/optimizely/notification_center.rb
7+
lib/optimizely.rb
8+
lib/optimizely/user_profile_service.rb
9+
-
10+
CONTRIBUTING.md
11+
.rubocop.yml

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.0.2
2+
June 19th, 2018
3+
4+
- Fix: send impression event for Feature Test when Feature is disabled ([#110](https://github.com/optimizely/ruby-sdk/pull/110)).
5+
16
## 2.0.1
27
April 25th, 2018
38

docs/README.md renamed to doc/README.md

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77
* There's a possible chance your Ruby install lacks RDoc, which is occasionally used by YARD to convert markup to HTML. If RDoc not installed, install by issuing:
88
* `$ apt-get install rdoc`
99

10-
* `$ yardoc 'lib/**/*.rb'...etc...`
11-
12-
**OR**
13-
14-
* `$ yardoc 'lib/*.rb' 'lib/optimizely/event_dispatcher.rb' 'lib/optimizely/notification_center.rb' 'lib/optimizely/logger.rb' 'lib/optimizely/error_handler.rb' 'lib/optimizely/user_profile_service.rb'`
10+
* `$ yardoc`
1511

1612
* This will generate HTML documentation in **doc** directory.
1713
* Open **index.html** in **doc** directory.

lib/optimizely.rb

+147-142
Large diffs are not rendered by default.

lib/optimizely/event_dispatcher.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ def dispatch_event(event); end
2525
end
2626

2727
class EventDispatcher
28+
# @api constants
2829
REQUEST_TIMEOUT = 10
2930

31+
# Dispatch the event being represented by the Event object.
32+
#
33+
# @param event - Event object
3034
def dispatch_event(event)
31-
# Dispatch the event being represented by the Event object.
32-
#
33-
# event - Event object
34-
3535
if event.http_verb == :get
3636
begin
3737
HTTParty.get(event.url, headers: event.headers, query: event.params, timeout: REQUEST_TIMEOUT)

lib/optimizely/notification_center.rb

+27-29
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#
1818
module Optimizely
1919
class NotificationCenter
20-
attr_reader :notifications
21-
attr_reader :notification_id
20+
# @api no-doc
21+
attr_reader :notifications, :notification_id
2222

2323
NOTIFICATION_TYPES = {
2424
ACTIVATE: 'ACTIVATE: experiment, user_id, attributes, variation, event',
@@ -33,16 +33,14 @@ def initialize(logger, error_handler)
3333
@error_handler = error_handler
3434
end
3535

36-
def add_notification_listener(notification_type, notification_callback)
37-
# Adds notification callback to the notification center
38-
39-
# Args:
40-
# notification_type: one of the constants in NOTIFICATION_TYPES
41-
# notification_callback: function to call when the event is sent
42-
43-
# Returns:
44-
# notification ID used to remove the notification
36+
# Adds notification callback to the notification center
37+
#
38+
# @param notification_type - One of the constants in NOTIFICATION_TYPES
39+
# @param notification_callback - Function to call when the event is sent
40+
#
41+
# @return [notification ID] Used to remove the notification
4542

43+
def add_notification_listener(notification_type, notification_callback)
4644
return nil unless notification_type_valid?(notification_type)
4745

4846
unless notification_callback
@@ -64,13 +62,13 @@ def add_notification_listener(notification_type, notification_callback)
6462
notification_id
6563
end
6664

67-
def remove_notification_listener(notification_id)
68-
# Removes previously added notification callback
65+
# Removes previously added notification callback
66+
#
67+
# @param notification_id
68+
#
69+
# @return [Boolean] The function returns true if found and removed, false otherwise
6970

70-
# Args:
71-
# notification_id:
72-
# Returns:
73-
# The function returns true if found and removed, false otherwise
71+
def remove_notification_listener(notification_id)
7472
unless notification_id
7573
@logger.log Logger::ERROR, 'Notification ID can not be empty.'
7674
return nil
@@ -86,30 +84,30 @@ def remove_notification_listener(notification_id)
8684
false
8785
end
8886

89-
def clear_notifications(notification_type)
90-
# Removes notifications for a certain notification type
91-
#
92-
# Args:
93-
# notification_type: one of the constants in NOTIFICATION_TYPES
87+
# Removes notifications for a certain notification type
88+
#
89+
# @param notification_type - one of the constants in NOTIFICATION_TYPES
9490

91+
def clear_notifications(notification_type)
9592
return nil unless notification_type_valid?(notification_type)
9693

9794
@notifications[notification_type] = []
9895
@logger.log Logger::INFO, "All callbacks for notification type #{notification_type} have been removed."
9996
end
10097

98+
# Removes all notifications
10199
def clean_all_notifications
102-
# Removes all notifications
103100
@notifications.each_key { |key| @notifications[key] = [] }
104101
end
105102

103+
# Sends off the notification for the specific event. Uses var args to pass in a
104+
# arbitrary list of parameters according to which notification type was sent
105+
#
106+
# @param notification_type - one of the constants in NOTIFICATION_TYPES
107+
# @param args - list of arguments to the callback
108+
#
109+
# @api no-doc
106110
def send_notifications(notification_type, *args)
107-
# Sends off the notification for the specific event. Uses var args to pass in a
108-
# arbitrary list of parameters according to which notification type was sent
109-
110-
# Args:
111-
# notification_type: one of the constants in NOTIFICATION_TYPES
112-
# args: list of arguments to the callback
113111
return nil unless notification_type_valid?(notification_type)
114112

115113
@notifications[notification_type].each do |notification|

lib/optimizely/user_profile_service.rb

+9-12
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,15 @@ class BaseUserProfileService
2121
# Class encapsulating user profile service functionality.
2222
# Override with your own implementation for storing and retrieving user profiles.
2323

24-
def lookup(user_id)
25-
# Retrieve the Hash user profile associated with a given user ID.
26-
#
27-
# user_id - String user ID
28-
#
29-
# Returns Hash user profile.
30-
end
24+
# Retrieve the Hash user profile associated with a given user ID.
25+
#
26+
# @param user_id - String user ID
27+
# @return [Hash] user profile.
28+
def lookup(user_id); end
3129

32-
def save(user_profile)
33-
# Saves a given user profile.
34-
#
35-
# user_profile - Hash user profile.
36-
end
30+
# Saves a given user profile.
31+
#
32+
# @param user_profile - Hash user profile.
33+
def save(user_profile); end
3734
end
3835
end

lib/optimizely/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
#
1818
module Optimizely
1919
CLIENT_ENGINE = 'ruby-sdk'
20-
VERSION = '2.0.1'
20+
VERSION = '2.0.2'
2121
end

spec/project_spec.rb

+47-1
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,8 @@ class InvalidErrorHandler; end
834834
expect(spy_logger).to have_received(:log).once.with(Logger::INFO, "Feature 'multi_variate_feature' is enabled for user 'test_user'.")
835835
end
836836

837-
it 'should return false, if the user is bucketed into a feature experiment but the featureEnabled property is false' do
837+
it 'should return false and send impression if the user is bucketed into a feature experiment but the featureEnabled property is false' do
838+
allow(project_instance.event_dispatcher).to receive(:dispatch_event).with(instance_of(Optimizely::Event))
838839
experiment_to_return = config_body['experiments'][3]
839840
variation_to_return = experiment_to_return['variations'][1]
840841
decision_to_return = Optimizely::DecisionService::Decision.new(
@@ -846,6 +847,7 @@ class InvalidErrorHandler; end
846847
allow(project_instance.decision_service).to receive(:get_variation_for_feature).and_return(decision_to_return)
847848

848849
expect(project_instance.is_feature_enabled('multi_variate_feature', 'test_user')).to be false
850+
expect(project_instance.event_dispatcher).to have_received(:dispatch_event).with(instance_of(Optimizely::Event)).once
849851
expect(spy_logger).to have_received(:log).once.with(Logger::INFO, "Feature 'multi_variate_feature' is not enabled for user 'test_user'.")
850852
end
851853
end
@@ -893,6 +895,17 @@ class InvalidErrorHandler; end
893895
user_id = 'test_user'
894896
user_attributes = {}
895897

898+
it 'should return nil when called with invalid project config' do
899+
logger = double('logger')
900+
allow(logger).to receive(:log)
901+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
902+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
903+
expect(invalid_project.get_feature_variable_string('string_single_variable_feature', 'string_variable', user_id, user_attributes))
904+
.to eq(nil)
905+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
906+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_string.')
907+
end
908+
896909
describe 'when the feature flag is enabled for the user' do
897910
describe 'and a variable usage instance is not found' do
898911
it 'should return the default variable value' do
@@ -1027,6 +1040,17 @@ class InvalidErrorHandler; end
10271040
user_id = 'test_user'
10281041
user_attributes = {}
10291042

1043+
it 'should return nil when called with invalid project config' do
1044+
logger = double('logger')
1045+
allow(logger).to receive(:log)
1046+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
1047+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
1048+
expect(invalid_project.get_feature_variable_boolean('boolean_single_variable_feature', 'boolean_variable', user_id, user_attributes))
1049+
.to eq(nil)
1050+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
1051+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_boolean.')
1052+
end
1053+
10301054
it 'should return the variable value for the variation for the user is bucketed into' do
10311055
boolean_feature = project_instance.config.feature_flag_key_map['boolean_single_variable_feature']
10321056
rollout = project_instance.config.rollout_id_map[boolean_feature['rolloutId']]
@@ -1053,6 +1077,17 @@ class InvalidErrorHandler; end
10531077
user_id = 'test_user'
10541078
user_attributes = {}
10551079

1080+
it 'should return nil when called with invalid project config' do
1081+
logger = double('logger')
1082+
allow(logger).to receive(:log)
1083+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
1084+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
1085+
expect(invalid_project.get_feature_variable_double('double_single_variable_feature', 'double_variable', user_id, user_attributes))
1086+
.to eq(nil)
1087+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
1088+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_double.')
1089+
end
1090+
10561091
it 'should return the variable value for the variation for the user is bucketed into' do
10571092
double_feature = project_instance.config.feature_flag_key_map['double_single_variable_feature']
10581093
experiment_to_return = project_instance.config.experiment_id_map[double_feature['experimentIds'][0]]
@@ -1080,6 +1115,17 @@ class InvalidErrorHandler; end
10801115
user_id = 'test_user'
10811116
user_attributes = {}
10821117

1118+
it 'should return nil when called with invalid project config' do
1119+
logger = double('logger')
1120+
allow(logger).to receive(:log)
1121+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
1122+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
1123+
expect(invalid_project.get_feature_variable_integer('integer_single_variable_feature', 'integer_variable', user_id, user_attributes))
1124+
.to eq(nil)
1125+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
1126+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_integer.')
1127+
end
1128+
10831129
it 'should return the variable value for the variation for the user is bucketed into' do
10841130
integer_feature = project_instance.config.feature_flag_key_map['integer_single_variable_feature']
10851131
experiment_to_return = project_instance.config.experiment_id_map[integer_feature['experimentIds'][0]]

0 commit comments

Comments
 (0)