Skip to content

Commit

Permalink
suggestion on a simpler approach
Browse files Browse the repository at this point in the history
  • Loading branch information
rarruda committed Mar 1, 2022
1 parent be08c16 commit ead654b
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 181 deletions.
72 changes: 42 additions & 30 deletions lib/unleash/constraint.rb
@@ -1,29 +1,47 @@
require 'date'
require 'unleash/constraints/contains_constraints'
require 'unleash/constraints/date_constraints'
require 'unleash/constraints/numeric_constraints'
require 'unleash/constraints/semver_constraints'
require 'unleash/constraints/string_constraints'

module Unleash
class Constraint
attr_accessor :context_name, :operator, :value, :inverted, :case_insensitive

VALID_OPERATORS = [
ConstraintMatcher::ContainsConstraint::OPERATORS,
ConstraintMatcher::StringConstraint::OPERATORS,
ConstraintMatcher::NumericConstraint::OPERATORS,
ConstraintMatcher::DateConstraint::OPERATORS,
ConstraintMatcher::SemverConstraint::OPERATORS
].flatten.freeze
# rubocop:disable Style/RescueModifier
OPERATORS = {
IN: lambda { |context_value, constraint_value| constraint_value.include? context_value },
NOT_IN: lambda { |context_value, constraint_value| !constraint_value.include? context_value },
STR_STARTS_WITH: lambda { |context_value, constraint_value| constraint_value.any?{ |v| context_value.start_with? v } },
STR_ENDS_WITH: lambda { |context_value, constraint_value| constraint_value.any?{ |v| context_value.end_with? v } },
STR_CONTAINS: lambda { |context_value, constraint_value| constraint_value.any?{ |v| context_value.include? v } },
# another possible solution:
# NUM_EQ: lambda do |context_value, constraint_value|
# begin
# (Float(constraint_value) - Float(context_value)).abs < 0.001
# rescue ArgumentError
# false
# end
# end,
NUM_EQ: lambda { |context_value, constraint_value| (Float(constraint_value) - Float(context_value)).abs < 0.001 rescue false },
NUM_LT: lambda { |context_value, constraint_value| Float(constraint_value) > Float(context_value) rescue false },
NUM_LTE: lambda { |context_value, constraint_value| Float(constraint_value) >= Float(context_value) rescue false },
NUM_GT: lambda { |context_value, constraint_value| Float(constraint_value) < Float(context_value) rescue false },
NUM_GTE: lambda { |context_value, constraint_value| Float(constraint_value) <= Float(context_value) rescue false },
DATE_AFTER: lambda { |context_value, constraint_value| DateTime.parse(constraint_value) < DateTime.parse(context_value) rescue false },
DATE_BEFORE: lambda { |context_value, constraint_value| DateTime.parse(constraint_value) > DateTime.parse(context_value) rescue false },
SEMVER_EQ: lambda { |context_value, constraint_value| Gem::Version.new(constraint_value) == Gem::Version.new(context_value) rescue false },
SEMVER_GT: lambda { |context_value, constraint_value| Gem::Version.new(constraint_value) < Gem::Version.new(context_value) rescue false },
SEMVER_LT: lambda { |context_value, constraint_value| Gem::Version.new(constraint_value) > Gem::Version.new(context_value) rescue false },
# or maybe this more concise syntax?
# SEMVER_LT: ->(context_value, constraint_value){ Gem::Version.new(constraint_value) > Gem::Version.new(context_value) rescue false },
}.freeze
# rubocop:enable Style/RescueModifier


def initialize(context_name, operator, value = [], inverted: false, case_insensitive: false)
raise ArgumentError, "context_name is not a String" unless context_name.is_a?(String)
raise ArgumentError, "operator does not hold a valid value:" + VALID_OPERATORS unless VALID_OPERATORS.include? operator
raise ArgumentError, "operator does not hold a valid value:" + OPERATORS.keys unless OPERATORS.include? operator.to_sym
raise ArgumentError, "value must either hold an array or a single string" unless value.is_a?(Array) || value.is_a?(String)

self.context_name = context_name
self.operator = operator
self.operator = operator.to_sym
self.value = value
self.inverted = inverted
self.case_insensitive = case_insensitive
Expand All @@ -38,25 +56,19 @@ def matches_context?(context)

private

# rubocop:disable Metrics/AbcSize
def matches_constraint?(context)
context_value = context.get_by_name(self.context_name)

if ConstraintMatcher::ContainsConstraint.include? self.operator
ConstraintMatcher::ContainsConstraint.matches?(self.operator, context_value, self.value)
elsif ConstraintMatcher::StringConstraint.include? self.operator
ConstraintMatcher::StringConstraint.matches?(self.operator, context_value, self.value, case_insensitive: self.case_insensitive)
elsif ConstraintMatcher::NumericConstraint.include? self.operator
ConstraintMatcher::NumericConstraint.matches?(self.operator, context_value, self.value)
elsif ConstraintMatcher::DateConstraint.include? self.operator
ConstraintMatcher::DateConstraint.matches?(self.operator, context_value, self.value)
elsif ConstraintMatcher::SemverConstraint.include? self.operator
ConstraintMatcher::SemverConstraint.matches?(self.operator, context_value, self.value)
else
Unleash.logger.warn "Invalid constraint operator: #{self.operator}, this should be unreachable. Defaulting to false"
unless OPERATORS.include?(self.operator)
Unleash.logger.warn "Invalid constraint operator: #{self.operator}, this should be unreachable. Always returning false."
false
end

v = self.value.dup
context_value = context.get_by_name(self.context_name)

v.map!(&:upcase) if self.case_insensitive
context_value.upcase! if self.case_insensitive

OPERATORS[self.operator].call(context_value, v)
end
# rubocop:enable Metrics/AbcSize
end
end
19 changes: 0 additions & 19 deletions lib/unleash/constraints/contains_constraints.rb

This file was deleted.

30 changes: 0 additions & 30 deletions lib/unleash/constraints/date_constraints.rb

This file was deleted.

39 changes: 0 additions & 39 deletions lib/unleash/constraints/numeric_constraints.rb

This file was deleted.

33 changes: 0 additions & 33 deletions lib/unleash/constraints/semver_constraints.rb

This file was deleted.

30 changes: 0 additions & 30 deletions lib/unleash/constraints/string_constraints.rb

This file was deleted.

0 comments on commit ead654b

Please sign in to comment.