split 4.0.0.pre2 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +14 -1
  3. data/.rubocop.yml +2 -5
  4. data/CHANGELOG.md +26 -2
  5. data/CONTRIBUTING.md +1 -1
  6. data/Gemfile +2 -1
  7. data/README.md +4 -2
  8. data/Rakefile +4 -5
  9. data/gemfiles/5.2.gemfile +1 -3
  10. data/gemfiles/6.0.gemfile +1 -3
  11. data/gemfiles/{5.0.gemfile → 6.1.gemfile} +2 -4
  12. data/gemfiles/{5.1.gemfile → 7.0.gemfile} +3 -4
  13. data/lib/split/algorithms/block_randomization.rb +5 -6
  14. data/lib/split/algorithms/whiplash.rb +16 -18
  15. data/lib/split/algorithms.rb +22 -0
  16. data/lib/split/alternative.rb +21 -22
  17. data/lib/split/cache.rb +0 -1
  18. data/lib/split/combined_experiments_helper.rb +4 -4
  19. data/lib/split/configuration.rb +83 -84
  20. data/lib/split/dashboard/helpers.rb +6 -7
  21. data/lib/split/dashboard/pagination_helpers.rb +53 -54
  22. data/lib/split/dashboard/public/style.css +5 -2
  23. data/lib/split/dashboard/views/index.erb +19 -4
  24. data/lib/split/dashboard.rb +29 -23
  25. data/lib/split/encapsulated_helper.rb +4 -6
  26. data/lib/split/experiment.rb +84 -88
  27. data/lib/split/experiment_catalog.rb +6 -5
  28. data/lib/split/extensions/string.rb +1 -1
  29. data/lib/split/goals_collection.rb +8 -10
  30. data/lib/split/helper.rb +19 -19
  31. data/lib/split/metric.rb +4 -5
  32. data/lib/split/persistence/cookie_adapter.rb +44 -47
  33. data/lib/split/persistence/dual_adapter.rb +7 -8
  34. data/lib/split/persistence/redis_adapter.rb +2 -3
  35. data/lib/split/persistence/session_adapter.rb +0 -2
  36. data/lib/split/persistence.rb +4 -4
  37. data/lib/split/redis_interface.rb +1 -2
  38. data/lib/split/trial.rb +23 -24
  39. data/lib/split/user.rb +12 -13
  40. data/lib/split/version.rb +1 -1
  41. data/lib/split/zscore.rb +1 -3
  42. data/lib/split.rb +26 -25
  43. data/spec/algorithms/block_randomization_spec.rb +6 -5
  44. data/spec/algorithms/weighted_sample_spec.rb +6 -5
  45. data/spec/algorithms/whiplash_spec.rb +4 -5
  46. data/spec/alternative_spec.rb +35 -36
  47. data/spec/cache_spec.rb +15 -19
  48. data/spec/combined_experiments_helper_spec.rb +18 -17
  49. data/spec/configuration_spec.rb +32 -38
  50. data/spec/dashboard/pagination_helpers_spec.rb +69 -67
  51. data/spec/dashboard/paginator_spec.rb +10 -9
  52. data/spec/dashboard_helpers_spec.rb +19 -18
  53. data/spec/dashboard_spec.rb +67 -35
  54. data/spec/encapsulated_helper_spec.rb +12 -14
  55. data/spec/experiment_catalog_spec.rb +14 -13
  56. data/spec/experiment_spec.rb +121 -123
  57. data/spec/goals_collection_spec.rb +17 -15
  58. data/spec/helper_spec.rb +379 -382
  59. data/spec/metric_spec.rb +14 -14
  60. data/spec/persistence/cookie_adapter_spec.rb +23 -8
  61. data/spec/persistence/dual_adapter_spec.rb +71 -71
  62. data/spec/persistence/redis_adapter_spec.rb +25 -26
  63. data/spec/persistence/session_adapter_spec.rb +2 -3
  64. data/spec/persistence_spec.rb +1 -2
  65. data/spec/redis_interface_spec.rb +16 -14
  66. data/spec/spec_helper.rb +15 -13
  67. data/spec/split_spec.rb +11 -11
  68. data/spec/support/cookies_mock.rb +1 -2
  69. data/spec/trial_spec.rb +61 -60
  70. data/spec/user_spec.rb +36 -36
  71. data/split.gemspec +20 -20
  72. metadata +9 -10
  73. data/.rubocop_todo.yml +0 -226
  74. data/Appraisals +0 -19
