Sha256: 6f4fa7b1d41d2612a1ff8c8116147257880e37068bd4cb9599045f884a488c62

Contents?: true

Size: 1.24 KB

Versions: 3

Compression:

Stored size: 1.24 KB

Contents

require 'digest'

class TestTrack::VariantCalculator
  include TestTrack::RequiredOptions

  attr_reader :visitor, :split_name

  delegate :split_registry, to: :visitor

  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

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

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

  def sorted_variants
    weighting.keys.sort
  end

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

  def assignment_bucket
    @assignment_bucket ||= hash_fixnum % 100
  end

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

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

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
test_track_rails_client-4.0.0.alpha29 app/models/test_track/variant_calculator.rb
test_track_rails_client-4.0.0.alpha28 app/models/test_track/variant_calculator.rb
test_track_rails_client-4.0.0.alpha27 app/models/test_track/variant_calculator.rb