vanity 1.8.1 → 1.8.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.
@@ -1,23 +1,65 @@
1
1
  language: ruby
2
2
  bundler_args: --without development
3
- script: 'rake appraisal test'
3
+ script: 'bundle exec rake test'
4
4
  services:
5
5
  - mongodb
6
6
  rvm:
7
7
  - 1.8.7
8
8
  - 1.9.3
9
9
  - 2.0.0
10
- - ruby-head
11
10
  env:
12
11
  - DB=mongodb
13
12
  - DB=redis
14
13
  - DB=mysql
15
14
  #- DB=postgres
15
+ gemfile:
16
+ - Gemfile
17
+ - gemfiles/rails3.gemfile
18
+ - gemfiles/rails31.gemfile
19
+ - gemfiles/rails32.gemfile
16
20
  before_script:
21
+ - if [[ "`basename $BUNDLE_GEMFILE`" == "Gemfile" ]]; then rvm rubygems 1.8.25; fi # Rubygems 2.0.x fails with Rails 2.3
17
22
  - "mysql -e 'create database vanity_test;' >/dev/null"
18
- - "rake appraisal:install"
19
- #- "psql -c 'create database vanity_test;' -U postgres >/dev/null"
23
+ #- if [[ "$DB" == "pgsql" ]]; then psql -c 'create database vanity_test;' -U postgres >/dev/null; fi
20
24
  matrix:
21
- allow_failures:
25
+ exclude:
26
+ # Rails 2 is not officially supported on Ruby 1.9.3
27
+ - rvm: 1.9.3
28
+ env: DB=mongodb
29
+ gemfile: Gemfile
30
+ - rvm: 1.9.3
31
+ env: DB=redis
32
+ gemfile: Gemfile
33
+ - rvm: 1.9.3
34
+ env: DB=mysql
35
+ gemfile: Gemfile
36
+ # Rails <= 3.2 is not officially supported on Ruby 2.0.0
37
+ - rvm: 2.0.0
38
+ env: DB=mongodb
39
+ gemfile: Gemfile
40
+ - rvm: 2.0.0
41
+ env: DB=redis
42
+ gemfile: Gemfile
43
+ - rvm: 2.0.0
44
+ env: DB=mysql
45
+ gemfile: Gemfile
46
+ - rvm: 2.0.0
47
+ env: DB=mongodb
48
+ gemfile: gemfiles/rails3.gemfile
22
49
  - rvm: 2.0.0
50
+ env: DB=redis
51
+ gemfile: gemfiles/rails3.gemfile
52
+ - rvm: 2.0.0
53
+ env: DB=mysql
54
+ gemfile: gemfiles/rails3.gemfile
55
+ allow_failures:
23
56
  - rvm: ruby-head
57
+ - rvm: 2.0.0
58
+ env: DB=mongodb
59
+ gemfile: gemfiles/rails31.gemfile
60
+ - rvm: 2.0.0
61
+ env: DB=redis
62
+ gemfile: gemfiles/rails31.gemfile
63
+ - rvm: 2.0.0
64
+ env: DB=mysql
65
+ gemfile: gemfiles/rails31.gemfile
data/Appraisals CHANGED
@@ -1,15 +1,17 @@
1
1
  appraise "rails3" do
2
2
  gem "rails", "3.0.11"
3
+ gem "fastthread", :git => "git://github.com/zoltankiss/fastthread.git", :platforms => :mri_20
3
4
  gem "passenger", "~>3.0"
4
5
  end
5
6
 
6
7
  appraise "rails31" do
7
8
  gem "rails", "3.1.3"
9
+ gem "fastthread", :git => "git://github.com/zoltankiss/fastthread.git", :platforms => :mri_20
8
10
  gem "passenger", "~>3.0"
9
11
  end
10
12
 
11
13
  appraise "rails32" do
12
14
  gem "rails", "3.2.1"
15
+ gem "fastthread", :git => "git://github.com/zoltankiss/fastthread.git", :platforms => :mri_20
13
16
  gem "passenger", "~>3.0"
14
17
  end
15
-
data/CHANGELOG CHANGED
@@ -1,8 +1,14 @@
1
+ == 1.8.2 (2013-10-27)
2
+
3
+ Optimize metric_values query (@zawaideh).
4
+ Add an on_assignment hook for experiments which is called when an identity is given an assignment in ab_test (@lotze)
5
+ Finish Ruby 2.0 compatiblity with testing setup and add ActionMailer test coverage (@phillbaker).
6
+
1
7
  == 1.8.1 (2013-10-05)
2
8
 
3
9
  Added vanity_experiments helper for rails to return read only copy of active experiments (@iceberg901).
4
10
  Fixed support for Mass Assignment on Rails 3.2 (@hcarver).