@@ -3,7 +3,7 @@
3
3
  module Split
4
4
  module Persistence
5
5
  class DualAdapter
6
- def self.with_config(options={})
6
+ def self.with_config(options = {})
7
7
  self.config.merge!(options)
8
8
  self
9
9
  end
@@ -72,14 +72,13 @@ module Split
72
72
  end
73
73
 
74
74
  private
75
+ def decrement_participation?(old_value, value)
76
+ !old_value.nil? && !value.nil? && old_value != value
77
+ end
75
78
 
76
- def decrement_participation?(old_value, value)
77
- !old_value.nil? && !value.nil? && old_value != value
78
- end
79
-
80
- def decrement_participation(key, value)
81
- Split.redis.hincrby("#{key}:#{value}", 'participant_count', -1)
82
- end
79
+ def decrement_participation(key, value)
80
+ Split.redis.hincrby("#{key}:#{value}", "participant_count", -1)
81
+ end
83
82
  end
84
83
  end
85
84
  end
@@ -3,7 +3,7 @@
3
3
  module Split
4
4
  module Persistence
5
5
  class RedisAdapter
6
- DEFAULT_CONFIG = {:namespace => 'persistence'}.freeze
6
+ DEFAULT_CONFIG = { namespace: "persistence" }.freeze
7
7
 
8
8
  attr_reader :redis_key
9
9
 
@@ -44,7 +44,7 @@ module Split
44
44
  new(nil, user_id)
45
45
  end
46
46
 
47
- def self.with_config(options={})
47
+ def self.with_config(options = {})
48
48
  self.config.merge!(options)
49
49
  self
50
50
  end
@@ -56,7 +56,6 @@ module Split
56
56
  def self.reset_config!
57
57
  @config = DEFAULT_CONFIG.dup
58
58
  end
59
-
60
59
  end
61
60
  end
62
61
  end
@@ -3,7 +3,6 @@
3
3
  module Split
4
4
  module Persistence
5
5
  class SessionAdapter
6
-
7
6
  def initialize(context)
8
7
  @session = context.session
9
8
  @session[:split] ||= {}
@@ -24,7 +23,6 @@ module Split
24
23
  def keys
25
24
  @session[:split].keys
26
25
  end
27
-
28
26
  end
29
27
  end
30
28
  end
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Split
4
4
  module Persistence
5
- require 'split/persistence/cookie_adapter'
6
- require 'split/persistence/dual_adapter'
7
- require 'split/persistence/redis_adapter'
8
- require 'split/persistence/session_adapter'
5
+ require "split/persistence/cookie_adapter"
6
+ require "split/persistence/dual_adapter"
7
+ require "split/persistence/redis_adapter"
8
+ require "split/persistence/session_adapter"
9
9
 
