optimizely-sdk 2.0.0.beta → 2.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Copyright 2016-2017, Optimizely and contributors
3
5
  #
@@ -16,7 +18,6 @@
16
18
  module Optimizely
17
19
  module Helpers
18
20
  module Constants
19
-
20
21
  JSON_SCHEMA_V2 = {
21
22
  'type' => 'object',
22
23
  'properties' => {
@@ -49,9 +50,9 @@ module Optimizely
49
50
  'type' => 'integer'
50
51
  }
51
52
  },
52
- 'required' => [
53
- 'entityId',
54
- 'endOfRange'
53
+ 'required' => %w[
54
+ entityId
55
+ endOfRange
55
56
  ]
56
57
  }
57
58
  },
@@ -84,9 +85,9 @@ module Optimizely
84
85
  'type' => 'string'
85
86
  }
86
87
  },
87
- 'required' => [
88
- 'id',
89
- 'key'
88
+ 'required' => %w[
89
+ id
90
+ key
90
91
  ]
91
92
  }
92
93
  },
@@ -102,9 +103,9 @@ module Optimizely
102
103
  'type' => 'integer'
103
104
  }
104
105
  },
105
- 'required' => [
106
- 'entityId',
107
- 'endOfRange'
106
+ 'required' => %w[
107
+ entityId
108
+ endOfRange
108
109
  ]
109
110
  }
110
111
  },
@@ -118,24 +119,24 @@ module Optimizely
118
119
  'type' => 'object'
119
120
  }
120
121
  },
121
- 'required' => [
122
- 'id',
123
- 'layerId',
124
- 'key',
125
- 'status',
126
- 'variations',
127
- 'trafficAllocation',
128
- 'audienceIds',
129
- 'forcedVariations'
122
+ 'required' => %w[
123
+ id
124
+ layerId
125
+ key
126
+ status
127
+ variations
128
+ trafficAllocation
129
+ audienceIds
130
+ forcedVariations
130
131
  ]
131
132
  }
132
133
  }
133
134
  },
134
- 'required' => [
135
- 'id',
136
- 'policy',
137
- 'trafficAllocation',
138
- 'experiments'
135
+ 'required' => %w[
136
+ id
137
+ policy
138
+ trafficAllocation
139
+ experiments
139
140
  ]
140
141
  }
141
142
  },
@@ -168,9 +169,9 @@ module Optimizely
168
169
  'type' => 'string'
169
170
  }
170
171
  },
171
- 'required' => [
172
- 'id',
173
- 'key'
172
+ 'required' => %w[
173
+ id
174
+ key
174
175
  ]
175
176
  }
176
177
  },
@@ -186,9 +187,9 @@ module Optimizely
186
187
  'type' => 'integer'
187
188
  }
188
189
  },
189
- 'required' => [
190
- 'entityId',
191
- 'endOfRange'
190
+ 'required' => %w[
191
+ entityId
192
+ endOfRange
192
193
  ]
193
194
  }
194
195
  },
@@ -202,15 +203,15 @@ module Optimizely
202
203
  'type' => 'object'
203
204
  }
204
205
  },
205
- 'required' => [
206
- 'id',
207
- 'key',
208
- 'variations',
209
- 'trafficAllocation',
210
- 'audienceIds',
211
- 'forcedVariations',
212
- 'status',
213
- 'layerId'
206
+ 'required' => %w[
207
+ id
208
+ key
209
+ variations
210
+ trafficAllocation
211
+ audienceIds
212
+ forcedVariations
213
+ status
214
+ layerId
214
215
  ]
215
216
  }
216
217
  },
@@ -232,10 +233,10 @@ module Optimizely
232
233
  'type' => 'string'
233
234
  }
234
235
  },
235
- 'required' => [
236
- 'key',
237
- 'experimentIds',
238
- 'id'
236
+ 'required' => %w[
237
+ key
238
+ experimentIds
239
+ id
239
240
  ]
240
241
  }
241
242
  },
@@ -254,10 +255,10 @@ module Optimizely
254
255
  'type' => 'string'
255
256
  }
256
257
  },
257
- 'required' => [
258
- 'id',
259
- 'name',
260
- 'conditions'
258
+ 'required' => %w[
259
+ id
260
+ name
261
+ conditions
261
262
  ]
262
263
  }
263
264
  },
@@ -271,11 +272,11 @@ module Optimizely
271
272
  },
272
273
  'key' => {
273
274
  'type' => 'string'
274
- },
275
+ }
275
276
  },
276
- 'required' => [
277
- 'id',
278
- 'key',
277
+ 'required' => %w[
278
+ id
279
+ key
279
280
  ]
280
281
  }
281
282
  },
@@ -286,25 +287,25 @@ module Optimizely
286
287
  'type' => 'string'
287
288
  }
288
289
  },
