splitclient-rb 6.0.1 → 6.1.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -1
  3. data/.simplecov +1 -0
  4. data/README.md +2 -2
  5. data/lib/splitclient-rb.rb +1 -0
  6. data/lib/splitclient-rb/clients/split_client.rb +30 -9
  7. data/lib/splitclient-rb/engine/api/client.rb +8 -9
  8. data/lib/splitclient-rb/engine/api/events.rb +4 -2
  9. data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +10 -8
  10. data/lib/splitclient-rb/engine/api/impressions.rb +4 -2
  11. data/lib/splitclient-rb/engine/api/metrics.rb +5 -5
  12. data/lib/splitclient-rb/engine/api/segments.rb +5 -1
  13. data/lib/splitclient-rb/engine/api/splits.rb +4 -4
  14. data/lib/splitclient-rb/engine/matchers/all_keys_matcher.rb +8 -13
  15. data/lib/splitclient-rb/engine/matchers/between_matcher.rb +12 -23
  16. data/lib/splitclient-rb/engine/matchers/combiners.rb +3 -1
  17. data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +16 -24
  18. data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +10 -7
  19. data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +7 -6
  20. data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +19 -8
  21. data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +8 -3
  22. data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +21 -6
  23. data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +17 -8
  24. data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +11 -23
  25. data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +7 -6
  26. data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +13 -25
  27. data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +13 -25
  28. data/lib/splitclient-rb/engine/matchers/matcher.rb +30 -0
  29. data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +6 -2
  30. data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +8 -22
  31. data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +10 -7
  32. data/lib/splitclient-rb/engine/matchers/set_matcher.rb +7 -1
  33. data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +18 -5
  34. data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +7 -25
  35. data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +33 -35
  36. data/lib/splitclient-rb/managers/split_manager.rb +10 -3
  37. data/lib/splitclient-rb/split_config.rb +34 -9
  38. data/lib/splitclient-rb/split_factory.rb +27 -0
  39. data/lib/splitclient-rb/validators.rb +104 -36
  40. data/lib/splitclient-rb/version.rb +1 -1
  41. metadata +6 -4
@@ -1,5 +1,6 @@
1
1
  module SplitIoClient
2
2
  class SplitFactory
3
+ ROOT_PROCESS_ID = Process.pid
3
4
  include SplitIoClient::Cache::Repositories
4
5
  include SplitIoClient::Cache::Stores
5
6
 
@@ -25,7 +26,21 @@ module SplitIoClient
25
26
  @client = SplitClient.new(@api_key, @adapter, @splits_repository, @segments_repository, @impressions_repository, @metrics_repository, @events_repository)
26
27
  @manager = SplitManager.new(@api_key, @adapter, @splits_repository)
27
28
 
29
+ validate_api_key
30
+
28
31
  @sdk_blocker.block if SplitIoClient.configuration.block_until_ready > 0
32
+
33
+
34
+ at_exit do
35
+ unless ENV['SPLITCLIENT_ENV'] == 'test'
36
+ if (Process.pid == ROOT_PROCESS_ID)
37
+ SplitIoClient.configuration.logger.info('Split SDK shutdown started...')
38
+ @client.destroy
39
+ stop!
40
+ SplitIoClient.configuration.logger.info('Split SDK shutdown complete')
41
+ end
42
+ end
43
+ end
29
44
  end
30
45
 
31
46
  def start!
@@ -65,5 +80,17 @@ module SplitIoClient
65
80
  end
66
81
 
67
82
  alias resume! start!
83
+
84
+ private
85
+
86
+ def validate_api_key
87
+ if(@api_key.nil?)
88
+ SplitIoClient.configuration.logger.error('Factory Instantiation: you passed a nil api_key, api_key must be a non-empty String')
89
+ SplitIoClient.configuration.valid_mode = false
90
+ elsif (@api_key.empty?)
91
+ SplitIoClient.configuration.logger.error('Factory Instantiation: you passed and empty api_key, api_key must be a non-empty String')
92
+ SplitIoClient.configuration.valid_mode = false
93
+ end
94
+ end
68
95
  end
