Skip to content

Commit 91b9266

Browse files
authored
Merge pull request #532 from splitio/Feature/Semver
Feature/semver
2 parents 6eafede + 2a54d08 commit 91b9266

29 files changed

+1378
-3
lines changed

lib/splitclient-rb.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@
9090
require 'splitclient-rb/engine/matchers/equal_to_boolean_matcher'
9191
require 'splitclient-rb/engine/matchers/equal_to_matcher'
9292
require 'splitclient-rb/engine/matchers/matches_string_matcher'
93+
require 'splitclient-rb/engine/matchers/semver'
94+
require 'splitclient-rb/engine/matchers/equal_to_semver_matcher'
95+
require 'splitclient-rb/engine/matchers/greater_than_or_equal_to_semver_matcher'
96+
require 'splitclient-rb/engine/matchers/less_than_or_equal_to_semver_matcher'
97+
require 'splitclient-rb/engine/matchers/between_semver_matcher'
98+
require 'splitclient-rb/engine/matchers/in_list_semver_matcher'
9399
require 'splitclient-rb/engine/evaluator/splitter'
94100
require 'splitclient-rb/engine/impressions/noop_unique_keys_tracker'
95101
require 'splitclient-rb/engine/impressions/unique_keys_tracker'

lib/splitclient-rb/cache/repositories/splits_repository.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ class SplitsRepository < Repository
2929
size: 100
3030
}
3131
],
32-
label: "unsupported matcher type"
33-
}]
32+
label: "targeting rule type unsupported by sdk"
33+
}]
34+
3435
def initialize(config, flag_sets_repository, flag_set_filter)
3536
super(config)
3637
@tt_cache = {}

