optimizely-sdk 2.0.0.beta → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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