5
- Fixed commandlin usage (@phillbaker).
11
+ Fixed commandline usage (@phillbaker).
6
12
 
7
13
 
8
14
  == 1.8.0 (2012-03-12)
data/Gemfile CHANGED
@@ -1,22 +1,33 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
- gem "appraisal"
4
+ # Frameworks
5
+ gem "rack"
6
+ gem "rails", "~>2.3.8"
7
+
8
+ # Servers
9
+ gem "passenger", "~>2.0"
10
+
11
+ # Persistence
5
12
  gem "bson_ext"
6
- gem "garb"
7
- gem "mocha"
8
13
  gem "mongo"
9
- gem "bson_ext"
10
14
  gem "mysql"
11
- gem "passenger", "~>2.0"
12
15
  gem "pg"
13
- gem "rails", "~>2.3.8"
14
- gem "rack"
15
- gem "shoulda"
16
- gem "timecop"
17
- gem "webmock"
16
+
17
+ # APIs
18
+ gem "garb"
19
+
20
+ # Compatibility
18
21
  gem "SystemTimer", "1.2.3", :platforms => :mri_18
19
22
 
23
+ # Testing
24
+ gem "appraisal"
25
+
26
+ gem "mocha", :require=>false
27
+ gem "shoulda", :require=>false # Requires test/unit
28
+ gem "timecop", :require=>false
29
+ gem "webmock", :require=>false
30
+
20
31
  group :development do
21
32
  gem "jekyll"
22
33
  gem "rake"
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vanity (1.8.1)
4
+ vanity (1.8.2)
5
5
  redis (~> 2.0)
6
6
  redis-namespace (~> 1.0.0)
7
7
 
@@ -1,5 +1,5 @@
1
1
  = Vanity
