kameleoon-client-ruby 3.3.0 → 3.5.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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kameleoon/configuration/custom_data_info.rb +16 -8
  3. data/lib/kameleoon/configuration/data_file.rb +52 -16
  4. data/lib/kameleoon/configuration/feature_flag.rb +11 -1
  5. data/lib/kameleoon/configuration/rule.rb +4 -0
  6. data/lib/kameleoon/configuration/settings.rb +13 -8
  7. data/lib/kameleoon/configuration/variation_exposition.rb +4 -0
  8. data/lib/kameleoon/data/browser.rb +4 -0
  9. data/lib/kameleoon/data/conversion.rb +4 -0
  10. data/lib/kameleoon/data/cookie.rb +4 -0
  11. data/lib/kameleoon/data/custom_data.rb +11 -3
  12. data/lib/kameleoon/data/data.rb +30 -4
  13. data/lib/kameleoon/data/device.rb +4 -0
  14. data/lib/kameleoon/data/geolocation.rb +5 -0
  15. data/lib/kameleoon/data/kcs_heat.rb +4 -0
  16. data/lib/kameleoon/data/manager/assigned_variation.rb +8 -1
  17. data/lib/kameleoon/data/manager/data_array_storage.rb +7 -0
  18. data/lib/kameleoon/data/manager/data_map_storage.rb +7 -0
  19. data/lib/kameleoon/data/manager/page_view_visit.rb +4 -0
  20. data/lib/kameleoon/data/manager/visitor.rb +197 -73
  21. data/lib/kameleoon/data/manager/visitor_manager.rb +54 -17
  22. data/lib/kameleoon/data/mapping_identifier.rb +33 -0
  23. data/lib/kameleoon/data/operating_system.rb +4 -0
  24. data/lib/kameleoon/data/page_view.rb +6 -1
  25. data/lib/kameleoon/data/unique_identifier.rb +11 -0
  26. data/lib/kameleoon/data/user_agent.rb +4 -0
  27. data/lib/kameleoon/data/visitor_visits.rb +4 -0
  28. data/lib/kameleoon/hybrid/manager.rb +19 -7
  29. data/lib/kameleoon/kameleoon_client.rb +477 -178
  30. data/lib/kameleoon/kameleoon_client_config.rb +65 -18
  31. data/lib/kameleoon/kameleoon_client_factory.rb +15 -2
  32. data/lib/kameleoon/logging/default_logger.rb +20 -0
  33. data/lib/kameleoon/logging/kameleoon_logger.rb +77 -0
  34. data/lib/kameleoon/logging/logger.rb +12 -0
  35. data/lib/kameleoon/managers/data/data_manager.rb +36 -0
  36. data/lib/kameleoon/managers/remote_data/remote_data_manager.rb +32 -15
  37. data/lib/kameleoon/managers/tracking/tracking_builder.rb +149 -0
  38. data/lib/kameleoon/managers/tracking/tracking_manager.rb +98 -0
  39. data/lib/kameleoon/managers/tracking/visitor_tracking_registry.rb +94 -0
  40. data/lib/kameleoon/managers/warehouse/warehouse_manager.rb +22 -5
  41. data/lib/kameleoon/network/access_token_source.rb +46 -14
  42. data/lib/kameleoon/network/cookie/cookie_manager.rb +46 -7
  43. data/lib/kameleoon/network/net_provider.rb +2 -3
  44. data/lib/kameleoon/network/network_manager.rb +17 -21
  45. data/lib/kameleoon/network/request.rb +14 -3
  46. data/lib/kameleoon/network/response.rb +4 -0
  47. data/lib/kameleoon/network/url_provider.rb +3 -3
  48. data/lib/kameleoon/real_time/real_time_configuration_service.rb +10 -11
  49. data/lib/kameleoon/sdk_version.rb +31 -0
  50. data/lib/kameleoon/targeting/condition.rb +4 -2
  51. data/lib/kameleoon/targeting/conditions/browser_condition.rb +3 -3
  52. data/lib/kameleoon/targeting/conditions/cookie_condition.rb +10 -10
  53. data/lib/kameleoon/targeting/conditions/geolocation_condition.rb +0 -1
  54. data/lib/kameleoon/targeting/conditions/number_condition.rb +4 -4
  55. data/lib/kameleoon/targeting/conditions/operating_system_condition.rb +1 -2
  56. data/lib/kameleoon/targeting/conditions/sdk_language_condition.rb +2 -1
  57. data/lib/kameleoon/targeting/conditions/segment_condition.rb +3 -3
  58. data/lib/kameleoon/targeting/conditions/string_value_condition.rb +2 -1
  59. data/lib/kameleoon/targeting/models.rb +0 -14
  60. data/lib/kameleoon/targeting/targeting_manager.rb +35 -7
  61. data/lib/kameleoon/targeting/tree_builder.rb +10 -5
  62. data/lib/kameleoon/types/remote_visitor_data_filter.rb +13 -0
  63. data/lib/kameleoon/types/variable.rb +4 -0
  64. data/lib/kameleoon/types/variation.rb +8 -0
  65. data/lib/kameleoon/utils.rb +49 -0
  66. data/lib/kameleoon/version.rb +1 -27
  67. metadata +12 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '019ae7a1fe145f50f68beea1eb05bcae993d4061a2b1bdb2fe4324fc4215aa39'
