vanity 1.5.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +18 -0
- data/README.rdoc +18 -0
- data/Rakefile +1 -1
- data/lib/vanity/adapters/active_record_adapter.rb +7 -7
- data/lib/vanity/adapters/redis_adapter.rb +1 -1
- data/lib/vanity/playground.rb +24 -6
- data/lib/vanity/templates/_experiment.erb +1 -1
- data/lib/vanity/version.rb +1 -1
- data/test/myapp/log/production.log +110 -0
- data/test/rails_test.rb +17 -1
- data/vanity.gemspec +0 -1
- metadata +5 -28
data/CHANGELOG
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
== 1.5.2 (2011-04-11)
|
2
|
+
|
3
|
+
Fixed to work with redis-rb 2.2.0 (Kevin Menard).
|
4
|
+
|
5
|
+
Fixed to work with Postgresql: it complained that the index names generated by
|
6
|
+
add_index were too long, so I gave them shorter names (Robert Rasmussen).
|
7
|
+
|
8
|
+
Fixed SQL errors comparing an int to a varchar column, and no "as" on a column
|
9
|
+
alias (Robert Rasmussen).
|
10
|
+
|
11
|
+
Fixed auto-escaped text in the experiment template that I marked as html_safe
|
12
|
+
(Robert Rasmussen).
|
13
|
+
|
14
|
+
Added some Rails 3.x documentation to the 2-minute demo instructionsa (Andy Atkinson).
|
15
|
+
|
16
|
+
Fix to set collecting flag from vanity.yml config file.
|
17
|
+
|
18
|
+
|
1
19
|
== 1.5.1 (2010-12-20)
|
2
20
|
|
3
21
|
Fixes some minor bugs in RoR when including the Dashboard (netguru)
|
data/README.rdoc
CHANGED
@@ -10,6 +10,8 @@ http://farm3.static.flickr.com/2540/4099665871_497f274f68_o.jpg
|
|
10
10
|
|
11
11
|
<b>Step 1:</b> Start using Vanity in your Rails application:
|
12
12
|
|
13
|
+
== Rails 2.x configuration
|
14
|
+
|
13
15
|
Rails::Initializer.run do |config|
|
14
16
|
gem.config "vanity"
|
15
17
|
|
@@ -17,6 +19,10 @@ http://farm3.static.flickr.com/2540/4099665871_497f274f68_o.jpg
|
|
17
19
|
require "vanity"
|
18
20
|
end
|
19
21
|
end
|
22
|
+
|
23
|
+
== Rails 3 configuration
|
24
|
+
|
25
|
+
gem 'vanity' # in Gemfile, either outside of a group or inside of a bundler group
|
20
26
|
|
21
27
|
And:
|
22
28
|
|
@@ -31,6 +37,8 @@ And:
|
|
31
37
|
alternatives 19, 25, 29
|
32
38
|
metrics :signups
|
33
39
|
end
|
40
|
+
|
41
|
+
NOTE: If using a metric as above ("signups"), there needs to be a corresponding ruby file for that metric. Inside the "experiments" directory create a "metrics" directory with a file called "signup.rb". The contents of the file can describe the signup metric, refer to the "Metrics" Vanity documentation page for an example.
|
34
42
|
|
35
43
|
<b>Step 3:</b> Present the different options to your users:
|
36
44
|
|
@@ -53,6 +61,16 @@ And:
|
|
53
61
|
<b>Step 5:</b> Check the report:
|
54
62
|
|
55
63
|
vanity report --output vanity.html
|
64
|
+
|
65
|
+
== Rails 3
|
66
|
+
|
67
|
+
There is currently an issue with report generation. The vanity-talk Google Group has a couple posts that outline the issue for now. This is one of the posts: http://groups.google.com/group/vanity-talk/browse_thread/thread/343081a72a0cefb6
|
68
|
+
|
69
|
+
If you are collecting data (in development you need to opt-in to this by setting Vanity.playground.collecting = true in environments/development.rb) you can view experiment results with the vanity dashboard instead of the report.
|
70
|
+
|
71
|
+
The vanity dashboard setup instructions with Vanity work for Rails 3.x except the route is different. A Rails 3.x-style route would look like this:
|
72
|
+
|
73
|
+
`match '/vanity(/:action(/:id(.:format)))', :controller=>:vanity`
|
56
74
|
|
57
75
|
|
58
76
|
== Contributing
|
data/Rakefile
CHANGED
@@ -49,7 +49,7 @@ module Vanity
|
|
49
49
|
t.integer :alternative
|
50
50
|
t.integer :conversions
|
51
51
|
end
|
52
|
-
connection.add_index :vanity_conversions, [:vanity_experiment_id, :alternative]
|
52
|
+
connection.add_index :vanity_conversions, [:vanity_experiment_id, :alternative], :name => "by_experiment_id_and_alternative"
|
53
53
|
|
54
54
|
connection.create_table :vanity_participants do |t|
|
55
55
|
t.string :experiment_id
|
@@ -59,10 +59,10 @@ module Vanity
|
|
59
59
|
t.integer :converted
|
60
60
|
end
|
61
61
|
connection.add_index :vanity_participants, [:experiment_id]
|
62
|
-
connection.add_index :vanity_participants, [:experiment_id, :identity]
|
63
|
-
connection.add_index :vanity_participants, [:experiment_id, :shown]
|
64
|
-
connection.add_index :vanity_participants, [:experiment_id, :seen]
|
65
|
-
connection.add_index :vanity_participants, [:experiment_id, :converted]
|
62
|
+
connection.add_index :vanity_participants, [:experiment_id, :identity], :name => "by_experiment_id_and_identity"
|
63
|
+
connection.add_index :vanity_participants, [:experiment_id, :shown], :name => "by_experiment_id_and_shown"
|
64
|
+
connection.add_index :vanity_participants, [:experiment_id, :seen], :name => "by_experiment_id_and_seen"
|
65
|
+
connection.add_index :vanity_participants, [:experiment_id, :converted], :name => "by_experiment_id_and_converted"
|
66
66
|
|
67
67
|
VanitySchema.create(:version => 1)
|
68
68
|
end
|
@@ -124,7 +124,7 @@ module Vanity
|
|
124
124
|
def self.retrieve(experiment, identity, create = true, update_with = nil)
|
125
125
|
record = VanityParticipant.first(
|
126
126
|
:conditions =>
|
127
|
-
{:experiment_id => experiment.to_s, :identity => identity})
|
127
|
+
{:experiment_id => experiment.to_s, :identity => identity.to_s})
|
128
128
|
|
129
129
|
if record
|
130
130
|
record.update_attributes(update_with) if update_with
|
@@ -185,7 +185,7 @@ module Vanity
|
|
185
185
|
dates = (from.to_date..to.to_date).map(&:to_s)
|
186
186
|
conditions = [connection.quote_column_name('date') + ' IN (?)', dates]
|
187
187
|
order = "#{connection.quote_column_name('date')}"
|
188
|
-
select = "sum(#{connection.quote_column_name('value')}) value, #{connection.quote_column_name('date')}"
|
188
|
+
select = "sum(#{connection.quote_column_name('value')}) AS value, #{connection.quote_column_name('date')}"
|
189
189
|
group_by = "#{connection.quote_column_name('date')}"
|
190
190
|
|
191
191
|
values = record.vanity_metric_values.all(
|
@@ -16,7 +16,7 @@ module Vanity
|
|
16
16
|
class RedisAdapter < AbstractAdapter
|
17
17
|
def initialize(options)
|
18
18
|
@options = options.clone
|
19
|
-
@options[:db] ||= @options[:database] || (@options[:path] && @options
|
19
|
+
@options[:db] ||= @options[:database] || (@options[:path] && @options.delete(:path).split("/")[1].to_i)
|
20
20
|
@options[:thread_safe] = true
|
21
21
|
connect!
|
22
22
|
end
|
data/lib/vanity/playground.rb
CHANGED
@@ -21,16 +21,34 @@ module Vanity
|
|
21
21
|
# - load_path -- Path to load experiments/metrics from
|
22
22
|
# - logger -- Logger to use
|
23
23
|
def initialize(*args)
|
24
|
-
options =
|
25
|
-
|
24
|
+
options = Hash === args.last ? args.pop : {}
|
25
|
+
# In the case of Rails, use the Rails logger and collect only for
|
26
|
+
# production environment by default.
|
27
|
+
defaults = options[:rails] ? DEFAULTS.merge(:collecting => ::Rails.env.production?, :logger => ::Rails.logger) : DEFAULTS
|
28
|
+
if File.exists?("config/vanity.yml")
|
29
|
+
env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
|
30
|
+
config = YAML.load(ERB.new(File.read("config/vanity.yml")).result)[env]
|
31
|
+
if Hash === config
|
32
|
+
config = config.inject({}) { |h,kv| h[kv.first.to_sym] = kv.last ; h }
|
33
|
+
else
|
34
|
+
config = { :connection=>config }
|
35
|
+
end
|
36
|
+
else
|
37
|
+
config = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
@options = defaults.merge(config).merge(options)
|
26
41
|
if @options.values_at(:host, :port, :db).any?
|
27
42
|
warn "Deprecated: please specify Redis connection as URL (\"redis://host:port/db\")"
|
28
|
-
establish_connection :adapter=>"redis", :host
|
43
|
+
establish_connection :adapter=>"redis", :host=>@options[:host], :port=>@options[:port], :database=>@options[:db] || @options[:database]
|
29
44
|
elsif @options[:redis]
|
30
45
|
@adapter = RedisAdapter.new(:redis=>@options[:redis])
|
31
46
|
else
|
32
47
|
connection_spec = args.shift || @options[:connection]
|
33
|
-
|
48
|
+
if connection_spec
|
49
|
+
connection_spec = "redis://" + connection_spec unless connection_spec[/^\w+:/]
|
50
|
+
establish_connection connection_spec
|
51
|
+
end
|
34
52
|
end
|
35
53
|
|
36
54
|
warn "Deprecated: namespace option no longer supported directly" if @options[:namespace]
|
@@ -40,7 +58,7 @@ module Vanity
|
|
40
58
|
@logger.level = Logger::ERROR
|
41
59
|
end
|
42
60
|
@loading = []
|
43
|
-
@collecting =
|
61
|
+
@collecting = !!@options[:collecting]
|
44
62
|
end
|
45
63
|
|
46
64
|
# Deprecated. Use redis.server instead.
|
@@ -285,7 +303,7 @@ module Vanity
|
|
285
303
|
|
286
304
|
# In the case of Rails, use the Rails logger and collect only for
|
287
305
|
# production environment by default.
|
288
|
-
@playground = Playground.new(defined?(Rails)
|
306
|
+
@playground = Playground.new(:rails=>defined?(::Rails))
|
289
307
|
class << self
|
290
308
|
|
291
309
|
# The playground instance.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<h3><%=vanity_h experiment.name %> <span class="type">(<%= experiment.class.friendly_name %>)</span></h3>
|
2
|
-
<%= experiment.description.to_s.split(/\n\s*\n/).map { |para| vanity_html_safe(%{<p class="description">#{vanity_h para}</p>}) }.join %>
|
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
3
|
<%= render :file => Vanity.template("_" + experiment.type), :locals => {:experiment => experiment} %>
|
4
4
|
<p class="meta">Started <%= experiment.created_at.strftime("%a, %b %d") %>
|
5
5
|
<%= " | Completed #{experiment.completed_at.strftime("%a, %b %d")}" unless experiment.active? %></p>
|
data/lib/vanity/version.rb
CHANGED
@@ -3054,3 +3054,113 @@ Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
|
3054
3054
|
Processing MainController#index (for at 2010-12-20 16:51:45) [GET]
|
3055
3055
|
Parameters: {" "=>nil}
|
3056
3056
|
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3057
|
+
|
3058
|
+
|
3059
|
+
Processing MainController#index (for at 2011-04-11 14:36:53) [GET]
|
3060
|
+
Parameters: {" "=>nil}
|
3061
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3062
|
+
|
3063
|
+
|
3064
|
+
Processing MainController#index (for at 2011-04-11 14:37:51) [GET]
|
3065
|
+
Parameters: {" "=>nil}
|
3066
|
+
Completed in 12ms (View: 1 | 200 OK [http://:? ]
|
3067
|
+
|
3068
|
+
|
3069
|
+
Processing MainController#index (for at 2011-04-11 14:38:49) [GET]
|
3070
|
+
Parameters: {" "=>nil}
|
3071
|
+
Completed in 7ms (View: 1 | 200 OK [http://:? ]
|
3072
|
+
|
3073
|
+
|
3074
|
+
Processing MainController#index (for at 2011-04-11 14:40:48) [GET]
|
3075
|
+
Parameters: {" "=>nil}
|
3076
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3077
|
+
|
3078
|
+
|
3079
|
+
Processing MainController#index (for at 2011-04-11 14:47:11) [GET]
|
3080
|
+
Parameters: {" "=>nil}
|
3081
|
+
Completed in 9ms (View: 2 | 200 OK [http://:? ]
|
3082
|
+
|
3083
|
+
|
3084
|
+
Processing MainController#index (for at 2011-04-11 14:49:05) [GET]
|
3085
|
+
Parameters: {" "=>nil}
|
3086
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3087
|
+
|
3088
|
+
|
3089
|
+
Processing MainController#index (for at 2011-04-11 14:51:18) [GET]
|
3090
|
+
Parameters: {" "=>nil}
|
3091
|
+
Completed in 12ms (View: 1 | 200 OK [http://:? ]
|
3092
|
+
|
3093
|
+
|
3094
|
+
Processing MainController#index (for at 2011-04-11 14:52:58) [GET]
|
3095
|
+
Parameters: {" "=>nil}
|
3096
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3097
|
+
|
3098
|
+
|
3099
|
+
Processing MainController#index (for at 2011-04-11 15:29:31) [GET]
|
3100
|
+
Parameters: {" "=>nil}
|
3101
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3102
|
+
|
3103
|
+
|
3104
|
+
Processing MainController#index (for at 2011-04-11 15:31:08) [GET]
|
3105
|
+
Parameters: {" "=>nil}
|
3106
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3107
|
+
|
3108
|
+
|
3109
|
+
Processing MainController#index (for at 2011-04-11 15:31:56) [GET]
|
3110
|
+
Parameters: {" "=>nil}
|
3111
|
+
Completed in 8ms (View: 2 | 200 OK [http://:? ]
|
3112
|
+
|
3113
|
+
|
3114
|
+
Processing MainController#index (for at 2011-04-11 15:32:12) [GET]
|
3115
|
+
Parameters: {" "=>nil}
|
3116
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3117
|
+
|
3118
|
+
|
3119
|
+
Processing MainController#index (for at 2011-04-11 15:33:10) [GET]
|
3120
|
+
Parameters: {" "=>nil}
|
3121
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3122
|
+
|
3123
|
+
|
3124
|
+
Processing MainController#index (for at 2011-04-11 15:33:39) [GET]
|
3125
|
+
Parameters: {" "=>nil}
|
3126
|
+
Completed in 8ms (View: 3 | 200 OK [http://:? ]
|
3127
|
+
|
3128
|
+
|
3129
|
+
Processing MainController#index (for at 2011-04-11 15:34:00) [GET]
|
3130
|
+
Parameters: {" "=>nil}
|
3131
|
+
Completed in 9ms (View: 2 | 200 OK [http://:? ]
|
3132
|
+
|
3133
|
+
|
3134
|
+
Processing MainController#index (for at 2011-04-11 15:35:17) [GET]
|
3135
|
+
Parameters: {" "=>nil}
|
3136
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3137
|
+
|
3138
|
+
|
3139
|
+
Processing MainController#index (for at 2011-04-11 15:37:38) [GET]
|
3140
|
+
Parameters: {" "=>nil}
|
3141
|
+
Completed in 6ms (View: 2 | 200 OK [http://:? ]
|
3142
|
+
|
3143
|
+
|
3144
|
+
Processing MainController#index (for at 2011-04-11 15:38:23) [GET]
|
3145
|
+
Parameters: {" "=>nil}
|
3146
|
+
Completed in 8ms (View: 1 | 200 OK [http://:? ]
|
3147
|
+
|
3148
|
+
|
3149
|
+
Processing MainController#index (for at 2011-04-11 15:42:25) [GET]
|
3150
|
+
Parameters: {" "=>nil}
|
3151
|
+
Completed in 7ms (View: 1 | 200 OK [http://:? ]
|
3152
|
+
|
3153
|
+
|
3154
|
+
Processing MainController#index (for at 2011-04-11 15:43:22) [GET]
|
3155
|
+
Parameters: {" "=>nil}
|
3156
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3157
|
+
|
3158
|
+
|
3159
|
+
Processing MainController#index (for at 2011-04-11 15:43:59) [GET]
|
3160
|
+
Parameters: {" "=>nil}
|
3161
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3162
|
+
|
3163
|
+
|
3164
|
+
Processing MainController#index (for at 2011-04-11 15:44:31) [GET]
|
3165
|
+
Parameters: {" "=>nil}
|
3166
|
+
Completed in 9ms (View: 1 | 200 OK [http://:? ]
|
data/test/rails_test.rb
CHANGED
@@ -223,6 +223,23 @@ $stdout << Vanity.playground.connection
|
|
223
223
|
ensure
|
224
224
|
File.unlink yml.path
|
225
225
|
end
|
226
|
+
|
227
|
+
def test_collection_from_vanity_yaml
|
228
|
+
FileUtils.mkpath "tmp/config"
|
229
|
+
ENV["RAILS_ENV"] = "development"
|
230
|
+
File.open("tmp/config/vanity.yml", "w") do |io|
|
231
|
+
io.write <<-YML
|
232
|
+
development:
|
233
|
+
collecting: false
|
234
|
+
YML
|
235
|
+
end
|
236
|
+
assert_equal "false", load_rails(<<-RB)
|
237
|
+
initializer.after_initialize
|
238
|
+
$stdout << Vanity.playground.collecting?
|
239
|
+
RB
|
240
|
+
ensure
|
241
|
+
File.unlink "tmp/config/vanity.yml"
|
242
|
+
end
|
226
243
|
|
227
244
|
def test_collection_true_in_production_by_default
|
228
245
|
assert_equal "true", load_rails(<<-RB, "production")
|
@@ -262,7 +279,6 @@ $stdout << Vanity.playground.collecting?
|
|
262
279
|
RB
|
263
280
|
end
|
264
281
|
|
265
|
-
|
266
282
|
def load_rails(code, env = "production")
|
267
283
|
tmp = Tempfile.open("test.rb")
|
268
284
|
tmp.write <<-RB
|
data/vanity.gemspec
CHANGED
@@ -14,7 +14,6 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.files = Dir["{bin,lib,vendor,test}/**/*", "CHANGELOG", "MIT-LICENSE", "README.rdoc", "Rakefile", "Gemfile", "*.gemspec"]
|
15
15
|
spec.executable = "vanity"
|
16
16
|
|
17
|
-
spec.has_rdoc = true
|
18
17
|
spec.extra_rdoc_files = "README.rdoc", "CHANGELOG"
|
19
18
|
spec.rdoc_options = "--title", "Vanity #{spec.version}", "--main", "README.rdoc",
|
20
19
|
"--webcvs", "http://github.com/assaf/#{spec.name}"
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vanity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 5
|
9
|
-
- 1
|
10
|
-
version: 1.5.1
|
4
|
+
prerelease:
|
5
|
+
version: 1.5.2
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Assaf Arkin
|
@@ -15,8 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
13
|
+
date: 2011-04-11 00:00:00 Z
|
20
14
|
dependencies:
|
21
15
|
- !ruby/object:Gem::Dependency
|
22
16
|
name: redis
|
@@ -26,10 +20,6 @@ dependencies:
|
|
26
20
|
requirements:
|
27
21
|
- - ~>
|
28
22
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 0
|
33
23
|
version: "2.0"
|
34
24
|
type: :runtime
|
35
25
|
version_requirements: *id001
|
@@ -41,10 +31,6 @@ dependencies:
|
|
41
31
|
requirements:
|
42
32
|
- - ~>
|
43
33
|
- !ruby/object:Gem::Version
|
44
|
-
hash: 5
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
- 7
|
48
34
|
version: "0.7"
|
49
35
|
type: :runtime
|
50
36
|
version_requirements: *id002
|
@@ -126,14 +112,13 @@ files:
|
|
126
112
|
- Rakefile
|
127
113
|
- Gemfile
|
128
114
|
- vanity.gemspec
|
129
|
-
has_rdoc: true
|
130
115
|
homepage: http://vanity.labnotes.org
|
131
116
|
licenses: []
|
132
117
|
|
133
118
|
post_install_message: To get started run vanity --help
|
134
119
|
rdoc_options:
|
135
120
|
- --title
|
136
|
-
- Vanity 1.5.
|
121
|
+
- Vanity 1.5.2
|
137
122
|
- --main
|
138
123
|
- README.rdoc
|
139
124
|
- --webcvs
|
@@ -145,25 +130,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
145
130
|
requirements:
|
146
131
|
- - ">="
|
147
132
|
- !ruby/object:Gem::Version
|
148
|
-
hash: 57
|
149
|
-
segments:
|
150
|
-
- 1
|
151
|
-
- 8
|
152
|
-
- 7
|
153
133
|
version: 1.8.7
|
154
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
135
|
none: false
|
156
136
|
requirements:
|
157
137
|
- - ">="
|
158
138
|
- !ruby/object:Gem::Version
|
159
|
-
hash: 3
|
160
|
-
segments:
|
161
|
-
- 0
|
162
139
|
version: "0"
|
163
140
|
requirements: []
|
164
141
|
|
165
142
|
rubyforge_project:
|
166
|
-
rubygems_version: 1.
|
143
|
+
rubygems_version: 1.7.2
|
167
144
|
signing_key:
|
168
145
|
specification_version: 3
|
169
146
|
summary: Experience Driven Development framework for Ruby
|