69
96
  end
@@ -4,11 +4,12 @@ module SplitIoClient
4
4
  module Validators
5
5
  extend self
6
6
 
7
- def valid_get_treatment_parameters(key, split_name, matching_key, bucketing_key)
7
+ def valid_get_treatment_parameters(key, split_name, matching_key, bucketing_key, attributes)
8
8
  valid_key?(key) &&
9
9
  valid_split_name?(split_name) &&
10
10
  valid_matching_key?(matching_key) &&
11
- valid_bucketing_key?(key, bucketing_key)
11
+ valid_bucketing_key?(key, bucketing_key) &&
12
+ valid_attributes?(attributes)
12
13
  end
13
14
 
14
15
  def valid_get_treatments_parameters(split_names)
@@ -26,30 +27,45 @@ module SplitIoClient
26
27
  valid_split_name?(split_name, :split)
27
28
  end
28
29
 
30
+ def valid_matcher_arguments(args)
31
+ return false if !args.key?(:attributes) && !args.key?(:value)
32
+ return false if args.key?(:value) && args[:value].nil?
33
+ return false if args.key?(:attributes) && args[:attributes].nil?
34
+ true
35
+ end
36
+
29
37
  private
30
38
 
31
39
  def string?(value)
32
40
  value.is_a?(String) || value.is_a?(Symbol)
33
41
  end
34
42
 
43
+ def empty_string?(value)
44
+ value.is_a?(String) && value.empty?
45
+ end
46
+
35
47
  def number_or_string?(value)
36
- value.is_a?(Numeric) || string?(value)
48
+ (value.is_a?(Numeric) && !value.to_f.nan?) || string?(value)
37
49
  end
38
50
 
39
51
  def log_nil(key, method)
40
- SplitIoClient.configuration.logger.error("#{method}: #{key} cannot be nil")
52
+ SplitIoClient.configuration.logger.error("#{method}: you passed a nil #{key}, #{key} must be a non-empty String or a Symbol")
41
53
  end
42
54
 
43
- def log_string(key, method)
44
- SplitIoClient.configuration.logger.error("#{method}: #{key} must be a String or a Symbol")
55
+ def log_empty_string(key, method)
56
+ SplitIoClient.configuration.logger.error("#{method}: you passed an empty #{key}, #{key} must be a non-empty String or a Symbol")
45
57
  end
46
58
 
47
- def log_number_or_string(key, method)
48
- SplitIoClient.configuration.logger.error("#{method}: #{key} must be a String")
59
+ def log_invalid_type(key, method)
60
+ SplitIoClient.configuration.logger.error("#{method}: you passed an invalid #{key} type, #{key} must be a non-empty String or a Symbol")
49
61
  end
50
62
 
51
- def log_convert_numeric(key, method)
52
- SplitIoClient.configuration.logger.warn("#{method}: #{key} is not of type String, converting to String")
63
+ def log_convert_numeric(key, method, value)
64
+ SplitIoClient.configuration.logger.warn("#{method}: #{key} \"#{value}\" is not of type String, converting")
65
+ end
66
+
67
+ def log_key_too_long(key, method)
68
+ SplitIoClient.configuration.logger.error("#{method}: #{key} is too long - must be #{SplitIoClient.configuration.max_key_size} characters or less")
53
69
  end
54
70
 
55
71
  def valid_split_name?(split_name, method = :get_treatment)
@@ -59,7 +75,12 @@ module SplitIoClient
59
75
  end
60
76
 
61
77
  unless string?(split_name)
62
- log_string(:split_name, method)
78
+ log_invalid_type(:split_name, method)
79
+ return false
80
+ end
81
+
82
+ if empty_string?(split_name)
83
+ log_empty_string(:split_name, method)
63
84
  return false