4
- data.tar.gz: fe9637047ba81b006c1b19a4c85e82fa5641a4d3f666fe14cb28ee243076b6ac
3
+ metadata.gz: 283250365ae9bf4087ebffeb7a4de0e31cca91f06a865cdd4ad2cae1f88c692c
4
+ data.tar.gz: 31ab8ddbd1ef7524b41019a0afe442a47ee5b5e9e1d50649ed04aab625d7c3a3
5
5
  SHA512:
6
- metadata.gz: 5455718dd4a68c584c280e4004ff1c96e28b35d7bfcd9bd8299c68b9d0f3930bd064e16057ce71bbfc386911f106839f54a6398165e6966cad5ce5a4388ccbe9
7
- data.tar.gz: 7a2e231a4625c642a56354615999543c26d7e882d8fc7a2c743f7f4f045d01bc88d5dafd227757fd88f308053610f22f21bfa6cbadd79eafe2b7f2bc3a5e03b7
6
+ metadata.gz: 23f61dd193ad1bb7477ee44e0e2eb5c16bec625748b9ebdde37a9a6b9e71a4610a98c218a4e76addb66a5a55ecf2bcae1764f2aac8d9f9f8ebb6bbc3be86e318
7
+ data.tar.gz: d27d91e39fb5bc968ba414016642de07baef8ef7888f1d93969ae5fb67f07b903ba60b981de9387fa5c6eb20e99bd647d965fea0123841348f67a8aa66840f99
@@ -1,25 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'kameleoon/logging/kameleoon_logger'
4
+
3
5
  module Kameleoon
4
6
  # Module which contains all internal data of SDK
5
7
  module Configuration
6
-
7
8
  class CustomDataInfo
8
9
  attr_reader :local_only, :visitor_scope, :mapping_identifier_index
10
+
9
11
  SCOPE_VISITOR = 'VISITOR'
10
12
 
11
- def initialize(hashes, log_func = nil)
13
+ def initialize(hashes)
12
14
  @local_only = Set[]
13
15
  @visitor_scope = Set[]
14
- @log_func = log_func
15
16
  unless hashes.nil?
16
17
  for hash in hashes
17
18
  index = hash['index']
18
19
  @local_only.add(index) if hash['localOnly']
19
20
  @visitor_scope.add(index) if hash['scope'] == SCOPE_VISITOR
20
21
  if hash['isMappingIdentifier']
21
- if @mapping_identifier_index != nil
22
- @log_func&.call('More than one mapping identifier is set. Undefined behavior may occur on cross-device reconciliation.')
22
+ unless @mapping_identifier_index.nil?
23
+ Logging::KameleoonLogger.warning('More than one mapping identifier is set. Undefined behavior ' \
24
+ 'may occur on cross-device reconciliation.')
25
+
23
26
  end
24
27
  @mapping_identifier_index = index
25
28
  end
@@ -27,17 +30,22 @@ module Kameleoon
27
30
  end
28
31
  end
29
32
 
30
- def local_only? (index)
33
+ def local_only?(index)
31
34
  @local_only.include?(index)
32
35
  end
33
36
 
34
- def mapping_identifier? (index)
37
+ def mapping_identifier?(index)
35
38
  index == @mapping_identifier_index
36
39
  end
37
40
 
38
- def visitor_scope? (index)
41
+ def visitor_scope?(index)
39
42
  @visitor_scope.include?(index)
40
43
  end
