vanity 2.0.0.beta5 → 2.0.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
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