splitclient-rb 6.0.1.pre.rc2-java → 6.1.0-java

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -1
  3. data/.simplecov +1 -0
  4. data/CHANGES.txt +11 -1
  5. data/NEWS +6 -0
  6. data/README.md +2 -2
  7. data/lib/splitclient-rb.rb +1 -0
  8. data/lib/splitclient-rb/clients/split_client.rb +30 -9
  9. data/lib/splitclient-rb/engine/api/client.rb +8 -9
  10. data/lib/splitclient-rb/engine/api/events.rb +4 -2
  11. data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +10 -8
  12. data/lib/splitclient-rb/engine/api/impressions.rb +4 -2
  13. data/lib/splitclient-rb/engine/api/metrics.rb +5 -5
  14. data/lib/splitclient-rb/engine/api/segments.rb +5 -1
  15. data/lib/splitclient-rb/engine/api/splits.rb +4 -4
  16. data/lib/splitclient-rb/engine/matchers/all_keys_matcher.rb +8 -13
  17. data/lib/splitclient-rb/engine/matchers/between_matcher.rb +12 -23
  18. data/lib/splitclient-rb/engine/matchers/combiners.rb +3 -1
  19. data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +16 -24
  20. data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +10 -7
  21. data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +7 -6
  22. data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +19 -8
  23. data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +8 -3
  24. data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +21 -6
  25. data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +17 -8
  26. data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +11 -23
  27. data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +7 -6
  28. data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +13 -25
  29. data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +13 -25
  30. data/lib/splitclient-rb/engine/matchers/matcher.rb +30 -0
  31. data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +6 -2
  32. data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +8 -22
  33. data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +10 -7
  34. data/lib/splitclient-rb/engine/matchers/set_matcher.rb +7 -1
  35. data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +18 -5
  36. data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +7 -25
  37. data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +33 -35
  38. data/lib/splitclient-rb/managers/split_manager.rb +10 -3
  39. data/lib/splitclient-rb/split_config.rb +34 -9
  40. data/lib/splitclient-rb/split_factory.rb +27 -0
  41. data/lib/splitclient-rb/validators.rb +104 -36
  42. data/lib/splitclient-rb/version.rb +1 -1
  43. metadata +6 -4
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
- class BetweenMatcher
3
- MATCHER_TYPE = 'BETWEEN'.freeze
4
+ class BetweenMatcher < Matcher
5
+ MATCHER_TYPE = 'BETWEEN'
4
6
 
5
7
  attr_reader :attribute
6
8
 
@@ -12,30 +14,17 @@ module SplitIoClient
12
14
  end
13
15
 
14
16
  def match?(args)
15
- return false if !args.key?(:attributes) && !args.key?(:value)
16
- return false if args.key?(:value) && args[:value].nil?
17
- return false if args.key?(:attributes) && args[:attributes].nil?
17
+ SplitLogger.log_if_debug('[BetweenMatcher] evaluating value and attributes.')
18
+
19
+ return false unless SplitIoClient::Validators.valid_matcher_arguments(args)
18
20
 
19
21
  value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
22
+ SplitLogger.log_if_debug("[BetweenMatcher] Value from parameters: #{value}.")
20
23
  return false unless value.is_a?(Integer)
21
24
 
22
- (@start_value..@end_value).include? value
23
- end
24
-
25
- def equals?(obj)
26
- if obj.nil?
27
- false
28
- elsif !obj.instance_of?(BetweenMatcher)
29
- false
30
- elsif self.equal?(obj)
31
- true
32
- else
33
- false
34
- end
35
- end
36
-
37
- def string_type?
38
- false
25
+ matches = (@start_value..@end_value).cover? value
26
+ SplitLogger.log_if_debug("[BetweenMatcher] is #{value} between #{@start_value} and #{@end_value} -> #{matches} .")
27
+ matches
39
28
  end
40
29
 
41
30
  private
@@ -45,7 +34,7 @@ module SplitIoClient
45
34
  when 'NUMBER'
46
35
  value
47
36
  when 'DATETIME'
48
- value = value / 1000 if sdk_data
37
+ value /= 1000 if sdk_data
49
38
 
50
39
  SplitIoClient::Utilities.to_milis_zero_out_from_seconds(value)
51
40
  else
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SplitIoClient
2
4
  #
3
5
  # class to represent combiner values
4
6
  #
5
7
  class Combiners
6
8
  # available combiners of the sdk
7
- AND = 'AND'.freeze
9
+ AND = 'AND'
8
10
  end
9
11
  end
@@ -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'.freeze
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
- return false if @matchers.empty?
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
- return eval_and(args)
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
- args[:attributes] = args[:attributes].inject({}){ |memo, (k,v)| memo[k.to_sym] = v; memo } if args && args[:attributes]
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
- # @reutrn [string] string value of this matcher
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'.freeze
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
- return false if @remote_set.empty?
13
-
14
- @remote_set.subset? local_set(args[:attributes], @attribute)
15
- end
14
+ if @remote_set.empty?
15
+ SplitLogger.log_if_debug('[ContainsAllMatcher] Remote Set Empty')
16
+ return false
17
+ end
16
18
 
17
- def string_type?
18
- false
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'.freeze
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
- end
14
-
15
- def string_type?
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'.freeze
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
- return false if !args.key?(:attributes) && !args.key?(:value)
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
- value = args[:value] || args[:attributes].fetch(@attribute) do |a|
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'.freeze
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?(args[:evaluator].call(keys, @split, args[:attributes])[:treatment])
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'.freeze
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[:value] || args[:attributes].fetch(@attribute) do |a|
14
- args[:attributes][a.to_s] || args[:attributes][a.to_sym]
15
- end
15
+ value = get_value(args)
16
16
 
17
- return false if @suffix_list.empty?
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'.freeze
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[:attributes].fetch(@attribute) do |a|
14
- args[:attributes][a.to_s] || args[:attributes][a.to_sym]
15
- end
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
- value = false if value.to_s.downcase == 'false'
18
- value = true if value.to_s.downcase == 'true'
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'.freeze
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
- return false if !args.key?(:attributes) && !args.key?(:value)
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
- value.is_a?(Integer) ? (value == @value) : false
21
- end
18
+ return false unless SplitIoClient::Validators.valid_matcher_arguments(args)
22
19
 
23
- def equals?(obj)
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
- def string_type?
36
- false
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 = value / 1000 if sdk_data
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'.freeze
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) == @remote_set
13
- end
14
-
15
- def string_type?
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