44
+
45
+ def self.mapping_identifier?(custom_data_info, custom_data)
46
+ !custom_data_info.nil? && (custom_data.id == custom_data_info.mapping_identifier_index) && \
47
+ !(custom_data.values.empty? || custom_data.values[0].empty?)
48
+ end
41
49
  end
42
50
  end
43
51
  end
@@ -3,32 +3,32 @@
3
3
  require 'kameleoon/configuration/settings'
4
4
  require 'kameleoon/configuration/feature_flag'
5
5
  require 'kameleoon/configuration/custom_data_info'
6
+ require 'kameleoon/logging/kameleoon_logger'
6
7
 
7
8
  module Kameleoon
8
9
  module Configuration
9
10
  class DataFile
10
11
  attr_reader :settings, :feature_flags, :has_any_targeted_delivery_rule, :feature_flag_by_id, :rule_by_segment_id,
11
- :variation_by_id, :custom_data_info
12
+ :variation_by_id, :custom_data_info, :experiment_ids_with_js_css_variable
12
13
 
13
- def initialize(environment, log_func = nil)
14
- @settings = Settings.new
15
- @feature_flags = {}
16
- @environment = environment
17
- @log_func = log_func
18
- collect_indices
19
- @custom_data_info = Kameleoon::Configuration::CustomDataInfo.new(nil, @log_func)
14
+ def to_s
15
+ 'DataFile{' \
16
+ "environment:#{@environment}," \
17
+ "feature_flags:#{@feature_flags.size}," \
18
+ "settings:#{@settings}" \
19
+ '}'
20
20
  end
21
21
 
22
- def init(configuration)
23
- @settings.update(configuration['configuration'])
24
- configuration['featureFlags'].each do |raw|
25
- ff = FeatureFlag.new(raw)
26
- @feature_flags[ff.feature_key] = ff
22
+ def initialize(environment, configuration = nil)
23
+ Logging::KameleoonLogger.debug('CALL: DataFile.new(environment: %s)', environment)
24
+ @environment = environment
25
+ if configuration.nil?
26
+ init_default
27
+ else
28
+ init(configuration)
27
29
  end
28
- @has_any_targeted_delivery_rule = any_targeted_delivery_rule?
29
30
  collect_indices
30
- @custom_data_info = CustomDataInfo.new(configuration['customData'], @log_func)
31
- self
31
+ Logging::KameleoonLogger.debug('RETURN: DataFile.new(environment: %s)', environment)
32
32
  end
33
33
 
34
34
  def get_feature_flag(feature_key)
@@ -39,8 +39,34 @@ module Kameleoon
39
39
  ff
40
40
  end
41
41
 
42
+ def experiment_js_css_variable?(experiment_id)
43
+ @experiment_ids_with_js_css_variable.include?(experiment_id)
44
+ end
45
+
42
46
  private
43
47
 
48
+ def init_default
49
+ Logging::KameleoonLogger.debug('CALL: DataFile.init_default')
50
+ @settings = Settings.new
51
+ @feature_flags = {}
52
+ @has_any_targeted_delivery_rule = false
53
+ @custom_data_info = Kameleoon::Configuration::CustomDataInfo.new(nil)
54
+ Logging::KameleoonLogger.debug('RETURN: DataFile.init_default')
55
+ end
56
+
57
+ def init(configuration)
58
+ Logging::KameleoonLogger.debug('CALL: DataFile.init(configuration: %s)', configuration)
59
+ @settings = Settings.new(configuration['configuration'])
60
+ @feature_flags = {}
61
+ configuration['featureFlags'].each do |raw|
62
+ ff = FeatureFlag.new(raw)
63
+ @feature_flags[ff.feature_key] = ff
64
+ end
65
+ @has_any_targeted_delivery_rule = any_targeted_delivery_rule?
66
+ @custom_data_info = CustomDataInfo.new(configuration['customData'])
67
+ Logging::KameleoonLogger.debug('RETURN: DataFile.init(configuration: %s)', configuration)
68
+ end
69
+
44
70
  def any_targeted_delivery_rule?
45
71
  @feature_flags.any? { |_, ff| ff.environment_enabled && ff.rules.any?(&:targeted_delivery_type?) }
46
72
  end
@@ -49,21 +75,31 @@ module Kameleoon
49
75
  @feature_flag_by_id = {}
50
76
  @rule_by_segment_id = {}
51
77
  @variation_by_id = {}
