splitclient-rb 6.0.1 → 6.1.0.pre.rc1
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/.rubocop.yml +12 -1
- data/.simplecov +1 -0
- data/README.md +2 -2
- data/lib/splitclient-rb.rb +1 -0
- data/lib/splitclient-rb/clients/split_client.rb +30 -9
- data/lib/splitclient-rb/engine/api/client.rb +8 -9
- data/lib/splitclient-rb/engine/api/events.rb +4 -2
- data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +10 -8
- data/lib/splitclient-rb/engine/api/impressions.rb +4 -2
- data/lib/splitclient-rb/engine/api/metrics.rb +5 -5
- data/lib/splitclient-rb/engine/api/segments.rb +5 -1
- data/lib/splitclient-rb/engine/api/splits.rb +4 -4
- data/lib/splitclient-rb/engine/matchers/all_keys_matcher.rb +8 -13
- data/lib/splitclient-rb/engine/matchers/between_matcher.rb +12 -23
- data/lib/splitclient-rb/engine/matchers/combiners.rb +3 -1
- data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +16 -24
- data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +10 -7
- data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +7 -6
- data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +19 -8
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +8 -3
- data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +21 -6
- data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +17 -8
- data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +11 -23
- data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +7 -6
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +13 -25
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +13 -25
- data/lib/splitclient-rb/engine/matchers/matcher.rb +30 -0
- data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +6 -2
- data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +8 -22
- data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +10 -7
- data/lib/splitclient-rb/engine/matchers/set_matcher.rb +7 -1
- data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +18 -5
- data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +7 -25
- data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +33 -35
- data/lib/splitclient-rb/managers/split_manager.rb +10 -3
- data/lib/splitclient-rb/split_config.rb +34 -9
- data/lib/splitclient-rb/split_factory.rb +27 -0
- data/lib/splitclient-rb/validators.rb +104 -36
- data/lib/splitclient-rb/version.rb +1 -1
- metadata +6 -4
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
#
|
3
5
|
# class to implement the combining matcher
|
4
6
|
#
|
5
|
-
class CombiningMatcher
|
6
|
-
MATCHER_TYPE = 'COMBINING_MATCHER'
|
7
|
+
class CombiningMatcher < Matcher
|
8
|
+
MATCHER_TYPE = 'COMBINING_MATCHER'
|
7
9
|
|
8
10
|
def initialize(combiner = '', matchers = [])
|
9
11
|
@combiner = combiner
|
@@ -20,12 +22,18 @@ module SplitIoClient
|
|
20
22
|
#
|
21
23
|
# @return [boolean]
|
22
24
|
def match?(args)
|
23
|
-
|
25
|
+
if @matchers.empty?
|
26
|
+
SplitLogger.log_if_debug('[CombiningMatcher] Matchers Empty')
|
27
|
+
return false
|
28
|
+
end
|
24
29
|
|
25
30
|
case @combiner
|
26
31
|
when Combiners::AND
|
27
|
-
|
32
|
+
matches = eval_and(args)
|
33
|
+
SplitLogger.log_if_debug("[CombiningMatcher] Combiner AND result -> #{matches}")
|
34
|
+
return matches
|
28
35
|
else
|
36
|
+
SplitLogger.log_if_debug("[CombiningMatcher] Invalid Combiner Type - Combiner -> #{@combiner}")
|
29
37
|
@logger.error('Invalid combiner type')
|
30
38
|
end
|
31
39
|
|
@@ -43,7 +51,9 @@ module SplitIoClient
|
|
43
51
|
# @return [boolean] match value for combiner delegates
|
44
52
|
def eval_and(args)
|
45
53
|
# Convert all keys to symbols
|
46
|
-
|
54
|
+
if args && args[:attributes]
|
55
|
+
args[:attributes] = args[:attributes].each_with_object({}) { |(k, v), memo| memo[k.to_sym] = v }
|
56
|
+
end
|
47
57
|
@matchers.all? do |matcher|
|
48
58
|
if match_with_key?(matcher)
|
49
59
|
matcher.match?(value: args[:matching_key])
|
@@ -57,28 +67,10 @@ module SplitIoClient
|
|
57
67
|
matcher.respond_to?(:attribute) && matcher.attribute.nil? && matcher.string_type?
|
58
68
|
end
|
59
69
|
|
60
|
-
#
|
61
|
-
# evaluates if the given object equals the matcher
|
62
|
-
#
|
63
|
-
# @param obj [object] object to be evaluated
|
64
|
-
#
|
65
|
-
# @returns [boolean] true if obj equals the matcher
|
66
|
-
def equals?(obj)
|
67
|
-
if obj.nil?
|
68
|
-
false
|
69
|
-
elsif !obj.instance_of?(CombiningMatcher)
|
70
|
-
false
|
71
|
-
elsif self.equal?(obj)
|
72
|
-
true
|
73
|
-
else
|
74
|
-
false
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
70
|
#
|
79
71
|
# function to print string value for this matcher
|
80
72
|
#
|
81
|
-
# @
|
73
|
+
# @return [string] string value of this matcher
|
82
74
|
def to_s
|
83
75
|
@matcher_list.map(&:to_s).join("#{@combiner} ")
|
84
76
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
class ContainsAllMatcher < SetMatcher
|
3
|
-
MATCHER_TYPE = 'CONTAINS_ALL'
|
5
|
+
MATCHER_TYPE = 'CONTAINS_ALL'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -9,13 +11,14 @@ module SplitIoClient
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def match?(args)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
if @remote_set.empty?
|
15
|
+
SplitLogger.log_if_debug('[ContainsAllMatcher] Remote Set Empty')
|
16
|
+
return false
|
17
|
+
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
+
matches = @remote_set.subset? local_set(args[:attributes], @attribute)
|
20
|
+
SplitLogger.log_if_debug("[ContainsAllMatcher] Remote Set #{@remote_set} contains #{@attribute} -> #{matches}")
|
21
|
+
matches
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
class ContainsAnyMatcher < SetMatcher
|
3
|
-
MATCHER_TYPE = 'CONTAINS_ANY'
|
5
|
+
MATCHER_TYPE = 'CONTAINS_ANY'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -9,11 +11,10 @@ module SplitIoClient
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def match?(args)
|
12
|
-
local_set(args[:attributes], @attribute).intersect? @remote_set
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
false
|
14
|
+
matches = local_set(args[:attributes], @attribute).intersect? @remote_set
|
15
|
+
SplitLogger.log_if_debug("[ContainsAnyMatcher] Remote Set #{@remote_set} contains any \
|
16
|
+
#{@attribute} or #{args[:attributes]}-> #{matches}")
|
17
|
+
matches
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
class ContainsMatcher
|
3
|
-
MATCHER_TYPE = 'CONTAINS_WITH'
|
5
|
+
MATCHER_TYPE = 'CONTAINS_WITH'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -10,21 +12,30 @@ module SplitIoClient
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def match?(args)
|
13
|
-
|
14
|
-
return false if args.key?(:value) && args[:value].nil?
|
15
|
-
return false if args.key?(:attributes) && args[:attributes].nil?
|
15
|
+
SplitLogger.log_if_debug('[ContainsMatcher] evaluating value and attributes.')
|
16
16
|
|
17
|
-
|
18
|
-
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
19
|
-
end
|
17
|
+
return false unless SplitIoClient::Validators.valid_matcher_arguments(args)
|
20
18
|
|
19
|
+
value = get_value(args)
|
20
|
+
|
21
|
+
SplitLogger.log_if_debug("[ContainsMatcher] Value from parameters: #{value}.")
|
21
22
|
return false if @substr_list.empty?
|
22
23
|
|
23
|
-
@substr_list.any? { |substr| value.to_s.include? substr }
|
24
|
+
matches = @substr_list.any? { |substr| value.to_s.include? substr }
|
25
|
+
SplitLogger.log_if_debug("[ContainsMatcher] #{@value} contains any of #{@substr_list} -> #{matches} .")
|
26
|
+
matches
|
24
27
|
end
|
25
28
|
|
26
29
|
def string_type?
|
27
30
|
true
|
28
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def get_value(args)
|
36
|
+
args[:value] || args[:attributes].fetch(@attribute) do |a|
|
37
|
+
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
38
|
+
end
|
39
|
+
end
|
29
40
|
end
|
30
41
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
class DependencyMatcher
|
3
|
-
MATCHER_TYPE = 'IN_SPLIT_TREATMENT'
|
5
|
+
MATCHER_TYPE = 'IN_SPLIT_TREATMENT'
|
4
6
|
|
5
7
|
def initialize(split, treatments)
|
6
8
|
@split = split
|
@@ -9,8 +11,11 @@ module SplitIoClient
|
|
9
11
|
|
10
12
|
def match?(args)
|
11
13
|
keys = { matching_key: args[:matching_key], bucketing_key: args[:bucketing_key] }
|
12
|
-
|
13
|
-
@treatments.include?(
|
14
|
+
evaluate = args[:evaluator].call(keys, @split, args[:attributes])
|
15
|
+
matches = @treatments.include?(evaluate[:treatment])
|
16
|
+
SplitLogger.log_if_debug("[dependencyMatcher] Parent split #{@split} evaluated to #{evaluate[:treatment]} \
|
17
|
+
with label #{evaluate[:label]}. #{@split} evaluated treatment is part of [#{@treatments}] ? #{matches}.")
|
18
|
+
matches
|
14
19
|
end
|
15
20
|
|
16
21
|
def string_type?
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
class EndsWithMatcher
|
3
|
-
MATCHER_TYPE = 'ENDS_WITH'
|
5
|
+
MATCHER_TYPE = 'ENDS_WITH'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -10,17 +12,30 @@ module SplitIoClient
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def match?(args)
|
13
|
-
value = args
|
14
|
-
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
15
|
-
end
|
15
|
+
value = get_value(args)
|
16
16
|
|
17
|
-
|
17
|
+
SplitLogger.log_if_debug("[EndsWithMatcher] Value from parameters: #{value}.")
|
18
|
+
|
19
|
+
if @suffix_list.empty?
|
20
|
+
SplitLogger.log_if_debug('[EndsWithMatcher] Sufix List empty.')
|
21
|
+
return false
|
22
|
+
end
|
18
23
|
|
19
|
-
@suffix_list.any? { |suffix| value.to_s.end_with? suffix }
|
24
|
+
matches = @suffix_list.any? { |suffix| value.to_s.end_with? suffix }
|
25
|
+
SplitLogger.log_if_debug("[EndsWithMatcher] #{value} ends with any #{@suffix_list}")
|
26
|
+
matches
|
20
27
|
end
|
21
28
|
|
22
29
|
def string_type?
|
23
30
|
true
|
24
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def get_value(args)
|
36
|
+
args[:value] || args[:attributes].fetch(@attribute) do |a|
|
37
|
+
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
38
|
+
end
|
39
|
+
end
|
25
40
|
end
|
26
41
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
class EqualToBooleanMatcher
|
3
|
-
MATCHER_TYPE = 'EQUAL_TO_BOOLEAN'
|
5
|
+
MATCHER_TYPE = 'EQUAL_TO_BOOLEAN'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -10,18 +12,25 @@ module SplitIoClient
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def match?(args)
|
13
|
-
value = args
|
14
|
-
|
15
|
-
|
15
|
+
value = get_value(args)
|
16
|
+
value = false if value.to_s.casecmp('false').zero?
|
17
|
+
value = true if value.to_s.casecmp('true').zero?
|
16
18
|
|
17
|
-
|
18
|
-
value
|
19
|
-
|
20
|
-
value == @boolean
|
19
|
+
matches = value == @boolean
|
20
|
+
SplitLogger.log_if_debug("[EqualToBooleanMatcher] #{value} equals to #{@boolean} -> #{matches}")
|
21
|
+
matches
|
21
22
|
end
|
22
23
|
|
23
24
|
def string_type?
|
24
25
|
false
|
25
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def get_value(args)
|
31
|
+
args[:attributes].fetch(@attribute) do |a|
|
32
|
+
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
33
|
+
end
|
34
|
+
end
|
26
35
|
end
|
27
36
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
|
-
class EqualToMatcher
|
3
|
-
MATCHER_TYPE = 'EQUAL_TO'
|
4
|
+
class EqualToMatcher < Matcher
|
5
|
+
MATCHER_TYPE = 'EQUAL_TO'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -11,29 +13,15 @@ module SplitIoClient
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def match?(args)
|
14
|
-
|
15
|
-
return false if args.key?(:value) && args[:value].nil?
|
16
|
-
return false if args.key?(:attributes) && args[:attributes].nil?
|
17
|
-
|
18
|
-
value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
|
16
|
+
SplitLogger.log_if_debug('[EqualsToMatcher] evaluating value and attributes.')
|
19
17
|
|
20
|
-
|
21
|
-
end
|
18
|
+
return false unless SplitIoClient::Validators.valid_matcher_arguments(args)
|
22
19
|
|
23
|
-
|
24
|
-
if obj.nil?
|
25
|
-
false
|
26
|
-
elsif !obj.instance_of?(EqualToMatcher)
|
27
|
-
false
|
28
|
-
elsif self.equal?(obj)
|
29
|
-
true
|
30
|
-
else
|
31
|
-
false
|
32
|
-
end
|
33
|
-
end
|
20
|
+
value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
|
34
21
|
|
35
|
-
|
36
|
-
|
22
|
+
matches = value.is_a?(Integer) ? (value == @value) : false
|
23
|
+
SplitLogger.log_if_debug("[EqualsToMatcher] #{value} equals to #{@value} -> #{matches}")
|
24
|
+
matches
|
37
25
|
end
|
38
26
|
|
39
27
|
private
|
@@ -43,7 +31,7 @@ module SplitIoClient
|
|
43
31
|
when 'NUMBER'
|
44
32
|
value
|
45
33
|
when 'DATETIME'
|
46
|
-
value
|
34
|
+
value /= 1000 if sdk_data
|
47
35
|
|
48
36
|
SplitIoClient::Utilities.to_milis_zero_out_from_hour value
|
49
37
|
else
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
class EqualToSetMatcher < SetMatcher
|
3
|
-
MATCHER_TYPE = 'EQUAL_TO_SET'
|
5
|
+
MATCHER_TYPE = 'EQUAL_TO_SET'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -9,11 +11,10 @@ module SplitIoClient
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def match?(args)
|
12
|
-
local_set(args[:attributes], @attribute)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
false
|
14
|
+
set = local_set(args[:attributes], @attribute)
|
15
|
+
matches = set == @remote_set
|
16
|
+
SplitLogger.log_if_debug("[EqualsToSetMatcher] #{set} equals to #{@remote_set} -> #{matches}")
|
17
|
+
matches
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
|
-
class GreaterThanOrEqualToMatcher
|
3
|
-
MATCHER_TYPE = 'GREATER_THAN_OR_EQUAL_TO'
|
4
|
+
class GreaterThanOrEqualToMatcher < Matcher
|
5
|
+
MATCHER_TYPE = 'GREATER_THAN_OR_EQUAL_TO'
|
4
6
|
|
5
7
|
attr_reader :attribute
|
6
8
|
|
@@ -11,29 +13,15 @@ module SplitIoClient
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def match?(args)
|
14
|
-
|
15
|
-
return false if args.key?(:value) && args[:value].nil?
|
16
|
-
return false if args.key?(:attributes) && args[:attributes].nil?
|
17
|
-
|
18
|
-
value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
|
16
|
+
SplitLogger.log_if_debug('[GreaterThanOrEqualToMatcher] evaluating value and attributes.')
|
19
17
|
|
20
|
-
|
21
|
-
end
|
18
|
+
return false unless SplitIoClient::Validators.valid_matcher_arguments(args)
|
22
19
|
|
23
|
-
|
24
|
-
if obj.nil?
|
25
|
-
false
|
26
|
-
elsif !obj.instance_of?(GreaterThanOrEqualToMatcher)
|
27
|
-
false
|
28
|
-
elsif self.equal?(obj)
|
29
|
-
true
|
30
|
-
else
|
31
|
-
false
|
32
|
-
end
|
33
|
-
end
|
20
|
+
value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
|
34
21
|
|
35
|
-
|
36
|
-
|
22
|
+
matches = value.is_a?(Integer) ? (value >= @value) : false
|
23
|
+
SplitLogger.log_if_debug("[GreaterThanOrEqualToMatcher] #{value} greater than or equal to #{@value} -> #{matches}")
|
24
|
+
matches
|
37
25
|
end
|
38
26
|
|
39
27
|
private
|
@@ -41,10 +29,10 @@ module SplitIoClient
|
|
41
29
|
def formatted_value(value, sdk_data = false)
|
42
30
|
case @data_type
|
43
31
|
when 'NUMBER'
|
44
|
-
|
32
|
+
value
|
45
33
|
when 'DATETIME'
|
46
|
-
value
|
47
|
-
|
34
|
+
value /= 1000 if sdk_data # sdk returns already miliseconds, turning to seconds to do a correct zero_hour
|
35
|
+
SplitIoClient::Utilities.to_milis_zero_out_from_seconds(value)
|
48
36
|
else
|
49
37
|
@logger.error('Invalid data type')
|
50
38
|
end
|