vanity 2.0.0.beta5 → 2.0.0.beta6

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.
data/.travis.yml CHANGED
@@ -10,6 +10,7 @@ rvm:
10
10
  - 1.9.3
11
11
  - 2.0.0
12
12
  - 2.1.0
13
+ - 2.2.0
13
14
  - ruby-head
14
15
  env:
15
16
  - DB=mongodb
@@ -24,5 +25,7 @@ before_script:
24
25
  - 'echo ''gem: --no-ri --no-rdoc'' > ~/.gemrc' # skip installing docs for gems
25
26
  matrix:
26
27
  exclude:
28
+ - rvm: 2.2.0
29
+ gemfile: gemfiles/rails32.gemfile
27
30
  allow_failures:
28
31
  - rvm: ruby-head
data/Appraisals CHANGED
@@ -8,14 +8,15 @@ end
8
8
 
9
9
  appraise "rails4" do
10
10
  gem "mocha", "~> 1.0", :require=>false
11
- gem "rails", "4.0.0"
11
+ gem "rails", "4.0.13"
12
12
  gem "fastthread", :git => "git://github.com/zoltankiss/fastthread.git", :platforms => :mri_20
13
13
  gem "passenger", "~>3.0"
14
+ gem 'test-unit'
14
15
  end
15
16
 
16
17
  appraise "rails41" do
17
18
  gem "mocha", "~> 1.0", :require=>false
18
- gem "rails", "4.1.0"
19
+ gem "rails", "4.1.9"
19
20
  gem "fastthread", :git => "git://github.com/zoltankiss/fastthread.git", :platforms => :mri_20
20
21
  gem "passenger", "~>3.0"
21
22
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vanity (2.0.0.beta5)
4
+ vanity (2.0.0.beta6)
5
5
  i18n
6
6
 
7
7
  GEM
@@ -50,7 +50,7 @@ GEM
50
50
  redis-namespace (1.3.2)
51
51
  redis (~> 3.0.4)
52
52
  rubystats (0.2.3)
53
- sqlite3 (1.3.8)
53
+ sqlite3 (1.3.10)
54
54
  syntax (1.0.0)
55
55
  thor (0.18.1)
56
56
  timecop (0.3.5)
data/README.rdoc CHANGED
@@ -35,6 +35,15 @@ Add to your Gemfile:
35
35
 
36
36
  By default Vanity is configured to use Redis on localhost port 6379 with database 0.
37
37
 
38
+ A sample <code>config/vanity.yml</code> might look like:
39
+
40
+ test:
41
+ collecting: false
42
+ production:
43
+ adapter: redis
44
+ connection: redis://<%= ENV["REDIS_USER"] %>:<%= ENV["REDIS_PASSWORD"] %>@<%= ENV["REDIS_HOST"] %>:<%= ENV["REDIS_PORT"] %>/0
45
+
46
+
38
47
  ===== MongoDB Setup
39
48
 
40
49
  Add to your Gemfile:
@@ -70,10 +79,7 @@ A sample <code>config/vanity.yml</code> might look like:
70
79
  collecting: false
71
80
  production:
72
81
  adapter: active_record
73
- active_record_adapter: mysql
74
- database: vanity_test
75
- pool: 5
76
- timeout: 5000
82
+ active_record_adapter: default
77
83
 
78
84
  If you're going to store data in the database, run the generator and migrations to create the database schema:
79
85
 
@@ -86,7 +92,6 @@ Turn Vanity on, and pass a reference to a method that identifies a user. For exa
86
92
 
87
93
  class ApplicationController < ActionController::Base
88
94
  use_vanity :current_user
89
- layout false # exclude this if you want to use your application layout
90
95
  end
91
96
 