78
+ @experiment_ids_with_js_css_variable = Set.new
52
79
 
53
80
  @feature_flags.each_value do |feature_flag|
54
81
  @feature_flag_by_id[feature_flag.id] = feature_flag
55
82
  next if feature_flag.rules.nil?
56
83
 
84
+ has_feature_flag_variable_js_css = feature_flag_variable_js_css?(feature_flag)
57
85
  feature_flag.rules.each do |rule|
58
86
  @rule_by_segment_id[rule.segment_id] = rule
59
87
  rule.variation_by_exposition.each do |variation|
60
88
  @variation_by_id[variation.variation_id] = variation
61
89
  end
90
+ @experiment_ids_with_js_css_variable.add(rule.experiment_id) if has_feature_flag_variable_js_css
62
91
  end
63
92
  end
64
93
  @feature_flag_by_id.freeze
65
94
  @rule_by_segment_id.freeze
66
95
  @variation_by_id.freeze
96
+ @experiment_ids_with_js_css_variable.freeze
97
+ end
98
+
99
+ def feature_flag_variable_js_css?(feature_flag)
100
+ feature_flag.variations.first&.variables&.any? do |variable|
101
+ %w[JS CSS].include?(variable.type)
102
+ end
67
103
  end
68
104
  end
69
105
  end
@@ -14,6 +14,16 @@ module Kameleoon
14
14
  array&.map { |it| FeatureFlag.new(it) }
15
15
  end
16
16
 
17
+ def to_s
18
+ 'FeatureFlag{' \
19
+ "id:#{@id}, " \
20
+ "feature_key:#{@feature_key}, " \
21
+ "environment_enabled:#{@environment_enabled}, " \
22
+ "default_variation_key:#{@default_variation_key}, " \
23
+ "rules:#{@rules.size}" \
24
+ '}'
25
+ end
26
+
17
27
  def initialize(hash)
18
28
  @id = hash['id']
19
29
  @feature_key = hash['featureKey']
@@ -23,7 +33,7 @@ module Kameleoon
23
33
  @rules = Rule.create_from_array(hash['rules'])
24
34
  end
25
35
 
26
- def get_variation_key(key)
36
+ def get_variation_by_key(key)
27
37
  variations.select { |v| v.key == key }.first
28
38
  end
29
39
  end
@@ -36,6 +36,10 @@ module Kameleoon
36
36
  array&.map { |it| Rule.new(it) }
37
37
  end
38
38
 
39
+ def to_s
40
+ "Rule{id:#{@id}}"
41
+ end
42
+
39
43
  def initialize(hash)
40
44
  @id = hash['id']
41
45
  @order = hash['order']
@@ -9,16 +9,21 @@ module Kameleoon
9
9
  attr_accessor :real_time_update
10
10
  attr_reader :is_consent_required, :data_api_domain
11
11
 
12
- def initialize
13
- @real_time_update = false
14
- @is_consent_required = false
15
- @data_api_domain = nil
12
+ def to_s
13
+ "Settings{real_time_update:#{@real_time_update},is_consent_required:#{@is_consent_required}," \
14
+ "data_api_domain:#{@data_api_domain}}"
16
15
  end
17
16
 
18
- def update(configuration)
19
- @real_time_update = configuration['realTimeUpdate'] || false
20
- @is_consent_required = configuration['consentType'] == 'REQUIRED'
21
- @data_api_domain = configuration['dataApiDomain']
17
+ def initialize(configuration = nil)
18
+ if configuration.nil?
19
+ @real_time_update = false
20
+ @is_consent_required = false
21
+ @data_api_domain = nil
22
+ else
23
+ @real_time_update = configuration['realTimeUpdate'] || false
24
+ @is_consent_required = configuration['consentType'] == 'REQUIRED'
25
+ @data_api_domain = configuration['dataApiDomain']
26
+ end
22
27
  end
23
28
  end
24
29
  end
@@ -11,6 +11,10 @@ module Kameleoon
11
11
  array&.map { |it| VariationByExposition.new(it) }
12
12
  end
13
13
 
14
+ def to_s
15
+ "VariationByExposition{exposition:#{@exposition},variation_key:#{@variation_key},variation_id:#{@variation_id}}"
16
+ end
17
+
14
18
  def initialize(hash)
15
19
  @variation_key = hash['variationKey']
16
20
  @variation_id = hash['variationId']