lib/splitclient-rb/engine/api/splits.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ def since(since, fetch_options = { cache_control_headers: false, till: nil, sets
1616
start = Time.now
1717

1818
params = { s: SplitIoClient::Spec::FeatureFlags::SPEC_VERSION, since: since }
19-
params[:till] = fetch_options[:till] unless fetch_options[:till].nil?
2019
params[:sets] = @flag_sets_filter.join(",") unless @flag_sets_filter.empty?
20+
params[:till] = fetch_options[:till] unless fetch_options[:till].nil?
2121
@config.logger.debug("Fetching from splitChanges with #{params}: ")
2222
response = get_api("#{@config.base_uri}/splitChanges", @api_key, params, fetch_options[:cache_control_headers])
2323
if response.status == 414
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
module SplitIoClient
4+
class BetweenSemverMatcher < Matcher
5+
MATCHER_TYPE = 'BETWEEN_SEMVER'
6+
7+
attr_reader :attribute
8+
9+
def initialize(attribute, start_value, end_value, logger, validator)
10+
super(logger)
11+
@validator = validator
12+
@attribute = attribute
13+
@semver_start = SplitIoClient::Semver.build(start_value, logger)
14+
@semver_end = SplitIoClient::Semver.build(end_value, logger)
15+
@logger = logger
16+
end
17+
18+
def match?(args)
19+
return false unless verify_semver_arg?(args, 'BetweenSemverMatcher')
20+
21+
value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
22+
if value_to_match.nil? || @semver_start.nil? || @semver_end.nil?
23+
@logger.error('betweenStringMatcherData is required for BETWEEN_SEMVER matcher type')
24+
return false
25+
26+
end
27+
matches = ([0, -1].include?(@semver_start.compare(value_to_match)) &&
28+
[0, 1].include?(@semver_end.compare(value_to_match)))
29+
@logger.debug("[BetweenMatcher] #{value_to_match} matches -> #{matches}")
30+
matches
31+
end
32+
end
33+
end
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
module SplitIoClient
4+
class EqualToSemverMatcher < Matcher
5+
MATCHER_TYPE = 'EQUAL_TO_SEMVER'
6+
7+
attr_reader :attribute
8+
9+
def initialize(attribute, string_value, logger, validator)
10+
super(logger)
11+
@validator = validator
12+
@attribute = attribute
13+
@semver = SplitIoClient::Semver.build(string_value, logger)
14+
@logger = logger
15+
end
16+
17+
def match?(args)
18+
return false unless verify_semver_arg?(args, 'EqualsToSemverMatcher')
19+
20+
value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
21+
return false unless check_semver_value_to_match(value_to_match, MATCHER_TYPE)
22+
23+
matches = (@semver.version == value_to_match.version)
24+
@logger.debug("[EqualsToSemverMatcher] #{value_to_match} matches -> #{matches}")
25+
matches
26+
end
27+
end
28+
end
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
module SplitIoClient
4+
class GreaterThanOrEqualToSemverMatcher < Matcher
5+
MATCHER_TYPE = 'GREATER_THAN_OR_EQUAL_TO_SEMVER'
6+
7+
attr_reader :attribute
8+
9+
def initialize(attribute, string_value, logger, validator)
10+
super(logger)
11+
@validator = validator
12+
@attribute = attribute
13+
@semver = SplitIoClient::Semver.build(string_value, logger)
14+
@logger = logger
15+
end
16+
17+
def match?(args)
18+
return false unless verify_semver_arg?(args, 'GreaterThanOrEqualsToSemverMatcher')
19+
20+
value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
21+
return false unless check_semver_value_to_match(value_to_match, MATCHER_TYPE)
22+
23+
matches = [0, 1].include?(value_to_match.compare(@semver))
24+
@logger.debug("[GreaterThanOrEqualsToSemverMatcher] #{value_to_match} matches -> #{matches}")
25+
matches
26+
end
27+
end
28+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
module SplitIoClient
4+
class InListSemverMatcher < Matcher
5+
MATCHER_TYPE = 'IN_LIST_SEMVER'
6+
7+
attr_reader :attribute
8+
9+
def initialize(attribute, list_value, logger, validator)
10+
super(logger)
11+
@validator = validator
12+
@attribute = attribute
13+
@semver_list = []
14+
15+
list_value.map do |item|
16+
version = SplitIoClient::Semver.build(item, logger)
17+
@semver_list << version unless version.nil?
18+
end
19+
@logger = logger
20+
end
21+
22+
def match?(args)
23+
return false if @semver_list.empty? || !verify_semver_arg?(args, 'InListSemverMatcher')
24+
25+
value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
26+
if value_to_match.nil?
27+
@logger.error('whitelistMatcherData is required for IN_LIST_SEMVER matcher type')
28+
return false
29+
30+
end
31+
matches = (@semver_list.map { |item| item.version == value_to_match.version }).any? { |item| item == true }
32+
@logger.debug("[InListSemverMatcher] #{value_to_match} matches -> #{matches}")
33+
matches
34+
end
35+
end
36+
end
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
module SplitIoClient
4+
class LessThanOrEqualToSemverMatcher < Matcher
5+
MATCHER_TYPE = 'LESS_THAN_OR_EQUAL_TO_SEMVER'
6+
7+
attr_reader :attribute
8+
9+
def initialize(attribute, string_value, logger, validator)
10+
super(logger)
11+
@validator = validator
12+
@attribute = attribute
13+
@semver = SplitIoClient::Semver.build(string_value, logger)
14+
@logger = logger
15+
end
16+
17+
def match?(args)
18+
return false unless verify_semver_arg?(args, 'LessThanOrEqualsToSemverMatcher')
19+
20+
value_to_match = SplitIoClient::Semver.build(args[:attributes][@attribute.to_sym], @logger)
21+
return false unless check_semver_value_to_match(value_to_match, MATCHER_TYPE)
22+
23+
matches = [0, -1].include?(value_to_match.compare(@semver))
24+
@logger.debug("[LessThanOrEqualsToSemverMatcher] #{value_to_match} matches -> #{matches}")
25+
matches
26+
end
27+
end
28+
end

lib/splitclient-rb/engine/matchers/matcher.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,23 @@ def equals?(obj)
3030
def string_type?
3131
false
3232
end
33+
34+
private
35+
36+
def verify_semver_arg?(args, matcher_name)
37+
@logger.debug("[#{matcher_name}] evaluating value and attributes.")
38+
return false unless @validator.valid_matcher_arguments(args)
39+
40+
true
41+
end
42+
43+
def check_semver_value_to_match(value_to_match, matcher_spec_name)
44+
if value_to_match.nil? || @semver.nil?
45+
@logger.error("stringMatcherData is required for #{matcher_spec_name} matcher type")
46+
return false
47+
48+
end
49+
true
50+
end
3351
end
3452
end

0 commit comments

Comments
 (0)