vinted-ab 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6e46f66084e779a1eeca15edf6b3eba928b747b
4
- data.tar.gz: 5e47066cb8520292d863b97be976f42c7d93e0fa
3
+ metadata.gz: f227fe8202a3994a25c47c152ed4ca675ad5d571
4
+ data.tar.gz: f50d6b977402e19d57a62cba1a9affcf749d011a
5
5
  SHA512:
6
- metadata.gz: ed4970561d2c2ec748f29ea3d5c378d8b181a1dea026a12d6d7eea4fcaa0d930c5c55283bead185d8d81bb9f35e5a13675d56e4f455397ec58456e431c46310b
7
- data.tar.gz: b56781fed1989fe0f536afafbb7dcce815feb0a7bc99c2056bef91a5b15e4af1c5c5000eb6c02ec19277207da6a6493cc42fbf93994fcb48c791362ef106dd39
6
+ metadata.gz: dedbd7a58d4d5490e6a27677f36e31dc426ec762a063bbb10c7c2b80cd41fa11efed903e575a63f0dc301603f41529d30eb285e1e836ca39b5196e3b40f188bd
7
+ data.tar.gz: 41246c457af514bea7a803938b3418a87a195e4cae254abe0080ea081ffd6e850f5a183c1065af8a7a9077257af6b649c961b92cf2d29bbc1d67ee051a9d382c
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.1
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # ab
2
2
 