64
85
  end
65
86
 
@@ -82,41 +103,65 @@ module SplitIoClient
82
103
  end
83
104
 
84
105
  unless number_or_string?(matching_key)
85
- log_number_or_string(:matching_key, :get_treatment)
106
+ log_invalid_type(:matching_key, :get_treatment)
86
107
  return false
87
108
  end
88
109
 
89
- log_convert_numeric(:matching_key, :get_treatment) if matching_key.is_a? Numeric
110
+ if empty_string?(matching_key)
111
+ log_empty_string(:matching_key, :get_treatment)
112
+ return false
113
+ end
114
+
115
+ log_convert_numeric(:matching_key, :get_treatment, matching_key) if matching_key.is_a? Numeric
116
+
117
+ if matching_key.size > SplitIoClient.configuration.max_key_size
118
+ log_key_too_long(:matching_key, :get_treatment)
119
+ return false
120
+ end
90
121
 
91
122
  true
92
123
  end
93
124
 
94
125
  def valid_bucketing_key?(key, bucketing_key)
95
- if bucketing_key.nil?
96
- if key.is_a? Hash
97
- SplitIoClient.configuration.logger.warn('get_treatment: key object should have bucketing_key set')
126
+ if key.is_a? Hash
127
+ if bucketing_key.nil?
128
+ log_nil(:bucketing_key, :get_treatment)
129
+ return false
98
130
  end
99
- return true
100
- end
101
131
 
102
- unless number_or_string?(bucketing_key)
103
- log_number_or_string(:bucketing_key, :get_treatment)
104
- return false
105
- end
132
+ unless number_or_string?(bucketing_key)
133
+ log_invalid_type(:bucketing_key, :get_treatment)
134
+ return false
135
+ end
106
136
 
107
- log_convert_numeric(:bucketing_key, :get_treatment) if bucketing_key.is_a? Numeric
137
+ if empty_string?(bucketing_key)
138
+ log_empty_string(:bucketing_key, :get_treatment)
139
+ return false
140
+ end
141
+
142
+ log_convert_numeric(:bucketing_key, :get_treatment, bucketing_key) if bucketing_key.is_a? Numeric
143
+
144
+ if bucketing_key.size > SplitIoClient.configuration.max_key_size
145
+ log_key_too_long(:bucketing_key, :get_treatment)
146
+ return false
147
+ end
148
+ end
108
149
 
109
150
  true
110
151
  end
111
152
 
112
153
  def valid_split_names?(split_names)
113
- if split_names.nil?
114
- log_nil(:split_names, :get_treatments)
154
+ unless !split_names.nil? && split_names.is_a?(Array)
155
+ SplitIoClient.configuration.logger.error('get_treatments: split_names must be a non-empty Array')
115
156
  return false
116
157
  end
117
158
 
118
- unless split_names.is_a? Array
119
- SplitIoClient.configuration.logger.warn('get_treatments: split_names must be an Array')
159
+ true
160
+ end
161
+
162
+ def valid_attributes?(attributes)
163
+ unless attributes.nil? || attributes.is_a?(Hash)
164
+ SplitIoClient.configuration.logger.error('get_treatment: attributes must be of type Hash')
120
165
  return false
121
166
  end
122
167
 
@@ -130,11 +175,21 @@ module SplitIoClient
130
175
  end
131
176
 
132
177
  unless number_or_string?(key)
133
- log_number_or_string(:key, :track)
178
+ log_invalid_type(:key, :track)
134
179
  return false
135
180
  end
136
181
 
137
- log_convert_numeric(:key, :track) if key.is_a? Numeric
182
+ if empty_string?(key)
183
+ log_empty_string(:key, :track)
184
+ return false
185
+ end
186
+
187
+ log_convert_numeric(:key, :track, key) if key.is_a? Numeric
188
+
189
+ if key.size > SplitIoClient.configuration.max_key_size
190
+ log_key_too_long(:key, :track)
191
+ return false
192
+ end
138
193
 