92
97
  For more information, please see the {identity documentation}[http://vanity.labnotes.org/identity.html].
@@ -141,12 +146,15 @@ In <code>config/routes.rb</code>, add:
141
146
  get '/vanity/participant/:id' => 'vanity#participant'
142
147
  post '/vanity/complete'
143
148
  post '/vanity/chooses'
149
+ post '/vanity/reset'
144
150
  post '/vanity/add_participant'
151
+ get '/vanity/image'
145
152
 
146
153
  The controller should look like:
147
154
 
148
155
  class VanityController < ApplicationController
149
156
  include Vanity::Rails::Dashboard
157
+ layout false # exclude this if you want to use your application layout
150
158
  end
151
159
 
152
160
  == Registering participants with Javascript
@@ -165,10 +173,16 @@ Here's what's tested and known to work:
165
173
 
166
174
  Ruby 1.9.3
167
175
  Persistence: Redis, Mongo, ActiveRecord
168
- Rails: 3.2, 4.0
176
+ Rails: 3.2, 4.x
169
177
  Ruby 2.0
170
178
  Persistence: Redis, Mongo, ActiveRecord
171
- Rails: 3.2, 4.0
179
+ Rails: 3.2, 4.x
180
+ Ruby 2.1
181
+ Persistence: Redis, Mongo, ActiveRecord
182
+ Rails: 3.2, 4.x
183
+ Ruby 2.2
184
+ Persistence: Redis, Mongo, ActiveRecord
185
+ Rails: 4.0
172
186
 
173
187
  == Testing
174
188
 
@@ -15,6 +15,7 @@ en:
15
15
  converted_percentage: '%{alternative} converted at %{percentage}%.'
16
16
  currently_shown: 'currently shown'
17
17
  didnt_convert: '%{alternative} did not convert.'
18
+ experiment_has_been_reset: '%{name} experiment has been reset.'
18
19
  experiment_participants:
19
20
  one: 'There is one participant in this experiment.'
20
21
  other: 'There are %{count} participants in this experiment.'
@@ -32,6 +33,7 @@ en:
32
33
  participants:
33
34
  one: '1 participant'
34
35
  other: '%{count} participants'
36
+ reset: 'Reset'
35
37
  report: 'Vanity Report: %{timestamp}'
36
38
  result_isnt_significant: 'This result is not statistically significant, suggest you continue this experiment.'
37
39
  selected_as_best: '%{alternative} selected as the best alternative.'
@@ -7,7 +7,7 @@ GIT
7
7
  PATH
8
8
  remote: ..
9
9
  specs:
10
- vanity (2.0.0.beta5)
10
+ vanity (2.0.0.beta6)
11
11
  i18n
12
12
 
13
13
  GEM
@@ -14,9 +14,10 @@ gem "garb", "< 0.9.2"
14
14
  gem "timecop", :require=>false
15
15
  gem "webmock", :require=>false
16
16
  gem "mocha", "~> 1.0", :require=>false
17
- gem "rails", "4.0.0"
17
+ gem "rails", "4.0.13"
18
18
  gem "fastthread", :git=>"git://github.com/zoltankiss/fastthread.git", :platforms=>:mri_20
19
19
  gem "passenger", "~>3.0"
20
+ gem "test-unit"
20
21
 
21
22
  group :development do
22
23
  gem "appraisal", ">= 1.0.0.beta2"
@@ -7,33 +7,33 @@ GIT
7
7
  PATH
8
8
  remote: ..
9
9
  specs:
10
- vanity (2.0.0.beta5)
10
+ vanity (2.0.0.beta6)
11
11
  i18n
12
12
 
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
16
16
  RedCloth (4.2.9)
17
- actionmailer (4.0.0)
18
- actionpack (= 4.0.0)
19
- mail (~> 2.5.3)
20
- actionpack (4.0.0)
21
- activesupport (= 4.0.0)
17
+ actionmailer (4.0.13)
18
+ actionpack (= 4.0.13)
19
+ mail (~> 2.5, >= 2.5.4)
20
+ actionpack (4.0.13)
21
+ activesupport (= 4.0.13)
22
22
  builder (~> 3.1.0)
23
23
  erubis (~> 2.7.0)
24
24
  rack (~> 1.5.2)
25
25
  rack-test (~> 0.6.2)
26
- activemodel (4.0.0)
27
- activesupport (= 4.0.0)
26
+ activemodel (4.0.13)
27
+ activesupport (= 4.0.13)
28
28
  builder (~> 3.1.0)
29
- activerecord (4.0.0)
30
- activemodel (= 4.0.0)
29
+ activerecord (4.0.13)
30
+ activemodel (= 4.0.13)
31
31
  activerecord-deprecated_finders (~> 1.0.2)
32
- activesupport (= 4.0.0)
32
+ activesupport (= 4.0.13)
33
33
  arel (~> 4.0.0)
34
34
  activerecord-deprecated_finders (1.0.3)
35
- activesupport (4.0.0)
36
- i18n (~> 0.6, >= 0.6.4)
35
+ activesupport (4.0.13)
36
+ i18n (~> 0.6, >= 0.6.9)
37
37
  minitest (~> 4.2)
38
38
  multi_json (~> 1.3)
39
39
  thread_safe (~> 0.1)
@@ -45,8 +45,7 @@ GEM
45
45
  bundler
46
46
  rake
47
47
  thor (>= 0.14.0)
48
- arel (4.0.1)
49
- atomic (1.1.14)
48
+ arel (4.0.2)
50
49
  bson (1.9.2)
51
50
  bson_ext (1.9.2)
52
51
  bson (~> 1.9.2)
@@ -63,7 +62,7 @@ GEM
63
62
  activesupport (>= 2.2.0)
64
63
  crack (>= 0.1.6)
65
64
  hike (1.2.3)
66
- i18n (0.6.5)
65
+ i18n (0.7.0)
67
66
  integration (0.1.0)
68
67
  jekyll (0.11.2)
69
68
  albino (~> 1.3)
@@ -74,68 +73,65 @@ GEM
74
73
  maruku (~> 0.5)
75
74
  kramdown (0.13.5)
76
75
  liquid (2.3.0)
77
- mail (2.5.4)
78
- mime-types (~> 1.16)
79
- treetop (~> 1.4.8)
76
+ mail (2.6.3)
77
+ mime-types (>= 1.16, < 3)
80
78
  maruku (0.6.0)
81
79
  syntax (>= 1.0.0)
82
80
  metaclass (0.0.4)
83
- mime-types (1.25)
81
+ mime-types (2.4.3)
84
82
  minitest (4.7.5)
85
83
  mocha (1.0.0)
86
84
  metaclass (~> 0.0.1)
87
85
  mongo (1.9.2)
88
86
  bson (~> 1.9.2)
89
- multi_json (1.8.2)
87
+ multi_json (1.10.1)
90
88
  passenger (3.0.21)
91
89
  daemon_controller (>= 1.0.0)
92
90
  fastthread (>= 1.0.1)
93
91
  rack
94
92
  rake (>= 0.8.1)
95
- polyglot (0.3.3)
96
93
  posix-spawn (0.3.6)
94
+ power_assert (0.2.2)
97
95
  rack (1.5.2)
98
- rack-test (0.6.2)
96
+ rack-test (0.6.3)
99
97
  rack (>= 1.0)
100
- rails (4.0.0)
101
- actionmailer (= 4.0.0)
102
- actionpack (= 4.0.0)
103
- activerecord (= 4.0.0)
104
- activesupport (= 4.0.0)
98
+ rails (4.0.13)
99
+ actionmailer (= 4.0.13)
100
+ actionpack (= 4.0.13)
101
+ activerecord (= 4.0.13)
102
+ activesupport (= 4.0.13)
105
103
  bundler (>= 1.3.0, < 2.0)
106
- railties (= 4.0.0)
107
- sprockets-rails (~> 2.0.0)
108
- railties (4.0.0)
109
- actionpack (= 4.0.0)
110
- activesupport (= 4.0.0)
104
+ railties (= 4.0.13)
105
+ sprockets-rails (~> 2.0)
106
+ railties (4.0.13)
107
+ actionpack (= 4.0.13)
108
+ activesupport (= 4.0.13)
111
109
  rake (>= 0.8.7)
112
110
  thor (>= 0.18.1, < 2.0)
113
- rake (10.1.0)
111
+ rake (10.4.2)
114
112
  redis (3.0.6)
115
113
  redis-namespace (1.3.2)
116
114
  redis (~> 3.0.4)
117
115
  rubystats (0.2.3)
118
116
  safe_yaml (0.9.7)
119
- sprockets (2.10.0)
117
+ sprockets (2.12.3)
120
118
  hike (~> 1.2)
121
119
  multi_json (~> 1.0)
122
120
  rack (~> 1.0)
123
121
  tilt (~> 1.1, != 1.3.0)
124
- sprockets-rails (2.0.1)
122
+ sprockets-rails (2.2.4)
125
123
  actionpack (>= 3.0)
126
124
  activesupport (>= 3.0)
127
- sprockets (~> 2.8)
128
- sqlite3 (1.3.8)
125
+ sprockets (>= 2.8, < 4.0)
126
+ sqlite3 (1.3.10)
129
127
  syntax (1.0.0)
130
- thor (0.18.1)
131
- thread_safe (0.1.3)
132
- atomic
128
+ test-unit (3.0.9)
129
+ power_assert
130
+ thor (0.19.1)
131
+ thread_safe (0.3.4)
133
132
  tilt (1.4.1)
134
133
  timecop (0.6.3)
135
- treetop (1.4.15)
136
- polyglot
137
- polyglot (>= 0.3.1)
138
- tzinfo (0.3.38)
134
+ tzinfo (0.3.43)
139
135
  webmock (1.15.2)
140
136
  addressable (>= 2.2.7)
141
137
  crack (>= 0.3.2)
@@ -158,12 +154,13 @@ DEPENDENCIES
158
154
  mongo
159
155
  passenger (~> 3.0)
160
156
  rack
161
- rails (= 4.0.0)
157
+ rails (= 4.0.13)
162
158
  rake
163
159
  redis (>= 2.1)
164
160
  redis-namespace (>= 1.1.0)
165
161
  rubystats
166
162
  sqlite3
163
+ test-unit
167
164
  timecop
168
165
  vanity!
169
166
  webmock
@@ -14,7 +14,7 @@ gem "garb", "< 0.9.2"
14
14
  gem "timecop", :require=>false
15
15
  gem "webmock", :require=>false
16
16
  gem "mocha", "~> 1.0", :require=>false
17
- gem "rails", "4.1.0"
17
+ gem "rails", "4.1.9"
18
18
  gem "fastthread", :git=>"git://github.com/zoltankiss/fastthread.git", :platforms=>:mri_20
19
19
  gem "passenger", "~>3.0"
20
20
 
@@ -7,34 +7,34 @@ GIT
7
7
  PATH
8
8
  remote: .././
9
9
  specs:
10
- vanity (2.0.0.beta5)
10
+ vanity (2.0.0.beta6)
11
11
  i18n
12
12
 
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
16
16
  RedCloth (4.2.9)
17
- actionmailer (4.1.0)
18
- actionpack (= 4.1.0)
19
- actionview (= 4.1.0)
20
- mail (~> 2.5.4)
21
- actionpack (4.1.0)
22
- actionview (= 4.1.0)
23
- activesupport (= 4.1.0)
17
+ actionmailer (4.1.9)
18
+ actionpack (= 4.1.9)
19
+ actionview (= 4.1.9)
20
+ mail (~> 2.5, >= 2.5.4)
21
+ actionpack (4.1.9)
22
+ actionview (= 4.1.9)
23
+ activesupport (= 4.1.9)
24
24
  rack (~> 1.5.2)
25
25
  rack-test (~> 0.6.2)
26
- actionview (4.1.0)
27
- activesupport (= 4.1.0)
26
+ actionview (4.1.9)
27
+ activesupport (= 4.1.9)
28
28
  builder (~> 3.1)
29
29
  erubis (~> 2.7.0)
30
- activemodel (4.1.0)
31
- activesupport (= 4.1.0)
30
+ activemodel (4.1.9)
31
+ activesupport (= 4.1.9)
32
32
  builder (~> 3.1)
33
- activerecord (4.1.0)
34
- activemodel (= 4.1.0)
35
- activesupport (= 4.1.0)
33
+ activerecord (4.1.9)
34
+ activemodel (= 4.1.9)
35
+ activesupport (= 4.1.9)
36
36
  arel (~> 5.0.0)
37
- activesupport (4.1.0)
37
+ activesupport (4.1.9)
38
38
  i18n (~> 0.6, >= 0.6.9)
39
39
  json (~> 1.7, >= 1.7.7)
40
40
  minitest (~> 5.1)
@@ -67,7 +67,7 @@ GEM
67
67
  crack (>= 0.1.6)
68
68
  highline (1.6.21)
69
69
  hike (1.2.3)
70
- i18n (0.6.9)
70
+ i18n (0.7.0)
71
71
  integration (0.1.0)
72
72
  jekyll (1.5.1)
73
73
  classifier (~> 1.3)
@@ -80,24 +80,23 @@ GEM
80
80
  redcarpet (~> 2.3.0)
81
81
  safe_yaml (~> 1.0)
82
82
  toml (~> 0.1.0)
83
- json (1.8.1)
83
+ json (1.8.2)
84
84
  liquid (2.5.5)
85
85
  listen (1.3.1)
86
86
  rb-fsevent (>= 0.9.3)
87
87
  rb-inotify (>= 0.9)
88
88
  rb-kqueue (>= 0.2)
89
- mail (2.5.4)
90
- mime-types (~> 1.16)
91
- treetop (~> 1.4.8)
89
+ mail (2.6.3)
90
+ mime-types (>= 1.16, < 3)
92
91
  maruku (0.7.0)
93
92
  metaclass (0.0.4)
94
- mime-types (1.25.1)
95
- minitest (5.3.3)
93
+ mime-types (2.4.3)
94
+ minitest (5.5.1)
96
95
  mocha (1.1.0)
97
96
  metaclass (~> 0.0.1)
98
97
  mongo (1.10.0)
99
98
  bson (~> 1.10.0)
100
- multi_json (1.9.2)
99
+ multi_json (1.10.1)
101
100
  parslet (1.5.0)
102
101
  blankslate (~> 2.0)
103
102
  passenger (3.0.21)
@@ -105,30 +104,29 @@ GEM
105
104
  fastthread (>= 1.0.1)
106
105
  rack
107
106
  rake (>= 0.8.1)
108
- polyglot (0.3.4)
109
107
  posix-spawn (0.3.8)
110
108
  pygments.rb (0.5.4)
111
109
  posix-spawn (~> 0.3.6)
112
110
  yajl-ruby (~> 1.1.0)
113
111
  rack (1.5.2)
114
- rack-test (0.6.2)
112
+ rack-test (0.6.3)
115
113
  rack (>= 1.0)
116
- rails (4.1.0)
117
- actionmailer (= 4.1.0)
118
- actionpack (= 4.1.0)
119
- actionview (= 4.1.0)
120
- activemodel (= 4.1.0)
121
- activerecord (= 4.1.0)
122
- activesupport (= 4.1.0)
114
+ rails (4.1.9)
115
+ actionmailer (= 4.1.9)
116
+ actionpack (= 4.1.9)
117
+ actionview (= 4.1.9)
118
+ activemodel (= 4.1.9)
119
+ activerecord (= 4.1.9)
120
+ activesupport (= 4.1.9)
123
121
  bundler (>= 1.3.0, < 2.0)
124
- railties (= 4.1.0)
122
+ railties (= 4.1.9)
125
123
  sprockets-rails (~> 2.0)
126
- railties (4.1.0)
127
- actionpack (= 4.1.0)
128
- activesupport (= 4.1.0)
124
+ railties (4.1.9)
125
+ actionpack (= 4.1.9)
126
+ activesupport (= 4.1.9)
129
127
  rake (>= 0.8.7)
130
128
  thor (>= 0.18.1, < 2.0)
131
- rake (10.3.1)
129
+ rake (10.4.2)
132
130
  rb-fsevent (0.9.4)
133
131
  rb-inotify (0.9.3)
134
132
  ffi (>= 0.5.0)
@@ -139,27 +137,24 @@ GEM
139
137
  redis-namespace (1.4.1)
140
138
  redis (~> 3.0.4)
141
139
  rubystats (0.2.3)
142
- safe_yaml (1.0.3)
143
- sprockets (2.12.1)
140
+ safe_yaml (1.0.4)
141
+ sprockets (2.12.3)
144
142
  hike (~> 1.2)
145
143
  multi_json (~> 1.0)
146
144
  rack (~> 1.0)
147
145
  tilt (~> 1.1, != 1.3.0)
148
- sprockets-rails (2.1.3)
146
+ sprockets-rails (2.2.4)
149
147
  actionpack (>= 3.0)
150
148
  activesupport (>= 3.0)
151
- sprockets (~> 2.8)
152
- sqlite3 (1.3.9)
149
+ sprockets (>= 2.8, < 4.0)
150
+ sqlite3 (1.3.10)
153
151
  thor (0.19.1)
154
- thread_safe (0.3.3)
152
+ thread_safe (0.3.4)
155
153
  tilt (1.4.1)
156
154
  timecop (0.7.1)
157
155
  toml (0.1.1)
158
156
  parslet (~> 1.5.0)
159
- treetop (1.4.15)
160
- polyglot
161
- polyglot (>= 0.3.1)
162
- tzinfo (1.1.0)
157
+ tzinfo (1.2.2)
163
158
  thread_safe (~> 0.1)
164
159
  webmock (1.17.4)
165
160
  addressable (>= 2.2.7)
@@ -184,7 +179,7 @@ DEPENDENCIES
184
179
  mongo
185
180
  passenger (~> 3.0)
186
181
  rack
187
- rails (= 4.1.0)
182
+ rails (= 4.1.9)
188
183
  rake
189
184
  redis (>= 2.1)
190
185
  redis-namespace (>= 1.1.0)
@@ -7,7 +7,7 @@ GIT
7
7
  PATH
8
8
  remote: ..
9
9
  specs:
10
- vanity (2.0.0.beta5)
10
+ vanity (2.0.0.beta6)
11
11
  i18n
12
12
 
13
13
  GEM
data/lib/vanity.rb CHANGED
@@ -15,7 +15,6 @@ module Vanity
15
15
  end
16
16
 
17
17
  require "vanity/version"
18
- require "vanity/backport" if RUBY_VERSION < "1.9"
19
18
  # Metrics.
20
19
  require "vanity/metric/base"
21
20
  require "vanity/metric/active_record"
@@ -27,16 +27,12 @@ module Vanity
27
27
  end
28
28
  end
29
29
 
30
- # Schema model
31
- class VanitySchema < VanityRecord
32
- self.table_name = :vanity_schema
33
- end
34
-
35
30
  # Metric model
36
31
  class VanityMetric < VanityRecord
37
32
  UPDATED_AT_GRACE_PERIOD = 1.minute
38
33
  self.table_name = :vanity_metrics
39
34
  has_many :vanity_metric_values
35
+ attr_accessible :metric_id if needs_attr_accessible?
40
36
 
41
37
  def self.retrieve(metric)
42
38
  rails_agnostic_find_or_create_by(:metric_id, metric.to_s)
@@ -113,7 +109,7 @@ module Vanity
113
109
  end
114
110
 
115
111
  def active?
116
- VanityRecord.connected?
112
+ VanityRecord.connected? && VanityRecord.connection.active?
117
113
  end
118
114
 
119
115
  def disconnect!
@@ -223,7 +223,6 @@ module Vanity
223
223
  end
224
224
  end
225
225
  end
226
-
227
226
  end
228
227
  end
229
228
  end
@@ -28,6 +28,15 @@ module Vanity
28
28
  text
29
29
  end
30
30
 
31
+ class ProxyEmpty < String
32
+ def method_missing(method, *args, &block); self.class.new end
33
+ end
34
+
35
+ # prevent certain url helper methods from failing so we can run erb templates outside of rails for reports.
36
+ def method_missing(method, *args, &block)
37
+ %w(url_for flash).include?(method.to_s) ? ProxyEmpty.new : super
38
+ end
39
+
31
40
  # Dumbed down from Rails' simple_format.
32
41
  def vanity_simple_format(text, options={})
33
42
  open = "<p #{options.map { |k,v| "#{k}=\"#{CGI.escapeHTML v}\"" }.join(" ")}>"
@@ -445,6 +445,14 @@ module Vanity
445
445
  connection.destroy_experiment @id
446
446
  super
447
447
  end
448
+
449
+ # clears all collected data for the experiment
450
+ def reset
451
+ connection.destroy_experiment @id
452
+ connection.set_experiment_created_at @id, Time.now
453
+ @outcome = @completed_at = nil
454
+ self
455
+ end
448
456
 
449
457
  def save
450
458
  true_false unless @alternatives
@@ -39,6 +39,12 @@ module Vanity
39
39
  # use_vanity { |controller| controller.params[:project_id] }
40
40
  # end
41
41
  def use_vanity(symbol = nil, &block)
42
+ define_method :vanity_store_experiment_for_js do |name, alternative|
43
+ @_vanity_experiments ||= {}
44
+ @_vanity_experiments[name] ||= alternative
45
+ @_vanity_experiments[name].value
46
+ end
47
+
42
48
  if block
43
49
  define_method(:vanity_identity) { block.call(self) }
44
50
  else
@@ -317,6 +323,13 @@ module Vanity
317
323
  exp.chooses(exp.alternatives[params[:a].to_i].value)
318
324
  render :file=>Vanity.template("_experiment"), :locals=>{:experiment=>exp}
319
325
  end
326
+
327
+ def reset
328
+ exp = Vanity.playground.experiment(params[:e].to_sym)
329
+ exp.reset
330
+ flash[:notice] = I18n.t 'vanity.experiment_has_been_reset', name: exp.name
331
+ render :file=>Vanity.template("_experiment"), :locals=>{:experiment=>exp}
332
+ end
320
333
 
321
334
  # JS callback action used by vanity_js
322
335
  def add_participant
@@ -37,9 +37,7 @@ module Vanity
37
37
  # TODO refactor with Vanity::Rails::Helpers#ab_test
38
38
  request = respond_to?(:request) ? self.request : nil
39
39
  if Vanity.playground.using_js?
40
- @_vanity_experiments ||= {}
41
- @_vanity_experiments[name] ||= Vanity.playground.experiment(name).choose(request)
42
- value = @_vanity_experiments[name].value
40
+ value = Vanity.context.vanity_store_experiment_for_js name, Vanity.playground.experiment(name).choose(request)
43
41
  else
44
42
  value = Vanity.playground.experiment(name).choose(request).value
45
43
  end
@@ -99,7 +99,7 @@ module Vanity
99
99
  def after_create(record)
100
100
  return unless @playground.collecting?
101
101
  count = @ar_column ? (record.send(@ar_column) || 0) : 1
102
- call_hooks record.send(@ar_timestamp), nil, [count] if count > 0 && @ar_scoped.exists?(record)
102
+ call_hooks record.send(@ar_timestamp), nil, [count] if count > 0 && @ar_scoped.exists?(record.id)
103
103
  end
104
104
  end
105
105
  end
@@ -1,5 +1,11 @@
1
1
  <h3><%=vanity_h experiment.name %> <span class="type">(<%= experiment.class.friendly_name %>)</span></h3>
2
2
  <%= experiment.description.to_s.split(/\n\s*\n/).map { |para| vanity_html_safe(%{<p class="description">#{vanity_h para}</p>}) }.join.html_safe %>
3
+ <% if flash.notice %>
4
+ <p>
5
+ <%= flash.notice %>
6
+ </p>
7
+ <% end %>
8
+ <a class="button reset" title="<%= I18n.t('vanity.reset') %>" href="#" data-id="<%= experiment.id %>" data-url="<%= url_for(:action=>:reset, :e=>experiment.id) %>"><%= I18n.t 'vanity.reset' %></a>
3
9
  <%= render :file => Vanity.template("_" + experiment.type), :locals => {:experiment => experiment} %>
4
10
  <p class="meta">
5
11
  <%= I18n.t('vanity.started_at', :timestamp=>I18n.l(experiment.created_at, :format=>'%a, %b %d')) %>
@@ -1,5 +1,5 @@
1
1
  <ul class="experiments">
2
- <% experiments.sort_by { |id, experiment| experiment.created_at }.reverse.each do |id, experiment| %>
2
+ <% experiments.sort_by{|id, experiment| experiment.created_at}.sort_by{ |id, experiment| experiment.name }.reverse.each do |id, experiment| %>
3
3
  <li class="experiment <%= experiment.type %>" id="experiment_<%=vanity_h id.to_s %>">
4
4
  <%= render :file => Vanity.template("_experiment"), :locals => { :id => id, :experiment => experiment } %>
5
5
  </li>
@@ -79,4 +79,16 @@ $(function() {
79
79
  });
80
80
  return false;
81
81
  });
82
+
83
+ $(".experiment a.button.reset").live("click", function() {
84
+ if (confirm('Are you sure you want to reset the experiment? This will clear all collected data so far and restart the experiment from scratch. This cannot be undone.')){
85
+ var link = $(this);
86
+ $.ajax({
87
+ data: 'authenticity_token=' + encodeURIComponent(document.auth_token),
88
+ success: function(request){ $('#experiment_' + link.attr("data-id")).html(request) },
89
+ url: link.attr("data-url"), type: 'post'
90
+ });
91
+ }
92
+ return false;
93
+ });
82
94
  });