289
- 'required' => [
290
- 'projectId',
291
- 'accountId',
292
- 'experiments',
293
- 'events',
294
- 'groups',
295
- 'audiences',
296
- 'attributes',
297
- 'version',
298
- 'revision'
290
+ 'required' => %w[
291
+ projectId
292
+ accountId
293
+ experiments
294
+ events
295
+ groups
296
+ audiences
297
+ attributes
298
+ version
299
+ revision
299
300
  ]
300
- }
301
+ }.freeze
301
302
 
302
303
  VARIABLE_TYPES = {
303
304
  'BOOLEAN' => 'boolean',
304
305
  'DOUBLE' => 'double',
305
306
  'INTEGER' => 'integer',
306
307
  'STRING' => 'string'
307
- }
308
+ }.freeze
308
309
  end
309
310
  end
310
311
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
- # Copyright 2017, Optimizely and contributors
4
+ # Copyright 2017-2018, Optimizely and contributors
3
5
  #
4
6
  # Licensed under the Apache License, Version 2.0 (the "License");
5
7
  # you may not use this file except in compliance with the License.
@@ -21,35 +23,108 @@ module Optimizely
21
23
  module EventTagUtils
22
24
  module_function
23
25
 
24
- def get_revenue_value(event_tags)
26
+ REVENUE_EVENT_METRIC_NAME = 'revenue'
27
+ NUMERIC_EVENT_METRIC_NAME = 'value'
28
+
29
+ def get_revenue_value(event_tags, logger)
25
30
  # Grab the revenue value from the event tags. "revenue" is a reserved keyword.
26
- #
31
+ # The value will be parsed to an integer if possible.
32
+ # Example:
33
+ # 4.0 or "4.0" will be parsed to int(4).
34
+ # 4.1 will not be parsed and the method will return nil.
27
35
  # event_tags - Hash representing metadata associated with the event.
36
+ # logger - Optional component which provides a log method to log messages.
37
+ #
28
38
  # Returns revenue value as an integer number
29
39
  # Returns nil if revenue can't be retrieved from the event tags.
30
40
 
31
- if event_tags.nil? or !Helpers::Validator.attributes_valid?(event_tags)
41
+ if event_tags.nil?
42
+ logger.log(Logger::DEBUG, 'Event tags is undefined.')
43
+ return nil
44
+ end
45
+
46
+ unless Helpers::Validator.event_tags_valid?(event_tags)
47
+ logger.log(Logger::DEBUG, 'Event tags is not a hash.')
32
48
  return nil
33
49
  end
34
50
 
35
- unless event_tags.has_key?('revenue')
51
+ unless event_tags.key?(REVENUE_EVENT_METRIC_NAME)
52
+ logger.log(Logger::DEBUG, 'The revenue key is not defined in the event tags.')
36
53
  return nil
37
54
  end
38
55
 
39
- logger = SimpleLogger.new
40
- raw_value = event_tags['revenue']
56
+ if event_tags[REVENUE_EVENT_METRIC_NAME].nil?
57
+ logger.log(Logger::DEBUG, 'The revenue key is nil.')
58
+ return nil
59
+ end
41
60
 
42
- unless raw_value.is_a? Numeric
43
- logger.log(Logger::WARN, "Failed to parse revenue value #{raw_value} from event tags.")
61
+ raw_value = event_tags[REVENUE_EVENT_METRIC_NAME]
62
+
63
+ unless Helpers::Validator.string_numeric?(raw_value)
64
+ logger.log(Logger::WARN, 'Revenue value is not an integer or float, or is not a numeric string.')
44
65
  return nil
45
66
  end
46
67
 
47
- if raw_value.is_a? Float
68
+ raw_value = raw_value.to_f if raw_value.is_a? String
69
+
70
+ unless raw_value == raw_value.to_i
48
71
  logger.log(Logger::WARN, "Failed to parse revenue value #{raw_value} from event tags.")
49
72
  return nil
50
73
  end
51
74
 
