Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
001593f
feat (audience match types): Update condition evaluator for new audie…
rashidsp Dec 19, 2018
0412be0
adds absolute limit
rashidsp Dec 20, 2018
80569a1
feat (audience match types): Update audience evaluator and project co…
rashidsp Dec 24, 2018
ad7e32b
feat (audience match types): Update condition evaluator for new audie…
rashidsp Dec 26, 2018
8363bbf
feat(audience-match-types): Update audience evaluator and project con…
rashidsp Dec 26, 2018
3990bf1
feat(attribute_value): Don't target NAN, INF, -INF and > 2^53 (#148)
rashidsp Jan 2, 2019
0c6c795
feat(audiences): Audience combinations (#147)
rashidsp Jan 2, 2019
8d2b3ee
resolves conflicts
rashidsp Jan 3, 2019
9291b97
Updates header and resolves conflicts
rashidsp Jan 3, 2019
f5b37b2
nit: header update
rashidsp Jan 3, 2019
58330b3
Merge branch 'master' into rashid/audience-match-types
rashidsp Jan 3, 2019
8453091
fix: travis bundler issue
rashidsp Jan 4, 2019
37872e6
Merge branch 'master' into rashid/audience-match-types
rashidsp Jan 8, 2019
fabf023
feat(Audience Evaluation): Audience Logging
rashidsp Jan 8, 2019
4d9ad8f
Merge branch 'master' into rashid/audience-match-types
rashidsp Jan 9, 2019
e438ad2
Merge branch 'rashid/audience-match-types' into rashid/logging-for-au…
rashidsp Jan 9, 2019
0238950
addresses comments
rashidsp Jan 9, 2019
479bc84
Fix: user attribute check
rashidsp Jan 10, 2019
b591d49
Merge branch 'master' into rashid/logging-for-audience
rashidsp Jan 17, 2019
527d699
revises logging improvements
rashidsp Jan 18, 2019
0b7958e
Merge branch 'master' into rashid/logging-for-audience
rashidsp Jan 21, 2019
ad7745d
Updated according to doc
rashidsp Jan 28, 2019
7234863
Merge branch 'rashid/logging-for-audience' of github.com:optimizely/r…
rashidsp Jan 28, 2019
5468d37
Fix: return str bug.
rashidsp Feb 1, 2019
eb9770b
refact: new recommendations.
rashidsp Feb 8, 2019
455a697
refact: separated finite_number condition
rashidsp Feb 11, 2019
89184d7
Addressing feedback
rashidsp Feb 26, 2019
006dd0f
few minor updates
rashidsp Feb 28, 2019
8986472
Addressing feedback
rashidsp Mar 5, 2019
30d9330
review changes
rashidsp Mar 6, 2019
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refact: separated finite_number condition
  • Loading branch information
rashidsp committed Feb 11, 2019
commit 455a69797b369122e6cf28d03706f14c736d6eea
120 changes: 51 additions & 69 deletions lib/optimizely/custom_attribute_condition_evaluator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,25 @@ def exact_evaluator(condition)
user_provided_value = @user_attributes[condition['name']]

if user_provided_value.is_a?(Numeric) && condition_value.is_a?(Numeric)
unless Helpers::Validator.finite_number?(user_provided_value)

return nil unless valid_numeric_values?(user_provided_value, condition_value, condition)

return true if condition_value == user_provided_value

unless Helpers::Validator.same_types?(condition_value, user_provided_value)
@logger.log(
Logger::DEBUG,
format(
Helpers::Constants::AUDIENCE_EVALUATION_LOGS['INFINIT_ATTRIBUTE_VALUE'],
Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNEXPECTED_TYPE'],
condition,
user_provided_value
user_provided_value.class,
condition['name']
)
)
return nil
end

return true if condition_value.to_f == user_provided_value.to_f
return false
end

if !value_valid_for_exact_conditions?(user_provided_value) ||
Expand Down Expand Up @@ -171,38 +177,7 @@ def greater_than_evaluator(condition)
condition_value = condition['value']
user_provided_value = @user_attributes[condition['name']]

unless user_provided_value.is_a?(Numeric)
@logger.log(
Logger::DEBUG,
format(
Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNEXPECTED_TYPE'],
condition,
user_provided_value.class,
condition['name']
)
)
return nil
end

unless Helpers::Validator.finite_number?(user_provided_value)
@logger.log(
Logger::DEBUG,
format(
Helpers::Constants::AUDIENCE_EVALUATION_LOGS['INFINIT_ATTRIBUTE_VALUE'],
condition,
user_provided_value
)
)
return nil
end

unless Helpers::Validator.finite_number?(condition_value)
@logger.log(
Logger::WARN,
format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_CONDITION_VALUE'], condition)
)
return nil
end
return nil unless valid_numeric_values?(user_provided_value, condition_value, condition)

user_provided_value > condition_value
end
Expand All @@ -216,7 +191,21 @@ def less_than_evaluator(condition)
condition_value = condition['value']
user_provided_value = @user_attributes[condition['name']]

unless user_provided_value.is_a?(Numeric)
return nil unless valid_numeric_values?(user_provided_value, condition_value, condition)

user_provided_value < condition_value
end

def substring_evaluator(condition)
# Evaluate the given substring match condition for the given user attributes.
# Returns boolean true if the condition value is a substring of the user attribute value,
# false if the condition value is not a substring of the user attribute value,
# nil if the condition value isn't a string or the user attribute value isn't a string.

condition_value = condition['value']
user_provided_value = @user_attributes[condition['name']]

unless user_provided_value.is_a?(String)
@logger.log(
Logger::DEBUG,
format(
Expand All @@ -229,69 +218,62 @@ def less_than_evaluator(condition)
return nil
end

unless Helpers::Validator.finite_number?(user_provided_value)
@logger.log(
Logger::DEBUG,
format(
Helpers::Constants::AUDIENCE_EVALUATION_LOGS['INFINIT_ATTRIBUTE_VALUE'],
condition,
user_provided_value
)
)
return nil
end

unless Helpers::Validator.finite_number?(condition_value)
unless condition_value.is_a?(String)
@logger.log(
Logger::WARN,
format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_CONDITION_VALUE'], condition)
)
return nil
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: would be slightly better (and certainly more consistent with other SDKs) to reorder the above two blocks. If the condition_value isn't a string, that'd be indicative of a broader problem that might be resolved in a future SDK, where it might actually be legitimate for the user_provided_value to be a non-string.

(I know we check for non-nil user_provided_value before we get to either of these blocks, but at least that helps us increase code re-use...)


user_provided_value < condition_value
user_provided_value.include? condition_value
end

def substring_evaluator(condition)
# Evaluate the given substring match condition for the given user attributes.
# Returns boolean true if the condition value is a substring of the user attribute value,
# false if the condition value is not a substring of the user attribute value,
# nil if the condition value isn't a string or the user attribute value isn't a string.
private

condition_value = condition['value']
user_provided_value = @user_attributes[condition['name']]
def valid_numeric_values?(user_value, condition_value, condition)
# Returns true if user and condition values are valid numeric.
# false otherwise.

unless user_provided_value.is_a?(String)
unless user_value.is_a?(Numeric)
@logger.log(
Logger::DEBUG,
format(
Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNEXPECTED_TYPE'],
condition,
user_provided_value.class,
user_value.class,
condition['name']
)
)
return nil
return false
end

unless condition_value.is_a?(String)
unless Helpers::Validator.finite_number?(user_value)
@logger.log(
Logger::DEBUG,
format(
Helpers::Constants::AUDIENCE_EVALUATION_LOGS['INFINITE_ATTRIBUTE_VALUE'],
condition,
user_value
)
)
return false
end

unless Helpers::Validator.finite_number?(condition_value)
@logger.log(
Logger::WARN,
format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_CONDITION_VALUE'], condition)
)
return nil
return false
end

user_provided_value.include? condition_value
true
end

private

def value_valid_for_exact_conditions?(value)
# Returns true if the value is valid for exact conditions. Valid values include
# strings, booleans, and numbers that aren't NaN, -Infinity, or Infinity.

return Helpers::Validator.finite_number?(value) if value.is_a? Numeric
# strings and booleans.

(Helpers::Validator.boolean? value) || (value.is_a? String)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/optimizely/helpers/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ module Constants
'EVALUATING_AUDIENCE_WITH_CONDITIONS' => "Starting to evaluate audience '%s' with conditions: '%s'.",
'MISMATCH_TYPE' => "Audience condition '%s' evaluated as UNKNOWN because the value for " \
"user attribute '%s' is '%s' while expected is '%s'.",
'INFINIT_ATTRIBUTE_VALUE' => "Audience condition '%s' evaluated to UNKNOWN because the number value " \
'INFINITE_ATTRIBUTE_VALUE' => "Audience condition '%s' evaluated to UNKNOWN because the number value " \
"for user attribute '%s' is not in the range [-2^53, +2^53].",
'MISSING_ATTRIBUTE_VALUE' => "Audience condition '%s' evaluated as UNKNOWN because no value " \
"was passed for user attribute '%s'.",
Expand Down