Class: TestTrack::VariantCalculator

Inherits:
Object
  • Object
show all
Includes:
RequiredOptions
Defined in:
app/models/test_track/variant_calculator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ VariantCalculator

Returns a new instance of VariantCalculator.



10
11
12
13
14
# File 'app/models/test_track/variant_calculator.rb', line 10

def initialize(opts = {})
  @visitor = require_option!(opts, :visitor)
  @split_name = require_option!(opts, :split_name)
  raise "unknown opts: #{opts.keys.to_sentence}" if opts.present?
end

Instance Attribute Details

#split_nameObject (readonly)

Returns the value of attribute split_name.



6
7
8
# File 'app/models/test_track/variant_calculator.rb', line 6

def split_name
  @split_name
end

#visitorObject (readonly)

Returns the value of attribute visitor.



6
7
8
# File 'app/models/test_track/variant_calculator.rb', line 6

def visitor
  @visitor
end

Instance Method Details

#_variantObject



22
23
24
25
26
27
28
# File 'app/models/test_track/variant_calculator.rb', line 22

def _variant
  bucket_ceiling = 0
  sorted_variants.detect do |variant|
    bucket_ceiling += weighting[variant]
    bucket_ceiling > assignment_bucket
  end
end

#assignment_bucketObject



39
40
41
# File 'app/models/test_track/variant_calculator.rb', line 39

def assignment_bucket
  @assignment_bucket ||= hash_fixnum % 100
end

#hash_fixnumObject



43
44
45
# File 'app/models/test_track/variant_calculator.rb', line 43

def hash_fixnum
  split_visitor_hash.slice(0, 8).to_i(16)
end

#sorted_variantsObject



30
31
32
# File 'app/models/test_track/variant_calculator.rb', line 30

def sorted_variants
  weighting.keys.sort
end

#split_visitor_hashObject



47
48
49
# File 'app/models/test_track/variant_calculator.rb', line 47

def split_visitor_hash
  Digest::MD5.new.update(split_name.to_s + visitor.id.to_s).hexdigest
end

#variantObject



16
17
18
19
20
# File 'app/models/test_track/variant_calculator.rb', line 16

def variant
  return nil unless split_registry.loaded?

  @variant ||= _variant || raise("Assignment bucket out of range. #{assignment_bucket} unmatched in #{split_name}: #{weighting}")
end

#weightingObject



34
35
36
37
# File 'app/models/test_track/variant_calculator.rb', line 34

def weighting
  @weighting ||= split_registry.weights_for(split_name) ||
    raise("TestTrack split '#{split_name}' not found. Need to write/run a migration?")
end