ab_panel 0.3.3 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/ab_panel.gemspec +3 -3
- data/lib/ab_panel.rb +18 -0
- data/lib/ab_panel/controller_additions.rb +6 -4
- data/lib/ab_panel/version.rb +1 -1
- data/spec/ab_panel/config_spec.rb +6 -6
- data/spec/ab_panel/controller_additions_spec.rb +2 -2
- data/spec/ab_panel/javascript_spec.rb +2 -2
- data/spec/ab_panel_spec.rb +13 -13
- data/spec/array_spec.rb +13 -13
- data/spec/spec_helper.rb +0 -1
- data/spec/support/rails.rb +2 -2
- metadata +19 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ab8ac9d946978fcbccd263665138478ec313ffa
|
4
|
+
data.tar.gz: e1b49731529c1cfc1479b7016e134ea9283f0394
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65e75cf20b2ec836532920e46bafd64357f59c4fa6ea7e9422a096804ea73fab7232cec0a0a80279a5081a4abf021f7db1b545fffd1e3eba0c3578d515cfe890
|
7
|
+
data.tar.gz: 19d6c9284f032990bde35b91915b5b82e5c6063112124b674cb70dd620cb8f38ff570b185115dc0f8a0215736a703465255666a69a40643aeac9f529ec2c3727
|
data/.travis.yml
CHANGED
data/ab_panel.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = AbPanel::VERSION
|
9
9
|
spec.authors = ["Wouter de Vos", "Mark Mulder", "Peter de Ruijter"]
|
10
10
|
spec.email = ["wouter@springest.com", "markmulder@gmail.com", "hello@thisiswho.im"]
|
11
|
-
spec.description = %q{Run A/B test experiments on your Rails
|
12
|
-
spec.summary = %q{Run A/B test experiments on your Rails
|
11
|
+
spec.description = %q{Run A/B test experiments on your Rails 4+ site using Mixpanel as a backend.}
|
12
|
+
spec.summary = %q{Run A/B test experiments on your Rails 4+ site using Mixpanel as a backend.}
|
13
13
|
spec.homepage = "https://github.com/Springest/ab_panel"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -19,11 +19,11 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
-
spec.add_development_dependency "rails", '~> 3.2'
|
23
22
|
spec.add_development_dependency "rake"
|
24
23
|
spec.add_development_dependency "fakeweb"
|
25
24
|
spec.add_development_dependency "rspec"
|
26
25
|
spec.add_development_dependency "byebug"
|
27
26
|
|
27
|
+
spec.add_runtime_dependency "rails", '~> 4.0'
|
28
28
|
spec.add_runtime_dependency "mixpanel"
|
29
29
|
end
|
data/lib/ab_panel.rb
CHANGED
@@ -22,6 +22,16 @@ module AbPanel
|
|
22
22
|
Thread.current[:ab_panel_conditions] ||= assign_conditions!
|
23
23
|
end
|
24
24
|
|
25
|
+
def serialized_conditions
|
26
|
+
cs = {}
|
27
|
+
|
28
|
+
conditions.each_pair do |key, value|
|
29
|
+
cs[key] = value.marshal_dump
|
30
|
+
end
|
31
|
+
|
32
|
+
cs.to_json
|
33
|
+
end
|
34
|
+
|
25
35
|
# Set the experiment's conditions.
|
26
36
|
#
|
27
37
|
# This is used to persist conditions from
|
@@ -79,6 +89,14 @@ module AbPanel
|
|
79
89
|
def assign_conditions!(already_assigned=nil)
|
80
90
|
cs = {}
|
81
91
|
|
92
|
+
if already_assigned
|
93
|
+
already_assigned.each do |key, value|
|
94
|
+
already_assigned[key] = OpenStruct.new(already_assigned[key])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
already_assigned = OpenStruct.new already_assigned
|
99
|
+
|
82
100
|
experiments.each do |experiment|
|
83
101
|
cs[experiment] ||= {}
|
84
102
|
|
@@ -48,10 +48,12 @@ module AbPanel
|
|
48
48
|
# in the user's session.
|
49
49
|
def initialize_ab_panel!(options = {})
|
50
50
|
AbPanel.reset!
|
51
|
-
|
52
|
-
cookies.signed[
|
53
|
-
|
54
|
-
cookies.signed[
|
51
|
+
|
52
|
+
AbPanel.conditions = JSON.parse(cookies.signed[:ab_panel_conditions])
|
53
|
+
|
54
|
+
cookies.signed[:ab_panel_conditions] = AbPanel.serialized_conditions
|
55
|
+
AbPanel.funnels = Set.new(cookies.signed[:ab_panel_funnels])
|
56
|
+
cookies.signed[:ab_panel_funnels] = AbPanel.funnels
|
55
57
|
|
56
58
|
{
|
57
59
|
'distinct_id' => distinct_id,
|
data/lib/ab_panel/version.rb
CHANGED
@@ -4,32 +4,32 @@ describe AbPanel::Config do
|
|
4
4
|
let(:config) { AbPanel::Config.new }
|
5
5
|
context "config" do
|
6
6
|
before do
|
7
|
-
AbPanel::Config.
|
7
|
+
allow_any_instance_of(AbPanel::Config).to receive(:settings) { { exp1: { scenario1: 25, scenario2: 75 } } }
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '.experiments' do
|
11
11
|
subject { config.experiments }
|
12
|
-
it {
|
12
|
+
it { is_expected.to match_array [:exp1] }
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '.weights' do
|
16
16
|
subject { config.weights('exp1') }
|
17
17
|
|
18
|
-
it {
|
18
|
+
it { is_expected.to match_array [75.0, 25.0] }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
context "empty config" do
|
22
22
|
before do
|
23
|
-
YAML.
|
23
|
+
allow(YAML).to receive(:load) { false }
|
24
24
|
end
|
25
25
|
describe ".settings" do
|
26
26
|
subject { config.settings }
|
27
|
-
it {
|
27
|
+
it { is_expected.to eq nil }
|
28
28
|
end
|
29
29
|
|
30
30
|
describe ".experiments" do
|
31
31
|
subject { config.experiments }
|
32
|
-
it {
|
32
|
+
it { is_expected.to eq({}) }
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -13,9 +13,9 @@ describe AbPanel::ControllerAdditions do
|
|
13
13
|
|
14
14
|
describe "#distinct_id" do
|
15
15
|
let(:cookies) { {} }
|
16
|
-
before { controller.
|
16
|
+
before { expect(controller).to receive_message_chain(:cookies, :signed).and_return(cookies) }
|
17
17
|
subject { controller.distinct_id }
|
18
18
|
|
19
|
-
it {
|
19
|
+
it { is_expected.to match /^([A-Z]|[0-9])([A-Z]|[0-9])([A-Z]|[0-9])([A-Z]|[0-9])([A-Z]|[0-9])$/ }
|
20
20
|
end
|
21
21
|
end
|
@@ -5,12 +5,12 @@ describe AbPanel::Javascript do
|
|
5
5
|
AbPanel.set_env('distinct_id', 'distinct_id')
|
6
6
|
AbPanel.set_env(:properties, { post_name: 'test' })
|
7
7
|
result = JSON.parse(AbPanel::Javascript.environment)
|
8
|
-
result['distinct_id'].
|
8
|
+
expect(result['distinct_id']).to eq 'distinct_id'
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'works without extra properties' do
|
12
12
|
AbPanel.set_env(:properties, nil)
|
13
13
|
result = JSON.parse(AbPanel::Javascript.environment)
|
14
|
-
result['distinct_id'].
|
14
|
+
expect(result['distinct_id']).to eq 'distinct_id'
|
15
15
|
end
|
16
16
|
end
|
data/spec/ab_panel_spec.rb
CHANGED
@@ -4,14 +4,14 @@ describe AbPanel do
|
|
4
4
|
describe ".experiments" do
|
5
5
|
subject { AbPanel.experiments }
|
6
6
|
|
7
|
-
it {
|
7
|
+
it { is_expected.to match_array %w(experiment1 experiment2).map(&:to_sym) }
|
8
8
|
end
|
9
9
|
|
10
10
|
describe ".weights" do
|
11
11
|
let(:experiment) { AbPanel.experiments.first }
|
12
12
|
subject { AbPanel.weights(experiment) }
|
13
13
|
|
14
|
-
it {
|
14
|
+
it { is_expected.to eq [25, 25, 25, 25] }
|
15
15
|
|
16
16
|
describe "With a nonexistent experiment" do
|
17
17
|
let(:experiment) { :does_not_exist }
|
@@ -27,7 +27,7 @@ describe AbPanel do
|
|
27
27
|
|
28
28
|
let(:experiment) { AbPanel.experiments.first }
|
29
29
|
|
30
|
-
it {
|
30
|
+
it { is_expected.to match_array %w( scenario1 scenario2 scenario3 original ).map(&:to_sym) }
|
31
31
|
|
32
32
|
describe "With an nonexistent experiment" do
|
33
33
|
let(:experiment) { :does_not_exist }
|
@@ -41,8 +41,8 @@ describe AbPanel do
|
|
41
41
|
describe ".conditions" do
|
42
42
|
subject { AbPanel.conditions.experiment1 }
|
43
43
|
|
44
|
-
it {
|
45
|
-
it {
|
44
|
+
it { is_expected.to respond_to :scenario1? }
|
45
|
+
it { is_expected.to respond_to :original? }
|
46
46
|
|
47
47
|
describe 'uniqueness' do
|
48
48
|
let(:conditions) do
|
@@ -54,10 +54,10 @@ describe AbPanel do
|
|
54
54
|
]
|
55
55
|
end
|
56
56
|
|
57
|
-
it { conditions.any
|
58
|
-
it { conditions.all
|
59
|
-
it { conditions.select{|c| c}.size.
|
60
|
-
it { conditions.reject{|c| c}.size.
|
57
|
+
it { expect(conditions.any?).to be true }
|
58
|
+
it { expect(conditions.all?).to be false }
|
59
|
+
it { expect(conditions.select{|c| c}.size).to be 1 }
|
60
|
+
it { expect(conditions.reject{|c| c}.size).to be 3 }
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -72,24 +72,24 @@ describe AbPanel do
|
|
72
72
|
|
73
73
|
it 'adds a funnel' do
|
74
74
|
AbPanel.add_funnel('search')
|
75
|
-
AbPanel.funnels.to_a.
|
75
|
+
expect(AbPanel.funnels.to_a).to eq ['search']
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'only adds a funnel when present' do
|
79
79
|
AbPanel.add_funnel(nil)
|
80
|
-
AbPanel.funnels.to_a.
|
80
|
+
expect(AbPanel.funnels.to_a).to eq []
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'does not add a funnel twice' do
|
84
84
|
AbPanel.add_funnel('search')
|
85
85
|
AbPanel.add_funnel('search')
|
86
|
-
AbPanel.funnels.to_a.
|
86
|
+
expect(AbPanel.funnels.to_a).to eq ['search']
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'sets funnels' do
|
90
90
|
funnels = Set.new ['search', 'cta']
|
91
91
|
AbPanel.funnels = funnels
|
92
|
-
AbPanel.funnels.to_a.
|
92
|
+
expect(AbPanel.funnels.to_a).to eq funnels.to_a
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
data/spec/array_spec.rb
CHANGED
@@ -3,47 +3,47 @@ require 'spec_helper'
|
|
3
3
|
describe Array do
|
4
4
|
describe '.weighted_sample' do
|
5
5
|
before do
|
6
|
-
Kernel.
|
6
|
+
allow(Kernel).to receive(:rand) { 0.5 }
|
7
7
|
end
|
8
8
|
|
9
9
|
context "Stub test" do
|
10
10
|
subject { Kernel.rand }
|
11
|
-
it {
|
11
|
+
it { is_expected.to eq 0.5 }
|
12
12
|
end
|
13
13
|
|
14
14
|
let(:array) { [1, 2, 3, 4] }
|
15
15
|
subject { array.weighted_sample }
|
16
16
|
|
17
|
-
it {
|
17
|
+
it { is_expected.to eq 3 }
|
18
18
|
|
19
19
|
context "different random" do
|
20
20
|
before do
|
21
|
-
Kernel.
|
21
|
+
allow(Kernel).to receive(:rand) { 0 }
|
22
22
|
end
|
23
23
|
|
24
|
-
it {
|
24
|
+
it { is_expected.to eq 1 }
|
25
25
|
end
|
26
26
|
|
27
27
|
context "different random" do
|
28
28
|
before do
|
29
|
-
Kernel.
|
29
|
+
allow(Kernel).to receive(:rand) { 1 }
|
30
30
|
end
|
31
31
|
|
32
|
-
it {
|
32
|
+
it { is_expected.to eq 4 }
|
33
33
|
end
|
34
34
|
|
35
35
|
context "with weights" do
|
36
36
|
subject { array.weighted_sample([1, 0, 0, 0]) }
|
37
|
-
it {
|
37
|
+
it { is_expected.to eq 1 }
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
context "all the same weights" do
|
41
|
-
before { Kernel.
|
41
|
+
before { allow(Kernel).to receive(:rand) { 1 } }
|
42
42
|
subject { array.weighted_sample([0, 0, 0, 0]) }
|
43
|
-
it {
|
43
|
+
it { is_expected.to eq 4 }
|
44
44
|
context "random 0" do
|
45
|
-
before { Kernel.
|
46
|
-
it {
|
45
|
+
before { allow(Kernel).to receive(:rand) { 0 } }
|
46
|
+
it { is_expected.to eq 1 }
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/rails.rb
CHANGED
@@ -2,7 +2,7 @@ require 'rails'
|
|
2
2
|
|
3
3
|
RSpec.configure do |c|
|
4
4
|
c.before do
|
5
|
-
Rails.
|
6
|
-
Rails.
|
5
|
+
allow(Rails).to receive(:root) { File.expand_path( '../files', __FILE__ ) }
|
6
|
+
allow(Rails).to receive(:env) { 'test' }
|
7
7
|
end
|
8
8
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ab_panel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wouter de Vos
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-07-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -26,20 +26,6 @@ dependencies:
|
|
26
26
|
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '1.3'
|
29
|
-
- !ruby/object:Gem::Dependency
|
30
|
-
name: rails
|
31
|
-
requirement: !ruby/object:Gem::Requirement
|
32
|
-
requirements:
|
33
|
-
- - "~>"
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: '3.2'
|
36
|
-
type: :development
|
37
|
-
prerelease: false
|
38
|
-
version_requirements: !ruby/object:Gem::Requirement
|
39
|
-
requirements:
|
40
|
-
- - "~>"
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: '3.2'
|
43
29
|
- !ruby/object:Gem::Dependency
|
44
30
|
name: rake
|
45
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -96,6 +82,20 @@ dependencies:
|
|
96
82
|
- - ">="
|
97
83
|
- !ruby/object:Gem::Version
|
98
84
|
version: '0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: rails
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - "~>"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '4.0'
|
92
|
+
type: :runtime
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - "~>"
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '4.0'
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
100
|
name: mixpanel
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,7 +110,7 @@ dependencies:
|
|
110
110
|
- - ">="
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: '0'
|
113
|
-
description: Run A/B test experiments on your Rails
|
113
|
+
description: Run A/B test experiments on your Rails 4+ site using Mixpanel as a backend.
|
114
114
|
email:
|
115
115
|
- wouter@springest.com
|
116
116
|
- markmulder@gmail.com
|
@@ -228,10 +228,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
228
|
version: '0'
|
229
229
|
requirements: []
|
230
230
|
rubyforge_project:
|
231
|
-
rubygems_version: 2.2.
|
231
|
+
rubygems_version: 2.2.5
|
232
232
|
signing_key:
|
233
233
|
specification_version: 4
|
234
|
-
summary: Run A/B test experiments on your Rails
|
234
|
+
summary: Run A/B test experiments on your Rails 4+ site using Mixpanel as a backend.
|
235
235
|
test_files:
|
236
236
|
- example/.gitignore
|
237
237
|
- example/Gemfile
|