10
10
  ADAPTERS = {
11
11
  cookie: Split::Persistence::CookieAdapter,
@@ -24,7 +24,6 @@ module Split
24
24
  end
25
25
 
26
26
  private
27
-
28
- attr_accessor :redis
27
+ attr_accessor :redis
29
28
  end
30
29
  end
data/lib/split/trial.rb CHANGED
@@ -24,15 +24,15 @@ module Split
24
24
 
25
25
  def alternative
26
26
  @alternative ||= if @experiment.has_winner?
27
- @experiment.winner
28
- end
27
+ @experiment.winner
28
+ end
29
29
  end
30
30
 
31
31
  def alternative=(alternative)
32
32
  @alternative = if alternative.kind_of?(Split::Alternative)
33
33
  alternative
34
34
  else
35
- @experiment.alternatives.find{|a| a.name == alternative }
35
+ @experiment.alternatives.find { |a| a.name == alternative }
36
36
  end
37
37
  end
38
38
 
@@ -41,7 +41,7 @@ module Split
41
41
  if Array(goals).empty?
42
42
  alternative.increment_completion
43
43
  else
44
- Array(goals).each {|g| alternative.increment_completion(g) }
44
+ Array(goals).each { |g| alternative.increment_completion(g) }
45
45
  end
46
46
 
47
47
  run_callback context, Split.configuration.on_trial_complete
@@ -97,31 +97,30 @@ module Split
97
97
  end
98
98
 
99
99
  private
100
+ def run_callback(context, callback_name)
101
+ context.send(callback_name, self) if callback_name && context.respond_to?(callback_name, true)
102
+ end
100
103
 
101
- def run_callback(context, callback_name)
102
- context.send(callback_name, self) if callback_name && context.respond_to?(callback_name, true)
103
- end
104
-
105
- def override_is_alternative?
106
- @experiment.alternatives.map(&:name).include?(@options[:override])
107
- end
104
+ def override_is_alternative?
105
+ @experiment.alternatives.map(&:name).include?(@options[:override])
106
+ end
108
107
 
109
- def should_store_alternative?
110
- if @options[:override] || @options[:disabled]
111
- Split.configuration.store_override
112
- else
113
- !exclude_user?
108
+ def should_store_alternative?
109
+ if @options[:override] || @options[:disabled]
110
+ Split.configuration.store_override
111
+ else
112
+ !exclude_user?
113
+ end
114
114
  end
115
- end
116
115
 
117
- def cleanup_old_versions
118
- if @experiment.version > 0
119
- @user.cleanup_old_versions!(@experiment)
116
+ def cleanup_old_versions
117
+ if @experiment.version > 0
118
+ @user.cleanup_old_versions!(@experiment)
119
+ end
120
120
  end
121
- end
122
121
 
123
- def exclude_user?
124
- @options[:exclude] || @experiment.start_time.nil? || @user.max_experiments_reached?(@experiment.key)
125
- end
122
+ def exclude_user?
123
+ @options[:exclude] || @experiment.start_time.nil? || @user.max_experiments_reached?(@experiment.key)
124
+ end
126
125
  end
127
126
  end
data/lib/split/user.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'forwardable'
3
+ require "forwardable"
4
4
 
5
5
  module Split
6
6
  class User
@@ -26,10 +26,10 @@ module Split
26
26
  end
27
27
 
28
28
  def max_experiments_reached?(experiment_key)
29
- if Split.configuration.allow_multiple_experiments == 'control'
29
+ if Split.configuration.allow_multiple_experiments == "control"
30
30
  experiments = active_experiments
31
31
  experiment_key_without_version = key_without_version(experiment_key)
32
- count_control = experiments.count {|k, v| k == experiment_key_without_version || v == 'control'}
32
+ count_control = experiments.count { |k, v| k == experiment_key_without_version || v == "control" }
33
33
  experiments.size > count_control
34
34
  else
35
35
  !Split.configuration.allow_multiple_experiments &&
@@ -65,17 +65,16 @@ module Split
65
65
  end
66
66
 
67
67
  private
68
+ def keys_without_experiment(keys, experiment_key)
69
+ keys.reject { |k| k.match(Regexp.new("^#{experiment_key}(:finished)?$")) }
70
+ end
68
71
 
69
- def keys_without_experiment(keys, experiment_key)
70
- keys.reject { |k| k.match(Regexp.new("^#{experiment_key}(:finished)?$")) }
71
- end
72
-
73
- def keys_without_finished(keys)
74
- keys.reject { |k| k.include?(":finished") }
75
- end
72
+ def keys_without_finished(keys)
73
+ keys.reject { |k| k.include?(":finished") }
74
+ end
76
75
 
77
- def key_without_version(key)
78
- key.split(/\:\d(?!\:)/)[0]
79
- end
76
+ def key_without_version(key)
77
+ key.split(/\:\d(?!\:)/)[0]
78
+ end
80
79
  end
81
80
  end
data/lib/split/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Split
4
- VERSION = "4.0.0.pre2"
4
+ VERSION = "4.0.2"
5
5
  end
data/lib/split/zscore.rb CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Split
4
4
  class Zscore
5
-
6
5
  include Math
7
6
 
8
7
  def self.calculate(p1, n1, p2, n2)
@@ -51,8 +50,7 @@ module Split
51
50
  # Calculate z-score
52
51
  z_score = (p_1 - p_2)/(se)
53
52
 
54
- return z_score
55
-
53
+ z_score
56
54
  end
57
55
  end
58
56
  end
data/lib/split.rb CHANGED
@@ -1,29 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'redis'
3
+ require "redis"
4
4
 
5
- require 'split/algorithms/block_randomization'
6
- require 'split/algorithms/weighted_sample'
7
- require 'split/algorithms/whiplash'
8
- require 'split/alternative'
9
- require 'split/cache'
10
- require 'split/configuration'
11
- require 'split/encapsulated_helper'
12
- require 'split/exceptions'
13
- require 'split/experiment'
14
- require 'split/experiment_catalog'
15
- require 'split/extensions/string'
16
- require 'split/goals_collection'
17
- require 'split/helper'
18
- require 'split/combined_experiments_helper'
19
- require 'split/metric'
20
- require 'split/persistence'
21
- require 'split/redis_interface'
22
- require 'split/trial'
23
- require 'split/user'
24
- require 'split/version'
25
- require 'split/zscore'
26
- require 'split/engine' if defined?(Rails)
5
+ require "split/algorithms"
6
+ require "split/algorithms/block_randomization"
7
+ require "split/algorithms/weighted_sample"
8
+ require "split/algorithms/whiplash"
9
+ require "split/alternative"
10
+ require "split/cache"
11
+ require "split/configuration"
12
+ require "split/encapsulated_helper"
13
+ require "split/exceptions"
14
+ require "split/experiment"
15
+ require "split/experiment_catalog"
16
+ require "split/extensions/string"
17
+ require "split/goals_collection"
18
+ require "split/helper"
19
+ require "split/combined_experiments_helper"
20
+ require "split/metric"
21
+ require "split/persistence"
22
+ require "split/redis_interface"
23
+ require "split/trial"
24
+ require "split/user"
25
+ require "split/version"
26
+ require "split/zscore"
27
+ require "split/engine" if defined?(Rails)
27
28
 
28
29
  module Split
29
30
  extend self
@@ -75,8 +76,8 @@ end
75
76
  # Check to see if being run in a Rails application. If so, wait until before_initialize to run configuration so Gems that create ENV variables have the chance to initialize first.
76
77
  if defined?(::Rails)
77
78
  class Split::Railtie < Rails::Railtie
78
- config.before_initialize { Split.configure {} }
79
+ config.before_initialize { Split.configure { } }
79
80
  end
80
81
  else
81
- Split.configure {}
82
+ Split.configure { }
82
83
  end
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  describe Split::Algorithms::BlockRandomization do
4
-
5
- let(:experiment) { Split::Experiment.new 'experiment' }
6
- let(:alternative_A) { Split::Alternative.new 'A', 'experiment' }
7
- let(:alternative_B) { Split::Alternative.new 'B', 'experiment' }
8
- let(:alternative_C) { Split::Alternative.new 'C', 'experiment' }
6
+ let(:experiment) { Split::Experiment.new "experiment" }
7
+ let(:alternative_A) { Split::Alternative.new "A", "experiment" }
8
+ let(:alternative_B) { Split::Alternative.new "B", "experiment" }
9
+ let(:alternative_C) { Split::Alternative.new "C", "experiment" }
9
10
 
10
11
  before :each do
11
12
  allow(experiment).to receive(:alternatives) { [alternative_A, alternative_B, alternative_C] }
@@ -1,19 +1,20 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "spec_helper"
3
4
 
4
5
  describe Split::Algorithms::WeightedSample do
5
6
  it "should return an alternative" do
6
- experiment = Split::ExperimentCatalog.find_or_create('link_color', {'blue' => 100}, {'red' => 0 })
7
+ experiment = Split::ExperimentCatalog.find_or_create("link_color", { "blue" => 100 }, { "red" => 0 })
7
8
  expect(Split::Algorithms::WeightedSample.choose_alternative(experiment).class).to eq(Split::Alternative)
8
9
  end
9
10
 
10
11
  it "should always return a heavily weighted option" do
11
- experiment = Split::ExperimentCatalog.find_or_create('link_color', {'blue' => 100}, {'red' => 0 })
12
- expect(Split::Algorithms::WeightedSample.choose_alternative(experiment).name).to eq('blue')
12
+ experiment = Split::ExperimentCatalog.find_or_create("link_color", { "blue" => 100 }, { "red" => 0 })
13
+ expect(Split::Algorithms::WeightedSample.choose_alternative(experiment).name).to eq("blue")
13
14
  end
14
15
 
15
16
  it "should return one of the results" do
16
- experiment = Split::ExperimentCatalog.find_or_create('link_color', {'blue' => 1}, {'red' => 1 })
17
- expect(['red', 'blue']).to include Split::Algorithms::WeightedSample.choose_alternative(experiment).name
17
+ experiment = Split::ExperimentCatalog.find_or_create("link_color", { "blue" => 1 }, { "red" => 1 })
18
+ expect(["red", "blue"]).to include Split::Algorithms::WeightedSample.choose_alternative(experiment).name
18
19
  end
19
20
  end
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "spec_helper"
3
4
 
4
5
  describe Split::Algorithms::Whiplash do
5
-
6
6
  it "should return an algorithm" do
7
- experiment = Split::ExperimentCatalog.find_or_create('link_color', {'blue' => 1}, {'red' => 1 })
7
+ experiment = Split::ExperimentCatalog.find_or_create("link_color", { "blue" => 1 }, { "red" => 1 })
8
8
  expect(Split::Algorithms::Whiplash.choose_alternative(experiment).class).to eq(Split::Alternative)
9
9
  end
10
10
 
11
11
  it "should return one of the results" do
12
- experiment = Split::ExperimentCatalog.find_or_create('link_color', {'blue' => 1}, {'red' => 1 })
13
- expect(['red', 'blue']).to include Split::Algorithms::Whiplash.choose_alternative(experiment).name
12
+ experiment = Split::ExperimentCatalog.find_or_create("link_color", { "blue" => 1 }, { "red" => 1 })
13
+ expect(["red", "blue"]).to include Split::Algorithms::Whiplash.choose_alternative(experiment).name
14
14
  end
15
15
 
16
16
  it "should guess floats" do
@@ -20,5 +20,4 @@ describe Split::Algorithms::Whiplash do
20
20
  expect(Split::Algorithms::Whiplash.send(:arm_guess, 1000, 5).class).to eq(Float)
21
21
  expect(Split::Algorithms::Whiplash.send(:arm_guess, 10, -2).class).to eq(Float)
22
22
  end
23
-
24
23
  end
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
- require 'split/alternative'
4
2
 
5
- describe Split::Alternative do
3
+ require "spec_helper"
4
+ require "split/alternative"
6
5
 
6
+ describe Split::Alternative do
7
7
  let(:alternative) {
8
- Split::Alternative.new('Basket', 'basket_text')
8
+ Split::Alternative.new("Basket", "basket_text")
9
9
  }
10
10
 
11
11
  let(:alternative2) {
12
- Split::Alternative.new('Cart', 'basket_text')
12
+ Split::Alternative.new("Cart", "basket_text")
13
13
  }
14
14
 
15
15
  let!(:experiment) {
16
- Split::ExperimentCatalog.find_or_create({"basket_text" => ["purchase", "refund"]}, "Basket", "Cart")
16
+ Split::ExperimentCatalog.find_or_create({ "basket_text" => ["purchase", "refund"] }, "Basket", "Cart")
17
17
  }
18
18
 
19
19
  let(:goal1) { "purchase" }
@@ -24,48 +24,48 @@ describe Split::Alternative do
24
24
  end
25
25
 
26
26
  it "should have and only return the name" do
27
- expect(alternative.name).to eq('Basket')
27
+ expect(alternative.name).to eq("Basket")
28
28
  end
29
29
 
30
- describe 'weights' do
30
+ describe "weights" do
31
31
  it "should set the weights" do
32
- experiment = Split::Experiment.new('basket_text', :alternatives => [{'Basket' => 0.6}, {"Cart" => 0.4}])
32
+ experiment = Split::Experiment.new("basket_text", alternatives: [{ "Basket" => 0.6 }, { "Cart" => 0.4 }])
33
33
  first = experiment.alternatives[0]
34
- expect(first.name).to eq('Basket')
34
+ expect(first.name).to eq("Basket")
35
35
  expect(first.weight).to eq(0.6)
36
36
 
37
37
  second = experiment.alternatives[1]
38
- expect(second.name).to eq('Cart')
38
+ expect(second.name).to eq("Cart")
39
39
  expect(second.weight).to eq(0.4)
40
40
  end
41
41
 
42
42
  it "accepts probability on alternatives" do
43
43
  Split.configuration.experiments = {
44
- :my_experiment => {
45
- :alternatives => [
46
- { :name => "control_opt", :percent => 67 },
47
- { :name => "second_opt", :percent => 10 },
48
- { :name => "third_opt", :percent => 23 },
44
+ my_experiment: {
45
+ alternatives: [
46
+ { name: "control_opt", percent: 67 },
47
+ { name: "second_opt", percent: 10 },
48
+ { name: "third_opt", percent: 23 },
49
49
  ]
50
50
  }
51
51
  }
52
52
  experiment = Split::Experiment.new(:my_experiment)
53
53
  first = experiment.alternatives[0]
54
- expect(first.name).to eq('control_opt')
54
+ expect(first.name).to eq("control_opt")
55
55
  expect(first.weight).to eq(0.67)
56
56
 
57
57
  second = experiment.alternatives[1]
58
- expect(second.name).to eq('second_opt')
58
+ expect(second.name).to eq("second_opt")
59
59
  expect(second.weight).to eq(0.1)
60
60
  end
61
61
 
62
62
  it "accepts probability on some alternatives" do
63
63
  Split.configuration.experiments = {
64
- :my_experiment => {
65
- :alternatives => [
66
- { :name => "control_opt", :percent => 34 },
64
+ my_experiment: {
65
+ alternatives: [
66
+ { name: "control_opt", percent: 34 },
67
67
  "second_opt",
68
- { :name => "third_opt", :percent => 23 },
68
+ { name: "third_opt", percent: 23 },
69
69
  "fourth_opt",
70
70
  ],
71
71
  }
@@ -87,11 +87,11 @@ describe Split::Alternative do
87
87
  #
88
88
  it "allows name param without probability" do
89
89
  Split.configuration.experiments = {
90
- :my_experiment => {
91
- :alternatives => [
92
- { :name => "control_opt" },
90
+ my_experiment: {
91
+ alternatives: [
92
+ { name: "control_opt" },
93
93
  "second_opt",
94
- { :name => "third_opt", :percent => 64 },
94
+ { name: "third_opt", percent: 64 },
95
95
  ],
96
96
  }
97
97
  }
@@ -126,7 +126,7 @@ describe Split::Alternative do
126
126
 
127
127
  it "should save to redis" do
128
128
  alternative.save
129
- expect(Split.redis.exists?('basket_text:Basket')).to be true
129
+ expect(Split.redis.exists?("basket_text:Basket")).to be true
130
130
  end
131
131
 
132
132
  it "should increment participation count" do
@@ -166,7 +166,7 @@ describe Split::Alternative do
166
166
  expect(alternative2.control?).to be_falsey
167
167
  end
168
168
 
169
- describe 'unfinished_count' do
169
+ describe "unfinished_count" do
170
170
  it "should be difference between participant and completed counts" do
171
171
  alternative.increment_participation
172
172
  expect(alternative.unfinished_count).to eq(alternative.participant_count)
@@ -182,7 +182,7 @@ describe Split::Alternative do
182
182
  end
183
183
  end
184
184
 
185
- describe 'conversion rate' do
185
+ describe "conversion rate" do
186
186
  it "should be 0 if there are no conversions" do
187
187
  expect(alternative.completed_count).to eq(0)
188
188
  expect(alternative.conversion_rate).to eq(0)
@@ -225,8 +225,7 @@ describe Split::Alternative do
225
225
  end
226
226
  end
227
227
 
228
- describe 'z score' do
229
-
228
+ describe "z score" do
230
229
  it "should return an error string when the control has 0 people" do
231
230
  expect(alternative2.z_score).to eq("Needs 30+ participants.")
232
231
  expect(alternative2.z_score(goal1)).to eq("Needs 30+ participants.")
@@ -269,9 +268,9 @@ describe Split::Alternative do
269
268
 
270
269
  it "should be N/A for the control" do
271
270
  control = experiment.control
272
- expect(control.z_score).to eq('N/A')
273
- expect(control.z_score(goal1)).to eq('N/A')
274
- expect(control.z_score(goal2)).to eq('N/A')
271
+ expect(control.z_score).to eq("N/A")
272
+ expect(control.z_score(goal1)).to eq("N/A")
273
+ expect(control.z_score(goal2)).to eq("N/A")
275
274
  end
276
275
 
277
276
  it "should not blow up for Conversion Rates > 1" do
@@ -289,8 +288,8 @@ describe Split::Alternative do
289
288
 
290
289
  describe "extra_info" do
291
290
  it "reads saved value of recorded_info in redis" do
292
- saved_recorded_info = {"key_1" => 1, "key_2" => "2"}
293
- Split.redis.hset "#{alternative.experiment_name}:#{alternative.name}", 'recorded_info', saved_recorded_info.to_json
291
+ saved_recorded_info = { "key_1" => 1, "key_2" => "2" }
292
+ Split.redis.hset "#{alternative.experiment_name}:#{alternative.name}", "recorded_info", saved_recorded_info.to_json
294
293
  extra_info = alternative.extra_info
295
294
 
296
295
  expect(extra_info).to eql(saved_recorded_info)
data/spec/cache_spec.rb CHANGED
@@ -1,19 +1,18 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
2
 
4
- describe Split::Cache do
3
+ require "spec_helper"
5
4
 
5
+ describe Split::Cache do
6
6
  let(:namespace) { :test_namespace }
7
7
  let(:key) { :test_key }
8
8
  let(:now) { 1606189017 }
9
9
 
10
10
  before { allow(Time).to receive(:now).and_return(now) }
11
11
 
12
- describe 'clear' do
13
-
12
+ describe "clear" do
14
13
  before { Split.configuration.cache = true }
15
14
 
16
- it 'clears the cache' do
15
+ it "clears the cache" do
17
16
  expect(Time).to receive(:now).and_return(now).exactly(2).times
18
17
  Split::Cache.fetch(namespace, key) { Time.now }
19
18
  Split::Cache.clear
@@ -21,10 +20,10 @@ describe Split::Cache do
21
20
  end
22
21
  end
23
22
 
24
- describe 'clear_key' do
23
+ describe "clear_key" do
25
24
  before { Split.configuration.cache = true }
26
25
 
27
- it 'clears the cache' do
26
+ it "clears the cache" do
28
27
  expect(Time).to receive(:now).and_return(now).exactly(3).times
29
28
  Split::Cache.fetch(namespace, :key1) { Time.now }
30
29
  Split::Cache.fetch(namespace, :key2) { Time.now }
@@ -35,40 +34,37 @@ describe Split::Cache do
35
34
  end
36
35
  end
37
36
 
38
- describe 'fetch' do
39
-
37
+ describe "fetch" do
40
38
  subject { Split::Cache.fetch(namespace, key) { Time.now } }
41
39
 
42
- context 'when cache disabled' do
43
-
40
+ context "when cache disabled" do
44
41
  before { Split.configuration.cache = false }
45
42
 
46
- it 'returns the yield' do
43
+ it "returns the yield" do
47
44
  expect(subject).to eql(now)
48
45
  end
49
46
 
50
- it 'yields every time' do
47
+ it "yields every time" do
51
48
  expect(Time).to receive(:now).and_return(now).exactly(2).times
52
49
  Split::Cache.fetch(namespace, key) { Time.now }
53
50
  Split::Cache.fetch(namespace, key) { Time.now }
54
51
  end
55
52
  end
56
53
 
57
- context 'when cache enabled' do
58
-
54
+ context "when cache enabled" do
59
55
  before { Split.configuration.cache = true }
60
56
 
61
- it 'returns the yield' do
57
+ it "returns the yield" do
62
58
  expect(subject).to eql(now)
63
59
  end
64
60
 
65
- it 'yields once' do
61
+ it "yields once" do
66
62
  expect(Time).to receive(:now).and_return(now).once
67
63
  Split::Cache.fetch(namespace, key) { Time.now }
68
64
  Split::Cache.fetch(namespace, key) { Time.now }
69
65
  end
70
66
 
71
- it 'honors namespace' do
67
+ it "honors namespace" do
72
68
  expect(Split::Cache.fetch(:a, key) { :a }).to eql(:a)
73
69
  expect(Split::Cache.fetch(:b, key) { :b }).to eql(:b)
74
70
 
@@ -76,7 +72,7 @@ describe Split::Cache do
76
72
  expect(Split::Cache.fetch(:b, key) { :b }).to eql(:b)
77
73
  end
78
74
 
79
- it 'honors key' do
75
+ it "honors key" do
80
76
  expect(Split::Cache.fetch(namespace, :a) { :a }).to eql(:a)
81
77
  expect(Split::Cache.fetch(namespace, :b) { :b }).to eql(:b)
82
78