139
194
  true
140
195
  end
@@ -146,12 +201,20 @@ module SplitIoClient
146
201
  end
147
202
 
148
203
  unless string?(event_type)
149
- log_string(:event_type, :track)
204
+ log_invalid_type(:event_type, :track)
150
205
  return false
151
206
  end
152
207
 
153
- if (event_type.to_s =~ /[a-zA-Z0-9][-_\.a-zA-Z0-9]{0,62}/).nil?
154
- SplitIoClient.configuration.logger.error('track: event_type must adhere to [a-zA-Z0-9][-_\.a-zA-Z0-9]{0,62}')
208
+ if event_type.empty?
209
+ log_empty_string(:event_type, :track)
210
+ return false
211
+ end
212
+
213
+ if (event_type.to_s =~ /^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$/).nil?
214
+ SplitIoClient.configuration.logger.error("track: you passed '#{event_type}', " \
215
+ 'event_type must adhere to the regular expression ^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$. ' \
216
+ 'This means an event name must be alphanumeric, cannot be more than 80 characters long, ' \
217
+ 'and can only include a dash, underscore, period, or colon as separators of alphanumeric characters')
155
218
  return false
156
219
  end
157
220
 
@@ -165,21 +228,26 @@ module SplitIoClient
165
228
  end
166
229
 
167
230
  unless string?(traffic_type_name)
168
- log_string(:traffic_type_name, :track)
231
+ log_invalid_type(:traffic_type_name, :track)
169
232
  return false
170
233
  end
171
234
 
172
235
  if traffic_type_name.empty?
173
- SplitIoClient.configuration.logger.error('track: traffic_type_name must not be an empty String')
236
+ log_empty_string(:traffic_type_name, :track)
174
237
  return false
175
238
  end
176
239
 
240
+ unless traffic_type_name == traffic_type_name.downcase
241
+ SplitIoClient.configuration.logger.warn('track: traffic_type_name should be all lowercase - ' \
242
+ 'converting string to lowercase')
243
+ end
244
+
177
245
  true
178
246
  end
179
247
 
180
248
  def valid_value?(value)
181
- unless value.is_a?(Numeric) || value.nil?
182
- SplitIoClient.configuration.logger.error('track: value must be a number')
249
+ unless (value.is_a?(Numeric) && !value.to_f.nan?) || value.nil?
250
+ SplitIoClient.configuration.logger.error('track: value must be Numeric')
183
251
  return false
184
252
  end
185
253
 
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '6.0.1'
2
+ VERSION = '6.1.0.pre.rc1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.1
4
+ version: 6.1.0.pre.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-07 00:00:00.000000000 Z
11
+ date: 2019-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allocation_stats
@@ -272,6 +272,7 @@ extra_rdoc_files: []
272
272
  files:
273
273
  - ".gitignore"
274
274
  - ".rubocop.yml"
275
+ - ".simplecov"
275
276
  - CHANGES.txt
276
277
  - Detailed-README.md
277
278
  - Gemfile
@@ -336,6 +337,7 @@ files:
336
337
  - lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb
337
338
  - lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb
338
339
  - lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb
340
+ - lib/splitclient-rb/engine/matchers/matcher.rb
339
341
  - lib/splitclient-rb/engine/matchers/matches_string_matcher.rb
340
342
  - lib/splitclient-rb/engine/matchers/negation_matcher.rb
341
343
  - lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb
@@ -383,9 +385,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
383
385
  version: '0'
384
386
  required_rubygems_version: !ruby/object:Gem::Requirement
385
387
  requirements:
386
- - - ">="
388
+ - - ">"
387
389
  - !ruby/object:Gem::Version
388
- version: '0'
390
+ version: 1.3.1
389
391
  requirements: []
390
392
  rubyforge_project:
391
393
  rubygems_version: 2.7.6