vwo-sdk 1.3.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/vwo/logger.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'logger'
18
16
 
19
17
  class VWO
@@ -33,5 +31,13 @@ class VWO
33
31
  def log(level, message)
34
32
  @@logger_instance.log(level, message)
35
33
  end
34
+
35
+ def instance
36
+ @@logger_instance
37
+ end
38
+
39
+ def level
40
+ @@logger_instance.level
41
+ end
36
42
  end
37
43
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'json'
18
16
 
19
17
  class VWO
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require_relative '../logger'
18
16
  require_relative '../enums'
19
17
  require_relative '../utils/request'
@@ -62,13 +60,13 @@ class VWO
62
60
  variation_id: impression[:combination]
63
61
  )
64
62
  )
65
- return true
63
+ true
66
64
  else
67
65
  @logger.log(
68
66
  LogLevelEnum::ERROR,
69
67
  format(LogMessageEnum::ErrorMessages::IMPRESSION_FAILED, file: FileNameEnum::EventDispatcher, end_point: impression['url'])
70
68
  )
71
- return false
69
+ false
72
70
  end
73
71
  rescue StandardError
74
72
  @logger.log(
@@ -0,0 +1,114 @@
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../utils/function'
16
+ require_relative '../utils/segment'
17
+
18
+ class VWO
19
+ module Services
20
+ class OperandEvaluator
21
+ include VWO::Utils::Function
22
+ include VWO::Utils::Segment
23
+
24
+ # Checks if both values are same after 'down-casing'
25
+ # i.e. case insensitive check
26
+ #
27
+ # @param [String] :operand_value Leaf value from the segments
28
+ # @param [String] :custom_variables_value Value from the custom_variables
29
+ #
30
+ # @return [Boolean]
31
+ def lower?(operand_value, custom_variables_value)
32
+ operand_value.downcase == custom_variables_value.downcase
33
+ end
34
+
35
+ # Checks if custom_variables_value contains operand_value
36
+ #
37
+ # @param [String] :operand_value Leaf value from the segments
38
+ # @param [String] :custom_variables_value Value from the custom_variables
39
+ #
40
+ # @return [Boolean]
41
+ def contains?(operand_value, custom_variables_value)
42
+ custom_variables_value.include?(operand_value)
43
+ end
44
+
45
+ # Checks if custom_variables_value ends with operand_value
46
+ #
47
+ # @param [String] :operand_value Leaf value from the segments
48
+ # @param [String] :custom_variables_value Value from the custom_variables
49
+ #
50
+ # @return [Boolean]
51
+ def starts_with?(operand_value, custom_variables_value)
52
+ custom_variables_value.end_with?(operand_value)
53
+ end
54
+
55
+ # Checks if custom_variables_value starts with operand_value
56
+ #
57
+ # @param [String] :operand_value Leaf value from the segments
58
+ # @param [String] :custom_variables_value Value from the custom_variables
59
+ #
60
+ # @return [Boolean]
61
+ def ends_with?(operand_value, custom_variables_value)
62
+ custom_variables_value.start_with?(operand_value)
63
+ end
64
+
65
+ # Checks if custom_variables_value matches the regex specified by operand_value
66
+ #
67
+ # @param [String] :operand_value Leaf value from the segments
68
+ # @param [String] :custom_variables_value Value from the custom_variables
69
+ #
70
+ # @return [Boolean]
71
+ def regex?(operand_value, custom_variables_value)
72
+ pattern = Regexp.new operand_value
73
+ custom_variables_value =~ pattern
74
+ end
75
+
76
+ # Checks if both values are exactly same
77
+ #
78
+ # @param [String] :operand_value Leaf value from the segments
79
+ # @param [String] :custom_variables_value Value from the custom_variables
80
+ #
81
+ # @return [Boolean]
82
+ def equals?(operand_value, custom_variables_value)
83
+ custom_variables_value == operand_value
84
+ end
85
+
86
+ # Identifies the condition stated in the leaf node and evaluates the result
87
+ #
88
+ # @param [String] :operand_value Leaf value from the segments
89
+ # @param [String] :custom_variables_value Value from the custom_variables
90
+ #
91
+ # @return [Boolean]
92
+ def evaluate_operand?(operand, custom_variables)
93
+ # Extract custom_variable_key and custom_variables_value from operand
94
+
95
+ operand_key, operand = get_key_value(operand)
96
+
97
+ # Retrieve corresponding custom_variable value from custom_variables
98
+ custom_variables_value = custom_variables[operand_key]
99
+
100
+ # Pre process custom_variable value
101
+ custom_variables_value = process_custom_variables_value(custom_variables_value)
102
+
103
+ # Pre process operand value
104
+ operand_type, operand_value = process_operand_value(operand)
105
+
106
+ # Process the custom_variables_value and operand_value to make them of same type
107
+ operand_value, custom_variables_value = convert_to_true_types(operand_value, custom_variables_value)
108
+
109
+ # Call the self method corresponding to operand_type to evaluate the result
110
+ public_send("#{operand_type}?", operand_value, custom_variables_value)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,109 @@
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../logger'
16
+ require_relative '../enums'
17
+ require_relative './operand_evaluator'
18
+ require_relative '../utils/function'
19
+ require_relative '../utils/segment'
20
+ require_relative '../utils/validations'
21
+
22
+ class VWO
23
+ module Services
24
+ class SegmentEvaluator
25
+ include VWO::Enums
26
+ include VWO::Utils::Function
27
+ include VWO::Utils::Segment
28
+ include VWO::Utils::Validations
29
+
30
+ # Initializes this class with VWOLogger and OperandEvaluator
31
+ def initialize
32
+ @logger = VWO::Logger.get_instance
33
+ @operand_evaluator = OperandEvaluator.new
34
+ end
35
+
36
+ # A parser which recursively evaluates the expression tree represented by dsl,
37
+ # and returns the result
38
+ #
39
+ # @param[Hash] :dsl The segments defined in the campaign
40
+ # @param[Hash] :custom_variables Key/value pair of custom_attributes properties
41
+ #
42
+ # @return[Boolean]
43
+ #
44
+ def evaluate_util(dsl, custom_variables)
45
+ operator, sub_dsl = get_key_value(dsl)
46
+ if operator == OperatorTypes::NOT
47
+ !evaluate_util(sub_dsl, custom_variables)
48
+ elsif operator == OperatorTypes::AND
49
+ sub_dsl.all? { |y| evaluate_util(y, custom_variables) }
50
+ elsif operator == OperatorTypes::OR
51
+ sub_dsl.any? { |y| evaluate_util(y, custom_variables) }
52
+ elsif operator == OperandTypes::CUSTOM_VARIABLE
53
+ @operand_evaluator.evaluate_operand?(sub_dsl, custom_variables)
54
+ end
55
+ end
56
+
57
+ # Evaluates the custom_variables passed against the pre-segmentation condition defined
58
+ # in the corresponding campaign.
59
+ #
60
+ # @param[String] :campaign_key Running_campaign's key
61
+ # @param[String] :user_id Unique user identifier
62
+ # @param[Hash] :dsl Segments provided in the settings_file
63
+ # @param[Hash] :custom_variables Custom variables provided in the apis
64
+ #
65
+ # @return[Boolean] true if user passed pre-segmentation, else false
66
+ #
67
+ def evaluate(campaign_key, user_id, dsl, custom_variables)
68
+ result = evaluate_util(dsl, custom_variables) if valid_value?(dsl)
69
+ if result
70
+ @logger.log(
71
+ LogLevelEnum::INFO,
72
+ format(
73
+ LogMessageEnum::InfoMessages::USER_PASSED_PRE_SEGMENTATION,
74
+ file: FileNameEnum::SegmentEvaluator,
75
+ user_id: user_id,
76
+ campaign_key: campaign_key,
77
+ custom_variables: custom_variables
78
+ )
79
+ )
80
+ else
81
+ @logger.log(
82
+ LogLevelEnum::INFO,
83
+ format(
84
+ LogMessageEnum::InfoMessages::USER_FAILED_PRE_SEGMENTATION,
85
+ file: FileNameEnum::SegmentEvaluator,
86
+ user_id: user_id,
87
+ campaign_key: campaign_key,
88
+ custom_variables: custom_variables
89
+ )
90
+ )
91
+ end
92
+ result
93
+ rescue StandardError => e
94
+ @logger.log(
95
+ LogLevelEnum::ERROR,
96
+ format(
97
+ LogMessageEnum::ErrorMessages::PRE_SEGMENTATION_ERROR,
98
+ file: FileNameEnum::SegmentEvaluator,
99
+ user_id: user_id,
100
+ campaign_key: campaign_key,
101
+ custom_variables: custom_variables,
102
+ error_message: e
103
+ )
104
+ )
105
+ false
106
+ end
107
+ end
108
+ end
109
+ end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require_relative '../utils/function'
18
16
  require_relative '../utils/request'
19
17
  require_relative '../utils/validations'
@@ -46,7 +44,7 @@ class VWO
46
44
  is_valid_key = valid_number?(@account_id) || valid_string?(@account_id)
47
45
 
48
46
  unless is_valid_key && valid_string?(@sdk_key)
49
- STDERR.puts 'account_id and sdk_key are required for fetching account settings. Aborting!'
47
+ puts 'account_id and sdk_key are required for fetching account settings. Aborting!'
50
48
  return '{}'
51
49
  end
52
50
 
@@ -60,12 +58,12 @@ class VWO
60
58
  Got Status Code: #{settings_file_response.code}
61
59
  and message: #{settings_file_response.body}.
62
60
  DOC
63
- STDERR.puts message
61
+ puts message
64
62
  return
65
63
  end
66
64
  settings_file_response.body
67
65
  rescue StandardError => e
68
- STDERR.puts "Error fetching Settings File #{e}"
66
+ puts "Error fetching Settings File #{e}"
69
67
  end
70
68
 
71
69
  private
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require_relative '../logger'
18
16
  require_relative '../enums'
19
17
  require_relative '../utils/campaign'
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  class VWO
18
16
  # UserStorage Class is used to store user-variation mapping.
19
17
  # Override this class to implement your own functionality.
@@ -1,4 +1,4 @@
1
- # Copyright 2019 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2020 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require_relative '../logger'
18
16
  require_relative '../enums'
19
17
  require_relative '../constants'
@@ -25,18 +23,6 @@ class VWO
25
23
  include VWO::Enums
26
24
  include VWO::CONSTANTS
27
25
 
28
- # Finds and Returns campaign from given campaign_key.
29
- #
30
- # @param[Hash] :settings_file Settings file
31
- # @param[String] :campaign_key Campaign identifier key
32
- # @return[Hash] :campaign object
33
-
34
- def get_campaign(settings_file, campaign_key)
35
- (settings_file['campaigns'] || []).find do |campaign|
36
- campaign['key'] == campaign_key
37
- end
38
- end
39
-
40
26
  # Sets variation allocation range in the provided campaign
41
27
  #
42
28
  # @param [Hash]: Campaign object
@@ -72,23 +58,48 @@ class VWO
72
58
  end
73
59
 
74
60
  # Returns goal from given campaign_key and gaol_identifier.
75
- # @param[Hash] :settings_file Settings file
76
- # @param[String] :campaign_key Campaign identifier key
61
+ # @param[String] :campaign Campaign object
77
62
  # @param[String] :goal_identifier Goal identifier
78
63
  #
79
64
  # @return[Hash] Goal corresponding to Goal_identifier in respective campaign
80
65
 
81
- def get_campaign_goal(settings_file, campaign_key, goal_identifier)
82
- return unless settings_file && campaign_key && goal_identifier
83
-
84
- campaign = get_campaign(settings_file, campaign_key)
85
- return unless campaign
66
+ def get_campaign_goal(campaign, goal_identifier)
67
+ return unless campaign && goal_identifier
86
68
 
87
69
  campaign['goals'].find do |goal|
88
70
  goal['identifier'] == goal_identifier
89
71
  end
90
72
  end
91
73
 
74
+ # Returns segments from the campaign
75
+ # @param[Hash] campaign Running campaign
76
+ # @return[Hash] A dsl of segments
77
+ #
78
+ def get_segments(campaign)
79
+ campaign['segments']
80
+ end
81
+
82
+ # Returns control variation from a given campaign
83
+ # @param[Hash] campaign Running campaign
84
+ # @return[Hash] variation Control variation from the campaign, ie having id = 1
85
+
86
+ def get_control_variation(campaign)
87
+ campaign['variations'].find do |variation|
88
+ variation['id'] == 1
89
+ end
90
+ end
91
+
92
+ # Returns variable from given variables list.
93
+ # @params[Array] variables List of variables, whether in campaigns or inside variation
94
+ # @param[String] variable_key Variable identifier
95
+ # @return[Hash] Variable corresponding to variable_key in given variable list
96
+
97
+ def get_variable(variables, variable_key)
98
+ variables.find do |variable|
99
+ variable['key'] == variable_key
100
+ end
101
+ end
102
+
92
103
  private
93
104
 
94
105
  # Returns the bucket size of variation.
@@ -120,6 +131,17 @@ class VWO
120
131
  variation['name'] == variation_name
121
132
  end
122
133
  end
134
+
135
+ # Finds and Returns campaign from given campaign_key.
136
+ # [Hash] :settings_file Settings file for the project
137
+ # [String] :campaign_key Campaign identifier key
138
+ # @return[Hash] Campaign object
139
+
140
+ def get_campaign(settings_file, campaign_key)
141
+ settings_file['campaigns'].find do |campaign|
142
+ campaign['key'] == campaign_key
143
+ end
144
+ end
123
145
  end
124
146
  end
125
147
  end