absmartly-sdk 1.0.7 → 1.1.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +8 -25
- data/absmartly.gemspec +2 -1
- data/lib/absmartly/version.rb +1 -1
- data/lib/context.rb +83 -0
- data/lib/default_http_client.rb +1 -0
- data/lib/json/custom_field_value.rb +31 -0
- data/lib/json/experiment.rb +10 -3
- data/lib/json_expr/expr_evaluator.rb +3 -3
- metadata +22 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2a63e1c39032b6a7427c760d5b657d69bcee386e66f9bf4f809e1638d0224251
|
|
4
|
+
data.tar.gz: e8e2acb8a335ce2705aa22e72d000cde80e9a089daa16a4f096ebb3a4bdee88a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d7876ef4191d0da54a36aabb7b1c0da583182316ba618bb13cd5674c75063aae212d25cfd35761c29966c8d58c91187466fbab04e50cdabd6f051d5443dba97
|
|
7
|
+
data.tar.gz: 2fff9f84a10749f2bd9a65a505590e029364a21a20ea2622fd6a8de41c4b91cf11105b5a4aa5c42a163474ddbd7ea4d82aa768c6eeac39dbf73ffc23723293d6
|
data/Gemfile.lock
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
absmartly-sdk (1.0
|
|
4
|
+
absmartly-sdk (1.1.0)
|
|
5
5
|
arraybuffer (~> 0.0.6)
|
|
6
|
-
faraday (~>
|
|
6
|
+
faraday (~> 2.0)
|
|
7
|
+
faraday-retry (~> 2.0)
|
|
7
8
|
murmurhash3 (~> 0.1.7)
|
|
8
9
|
|
|
9
10
|
GEM
|
|
@@ -13,34 +14,16 @@ GEM
|
|
|
13
14
|
ast (2.4.2)
|
|
14
15
|
byebug (11.1.3)
|
|
15
16
|
diff-lcs (1.5.0)
|
|
16
|
-
faraday (
|
|
17
|
-
faraday-
|
|
18
|
-
faraday-em_synchrony (~> 1.0)
|
|
19
|
-
faraday-excon (~> 1.1)
|
|
20
|
-
faraday-httpclient (~> 1.0)
|
|
21
|
-
faraday-multipart (~> 1.0)
|
|
22
|
-
faraday-net_http (~> 1.0)
|
|
23
|
-
faraday-net_http_persistent (~> 1.0)
|
|
24
|
-
faraday-patron (~> 1.0)
|
|
25
|
-
faraday-rack (~> 1.0)
|
|
26
|
-
faraday-retry (~> 1.0)
|
|
17
|
+
faraday (2.7.4)
|
|
18
|
+
faraday-net_http (>= 2.0, < 3.1)
|
|
27
19
|
ruby2_keywords (>= 0.0.4)
|
|
28
|
-
faraday-
|
|
29
|
-
faraday-
|
|
30
|
-
|
|
31
|
-
faraday-httpclient (1.0.1)
|
|
32
|
-
faraday-multipart (1.0.4)
|
|
33
|
-
multipart-post (~> 2)
|
|
34
|
-
faraday-net_http (1.0.1)
|
|
35
|
-
faraday-net_http_persistent (1.2.0)
|
|
36
|
-
faraday-patron (1.0.0)
|
|
37
|
-
faraday-rack (1.0.0)
|
|
38
|
-
faraday-retry (1.0.3)
|
|
20
|
+
faraday-net_http (3.0.2)
|
|
21
|
+
faraday-retry (2.1.0)
|
|
22
|
+
faraday (~> 2.0)
|
|
39
23
|
io-console (0.5.6)
|
|
40
24
|
irb (1.2.6)
|
|
41
25
|
reline (>= 0.1.5)
|
|
42
26
|
json (2.6.2)
|
|
43
|
-
multipart-post (2.1.1)
|
|
44
27
|
murmurhash3 (0.1.7)
|
|
45
28
|
parallel (1.22.1)
|
|
46
29
|
parser (3.1.2.0)
|
data/absmartly.gemspec
CHANGED
|
@@ -32,7 +32,8 @@ Gem::Specification.new do |spec|
|
|
|
32
32
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
33
33
|
spec.require_paths = ["lib"]
|
|
34
34
|
|
|
35
|
-
spec.add_dependency "faraday", "~>
|
|
35
|
+
spec.add_dependency "faraday", "~> 2.0"
|
|
36
|
+
spec.add_dependency "faraday-retry", "~> 2.0"
|
|
36
37
|
spec.add_dependency "murmurhash3", "~> 0.1.7"
|
|
37
38
|
spec.add_dependency "arraybuffer", "~> 0.0.6"
|
|
38
39
|
|
data/lib/absmartly/version.rb
CHANGED
data/lib/context.rb
CHANGED
|
@@ -21,6 +21,7 @@ class Context
|
|
|
21
21
|
def initialize(clock, config, data_future, data_provider,
|
|
22
22
|
event_handler, event_logger, variable_parser, audience_matcher)
|
|
23
23
|
@index = []
|
|
24
|
+
@context_custom_fields = {}
|
|
24
25
|
@achievements = []
|
|
25
26
|
@assignment_cache = {}
|
|
26
27
|
@assignments = {}
|
|
@@ -203,6 +204,52 @@ class Context
|
|
|
203
204
|
default_value
|
|
204
205
|
end
|
|
205
206
|
|
|
207
|
+
def custom_field_keys
|
|
208
|
+
check_ready?(true)
|
|
209
|
+
keys = []
|
|
210
|
+
|
|
211
|
+
@data.experiments.each do |experiment|
|
|
212
|
+
custom_field_values = experiment.custom_field_values
|
|
213
|
+
if custom_field_values != nil
|
|
214
|
+
custom_field_values.each do |custom_field|
|
|
215
|
+
keys.append(custom_field.name)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
return keys.sort.uniq
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def custom_field_value(experimentName, key)
|
|
224
|
+
check_ready?(true)
|
|
225
|
+
|
|
226
|
+
experiment_custom_fields = @context_custom_fields[experimentName]
|
|
227
|
+
|
|
228
|
+
if experiment_custom_fields != nil
|
|
229
|
+
field = experiment_custom_fields[key]
|
|
230
|
+
if field != nil
|
|
231
|
+
return field.value
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
return nil
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def custom_field_type(experimentName, key)
|
|
239
|
+
check_ready?(true)
|
|
240
|
+
|
|
241
|
+
experiment_custom_fields = @context_custom_fields[experimentName]
|
|
242
|
+
|
|
243
|
+
if experiment_custom_fields != nil
|
|
244
|
+
field = experiment_custom_fields[key]
|
|
245
|
+
if field != nil
|
|
246
|
+
return field.type
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
return nil
|
|
251
|
+
end
|
|
252
|
+
|
|
206
253
|
def peek_variable_value(key, default_value)
|
|
207
254
|
check_ready?(true)
|
|
208
255
|
|
|
@@ -451,8 +498,11 @@ class Context
|
|
|
451
498
|
@data = data
|
|
452
499
|
@index = {}
|
|
453
500
|
@index_variables = {}
|
|
501
|
+
|
|
454
502
|
if data && !data.experiments.nil? && !data.experiments.empty?
|
|
455
503
|
data.experiments.each do |experiment|
|
|
504
|
+
@experimentCustomFieldValues = {}
|
|
505
|
+
|
|
456
506
|
experiment_variables = ExperimentVariables.new
|
|
457
507
|
experiment_variables.data = experiment
|
|
458
508
|
experiment_variables.variables ||= []
|
|
@@ -467,7 +517,36 @@ class Context
|
|
|
467
517
|
end
|
|
468
518
|
end
|
|
469
519
|
|
|
520
|
+
if !experiment.custom_field_values.nil?
|
|
521
|
+
experiment.custom_field_values.each do |custom_field_value|
|
|
522
|
+
value = ContextCustomFieldValues.new
|
|
523
|
+
value.type = custom_field_value.type
|
|
524
|
+
|
|
525
|
+
if !custom_field_value.value.nil?
|
|
526
|
+
custom_value = custom_field_value.value
|
|
527
|
+
|
|
528
|
+
if custom_field_value.type.start_with?("json")
|
|
529
|
+
value.value = @variable_parser.parse(self, experiment.name, custom_field_value.name, custom_value)
|
|
530
|
+
|
|
531
|
+
elsif custom_field_value.type.start_with?("boolean")
|
|
532
|
+
value.value = custom_value.to_bool
|
|
533
|
+
|
|
534
|
+
elsif custom_field_value.type.start_with?("number")
|
|
535
|
+
value.value = custom_value.to_i
|
|
536
|
+
|
|
537
|
+
else
|
|
538
|
+
value.value = custom_field_value.value
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
@experimentCustomFieldValues[custom_field_value.name] = value
|
|
542
|
+
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
|
|
470
548
|
@index[experiment.name] = experiment_variables
|
|
549
|
+
@context_custom_fields[experiment.name] = @experimentCustomFieldValues
|
|
471
550
|
end
|
|
472
551
|
end
|
|
473
552
|
end
|
|
@@ -544,5 +623,9 @@ class ExperimentVariables
|
|
|
544
623
|
attr_accessor :data, :variables
|
|
545
624
|
end
|
|
546
625
|
|
|
626
|
+
class ContextCustomFieldValues
|
|
627
|
+
attr_accessor :type, :value
|
|
628
|
+
end
|
|
629
|
+
|
|
547
630
|
class IllegalStateException < StandardError
|
|
548
631
|
end
|
data/lib/default_http_client.rb
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CustomFieldValue
|
|
4
|
+
attr_accessor :name, :type, :value
|
|
5
|
+
|
|
6
|
+
def initialize(name, value, type)
|
|
7
|
+
@name = name
|
|
8
|
+
@type = type
|
|
9
|
+
@value = value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def ==(o)
|
|
13
|
+
return true if self.object_id == o.object_id
|
|
14
|
+
return false if o.nil? || self.class != o.class
|
|
15
|
+
|
|
16
|
+
that = o
|
|
17
|
+
@name == that.name && @type == that.type && @value == that.value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def hash_code
|
|
21
|
+
{ name: @name, type: @type, value: @value }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
"CustomFieldValue{" +
|
|
26
|
+
"name='#{@name}'" +
|
|
27
|
+
", type='#{@type}'" +
|
|
28
|
+
", value='#{@value}'" +
|
|
29
|
+
"}"
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/json/experiment.rb
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
require_relative "../string"
|
|
4
4
|
require_relative "experiment_application"
|
|
5
5
|
require_relative "experiment_variant"
|
|
6
|
+
require_relative "custom_field_value"
|
|
6
7
|
|
|
7
8
|
class Experiment
|
|
8
9
|
attr_accessor :id, :name, :unit_type, :iteration, :seed_hi, :seed_lo, :split,
|
|
9
10
|
:traffic_seed_hi, :traffic_seed_lo, :traffic_split, :full_on_variant,
|
|
10
|
-
:applications, :variants, :audience_strict, :audience
|
|
11
|
+
:applications, :variants, :audience_strict, :audience, :custom_field_values
|
|
11
12
|
|
|
12
13
|
def initialize(args = {})
|
|
13
14
|
args.each do |name, value|
|
|
@@ -15,6 +16,10 @@ class Experiment
|
|
|
15
16
|
@applications = assign_to_klass(ExperimentApplication, value)
|
|
16
17
|
elsif name == :variants
|
|
17
18
|
@variants = assign_to_klass(ExperimentVariant, value)
|
|
19
|
+
elsif name == :customFieldValues
|
|
20
|
+
if value != nil
|
|
21
|
+
@custom_field_values = assign_to_klass(CustomFieldValue, value)
|
|
22
|
+
end
|
|
18
23
|
else
|
|
19
24
|
self.instance_variable_set("@#{name.to_s.underscore}", value)
|
|
20
25
|
end
|
|
@@ -42,7 +47,7 @@ class Experiment
|
|
|
42
47
|
@unit_type == that.unit_type && @split == that.split &&
|
|
43
48
|
@traffic_split == that.traffic_split && @applications == that.applications &&
|
|
44
49
|
@variants == that.variants && @audience_strict == that.audience_strict &&
|
|
45
|
-
@audience == that.audience
|
|
50
|
+
@audience == that.audience && @custom_field_values == that.custom_field_values
|
|
46
51
|
end
|
|
47
52
|
|
|
48
53
|
def hash_code
|
|
@@ -57,7 +62,8 @@ class Experiment
|
|
|
57
62
|
traffic_seed_lo: @traffic_seed_lo,
|
|
58
63
|
full_on_variant: @full_on_variant,
|
|
59
64
|
audience_strict: @audience_strict,
|
|
60
|
-
audience: @audience
|
|
65
|
+
audience: @audience,
|
|
66
|
+
custom_field_values: @custom_field_values
|
|
61
67
|
}
|
|
62
68
|
end
|
|
63
69
|
|
|
@@ -78,6 +84,7 @@ class Experiment
|
|
|
78
84
|
", variants=#{@variants.join}" +
|
|
79
85
|
", audienceStrict=#{@audience_strict}" +
|
|
80
86
|
", audience='#{@audience}'" +
|
|
87
|
+
", custom_field_values='#{@custom_field_values}'" +
|
|
81
88
|
"}"
|
|
82
89
|
end
|
|
83
90
|
end
|
|
@@ -32,7 +32,7 @@ class ExprEvaluator < Evaluator
|
|
|
32
32
|
def boolean_convert(x)
|
|
33
33
|
if x.is_a?(TrueClass) || x.is_a?(FalseClass)
|
|
34
34
|
return x
|
|
35
|
-
elsif x.is_a?(Numeric) || !(x =~ NUMERIC_REGEX).nil?
|
|
35
|
+
elsif x.is_a?(Numeric) || !(x.to_s =~ NUMERIC_REGEX).nil?
|
|
36
36
|
return !x.to_f.zero?
|
|
37
37
|
elsif x.is_a?(String)
|
|
38
38
|
return x != "false" && x != "0" && x != ""
|
|
@@ -44,7 +44,7 @@ class ExprEvaluator < Evaluator
|
|
|
44
44
|
def number_convert(x)
|
|
45
45
|
return if x.nil? || x.to_s.empty?
|
|
46
46
|
|
|
47
|
-
if x.is_a?(Numeric) || !(x =~ NUMERIC_REGEX).nil?
|
|
47
|
+
if x.is_a?(Numeric) || !(x.to_s =~ NUMERIC_REGEX).nil?
|
|
48
48
|
return x.to_f
|
|
49
49
|
elsif x.is_a?(TrueClass) || x.is_a?(FalseClass)
|
|
50
50
|
return x ? 1.0 : 0.0
|
|
@@ -57,7 +57,7 @@ class ExprEvaluator < Evaluator
|
|
|
57
57
|
return x
|
|
58
58
|
elsif x.is_a?(TrueClass) || x.is_a?(FalseClass)
|
|
59
59
|
return x.to_s
|
|
60
|
-
elsif x.is_a?(Numeric) || !(x =~ NUMERIC_REGEX).nil?
|
|
60
|
+
elsif x.is_a?(Numeric) || !(x.to_s =~ NUMERIC_REGEX).nil?
|
|
61
61
|
return x == x.to_i ? x.to_i.to_s : x.to_s
|
|
62
62
|
end
|
|
63
63
|
nil
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: absmartly-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- absmartly
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-11-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -16,14 +16,28 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: '2.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: faraday-retry
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: murmurhash3
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -102,6 +116,7 @@ files:
|
|
|
102
116
|
- lib/http_client.rb
|
|
103
117
|
- lib/json/attribute.rb
|
|
104
118
|
- lib/json/context_data.rb
|
|
119
|
+
- lib/json/custom_field_value.rb
|
|
105
120
|
- lib/json/experiment.rb
|
|
106
121
|
- lib/json/experiment_application.rb
|
|
107
122
|
- lib/json/experiment_variant.rb
|
|
@@ -142,7 +157,7 @@ metadata:
|
|
|
142
157
|
homepage_uri: https://github.com/absmartly/ruby-sdk
|
|
143
158
|
source_code_uri: https://github.com/absmartly/ruby-sdk
|
|
144
159
|
changelog_uri: https://github.com/absmartly/ruby-sdk
|
|
145
|
-
post_install_message:
|
|
160
|
+
post_install_message:
|
|
146
161
|
rdoc_options: []
|
|
147
162
|
require_paths:
|
|
148
163
|
- lib
|
|
@@ -158,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
158
173
|
version: '0'
|
|
159
174
|
requirements: []
|
|
160
175
|
rubygems_version: 3.4.10
|
|
161
|
-
signing_key:
|
|
176
|
+
signing_key:
|
|
162
177
|
specification_version: 4
|
|
163
178
|
summary: Absmartly gem
|
|
164
179
|
test_files: []
|