@@ -1,5 +1,5 @@
1
1
  module Vanity
2
- VERSION = "2.0.0.beta5"
2
+ VERSION = "2.0.0.beta6"
3
3
 
4
4
  module Version
5
5
  version = VERSION.to_s.split(".").map { |i| i.to_i }
data/test/cli_test.rb CHANGED
@@ -2,6 +2,10 @@ require "test_helper"
2
2
 
3
3
  describe "bin/vanity" do
4
4
 
5
+ before do
6
+ not_collecting!
7
+ end
8
+
5
9
  it "responds to version" do
6
10
  proc {
7
11
  IO.any_instance.expects(:puts)
@@ -27,4 +27,4 @@ describe Vanity::Commands do
27
27
  end
28
28
  end
29
29
  end
30
- end
30
+ end
@@ -9,14 +9,6 @@
9
9
  # Set databases in all environments since we may test loading Rails in non-
10
10
  # test environments
11
11
 
12
- development:
13
- adapter: sqlite3
14
- database: ":memory:"
15
-
16
12
  test:
17
13
  adapter: sqlite3
18
- database: ":memory:"
19
-
20
- production:
21
- adapter: sqlite3
22
- database: ":memory:"
14
+ database: vanity_test.sqlite3
@@ -609,7 +609,7 @@ class AbTestTest < ActionController::TestCase
609
609
  assert experiment(:abcd).score.alts.all? { |alt| alt.difference.nil? }
610
610
  assert_equal 1, experiment(:abcd).score.best.id
611
611
  assert_nil experiment(:abcd).score.choice
612
- assert_equal 2, experiment(:abcd).score.base.id
612
+ assert_includes [0,2,3], experiment(:abcd).score.base.id
613
613
  assert_equal 1, experiment(:abcd).score.least.id
614
614
  end
615
615
 
@@ -1021,6 +1021,27 @@ This experiment did not run long enough to find a clear winner.
1021
1021
  assert [:a, :b, :c].include?(choice)
1022
1022
  assert_equal choice, experiment(:simple).choose.value
1023
1023
  end
1024
+
1025
+ def test_reset_clears_participants
1026
+ new_ab_test :simple do
1027
+ alternatives :a, :b, :c
1028
+ metrics :coolness
1029
+ end
1030
+ experiment(:simple).chooses(:b)
1031
+ assert_equal experiment(:simple).alternatives[1].participants, 1
1032
+ experiment(:simple).reset
1033
+ assert_equal experiment(:simple).alternatives[1].participants, 0
1034
+ end
1035
+
1036
+ def test_clears_outcome_and_completed_at
1037
+ new_ab_test :simple do
1038
+ alternatives :a, :b, :c
1039
+ metrics :coolness
1040
+ end
1041
+ experiment(:simple).reset
1042
+ assert_nil experiment(:simple).outcome
1043
+ assert_nil experiment(:simple).completed_at
1044
+ end
1024
1045
 
1025
1046
 
1026
1047
  # -- Helper methods --
@@ -1,6 +1,13 @@
1
1
  require "test_helper"
2
2
 
3
+ # Pages accessible to everyone, e.g. sign in, community search.
3
4
  class UseVanityController < ActionController::Base
5
+ class TestModel
6
+ def test_method
7
+ ab_test(:pie_or_cake)
8
+ end
9
+ end
10
+
4
11
  attr_accessor :current_user
5
12
 
6
13
  def index
@@ -11,9 +18,37 @@ class UseVanityController < ActionController::Base
11
18
  ab_test(:pie_or_cake)
12
19
  render :inline => "<%= vanity_js -%>"
13
20
  end
21
+
22
+ def model_js
23
+ TestModel.new.test_method
24
+ render :inline => "<%= vanity_js -%>"
25
+ end
14
26
  end
15
27
 
16
- # Pages accessible to everyone, e.g. sign in, community search.
28
+ # class UseVanityControllerTest < ActionController::TestCase
29
+ # tests UseVanityController
30
+
31
+ # def setup
32
+ # super
33
+ # new_ab_test :pie_or_cake do
34
+ # metrics :sugar_high
35
+ # end
36
+
37
+ # # Class eval this instead of including in the controller to delay
38
+ # # execution until the request exists in the context of the test
39
+ # UseVanityController.class_eval do
40
+ # use_vanity :current_user
41
+ # end
42
+ # end
43
+
44
+ # def teardown
45
+ # super
46
+ # end
47
+
48
+ # def test_bootstraps_metric
49
+ # end
50
+ # end
51
+
17
52
  class UseVanityControllerTest < ActionController::TestCase
18
53
  tests UseVanityController
19
54
 
@@ -23,19 +58,34 @@ class UseVanityControllerTest < ActionController::TestCase
23
58
  new_ab_test :pie_or_cake do
24
59
  metrics :sugar_high
25
60
  end
61
+
62
+ # Class eval this instead of including in the controller to delay
63
+ # execution until the request exists in the context of the test
26
64
  UseVanityController.class_eval do
27
65
  use_vanity :current_user
28
66
  end
29
- if ::Rails.respond_to?(:application) # Rails 3 configuration
67
+
68
+ # Rails 3 configuration for cookies
69
+ if ::Rails.respond_to?(:application)
30
70
  ::Rails.application.config.session_options[:domain] = '.foo.bar'
31
71
  end
32
72
  end
33
73
 
74
+ def teardown
75
+ super
76
+ end
77
+
34
78
  def test_render_js_for_tests
35
79
  Vanity.playground.use_js!
36
80
  get :js
37
81
  assert_match /script.*v=pie_or_cake=.*script/m, @response.body
38
82
  end
83
+
84
+ def test_render_model_js_for_tests
85
+ Vanity.playground.use_js!
86
+ get :model_js
87
+ assert_match /script.*v=pie_or_cake=.*script/m, @response.body
88
+ end
39
89
 
40
90
  def test_chooses_sets_alternatives_for_rails_tests
41
91
  experiment(:pie_or_cake).chooses(true)
@@ -109,7 +159,7 @@ class UseVanityControllerTest < ActionController::TestCase
109
159
  assert_equal "576", @controller.send(:vanity_identity)
110
160
  end
111
161
 
112
- def test_vanity_identity_set_with_indentity_paramater
162
+ def test_vanity_identity_set_with_identity_paramater
113
163
  get :index, :_identity => "id_from_params"
114
164
  assert_equal "id_from_params", @controller.send(:vanity_identity)
115
165
  end
@@ -177,8 +227,4 @@ class UseVanityControllerTest < ActionController::TestCase
177
227
  assert_match /domain=.foo.bar/, @response["Set-Cookie"] if ::Rails.respond_to?(:application)
178
228
  end
179
229
 
180
- def teardown
181
- super
182
- end
183
-
184
230
  end
@@ -63,6 +63,17 @@ describe "Metric via playground" do
63
63
  assert Vanity.playground.metrics.empty?
64
64
  end
65
65
 
66
+ it "bootstraps the metric" do
67
+ File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
68
+ f.write <<-RUBY
69
+ metric "yawns/hour" do
70
+ end
71
+ RUBY
72
+ end
73
+ Vanity.playground.track!(:yawns_sec)
74
+ Vanity.playground.track!(:yawns_sec)
75
+ assert Vanity.playground.connection.get_metric_last_update_at(:yawns_sec)
76
+ end
66
77
  end
67
78
 
68
79
 
@@ -1,6 +1,10 @@
1
1
  require "test_helper"
2
2
 
3
3
  describe Vanity::Templates do
4
+ before do
5
+ not_collecting!
6
+ end
7
+
4
8
  describe "template" do
5
9
  it "resolves templates from the gem by default" do
6
10
  custom_view_path = File.expand_path(File.join(Rails.root, 'app', 'views', 'vanity'))
data/test/test_helper.rb CHANGED
@@ -49,7 +49,7 @@ module VanityTestHelpers
49
49
  DATABASE = {
50
50
  "redis"=>"redis://localhost/15",
51
51
  "mongodb"=>"mongodb://localhost/vanity",
52
- "active_record"=> { "adapter"=>"active_record", "active_record_adapter"=>"sqlite3", "database"=>"vanity_test.sqlite3", "timeout" => 10000, "busy_timeout" => 1000 },
52
+ "active_record"=> { "adapter"=>"active_record", "active_record_adapter"=>"default" },
53
53
  "mock"=>"mock:/"
54
54
  }[ENV["DB"]] or raise "No support yet for #{ENV["DB"]}"
55
55
 
@@ -69,7 +69,8 @@ module VanityTestHelpers
69
69
  # or reload an experiment (saved by the previous playground).
70
70
  def new_playground
71
71
  Vanity.playground = Vanity::Playground.new(:logger=>$logger, :load_path=>"tmp/experiments")
72
- Vanity.playground.establish_connection(DATABASE) unless Vanity.playground.connected?
72
+ ActiveRecord::Base.establish_connection
73
+ Vanity.playground.establish_connection(DATABASE)
73
74
  end
74
75
 
75
76
  # Defines the specified metrics (one or more names). Returns metric, or array
@@ -161,14 +162,10 @@ if defined?(ActionController::TestCase)
161
162
  end
162
163
 
163
164
  if ENV["DB"] == "active_record"
164
- connection = {}
165
- connection[:adapter] = VanityTestHelpers::DATABASE['active_record_adapter']
166
- connection[:database] = VanityTestHelpers::DATABASE['database']
167
- ActiveRecord::Base.establish_connection(connection)
165
+ ActiveRecord::Base.establish_connection
168
166
  ActiveRecord::Base.logger = $logger
169
167
 
170
168
  require "generators/templates/vanity_migration"
171
169
  VanityMigration.down rescue nil
172
170
  VanityMigration.up
173
- ActiveRecord::Base.connection_pool.disconnect!
174
171
  end
metadata CHANGED
@@ -1,55 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vanity
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta5
4
+ version: 2.0.0.beta6
5
+ prerelease: 6
5
6
  platform: ruby
6
7
  authors:
7
8
  - Assaf Arkin
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-01-25 00:00:00.000000000 Z
12
+ date: 2015-04-27 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: i18n
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - '>='
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - '>='
27
+ - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: bundler
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - '>='
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: 1.0.0
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - '>='
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: 1.0.0
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: minitest
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - '>='
51
+ - - ! '>='
46
52
  - !ruby/object:Gem::Version
47
53
  version: '4.2'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - '>='
59
+ - - ! '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '4.2'
55
62
  description: Mirror, mirror on the wall ...
@@ -117,7 +124,6 @@ files:
117
124
  - lib/vanity/adapters/mongodb_adapter.rb
118
125
  - lib/vanity/adapters/redis_adapter.rb
119
126
  - lib/vanity/autoconnect.rb
120
- - lib/vanity/backport.rb
121
127
  - lib/vanity/commands/list.rb
122
128
  - lib/vanity/commands/report.rb
123
129
  - lib/vanity/experiment/ab_test.rb
@@ -196,11 +202,10 @@ files:
196
202
  homepage: http://vanity.labnotes.org
197
203
  licenses:
198
204
  - MIT
199
- metadata: {}
200
205
  post_install_message: To get started run vanity --help
201
206
  rdoc_options:
202
207
  - --title
203
- - Vanity 2.0.0.beta5
208
+ - Vanity 2.0.0.beta6
204
209
  - --main
205
210
  - README.rdoc
206
211
  - --webcvs
@@ -208,20 +213,22 @@ rdoc_options:
208
213
  require_paths:
209
214
  - lib
210
215
  required_ruby_version: !ruby/object:Gem::Requirement
216
+ none: false
211
217
  requirements:
212
- - - '>='
218
+ - - ! '>='
213
219
  - !ruby/object:Gem::Version
214
220
  version: 1.9.3
215
221
  required_rubygems_version: !ruby/object:Gem::Requirement
222
+ none: false
216
223
  requirements:
217
- - - '>'
224
+ - - ! '>'
218
225
  - !ruby/object:Gem::Version
219
226
  version: 1.3.1
220
227
  requirements: []
221
228
  rubyforge_project:
222
- rubygems_version: 2.1.5
229
+ rubygems_version: 1.8.23
223
230
  signing_key:
224
- specification_version: 4
231
+ specification_version: 3
225
232
  summary: Experience Driven Development framework for Ruby
226
233
  test_files:
227
234
  - test/adapters/redis_adapter_test.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 64da19676a0a785baf7a4fad506d4919282a4622
4
- data.tar.gz: 4fde55bdf334eb8947891156e8ffa8e2c4db3d84
5
- SHA512:
6
- metadata.gz: f363b4c0d159729aab12104b5c748437fab61eabdec113eca24c6eb6e9f0b5bfc3b6a8490f467e7158a19c97cd28303a97af0a8cce059b32ffec77599e4e056a
7
- data.tar.gz: f4519c3151ff503cf5c329c528c6c55c7809342576739d66a2fb2cfa3d3bebb046a9d8e546569b744300867ee5b4519586adbbf8f57982ac89bd03613ac3dac0
@@ -1,25 +0,0 @@
1
- class Time
2
- unless method_defined?(:to_date)
3
- # Backported from Ruby 1.9.
4
- def to_date
5
- jd = Date.__send__(:civil_to_jd, year, mon, mday, Date::ITALY)
6
- Date.new!(Date.__send__(:jd_to_ajd, jd, 0, 0), 0, Date::ITALY)
7
- end
8
- end
9
- end
10
-
11
- class Date
12
- unless method_defined?(:to_date)
13
- # Backported from Ruby 1.9.
14
- def to_date
15
- self
16
- end
17
- end
18
-
19
- unless method_defined?(:to_time)
20
- # Backported from Ruby 1.9.
21
- def to_time
22
- Time.local(year, mon, mday)
23
- end
24
- end
25
- end