@@ -37,6 +37,10 @@ module Kameleoon
37
37
  class Browser < DuplicationUnsafeData
38
38
  attr_reader :type, :version
39
39
 
40
+ def to_s
41
+ "Browser{type:#{@type},version:#{@version}}"
42
+ end
43
+
40
44
  # @param [BrowserType] browser_type Browser type, can be: CHROME, INTERNET_EXPLORER, FIREFOX, SAFARI, OPERA, OTHER
41
45
  # @param [float] version Version of browser
42
46
  def initialize(browser_type, version = Float::NAN)
@@ -9,6 +9,10 @@ module Kameleoon
9
9
  class Conversion < DuplicationSafeData
10
10
  attr_reader :goal_id, :revenue, :negative
11
11
 
12
+ def to_s
13
+ "Conversion{goal_id:#{@goal_id},revenue:#{@revenue},negative:#{@negative}}"
14
+ end
15
+
12
16
  # @param [Integer] goal_id Id of the goal associated to the conversion
13
17
  # @param [Float] revenue Optional field - Revenue associated to the conversion.
14
18
  # @param [Boolean] negative Optional field - If the revenue is negative. By default it's positive.
@@ -9,6 +9,10 @@ module Kameleoon
9
9
  def initialize(cookies)
10
10
  @cookies = cookies
11
11
  end
12
+
13
+ def to_s
14
+ "Cookie{cookies:#{@cookies}}"
15
+ end
12
16
  end
13
17
  end
14
18
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
+ require 'kameleoon/logging/kameleoon_logger'
4
5
  require 'kameleoon/network/uri_helper'
5
6
  require_relative 'data'
6
7
 
@@ -8,7 +9,10 @@ module Kameleoon
8
9
  # Represents any custom data for targeting conditions
9
10
  class CustomData < DuplicationUnsafeData
10
11
  attr_reader :id, :values
11
- attr_accessor :is_mapping_identifier
12
+
13
+ def to_s
14
+ "CustomData{id:#{@id},values:#{@values}}"
15
+ end
12
16
 
13
17
  # @param [Integer] id Id of the custom data
14
18
  # @param [String] value Value of the custom data
@@ -33,9 +37,14 @@ module Kameleoon
33
37
  @id = arg0
34
38
  @values = args
35
39
  end
40
+
41
+ if @values.empty?
42
+ Logging::KameleoonLogger.error('Created a custom data %s with no values. It will not be tracked.', @id)
43
+ end
44
+
36
45
  return if @id.is_a?(Integer)
37
46
 
38
- warn "CustomData field 'id' must be of 'Integer' type"
47
+ Logging::KameleoonLogger.warning("CustomData field 'id' must be of 'Integer' type")
39
48
  @id = @id.is_a?(String) ? @id.to_i : -1
40
49
  end
41
50
  # rubocop:enable Metrics/MethodLength
@@ -51,7 +60,6 @@ module Kameleoon
51
60
  overwrite: 'true',
52
61
  nonce: nonce
53
62
  }
54
- params[:mappingIdentifier] = is_mapping_identifier if is_mapping_identifier
55
63
  Kameleoon::Network::UriHelper.encode_query(params)
56
64
  end
57
65
  end
@@ -18,21 +18,47 @@ module Kameleoon
18
18
  GEOLOCATION = 'GEOLOCATION'
19
19
  end
20
20
 
21
+ module DataState
22
+ UNSENT = 0
23
+ TRANSMITTING = 1
24
+ SENT = 2
25
+ end
26
+
21
27
  # Represents base class for any Kameleoon data
22
28
  class Data
23
- attr_reader :instance, :sent
29
+ attr_reader :instance
24
30
 
25
31
  def initialize(data_type)
26
32
  @instance = data_type
27
- @sent = false
33
+ @state = DataState::UNSENT
28
34
  end
29
35
 
30
36
  def obtain_full_post_text_line
31
37
  raise KameleoonError.new('ToDo: implement this method.'), 'ToDo: implement this method.'
32
38
  end
33
39
 
40
+ def unsent
41
+ @state == DataState::UNSENT
42
+ end
43
+
44
+ def transmitting
45
+ @state == DataState::TRANSMITTING
46
+ end
47
+
48
+ def sent
49
+ @state == DataState::SENT
50
+ end
51
+
52
+ def mark_as_unsent
53
+ @state = DataState::UNSENT if transmitting
54
+ end
55
+
56
+ def mark_as_transmitting
57
+ @state = DataState::TRANSMITTING if unsent
58
+ end
59
+
34
60
  def mark_as_sent