2
- {<img src="https://travis-ci.org/assaf/vanity.png?branch=feature/readme-update" alt="Build Status" />}[https://travis-ci.org/assaf/vanity]
2
+ {<img src="https://travis-ci.org/assaf/vanity.png?branch=master" alt="Build Status" />}[https://travis-ci.org/assaf/vanity]
3
3
 
4
4
  Vanity is an Experiment Driven Development framework for Rails.
5
5
 
@@ -96,13 +96,16 @@ If robots or spiders make up a significant portion of your sites traffic they ca
96
96
 
97
97
  == Compatibility Matrix
98
98
 
99
- Running Rails 2 on Ruby 2? Vanity probably won't work for you. But here's what does:
99
+ Here's what's tested and known to work:
100
100
 
101
- Persistence: Redis, Mongo, ActiveRecord
102
- Rails: 2.3, 3, 3.1, 3.2
103
- Ruby: 1.8.7, 1.9.3
101
+ Ruby 1.8.7, 1.9.3
102
+ Persistence: Redis, Mongo, ActiveRecord
103
+ Rails: 2.3, 3, 3.1, 3.2
104
+ Ruby 2.0
105
+ Persistence: Redis, Mongo, ActiveRecord
106
+ Rails: 3.2
104
107
 
105
- NOTE: Support for Rails 4 and Ruby 2.0 are coming soon!
108
+ NOTE: Support for Rails 4 is coming soon!
106
109
 
107
110
  == Contributing
108
111
 
@@ -2,19 +2,20 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal"
6
- gem "garb"
7
- gem "mocha"
8
- gem "mongo"
5
+ gem "rack"
9
6
  gem "bson_ext"
7
+ gem "mongo"
10
8
  gem "mysql"
11
9
  gem "pg"
12
- gem "rack"
13
- gem "shoulda"
14
- gem "timecop"
15
- gem "webmock"
10
+ gem "garb"
16
11
  gem "SystemTimer", "1.2.3", :platforms=>:mri_18
12
+ gem "appraisal"
13
+ gem "mocha", :require=>false
14
+ gem "shoulda", :require=>false
15
+ gem "timecop", :require=>false
16
+ gem "webmock", :require=>false
17
17
  gem "rails", "3.0.11"
18
+ gem "fastthread", :git=>"git://github.com/zoltankiss/fastthread.git", :platforms=>:mri_20
18
19
  gem "passenger", "~>3.0"
19
20
 
20
21
  gemspec :path=>"../"
@@ -1,7 +1,13 @@
1
+ GIT
2
+ remote: git://github.com/zoltankiss/fastthread.git
3
+ revision: 56e6ce7c1780797a354d5befe9a9a9869bbc7e3e
4
+ specs:
5
+ fastthread (1.0.7)
6
+
1
7
  PATH
2
8
  remote: /Users/phill/Development/ruby/vanity
3
9
  specs:
4
- vanity (1.8.1)
10
+ vanity (1.8.2)
5
11
  redis (~> 2.0)
6
12
  redis-namespace (~> 1.0.0)
7
13
 
@@ -49,7 +55,6 @@ GEM
49
55
  daemon_controller (1.0.0)
50
56
  erubis (2.6.6)
51
57
  abstract (>= 1.0.0)
52
- fastthread (1.0.7)
53
58
  garb (0.9.1)
54
59
  activesupport (>= 2.2.0)
55
60
  crack (>= 0.1.6)
@@ -121,6 +126,7 @@ DEPENDENCIES
121
126
  SystemTimer (= 1.2.3)
122
127
  appraisal
123
128
  bson_ext
129
+ fastthread!
124
130
  garb
125
131
  mocha
126
132
  mongo
@@ -2,19 +2,20 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal"
6
- gem "garb"
7
- gem "mocha"
8
- gem "mongo"
5
+ gem "rack"
9
6
  gem "bson_ext"
7
+ gem "mongo"
10
8
  gem "mysql"
11
9
  gem "pg"
12
- gem "rack"
13
- gem "shoulda"
14
- gem "timecop"
15
- gem "webmock"
10
+ gem "garb"
16
11
  gem "SystemTimer", "1.2.3", :platforms=>:mri_18
12
+ gem "appraisal"
13
+ gem "mocha", :require=>false
14
+ gem "shoulda", :require=>false
15
+ gem "timecop", :require=>false
16
+ gem "webmock", :require=>false
17
17
  gem "rails", "3.1.3"
18
+ gem "fastthread", :git=>"git://github.com/zoltankiss/fastthread.git", :platforms=>:mri_20
18
19
  gem "passenger", "~>3.0"
19
20
 
20
21
  gemspec :path=>"../"
@@ -1,7 +1,13 @@
1
+ GIT
2
+ remote: git://github.com/zoltankiss/fastthread.git
3
+ revision: 56e6ce7c1780797a354d5befe9a9a9869bbc7e3e
4
+ specs:
5
+ fastthread (1.0.7)
6
+
1
7
  PATH
2
8
  remote: /Users/phill/Development/ruby/vanity
3
9
  specs:
4
- vanity (1.8.1)
10
+ vanity (1.8.2)
5
11
  redis (~> 2.0)
6
12
  redis-namespace (~> 1.0.0)
7
13
 
@@ -49,7 +55,6 @@ GEM
49
55
  crack (0.3.1)
50
56
  daemon_controller (1.0.0)
51
57
  erubis (2.7.0)
52
- fastthread (1.0.7)
53
58
  garb (0.9.1)
54
59
  activesupport (>= 2.2.0)
55
60
  crack (>= 0.1.6)
@@ -132,6 +137,7 @@ DEPENDENCIES
132
137
  SystemTimer (= 1.2.3)
133
138
  appraisal
134
139
  bson_ext
140
+ fastthread!
135
141
  garb
136
142
  mocha
137
143
  mongo
@@ -2,19 +2,20 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal"
6
- gem "garb"
7
- gem "mocha"
8
- gem "mongo"
5
+ gem "rack"
9
6
  gem "bson_ext"
7
+ gem "mongo"
10
8
  gem "mysql"
11
9
  gem "pg"
12
- gem "rack"
13
- gem "shoulda"
14
- gem "timecop"
15
- gem "webmock"
10
+ gem "garb"
16
11
  gem "SystemTimer", "1.2.3", :platforms=>:mri_18
12
+ gem "appraisal"
13
+ gem "mocha", :require=>false
14
+ gem "shoulda", :require=>false
15
+ gem "timecop", :require=>false
16
+ gem "webmock", :require=>false
17
17
  gem "rails", "3.2.1"
18
+ gem "fastthread", :git=>"git://github.com/zoltankiss/fastthread.git", :platforms=>:mri_20
18
19
  gem "passenger", "~>3.0"
19
20
 
20
21
  gemspec :path=>"../"
@@ -1,7 +1,13 @@
1
+ GIT
2
+ remote: git://github.com/zoltankiss/fastthread.git
3
+ revision: 56e6ce7c1780797a354d5befe9a9a9869bbc7e3e
4
+ specs:
5
+ fastthread (1.0.7)
6
+
1
7
  PATH
2
8
  remote: /Users/phill/Development/ruby/vanity
3
9
  specs:
4
- vanity (1.8.1)
10
+ vanity (1.8.2)
5
11
  redis (~> 2.0)
6
12
  redis-namespace (~> 1.0.0)
7
13
 
@@ -48,7 +54,6 @@ GEM
48
54
  crack (0.3.1)
49
55
  daemon_controller (1.0.0)
50
56
  erubis (2.7.0)
51
- fastthread (1.0.7)
52
57
  garb (0.9.1)
53
58
  activesupport (>= 2.2.0)
54
59
  crack (>= 0.1.6)
@@ -130,6 +135,7 @@ DEPENDENCIES
130
135
  SystemTimer (= 1.2.3)
131
136
  appraisal
132
137
  bson_ext
138
+ fastthread!
133
139
  garb
134
140
  mocha
135
141
  mongo
@@ -31,6 +31,7 @@ require "vanity/adapters/mongodb_adapter"
31
31
  require "vanity/adapters/mock_adapter"
32
32
  # Playground.
33
33
  require "vanity/playground"
34
+ require "vanity/autoconnect"
34
35
  require "vanity/helpers"
35
36
  # Integration with various frameworks.
36
37
  require "vanity/frameworks"
@@ -110,6 +110,11 @@ module Vanity
110
110
  fail "Not implemented"
111
111
  end
112
112
 
113
+ # Determines if a participant already has seen this alternative in this experiment.
114
+ def ab_seen(experiment, identity, assignment)
115
+ fail "Not implemented"
116
+ end
117
+
113
118
  # Records a conversion in this experiment for the given alternative.
114
119
  # Associates a value with the conversion (default to 1). If implicit is
115
120
  # true, add particpant if not already recorded for this experiment. If
@@ -42,7 +42,7 @@ module Vanity
42
42
  class VanityExperiment < VanityRecord
43
43
  self.table_name = :vanity_experiments
44
44
  has_many :vanity_conversions, :dependent => :destroy
45
- attr_accessible :experiment_id if respond_to?(:attr_accessible)
45
+ attr_accessible :experiment_id if respond_to?(:attr_accessible)
46
46
 
47
47
  # Finds or creates the experiment
48
48
  def self.retrieve(experiment)
@@ -64,7 +64,7 @@ module Vanity
64
64
  # Participant model
65
65
  class VanityParticipant < VanityRecord
66
66
  self.table_name = :vanity_participants
67
- attr_accessible :experiment_id, :identity, :seen, :shown, :converted if respond_to?(:attr_accessible)
67
+ attr_accessible :experiment_id, :identity, :seen, :shown, :converted if respond_to?(:attr_accessible)
68
68
 
69
69
  # Finds the participant by experiment and identity. If
70
70
  # create is true then it will create the participant
@@ -127,7 +127,7 @@ module Vanity
127
127
  connection = VanityMetric.connection
128
128
  record = VanityMetric.retrieve(metric)
129
129
  dates = (from.to_date..to.to_date).map(&:to_s)
130
- conditions = [connection.quote_column_name('date') + ' IN (?)', dates]
130
+ conditions = [connection.quote_column_name('date') + ' BETWEEN ? AND ?', from.to_date, to.to_date]
131
131
  order = "#{connection.quote_column_name('date')}"
132
132
  select = "sum(#{connection.quote_column_name('value')}) AS value, #{connection.quote_column_name('date')}"
133
133
  group_by = "#{connection.quote_column_name('date')}"
@@ -216,12 +216,19 @@ module Vanity
216
216
  VanityParticipant.retrieve(experiment, identity, true, :seen => alternative)
217
217
  end
218
218
 
219
+ # Determines if a participant already has seen this alternative in this experiment.
220
+ def ab_seen(experiment, identity, alternative)
221
+ participant = VanityParticipant.retrieve(experiment, identity, false)
222
+ participant && participant.seen == alternative.id
223
+ end
224
+
219
225
  # Records a conversion in this experiment for the given alternative.
220
226
  # Associates a value with the conversion (default to 1). If implicit is
221
- # true, add particpant if not already recorded for this experiment. If
222
- # implicit is false (default), only add conversion is participant
227
+ # true, add participant if not already recorded for this experiment. If
228
+ # implicit is false (default), only add conversion if participant
223
229
  # previously recorded as participating in this experiment.
224
230
  def ab_add_conversion(experiment, alternative, identity, count = 1, implicit = false)
231
+ participant = VanityParticipant.retrieve(experiment, identity, false)
225
232
  VanityParticipant.retrieve(experiment, identity, implicit, :converted => alternative)
226
233
  VanityExperiment.retrieve(experiment).increment_conversion(alternative, count)
227
234
  end
@@ -150,6 +150,12 @@ module Vanity
150
150
  @participants.update({ :experiment=>experiment, :identity=>identity }, { "$push"=>{ :seen=>alternative } }, :upsert=>true)
151
151
  end
152
152
 
153
+ # Determines if a participant already has seen this alternative in this experiment.
154
+ def ab_seen(experiment, identity, alternative)
155
+ participant = @participants.find_one({ :experiment=>experiment, :identity=>identity }, { :fields=>[:seen] })
156
+ participant && participant["seen"].first == alternative.id
157
+ end
158
+
153
159
  def ab_add_conversion(experiment, alternative, identity, count = 1, implicit = false)
154
160
  if implicit
155
161
  @participants.update({ :experiment=>experiment, :identity=>identity }, { "$push"=>{ :seen=>alternative } }, :upsert=>true)