52
- logger.log(Logger::INFO, "Parsed revenue value #{raw_value} from event tags.")
75
+ logger.log(Logger::INFO, "Parsed revenue value #{raw_value.to_i} from event tags.")
76
+ raw_value.to_i
77
+ end
78
+
79
+ def get_numeric_value(event_tags, logger)
80
+ # Grab the numeric event value from the event tags. "value" is a reserved keyword.
81
+ # The value of 'value' can be a float or a numeric string
82
+ #
83
+ # event_tags - +Hash+ representing metadata associated with the event.
84
+ # logger - Optional component which provides a log method to log messages.
85
+ # Returns +Number+ | +nil+ if value can't be retrieved from the event tags.
86
+
87
+ if event_tags.nil?
88
+ logger.log(Logger::DEBUG, 'Event tags is undefined.')
89
+ return nil
90
+ end
91
+
92
+ unless Helpers::Validator.event_tags_valid?(event_tags)
93
+ logger.log(Logger::DEBUG, 'Event tags is not a dictionary.')
94
+ return nil
95
+ end
96
+
97
+ unless event_tags.key?(NUMERIC_EVENT_METRIC_NAME)
98
+ logger.log(Logger::DEBUG, 'The numeric metric key is not defined in the event tags.')
99
+ return nil
100
+ end
101
+
102
+ if event_tags[NUMERIC_EVENT_METRIC_NAME].nil?
103
+ logger.log(Logger::DEBUG, 'The numeric metric key is null.')
104
+ return nil
105
+ end
106
+
107
+ raw_value = event_tags[NUMERIC_EVENT_METRIC_NAME]
108
+
109
+ if raw_value.is_a?(TrueClass) || raw_value.is_a?(FalseClass)
110
+ logger.log(Logger::DEBUG, 'Provided numeric value is a boolean, which is an invalid format.')
111
+ return nil
112
+ end
113
+
114
+ if raw_value.is_a?(Array) || raw_value.is_a?(Hash) || raw_value.to_f.nan? || raw_value.to_f.infinite?
115
+ logger.log(Logger::DEBUG, 'Provided numeric value is in an invalid format.')
116
+ return nil
117
+ end
118
+
119
+ unless Helpers::Validator.string_numeric?(raw_value)
120
+ logger.log(Logger::DEBUG, 'Provided numeric value is not a numeric string.')
121
+ return nil
122
+ end
123
+
124
+ raw_value = raw_value.to_f
125
+
126
+ logger.log(Logger::INFO, "The numeric metric value #{raw_value} will be sent to results.")
127
+
53
128
  raw_value
54
129
  end
55
130
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
- # Copyright 2016, Optimizely and contributors
4
+ # Copyright 2016-2017, Optimizely and contributors
3
5
  #
4
6
  # Licensed under the Apache License, Version 2.0 (the "License");
5
7
  # you may not use this file except in compliance with the License.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Copyright 2016-2017, Optimizely and contributors
3
5
  #
@@ -50,7 +52,7 @@ module Optimizely
50
52
  # Returns boolean depending on validity of datafile.
51
53
 
52
54
  begin
53
- datafile = JSON.load(datafile)
55
+ datafile = JSON.parse(datafile)
54
56
  rescue
55
57
  return false
56
58
  end
@@ -87,6 +89,12 @@ module Optimizely
87
89
 
88
90
  logger.respond_to?(:log)
89
91
  end
92
+
93
+ def string_numeric?(str)
94
+ !Float(str).nil?
95
+ rescue
96
+ false
97
+ end
90
98
  end
91
99
  end
92
100
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Copyright 2017, Optimizely and contributors
3
5
  #
@@ -30,26 +32,28 @@ module Optimizely
30
32
  return_value = nil
31
33
 
32
34
  case variable_type
33
- when "boolean"
34
- return_value = value == "true"
35
- when "double"
35
+ when 'boolean'
36
+ return_value = value == 'true'
37
+ when 'double'
36
38
  begin
37
39
  return_value = Float(value)
38
40
  rescue => e
39
- logger.log(Logger::ERROR, "Unable to cast variable value '#{value}' to type '#{variable_type}': #{e.message}.")
41
+ logger.log(Logger::ERROR, "Unable to cast variable value '#{value}' to type "\
42
+ "'#{variable_type}': #{e.message}.")
40
43
  end
41
- when "integer"
44
+ when 'integer'
42
45
  begin
43
46
  return_value = Integer(value)
44
47
  rescue => e
45
- logger.log(Logger::ERROR, "Unable to cast variable value '#{value}' to type '#{variable_type}': #{e.message}.")
48
+ logger.log(Logger::ERROR, "Unable to cast variable value '#{value}' to type "\
49
+ "'#{variable_type}': #{e.message}.")
46
50
  end
47
51
  else
48
52
  # default case is string
49
53
  return_value = value
50
54
  end
51
55
 
52
- return return_value
56
+ return_value
53
57
  end
54
58
  end
55
59
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
- # Copyright 2016, Optimizely and contributors
4
+ # Copyright 2016-2017, Optimizely and contributors
3
5
  #
4
6
  # Licensed under the Apache License, Version 2.0 (the "License");
5
7
  # you may not use this file except in compliance with the License.
@@ -19,15 +21,13 @@ module Optimizely
19
21
  class BaseLogger
20
22
  # Class encapsulating logging functionality. Override with your own logger providing log method.
21
23
 
22
- def log(_level, _message)
23
- end
24
+ def log(_level, _message); end
24
25
  end
25
26
 
26
27
  class NoOpLogger < BaseLogger
27
28
  # Class providing log method which logs nothing.
28
29
 
29
- def log(_level, _message)
30
- end
30
+ def log(_level, _message); end
31
31
  end
32
32
 
33
33
  class SimpleLogger < BaseLogger