35
- @sent = true
61
+ @state = DataState::SENT
36
62
  @nonce = nil
37
63
  end
38
64
  end
@@ -52,7 +78,7 @@ module Kameleoon
52
78
  private
53
79
 
54
80
  def nonce
55
- @nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH) if !@sent && @nonce.nil?
81
+ @nonce = Kameleoon::Utils.generate_random_string(NONCE_LENGTH) if !sent && @nonce.nil?
56
82
  @nonce
57
83
  end
58
84
  end
@@ -15,6 +15,10 @@ module Kameleoon
15
15
  class Device < DuplicationUnsafeData
16
16
  attr_reader :device_type
17
17
 
18
+ def to_s
19
+ "Device{device_type:#{@device_type}}"
20
+ end
21
+
18
22
  def initialize(device_type)
19
23
  super(DataType::DEVICE)
20
24
  @device_type = device_type
@@ -5,6 +5,11 @@ module Kameleoon
5
5
  class Geolocation < DuplicationUnsafeData
6
6
  attr_reader :country, :region, :city, :postal_code, :latitude, :longitude
7
7
 
8
+ def to_s
9
+ "Geolocation{country:'#{@country}',region:'#{@region}',city:'#{@city}',postal_code:'#{@postal_code}'," \
10
+ "latitude:#{@latitude},longitude:#{@longitude}}"
11
+ end
12
+
8
13
  # @param [String] country Country of visitor's geolocation. Required
9
14
  # @param [String] region Region of visitor's geolocation. Optional
10
15
  # @param [String] city City of visitor's geolocation. Optional
@@ -9,4 +9,8 @@ module Kameleoon
9
9
  @values.freeze
10
10
  end
11
11
  end
12
+
13
+ def to_s
14
+ "KcsHeat{values:#{@values}}"
15
+ end
12
16
  end
@@ -13,7 +13,14 @@ module Kameleoon
13
13
 
14
14
  attr_reader :experiment_id, :variation_id, :rule_type, :assignment_time
15
15
 
16
- def initialize(experiment_id, variation_id, rule_type = Kameleoon::Configuration::RuleType::UNKNOWN, assignment_time: nil)
16
+ def to_s
17
+ "AssignedVariation{experiment_id:#{@experiment_id},variation_id:#{@variation_id}," \
18
+ "assignment_time:#{@assignment_time},rule_type:#{@rule_type}}"
19
+ end
20
+
21
+ def initialize(
22
+ experiment_id, variation_id, rule_type = Kameleoon::Configuration::RuleType::UNKNOWN, assignment_time: nil
23
+ )
17
24
  super(DataType::ASSIGNED_VARIATION)
18
25
  @experiment_id = experiment_id
19
26
  @variation_id = variation_id
@@ -6,6 +6,13 @@ module Kameleoon
6
6
  # DataArrayStorage is a readonly accessor to a sequntial storage of specific visitor data.
7
7
  # It is thread-safe
8
8
  class DataArrayStorage
9
+
10
+ def to_s
11
+ values = []
12
+ enumerate { |v| values << v }
13
+ "DataArrayStorage{values:#{values.join(',')}}"
14
+ end
15
+
9
16
  def initialize(mutex, array)
10
17
  @mutex = mutex
11
18
  @array = array
@@ -6,6 +6,13 @@ module Kameleoon
6
6
  # DataMapStorage is a readonly accessor to a key-value based storage of specific visitor data.
7
7
  # It is thread-safe
8
8
  class DataMapStorage
9
+
10
+ def to_s
11
+ values = []
12
+ enumerate { |v| values << v }
13
+ "DataMapStorage{values:#{values.join(',')}}"
14
+ end
15
+
9
16
  def initialize(mutex, map)
10
17
  @mutex = mutex
11
18
  @map = map
@@ -5,6 +5,10 @@ module Kameleoon
5
5
  class PageViewVisit
6
6
  attr_reader :page_view, :count, :last_timestamp
7
7
 
8
+ def to_s
9
+ "PageViewVisit{last_timestamp:#{@last_timestamp},count:#{@count},page_view:#{@page_view}}"
10
+ end
11
+
8
12
  def initialize(page_view, count = 1, timestamp = nil)
9
13
  @page_view = page_view
10
14
  @count = count