3
3
  [![Code Climate](https://codeclimate.com/github/vinted/ab.png)](https://codeclimate.com/github/vinted/ab)
4
+ [![Build Status](https://secure.travis-ci.org/vinted/ab.png)](http://travis-ci.org/vinted/ab)
4
5
  [![Gem Version](https://badge.fury.io/rb/vinted-ab.png)](http://badge.fury.io/rb/vinted-ab)
5
6
  [![Dependency Status](https://gemnasium.com/vinted/ab.png)](https://gemnasium.com/vinted/ab)
6
7
 
@@ -19,6 +20,11 @@ ab = Ab::Tests.new(configuration, identifier)
19
20
  Ab::Tests.before_picking_variant { |test| puts "picking variant for #{test}" }
20
21
  Ab::Tests.after_picking_variant { |test, variant| puts "#{variant_name}" }
21
22
 
23
+ # by default messages are logged to null logger. Can be changed by setting your own logger:
24
+ Ab.configure do |config|
25
+ config.logger = Logger.new($stdout)
26
+ end
27
+
22
28
  # ab.test never returns nil, but #variant can
23
29
  case ab.test.variant
24
30
  when 'red_button'
@@ -32,6 +38,9 @@ end
32
38
  # calls #variant underneath, results of that call are cached
33
39
  puts 'red button' if ab.test.red_button?
34
40
 
41
+ # non existant variants return false
42
+ puts 'this will not get printed' if ab.test.there_is_no_button?
43
+
35
44
  # both start_at and end_at dates are accessible
36
45
  puts 'newbie button' if user.created_at > ab.test.start_at && ab.test.for_newbies?
37
46
  ```
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
- require 'bundler/gem_tasks'
1
+ #!/usr/bin/env rake
2
+ require 'bundler'
3
+ require 'rspec/core/rake_task'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task(:default).clear
9
+ task default: [:spec]
data/ab.gemspec CHANGED
@@ -19,10 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency 'bundler', '~> 1.3'
23
- spec.add_development_dependency 'rake', '~> 10.1', '>= 10.1.0'
24
- spec.add_development_dependency 'rspec', '~> 2.14', '>= 2.14.0'
25
- spec.add_development_dependency 'rspec-its', '~> 1.0.1'
22
+ spec.add_development_dependency 'rake', '~> 10.3'
23
+ spec.add_development_dependency 'rspec', '~> 3.0'
24
+ spec.add_development_dependency 'rspec-its', '~> 1.0'
26
25
  spec.add_development_dependency 'json-schema', '~> 2.2.2', '>= 2.2.2'
27
26
  spec.add_development_dependency 'ruby-prof', '~> 0.15.0', '>= 0.15.0'
28
27
  spec.add_development_dependency 'pry', '~> 0.10.0', '>= 0.10.0'
data/lib/ab.rb CHANGED
@@ -1,4 +1,9 @@
1
+ require 'securerandom'
2
+ require 'date'
3
+ require 'logger'
1
4
  require 'ab/version'
5
+ require 'ab/configuration'
6
+ require 'ab/missing_variant'
2
7
  require 'ab/null_test'
3
8
  require 'ab/variant'
4
9
  require 'ab/test'
@@ -1,5 +1,7 @@
1
1
  module Ab
2
2
  class AssignedTest
3
+ include Ab::MissingVariant
4
+
3
5
  def initialize(test, id)
4
6
  @test, @id = test, id
5
7
  variants.each do |name|
@@ -0,0 +1,22 @@
1
+ module Ab
2
+ class << self
3
+ attr_writer :config
4
+
5
+ def config
6
+ @config ||= Config.new
7
+ end
8
+
9
+ def configure
10
+ @config ||= Config.new
11
+ yield(@config)
12
+ end
13
+ end
14
+
15
+ class Config
16
+ attr_accessor :logger
17
+
18
+ def initialize
19
+ @logger = Logger.new(nil)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ module Ab
2
+ module MissingVariant
3
+ def method_missing(meth, *args, &block)
4
+ if variant_method?(meth)
5
+ log_missing_variant(meth)
6
+ false
7
+ else
8
+ super
9
+ end
10
+ end
11
+
12
+ def respond_to_missing?(meth, *)
13
+ variant_method?(meth) ? true : super
14
+ end
15
+
16
+ private
17
+
18
+ def variant_method?(meth)
19
+ meth.to_s.end_with?('?')
20
+ end
21
+
22
+ def log_missing_variant(meth)
23
+ Ab.config.logger.debug("[AB_testing] Checking non-existing variant: #{meth}")
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,7 @@
1
1
  module Ab
2
2
  class NullTest
3
+ include Ab::MissingVariant
4
+
3
5
  def variant
4
6
  end
5
7
 
@@ -10,14 +12,5 @@ module Ab
10
12
  def end_at
11
13
  Test::DEFAULT_END_AT
12
14
  end
13
-
14
-
15
- def method_missing(meth, *args, &block)
16
- meth.to_s.end_with?('?') ? false : super
17
- end
18
-
19
- def respond_to?(meth)
20
- meth.to_s.end_with?('?') ? true : super
21
- end
22
15
  end
23
16
  end
@@ -34,7 +34,7 @@ module Ab
34
34
  @null_test ||= NullTest.new
35
35
  end
36
36
 
37
- def respond_to?(*)
37
+ def respond_to_missing?(*)
38
38
  true
39
39
  end
40
40
  end
@@ -1,3 +1,3 @@
1
1
  module Ab
2
- VERSION = '0.2.4'
2
+ VERSION = '0.2.5'
3
3
  end
@@ -16,6 +16,17 @@ module Ab
16
16
  let(:buckets) { 1..1000 }
17
17
  let(:thousand_variants) { 1.upto(1000).map { |i| AssignedTest.new(test, i).variant } }
18
18
 
19
+ context 'with non existent variant' do
20
+ let(:variants) { [OpenStruct.new(name: 'enabled', accumulated_chance_weight: 2)] }
21
+ let(:message) { '[AB_testing] Checking non-existing variant: disabled?' }
22
+
23
+ before { Ab.config.logger.should_receive(:debug).with(message) }
24
+
25
+ subject { assigned_test.disabled? }
26
+
27
+ it { should be false }
28
+ end
29
+
19
30
  describe '#variant' do
20
31
  subject { assigned_test.variant }
21
32
 
@@ -0,0 +1,23 @@
1
+ {
2
+ "salt": "61b81d7844c40c4057ebe6fc1a7a4a54",
3
+ "bucket_count": 20,
4
+ "ab_tests": [
5
+ {
6
+ "id": 6,
7
+ "name": "no_end",
8
+ "seed": "1995f6808c018b6dd91a3bc927fd7e92",
9
+ "start_at": "1605-11-05T00:00:00+0100",
10
+ "all_buckets": true,
11
+ "variants": [
12
+ {
13
+ "name": "green",
14
+ "chance_weight": 1
15
+ },
16
+ {
17
+ "name": "red",
18
+ "chance_weight": 1
19
+ }
20
+ ]
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "test": "no_end",
3
+ "variants": {
4
+ "green": [1, 2, 3, 7, 8, 9, 12, 19, 31, 34],
5
+ "red": [6, 13, 18, 22, 23, 26, 27, 29, 36, 39]
6
+ }
7
+ }
@@ -9,11 +9,11 @@ module Ab
9
9
  its(:end_at) { should_not be_nil }
10
10
 
11
11
  specify 'does not raise for method ending in question mark' do
12
- expect { subject.bla? }.to_not raise_error
12
+ lambda { subject.bla? }.should_not raise_error
13
13
  end
14
14
 
15
15
  specify 'raises for method not ending in question mark' do
16
- expect { subject.bla }.to raise_error
16
+ lambda { subject.bla }.should raise_error
17
17
  end
18
18
  end
19
19
  end
@@ -1,8 +1,9 @@
1
+ require 'json'
1
2
  require 'rspec'
2
3
  require 'rspec/its'
3
4
  require 'ab'
4
5
 
5
6
  RSpec.configure do |config|
6
- config.color = true
7
- config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.expect_with(:rspec) { |c| c.syntax = :should }
8
+ config.mock_with(:rspec) { |c| c.syntax = :should }
8
9
  end
@@ -52,7 +52,7 @@ module Ab
52
52
  subject { tests }
53
53
 
54
54
  specify 'has no public methods' do
55
- (subject.public_methods(false) - [:method_missing, :respond_to?, :all]).count.should == 0
55
+ (subject.public_methods(false) - [:method_missing, :respond_to_missing?, :all]).count.should == 0
56
56
  end
57
57
 
58
58
  context 'single experiment with single variant' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vinted-ab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mindaugas Mozūras
@@ -9,76 +9,50 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-08 00:00:00.000000000 Z
12
+ date: 2015-05-19 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '1.3'
21
- type: :development
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - "~>"
26
- - !ruby/object:Gem::Version
27
- version: '1.3'
28
14
  - !ruby/object:Gem::Dependency
29
15
  name: rake
30
16
  requirement: !ruby/object:Gem::Requirement
31
17
  requirements:
32
18
  - - "~>"
33
19
  - !ruby/object:Gem::Version
34
- version: '10.1'
35
- - - ">="
36
- - !ruby/object:Gem::Version
37
- version: 10.1.0
20
+ version: '10.3'
38
21
  type: :development
39
22
  prerelease: false
40
23
  version_requirements: !ruby/object:Gem::Requirement
41
24
  requirements:
42
25
  - - "~>"
43
26
  - !ruby/object:Gem::Version
44
- version: '10.1'
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 10.1.0
27
+ version: '10.3'
48
28
  - !ruby/object:Gem::Dependency
49
29
  name: rspec
50
30
  requirement: !ruby/object:Gem::Requirement
51
31
  requirements:
52
32
  - - "~>"
53
33
  - !ruby/object:Gem::Version
54
- version: '2.14'
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: 2.14.0
34
+ version: '3.0'
58
35
  type: :development
59
36
  prerelease: false
60
37
  version_requirements: !ruby/object:Gem::Requirement
61
38
  requirements:
62
39
  - - "~>"
63
40
  - !ruby/object:Gem::Version
64
- version: '2.14'
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: 2.14.0
41
+ version: '3.0'
68
42
  - !ruby/object:Gem::Dependency
69
43
  name: rspec-its
70
44
  requirement: !ruby/object:Gem::Requirement
71
45
  requirements:
72
46
  - - "~>"
73
47
  - !ruby/object:Gem::Version
74
- version: 1.0.1
48
+ version: '1.0'
75
49
  type: :development
76
50
  prerelease: false
77
51
  version_requirements: !ruby/object:Gem::Requirement
78
52
  requirements:
79
53
  - - "~>"
80
54
  - !ruby/object:Gem::Version
81
- version: 1.0.1
55
+ version: '1.0'
82
56
  - !ruby/object:Gem::Dependency
83
57
  name: json-schema
84
58
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +123,7 @@ extra_rdoc_files: []
149
123
  files:
150
124
  - ".gitignore"
151
125
  - ".rubocop.yml"
126
+ - ".travis.yml"
152
127
  - Gemfile
153
128
  - LICENSE
154
129
  - README.md
@@ -157,6 +132,8 @@ files:
157
132
  - config.json
158
133
  - lib/ab.rb
159
134
  - lib/ab/assigned_test.rb
135
+ - lib/ab/configuration.rb
136
+ - lib/ab/missing_variant.rb
160
137
  - lib/ab/null_test.rb
161
138
  - lib/ab/test.rb
162
139
  - lib/ab/tests.rb
@@ -181,6 +158,8 @@ files:
181
158
  - spec/examples/multiple_variants/output.json
182
159
  - spec/examples/no_buckets/input.json
183
160
  - spec/examples/no_buckets/output.json
161
+ - spec/examples/no_end/input.json
162
+ - spec/examples/no_end/output.json
184
163
  - spec/examples/no_variants/input.json
185
164
  - spec/examples/no_variants/output.json
186
165
  - spec/examples/zero_buckets/input.json
@@ -212,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
191
  version: 1.3.6
213
192
  requirements: []
214
193
  rubyforge_project:
215
- rubygems_version: 2.3.0
194
+ rubygems_version: 2.4.5
216
195
  signing_key:
217
196
  specification_version: 4
218
197
  summary: AB testing gem used internally by Vinted