vanity 1.8.0 → 1.8.1
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.
- checksums.yaml +7 -0
- data/.travis.yml +9 -1
- data/Appraisals +0 -4
- data/CHANGELOG +18 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +5 -5
- data/README.rdoc +42 -27
- data/Rakefile +2 -2
- data/bin/vanity +65 -12
- data/gemfiles/rails3.gemfile +1 -1
- data/gemfiles/rails3.gemfile.lock +4 -4
- data/gemfiles/rails31.gemfile +1 -1
- data/gemfiles/rails31.gemfile.lock +4 -4
- data/gemfiles/rails32.gemfile +1 -1
- data/gemfiles/rails32.gemfile.lock +4 -4
- data/lib/vanity/adapters/active_record_adapter.rb +4 -0
- data/lib/vanity/commands/report.rb +35 -14
- data/lib/vanity/experiment/base.rb +8 -8
- data/lib/vanity/frameworks/rails.rb +41 -17
- data/lib/vanity/templates/_vanity.js.erb +16 -20
- data/lib/vanity/version.rb +1 -1
- data/test/cli_test.rb +53 -0
- data/test/dummy/config/application.rb +6 -0
- data/test/rails_helper_test.rb +24 -3
- metadata +45 -44
- data/gemfiles/rails2.gemfile +0 -20
- data/gemfiles/rails2.gemfile.lock +0 -85
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA512:
|
3
|
+
data.tar.gz: cf97c9c3b23e4edf20b47b84fda3f7f31eed9f770ca16c3fd4850bc38b542a2c335fa91c3b68ec912ffa21ccfa14eb14f4b3fc370016bcf797852d6089f99075
|
4
|
+
metadata.gz: 2377c5146a59528271b9bfc244236e8d7a3b142676bafbee8d527a0037a7a1cab0bf065e086922f3b354ef4f798a17d0e0f9aaa5e0fd7f04367970a660fd691e
|
5
|
+
SHA1:
|
6
|
+
data.tar.gz: e713ef94697abdc32fb3dc46e960b83d703f0451
|
7
|
+
metadata.gz: ece1cada68e0f549be1ad0cf0fea02f7ce387c75
|
data/.travis.yml
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
language: ruby
|
2
2
|
bundler_args: --without development
|
3
3
|
script: 'rake appraisal test'
|
4
|
+
services:
|
5
|
+
- mongodb
|
4
6
|
rvm:
|
5
7
|
- 1.8.7
|
6
|
-
- 1.9.
|
8
|
+
- 1.9.3
|
9
|
+
- 2.0.0
|
10
|
+
- ruby-head
|
7
11
|
env:
|
8
12
|
- DB=mongodb
|
9
13
|
- DB=redis
|
@@ -13,3 +17,7 @@ before_script:
|
|
13
17
|
- "mysql -e 'create database vanity_test;' >/dev/null"
|
14
18
|
- "rake appraisal:install"
|
15
19
|
#- "psql -c 'create database vanity_test;' -U postgres >/dev/null"
|
20
|
+
matrix:
|
21
|
+
allow_failures:
|
22
|
+
- rvm: 2.0.0
|
23
|
+
- rvm: ruby-head
|
data/Appraisals
CHANGED
data/CHANGELOG
CHANGED
@@ -1,9 +1,23 @@
|
|
1
|
+
== 1.8.1 (2013-10-05)
|
2
|
+
|
3
|
+
Added vanity_experiments helper for rails to return read only copy of active experiments (@iceberg901).
|
4
|
+
Fixed support for Mass Assignment on Rails 3.2 (@hcarver).
|
5
|
+
Fixed commandlin usage (@phillbaker).
|
6
|
+
|
7
|
+
|
8
|
+
== 1.8.0 (2012-03-12)
|
9
|
+
|
10
|
+
Improved support for Rails 3.1 and Rails 3.2. Thanks to masverba, Daan and IsaacLewis.
|
11
|
+
|
12
|
+
Finer Grained Exceptions for Missing Experiments (Nick Barnwell)
|
13
|
+
|
14
|
+
|
1
15
|
== 1.7.1 (2011-09-30)
|
2
16
|
|
3
17
|
Minor change in locating config file (Ariel Salomon)
|
4
18
|
|
5
19
|
Allow for table names in specified :timestamps (Peter Kovacs)
|
6
|
-
|
20
|
+
|
7
21
|
When a named scope includes a join, created_at can be ambiguous. Use
|
8
22
|
|
9
23
|
metric "Sky is limit" do
|
@@ -28,7 +42,7 @@ connections are deprecated in favor of using the connection option with a URI
|
|
28
42
|
|
29
43
|
1.7.0 adds support for ActionMailer, for example:
|
30
44
|
|
31
|
-
class UserMailer < ActionMailer::Base
|
45
|
+
class UserMailer < ActionMailer::Base
|
32
46
|
def invite_email(user)
|
33
47
|
use_vanity_mailer user
|
34
48
|
mail :to => user.email, :subject => ab_test(:invite_subject)
|
@@ -218,7 +232,7 @@ To view Google Analytics metrics from within Vanity, first make sure you are
|
|
218
232
|
using Garb. For example, in your Gemfile:
|
219
233
|
|
220
234
|
gem "vanity", "1.3.0"
|
221
|
-
gem "garb", "0.5.0"
|
235
|
+
gem "garb", "0.5.0"
|
222
236
|
|
223
237
|
Next, authenticate using your account credentials. For example, in your
|
224
238
|
config/environments/production.rb:
|
@@ -310,7 +324,7 @@ Much thanks to Ian Sefferman for fixing issues with Ruby 1.8.7 and Rails support
|
|
310
324
|
* Added: Metrics.
|
311
325
|
* Added: Use Vanity.playground.mock! when running tests and you'd rather not access a live Redis server.
|
312
326
|
* Changed: A/B tests now using metrics for tracking.
|
313
|
-
* Changed: Now throwing NameError instead of LoadError when failing to load experiment/metric. NameError can be rescued on same line.
|
327
|
+
* Changed: Now throwing NameError instead of LoadError when failing to load experiment/metric. NameError can be rescued on same line.
|
314
328
|
* Changed: New, easier URL mapping for Dashboard: map.vanity "/vanity", :controller=>:vanity.
|
315
329
|
* Changed: All tests are green on Ruby 1.8.6, 1.8.7 and 1.9.1.
|
316
330
|
* Changed: Switched to redis-rb from http://github.com/ezmobius/redis-rb.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vanity (1.8.
|
4
|
+
vanity (1.8.1)
|
5
5
|
redis (~> 2.0)
|
6
6
|
redis-namespace (~> 1.0.0)
|
7
7
|
|
8
8
|
GEM
|
9
|
-
remote:
|
9
|
+
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
RedCloth (4.2.9)
|
12
12
|
SystemTimer (1.2.3)
|
@@ -23,7 +23,7 @@ GEM
|
|
23
23
|
addressable (2.2.7)
|
24
24
|
albino (1.3.3)
|
25
25
|
posix-spawn (>= 0.3.6)
|
26
|
-
appraisal (0.
|
26
|
+
appraisal (0.5.2)
|
27
27
|
bundler
|
28
28
|
rake
|
29
29
|
bson (1.6.0)
|
@@ -69,9 +69,9 @@ GEM
|
|
69
69
|
activeresource (= 2.3.14)
|
70
70
|
activesupport (= 2.3.14)
|
71
71
|
rake (>= 0.8.3)
|
72
|
-
rake (
|
72
|
+
rake (10.1.0)
|
73
73
|
redis (2.2.2)
|
74
|
-
redis-namespace (1.0.
|
74
|
+
redis-namespace (1.0.4)
|
75
75
|
redis (< 3.0.0)
|
76
76
|
shoulda (3.0.1)
|
77
77
|
shoulda-context (~> 1.0.0)
|
data/README.rdoc
CHANGED
@@ -1,16 +1,21 @@
|
|
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]
|
3
|
+
|
1
4
|
Vanity is an Experiment Driven Development framework for Rails.
|
2
5
|
|
3
6
|
* All about Vanity: http://vanity.labnotes.org
|
4
|
-
* On
|
7
|
+
* On Github: http://github.com/assaf/vanity
|
5
8
|
|
6
9
|
http://farm3.static.flickr.com/2540/4099665871_497f274f68_o.jpg
|
7
10
|
|
8
11
|
|
9
12
|
== A/B Testing With Rails (In 5 Easy Steps)
|
10
13
|
|
11
|
-
<b>Step 1:</b> Start using Vanity in your Rails application
|
14
|
+
=== <b>Step 1:</b> Start using Vanity in your Rails application
|
15
|
+
|
16
|
+
==== Step 1.1
|
12
17
|
|
13
|
-
|
18
|
+
===== Rails 2.x installation
|
14
19
|
|
15
20
|
Rails::Initializer.run do |config|
|
16
21
|
gem.config "vanity"
|
@@ -19,39 +24,49 @@ http://farm3.static.flickr.com/2540/4099665871_497f274f68_o.jpg
|
|
19
24
|
require "vanity"
|
20
25
|
end
|
21
26
|
end
|
22
|
-
|
23
|
-
|
27
|
+
|
28
|
+
===== Rails 3 installation
|
24
29
|
|
25
30
|
Add to your Gemfile:
|
26
|
-
|
31
|
+
|
27
32
|
gem "vanity"
|
28
33
|
|
29
|
-
|
34
|
+
===== Rails 4 installation
|
35
|
+
|
36
|
+
Coming soon!
|
37
|
+
|
38
|
+
==== Step 1.2
|
39
|
+
|
40
|
+
Choose a method to store experiment results: for Redis or an external tracking mechanism, migrations aren't needed. Mongo is also available. To use a relational database, via ActiveRecord, run the generator and migrations to create the database schema:
|
30
41
|
|
31
42
|
$ rails generate vanity
|
32
43
|
$ rake db:migrate
|
33
|
-
|
34
|
-
|
44
|
+
|
45
|
+
==== Step 1.3
|
46
|
+
|
47
|
+
add to your application controller:
|
35
48
|
|
36
49
|
class ApplicationController < ActionController::Base
|
37
50
|
use_vanity :current_user
|
38
51
|
end
|
39
52
|
|
40
|
-
<b>Step 2:</b> Define your first A/B test
|
53
|
+
=== <b>Step 2:</b> Define your first A/B test
|
54
|
+
|
55
|
+
This experiment goes in the file <code>experiments/price_options.rb</code>:
|
41
56
|
|
42
57
|
ab_test "Price options" do
|
43
58
|
description "Mirror, mirror on the wall, who's the better price of all?"
|
44
59
|
alternatives 19, 25, 29
|
45
60
|
metrics :signups
|
46
61
|
end
|
47
|
-
|
48
|
-
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 "signups.rb". The contents of the file can describe the signup metric, refer to the "Metrics" Vanity documentation page for an example.
|
49
62
|
|
50
|
-
|
63
|
+
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 "signups.rb". The contents of the file can describe the signup metric, refer to the "Metrics" Vanity documentation page for an example.
|
64
|
+
|
65
|
+
=== <b>Step 3:</b> Present the different options to your users
|
51
66
|
|
52
67
|
<h2>Get started for only $<%= ab_test :price_options %> a month!</h2>
|
53
68
|
|
54
|
-
<b>Step 4:</b> Measure conversion
|
69
|
+
=== <b>Step 4:</b> Measure conversion
|
55
70
|
|
56
71
|
class SignupController < ApplicationController
|
57
72
|
def signup
|
@@ -65,21 +80,11 @@ Add to your application controller:
|
|
65
80
|
end
|
66
81
|
end
|
67
82
|
|
68
|
-
<b>Step 5:</b> Check the report:
|
83
|
+
=== <b>Step 5:</b> Check the report:
|
69
84
|
|
70
85
|
vanity report --output vanity.html
|
71
|
-
|
72
|
-
|
73
|
-
== Rails 3
|
74
|
-
|
75
|
-
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
|
76
|
-
|
77
|
-
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.
|
78
|
-
|
79
|
-
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:
|
80
|
-
|
81
|
-
`match '/vanity(/:action(/:id(.:format)))', :controller=>:vanity`
|
82
86
|
|
87
|
+
Or see instructions for viewing the results using Rails.
|
83
88
|
|
84
89
|
== Registering participants with Javascript
|
85
90
|
|
@@ -89,6 +94,16 @@ If robots or spiders make up a significant portion of your sites traffic they ca
|
|
89
94
|
* Set Vanity.playground.add_participant_path = '/path/to/vanity/action', this should point to the add_participant path that is added with Vanity::Rails::Dashboard, make sure that this action is available to all users
|
90
95
|
* Add <%= vanity_js %> to any page that needs uses an ab_test. vanity_js needs to be included after your call to ab_test so that it knows which version of the experiment the participant is a member of. The helper will render nothing if the there are no ab_tests running on the current page, so adding vanity_js to the bottom of your layouts is a good option. Keep in mind that if you call use_js! and don't include vanity_js in your view no participants will be recorded.
|
91
96
|
|
97
|
+
== Compatibility Matrix
|
98
|
+
|
99
|
+
Running Rails 2 on Ruby 2? Vanity probably won't work for you. But here's what does:
|
100
|
+
|
101
|
+
Persistence: Redis, Mongo, ActiveRecord
|
102
|
+
Rails: 2.3, 3, 3.1, 3.2
|
103
|
+
Ruby: 1.8.7, 1.9.3
|
104
|
+
|
105
|
+
NOTE: Support for Rails 4 and Ruby 2.0 are coming soon!
|
106
|
+
|
92
107
|
== Contributing
|
93
108
|
|
94
109
|
* Fork the project
|
@@ -102,7 +117,7 @@ If robots or spiders make up a significant portion of your sites traffic they ca
|
|
102
117
|
|
103
118
|
== Credits/License
|
104
119
|
|
105
|
-
Original code, copyright of Assaf Arkin, released under the MIT license.
|
120
|
+
Original code, copyright of Assaf Arkin, released under the MIT license.
|
106
121
|
|
107
122
|
Documentation available under the Creative Commons Attribution license.
|
108
123
|
|
data/Rakefile
CHANGED
@@ -17,7 +17,7 @@ task :install=>:build do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
desc "Push new release to gemcutter and git tag"
|
20
|
-
task :push=>["
|
20
|
+
task :push=>["build"] do
|
21
21
|
sh "git push"
|
22
22
|
puts "Tagging version #{spec.version} .."
|
23
23
|
sh "git tag v#{spec.version}"
|
@@ -33,7 +33,7 @@ desc "Test everything"
|
|
33
33
|
task "test:all"=>"test:adapters"
|
34
34
|
|
35
35
|
# Ruby versions we're testing with.
|
36
|
-
RUBIES = %w{1.8.7 1.9.2}
|
36
|
+
RUBIES = %w{1.8.7 1.9.2 2.0.0}
|
37
37
|
|
38
38
|
# Use rake test:rubies to run all combination of tests (see test:adapters) using
|
39
39
|
# all the versions of Ruby specified in RUBIES. Or to test a specific version of
|
data/bin/vanity
CHANGED
@@ -1,16 +1,69 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
# Is there a better way to detect Rails?
|
3
|
+
if File.exist?("config/boot.rb") && File.exist?("config/environment.rb")
|
4
|
+
require "./config/environment"
|
5
|
+
else
|
6
|
+
path = File.expand_path("../lib", File.dirname(__FILE__))
|
7
|
+
$LOAD_PATH.unshift path unless $LOAD_PATH.include?(path)
|
8
|
+
require "vanity"
|
9
|
+
end
|
8
10
|
|
9
|
-
require
|
10
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
-
Pathname.new(__FILE__).realpath)
|
11
|
+
require "optparse"
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
playground = Vanity.playground
|
14
|
+
options = Struct.new(:output).new
|
15
|
+
opts = OptionParser.new("", 24, " ") do |opts|
|
16
|
+
opts.banner = "Usage: #{File.basename($0)} [options] command\n"
|
17
|
+
opts.banner << "Commands:\n"
|
18
|
+
opts.banner << " list List all experiments and metrics\n"
|
19
|
+
opts.banner << " report Report on all running experiments/metrics\n"
|
20
|
+
opts.banner << " upgrade Upgrade your database when deploying new release\n"
|
15
21
|
|
16
|
-
|
22
|
+
opts.separator ""
|
23
|
+
opts.separator "Reporting options:"
|
24
|
+
opts.on "--output FILE", "Write report to this file (default: stdout)" do |path|
|
25
|
+
options.output = path
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.separator ""
|
29
|
+
opts.separator "Common options:"
|
30
|
+
opts.on "--load_path PATH", "Path to experiments directory (default: #{playground.load_path})" do |path|
|
31
|
+
playground.load_path = path
|
32
|
+
end
|
33
|
+
opts.on "-d", "--database url", "Database connection URL (e.g. redis:/localhost:6379)" do |conn|
|
34
|
+
playground.establish_connection conn
|
35
|
+
end
|
36
|
+
opts.on "--redis HOST:PORT:DB", "DEPRECATED: Redis server host (default: localhost:6379)" do |redis|
|
37
|
+
host, port, db = redis.split(":")
|
38
|
+
playground.establish_connection "redis:/#{host}:#{port}/#{db}"
|
39
|
+
end
|
40
|
+
opts.on_tail "-h", "--help", "Show this message" do
|
41
|
+
puts opts.to_s.gsub(/^.*DEPRECATED.*$/s, '')
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
opts.on_tail "-v", "--version", "Show version" do
|
45
|
+
puts "Vanity #{Vanity::Version::STRING}"
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.parse!(ARGV)
|
51
|
+
if ARGV.empty?
|
52
|
+
puts opts.banner
|
53
|
+
exit
|
54
|
+
end
|
55
|
+
|
56
|
+
ARGV.each do |cmd|
|
57
|
+
case cmd
|
58
|
+
when "report"
|
59
|
+
require "vanity/commands/report"
|
60
|
+
Vanity::Commands.report options.output
|
61
|
+
when "list"
|
62
|
+
require "vanity/commands/list"
|
63
|
+
Vanity::Commands.list
|
64
|
+
when "upgrade"
|
65
|
+
require "vanity/commands/upgrade"
|
66
|
+
Vanity::Commands.upgrade
|
67
|
+
else puts "No such command: #{cmd}"
|
68
|
+
end
|
69
|
+
end
|
data/gemfiles/rails3.gemfile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
PATH
|
2
|
-
remote: /Users/
|
2
|
+
remote: /Users/phill/Development/ruby/vanity
|
3
3
|
specs:
|
4
|
-
vanity (1.8.
|
4
|
+
vanity (1.8.1)
|
5
5
|
redis (~> 2.0)
|
6
6
|
redis-namespace (~> 1.0.0)
|
7
7
|
|
8
8
|
GEM
|
9
|
-
remote:
|
9
|
+
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
SystemTimer (1.2.3)
|
12
12
|
abstract (1.0.0)
|
@@ -97,7 +97,7 @@ GEM
|
|
97
97
|
rdoc (3.12)
|
98
98
|
json (~> 1.4)
|
99
99
|
redis (2.2.2)
|
100
|
-
redis-namespace (1.0.
|
100
|
+
redis-namespace (1.0.4)
|
101
101
|
redis (< 3.0.0)
|
102
102
|
shoulda (3.0.1)
|
103
103
|
shoulda-context (~> 1.0.0)
|
data/gemfiles/rails31.gemfile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
PATH
|
2
|
-
remote: /Users/
|
2
|
+
remote: /Users/phill/Development/ruby/vanity
|
3
3
|
specs:
|
4
|
-
vanity (1.8.
|
4
|
+
vanity (1.8.1)
|
5
5
|
redis (~> 2.0)
|
6
6
|
redis-namespace (~> 1.0.0)
|
7
7
|
|
8
8
|
GEM
|
9
|
-
remote:
|
9
|
+
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
SystemTimer (1.2.3)
|
12
12
|
actionmailer (3.1.3)
|
@@ -103,7 +103,7 @@ GEM
|
|
103
103
|
rdoc (3.12)
|
104
104
|
json (~> 1.4)
|
105
105
|
redis (2.2.2)
|
106
|
-
redis-namespace (1.0.
|
106
|
+
redis-namespace (1.0.4)
|
107
107
|
redis (< 3.0.0)
|
108
108
|
shoulda (3.0.1)
|
109
109
|
shoulda-context (~> 1.0.0)
|
data/gemfiles/rails32.gemfile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
PATH
|
2
|
-
remote: /Users/
|
2
|
+
remote: /Users/phill/Development/ruby/vanity
|
3
3
|
specs:
|
4
|
-
vanity (1.8.
|
4
|
+
vanity (1.8.1)
|
5
5
|
redis (~> 2.0)
|
6
6
|
redis-namespace (~> 1.0.0)
|
7
7
|
|
8
8
|
GEM
|
9
|
-
remote:
|
9
|
+
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
SystemTimer (1.2.3)
|
12
12
|
actionmailer (3.2.1)
|
@@ -101,7 +101,7 @@ GEM
|
|
101
101
|
rdoc (3.12)
|
102
102
|
json (~> 1.4)
|
103
103
|
redis (2.2.2)
|
104
|
-
redis-namespace (1.0.
|
104
|
+
redis-namespace (1.0.4)
|
105
105
|
redis (< 3.0.0)
|
106
106
|
shoulda (3.0.1)
|
107
107
|
shoulda-context (~> 1.0.0)
|
@@ -32,6 +32,8 @@ module Vanity
|
|
32
32
|
|
33
33
|
# Metric value
|
34
34
|
class VanityMetricValue < VanityRecord
|
35
|
+
attr_accessible :date, :index, :value if respond_to?(:attr_accessible)
|
36
|
+
|
35
37
|
self.table_name = :vanity_metric_values
|
36
38
|
belongs_to :vanity_metric
|
37
39
|
end
|
@@ -40,6 +42,7 @@ module Vanity
|
|
40
42
|
class VanityExperiment < VanityRecord
|
41
43
|
self.table_name = :vanity_experiments
|
42
44
|
has_many :vanity_conversions, :dependent => :destroy
|
45
|
+
attr_accessible :experiment_id if respond_to?(:attr_accessible)
|
43
46
|
|
44
47
|
# Finds or creates the experiment
|
45
48
|
def self.retrieve(experiment)
|
@@ -61,6 +64,7 @@ module Vanity
|
|
61
64
|
# Participant model
|
62
65
|
class VanityParticipant < VanityRecord
|
63
66
|
self.table_name = :vanity_participants
|
67
|
+
attr_accessible :experiment_id, :identity, :seen, :shown, :converted if respond_to?(:attr_accessible)
|
64
68
|
|
65
69
|
# Finds the participant by experiment and identity. If
|
66
70
|
# create is true then it will create the participant
|
@@ -2,30 +2,28 @@ require "erb"
|
|
2
2
|
require "cgi"
|
3
3
|
|
4
4
|
module Vanity
|
5
|
-
|
5
|
+
|
6
6
|
# Render method available to templates (when used by Vanity command line,
|
7
7
|
# outside Rails).
|
8
8
|
module Render
|
9
|
-
|
9
|
+
|
10
10
|
# Render the named template. Used for reporting and the dashboard.
|
11
|
-
def render(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
erb.filename = path
|
21
|
-
erb.result(locals.instance_eval { binding })
|
11
|
+
def render(path_or_options, locals = {})
|
12
|
+
if path_or_options.respond_to?(:keys)
|
13
|
+
render_erb(
|
14
|
+
path_or_options[:file] || path_or_options[:partial],
|
15
|
+
path_or_options[:locals]
|
16
|
+
)
|
17
|
+
else
|
18
|
+
render_erb(path_or_options, locals)
|
19
|
+
end
|
22
20
|
end
|
23
21
|
|
24
22
|
# Escape HTML.
|
25
23
|
def vanity_h(html)
|
26
24
|
CGI.escapeHTML(html.to_s)
|
27
25
|
end
|
28
|
-
|
26
|
+
|
29
27
|
def vanity_html_safe(text)
|
30
28
|
text
|
31
29
|
end
|
@@ -38,6 +36,29 @@ module Vanity
|
|
38
36
|
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') + # 1 newline -> br
|
39
37
|
"</p>"
|
40
38
|
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def render_erb(path, locals = {})
|
43
|
+
locals[:playground] = self
|
44
|
+
keys = locals.keys
|
45
|
+
struct = Struct.new(*keys)
|
46
|
+
struct.send :include, Render
|
47
|
+
locals = struct.new(*locals.values_at(*keys))
|
48
|
+
dir, base = File.split(path)
|
49
|
+
path = File.join(dir, partialize(base))
|
50
|
+
erb = ERB.new(File.read(path), nil, '<>')
|
51
|
+
erb.filename = path
|
52
|
+
erb.result(locals.instance_eval { binding })
|
53
|
+
end
|
54
|
+
|
55
|
+
def partialize(template_name)
|
56
|
+
if template_name[0] != '_'
|
57
|
+
"_#{template_name}"
|
58
|
+
else
|
59
|
+
template_name
|
60
|
+
end
|
61
|
+
end
|
41
62
|
end
|
42
63
|
|
43
64
|
# Commands available when running Vanity from the command line (see bin/vanity).
|
@@ -34,7 +34,7 @@ module Vanity
|
|
34
34
|
class Base
|
35
35
|
|
36
36
|
class << self
|
37
|
-
|
37
|
+
|
38
38
|
# Returns the type of this class as a symbol (e.g. AbTest becomes
|
39
39
|
# ab_test).
|
40
40
|
def type
|
@@ -94,7 +94,7 @@ module Vanity
|
|
94
94
|
def type
|
95
95
|
self.class.type
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
# Defines how we obtain an identity for the current experiment. Usually
|
99
99
|
# Vanity gets the identity form a session object (see use_vanity), but
|
100
100
|
# there are cases where you want a particular experiment to use a
|
@@ -126,7 +126,7 @@ module Vanity
|
|
126
126
|
@description = text if text
|
127
127
|
@description
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
130
|
|
131
131
|
# -- Experiment completion --
|
132
132
|
|
@@ -152,7 +152,7 @@ module Vanity
|
|
152
152
|
def completed_at
|
153
153
|
@completed_at ||= connection.get_experiment_completed_at(@id)
|
154
154
|
end
|
155
|
-
|
155
|
+
|
156
156
|
# Returns true if experiment active, false if completed.
|
157
157
|
def active?
|
158
158
|
!@playground.collecting? || !connection.is_experiment_completed?(@id)
|
@@ -180,7 +180,7 @@ module Vanity
|
|
180
180
|
|
181
181
|
def default_identify(context)
|
182
182
|
raise "No Vanity.context" unless context
|
183
|
-
raise "Vanity.context does not respond to vanity_identity" unless context.respond_to?(:vanity_identity)
|
183
|
+
raise "Vanity.context does not respond to vanity_identity" unless context.respond_to?(:vanity_identity, true)
|
184
184
|
context.send(:vanity_identity) or raise "Vanity.context.vanity_identity - no identity"
|
185
185
|
end
|
186
186
|
|
@@ -195,7 +195,7 @@ module Vanity
|
|
195
195
|
end
|
196
196
|
end
|
197
197
|
end
|
198
|
-
|
198
|
+
|
199
199
|
# Returns key for this experiment, or with an argument, return a key
|
200
200
|
# using the experiment as the namespace. Examples:
|
201
201
|
# key => "vanity:experiments:green_button"
|
@@ -208,11 +208,11 @@ module Vanity
|
|
208
208
|
def connection
|
209
209
|
@playground.connection
|
210
210
|
end
|
211
|
-
|
211
|
+
|
212
212
|
end
|
213
213
|
end
|
214
214
|
|
215
215
|
class NoExperimentError < NameError
|
216
216
|
end
|
217
|
-
|
217
|
+
|
218
218
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Vanity
|
2
|
-
module Rails
|
2
|
+
module Rails
|
3
3
|
def self.load!
|
4
4
|
Vanity.playground.load_path = ::Rails.root + Vanity.playground.load_path
|
5
5
|
Vanity.playground.logger ||= ::Rails.logger
|
@@ -93,8 +93,8 @@ module Vanity
|
|
93
93
|
end
|
94
94
|
protected :use_vanity_mailer
|
95
95
|
end
|
96
|
-
|
97
|
-
|
96
|
+
|
97
|
+
|
98
98
|
# Vanity needs these filters. They are includes in ActionController and
|
99
99
|
# automatically added when you use #use_vanity in your controller.
|
100
100
|
module Filters
|
@@ -142,7 +142,7 @@ module Vanity
|
|
142
142
|
def vanity_reload_filter
|
143
143
|
Vanity.playground.reload!
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
# Filter to track metrics
|
147
147
|
# pass _track param along to call track! on that alternative
|
148
148
|
def vanity_track_filter
|
@@ -150,7 +150,7 @@ module Vanity
|
|
150
150
|
track! params[:_track]
|
151
151
|
end
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
protected :vanity_context_filter, :vanity_query_parameter_filter, :vanity_reload_filter
|
155
155
|
end
|
156
156
|
|
@@ -182,14 +182,10 @@ module Vanity
|
|
182
182
|
# <%= count %> features to choose from!
|
183
183
|
# <% end %>
|
184
184
|
def ab_test(name, &block)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
else
|
190
|
-
value = Vanity.playground.experiment(name.to_sym).choose.value
|
191
|
-
end
|
192
|
-
|
185
|
+
@_vanity_experiments ||= {}
|
186
|
+
@_vanity_experiments[name] ||= Vanity.playground.experiment(name.to_sym).choose
|
187
|
+
value = @_vanity_experiments[name].value
|
188
|
+
|
193
189
|
if block
|
194
190
|
content = capture(value, &block)
|
195
191
|
if defined?(block_called_from_erb?) && block_called_from_erb?(block)
|
@@ -201,13 +197,13 @@ module Vanity
|
|
201
197
|
value
|
202
198
|
end
|
203
199
|
end
|
204
|
-
|
200
|
+
|
205
201
|
# Generate url with the identity of the current user and the metric to track on click
|
206
202
|
def vanity_track_url_for(identity, metric, options = {})
|
207
203
|
options = options.merge(:_identity => identity, :_track => metric)
|
208
204
|
url_for(options)
|
209
205
|
end
|
210
|
-
|
206
|
+
|
211
207
|
# Generate url with the fingerprint for the current Vanity experiment
|
212
208
|
def vanity_tracking_image(identity, metric, options = {})
|
213
209
|
options = options.merge(:controller => :vanity, :action => :image, :_identity => identity, :_track => metric)
|
@@ -215,7 +211,7 @@ module Vanity
|
|
215
211
|
end
|
216
212
|
|
217
213
|
def vanity_js
|
218
|
-
return if @_vanity_experiments.nil?
|
214
|
+
return if @_vanity_experiments.nil? || @_vanity_experiments.empty?
|
219
215
|
javascript_tag do
|
220
216
|
render :file => Vanity.template("_vanity.js.erb")
|
221
217
|
end
|
@@ -236,6 +232,34 @@ module Vanity
|
|
236
232
|
def vanity_simple_format(text, html_options={})
|
237
233
|
vanity_html_safe(simple_format(text, html_options))
|
238
234
|
end
|
235
|
+
|
236
|
+
# Return a copy of the active experiments on a page
|
237
|
+
#
|
238
|
+
# @example Render some info about each active experiment in development mode
|
239
|
+
# <% if Rails.env.development? %>
|
240
|
+
# <% vanity_experiments.each do |name, alternative| %>
|
241
|
+
# <span>Participating in <%= name %>, seeing <%= alternative %>:<%= alternative.value %> </span>
|
242
|
+
# <% end %>
|
243
|
+
# <% end %>
|
244
|
+
# @example Push experiment values into javascript for use there
|
245
|
+
# <% experiments = vanity_experiments %>
|
246
|
+
# <% unless experiments.empty? %>
|
247
|
+
# <script>
|
248
|
+
# <% experiments.each do |name, alternative| %>
|
249
|
+
# myAbTests.<%= name.to_s.camelize(:lower) %> = '<%= alternative.value %>';
|
250
|
+
# <% end %>
|
251
|
+
# </script>
|
252
|
+
# <% end %>
|
253
|
+
def vanity_experiments
|
254
|
+
@_vanity_experiments ||= {}
|
255
|
+
experiments = {}
|
256
|
+
|
257
|
+
@_vanity_experiments.each do |name, alternative|
|
258
|
+
experiments[name] = alternative.clone
|
259
|
+
end
|
260
|
+
|
261
|
+
return experiments
|
262
|
+
end
|
239
263
|
end
|
240
264
|
|
241
265
|
|
@@ -269,7 +293,7 @@ module Vanity
|
|
269
293
|
render :status => 200, :nothing => true
|
270
294
|
end
|
271
295
|
end
|
272
|
-
|
296
|
+
|
273
297
|
module TrackingImage
|
274
298
|
def image
|
275
299
|
# send image
|
@@ -1,20 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
httpRequest.send(params);
|
18
|
-
}
|
19
|
-
<% end %>
|
20
|
-
<% end %>
|
1
|
+
var httpRequest;
|
2
|
+
<% @_vanity_experiments.each do |name, alternative| %>
|
3
|
+
var params = "e=<%= name %>&a=<%= alternative.id %>&authenticity_token=" + encodeURIComponent("<%= form_authenticity_token %>");
|
4
|
+
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
|
5
|
+
httpRequest = new XMLHttpRequest();
|
6
|
+
} else if (window.ActiveXObject) { // IE
|
7
|
+
try { httpRequest = new ActiveXObject("Msxml2.XMLHTTP"); }
|
8
|
+
catch (e) { }
|
9
|
+
}
|
10
|
+
if (httpRequest) {
|
11
|
+
httpRequest.open('POST', "<%= Vanity.playground.add_participant_path %>", true);
|
12
|
+
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
13
|
+
httpRequest.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
14
|
+
httpRequest.send(params);
|
15
|
+
}
|
16
|
+
<% end %>
|
data/lib/vanity/version.rb
CHANGED
data/test/cli_test.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require "test/test_helper"
|
2
|
+
|
3
|
+
class PlaygroundTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_responds_to_version
|
6
|
+
(RUBY_VERSION == "1.8.7" ? Object : IO).any_instance.expects(:puts)
|
7
|
+
ARGV.clear
|
8
|
+
ARGV << '--version'
|
9
|
+
load "bin/vanity"
|
10
|
+
rescue SystemExit => e
|
11
|
+
assert e.status == 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_responds_to_help
|
15
|
+
(RUBY_VERSION == "1.8.7" ? Object : IO).any_instance.expects(:puts)
|
16
|
+
ARGV.clear
|
17
|
+
ARGV << '--help'
|
18
|
+
load "bin/vanity"
|
19
|
+
rescue SystemExit => e
|
20
|
+
assert e.status == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_responds_to_list
|
24
|
+
require "vanity/commands/list"
|
25
|
+
Vanity::Commands.expects(:list)
|
26
|
+
ARGV.clear
|
27
|
+
ARGV << 'list'
|
28
|
+
load "bin/vanity"
|
29
|
+
rescue SystemExit => e
|
30
|
+
assert e.status == 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_responds_to_report
|
34
|
+
require "vanity/commands/report"
|
35
|
+
Vanity::Commands.expects(:report)
|
36
|
+
ARGV.clear
|
37
|
+
ARGV << 'report'
|
38
|
+
load "bin/vanity"
|
39
|
+
rescue SystemExit => e
|
40
|
+
assert e.status == 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_responds_to_unknown_commands
|
44
|
+
require "vanity/commands/upgrade"
|
45
|
+
Vanity::Commands.expects(:upgrade)
|
46
|
+
ARGV.clear
|
47
|
+
ARGV << 'upgrade'
|
48
|
+
load "bin/vanity"
|
49
|
+
rescue SystemExit => e
|
50
|
+
assert e.status == 0
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -35,6 +35,12 @@ module Dummy
|
|
35
35
|
# JavaScript files you want as :defaults (application.js is always included).
|
36
36
|
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
|
37
37
|
|
38
|
+
# Enforce whitelist mode for mass assignment.
|
39
|
+
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
40
|
+
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
41
|
+
# parameters by using an attr_accessible or attr_protected declaration.
|
42
|
+
config.active_record.whitelist_attributes = true if ActiveRecord::Base.respond_to?(:whitelist_attributes=)
|
43
|
+
|
38
44
|
# Configure the default encoding used in templates for Ruby 1.9.
|
39
45
|
config.encoding = "utf-8"
|
40
46
|
|
data/test/rails_helper_test.rb
CHANGED
@@ -21,18 +21,39 @@ class RailsHelperTest < ActionView::TestCase
|
|
21
21
|
Vanity.playground.use_js!
|
22
22
|
result = ab_test(:pie_or_cake)
|
23
23
|
assert [:pie, :cake].include?(result)
|
24
|
-
10.times do
|
24
|
+
10.times do
|
25
25
|
assert result == ab_test(:pie_or_cake)
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def test_vanity_track_url_for_returns_url_with_identity_and_metrics
|
30
30
|
self.expects(:url_for).with(:controller => "controller", :action => "action", :_identity => '123', :_track => :sugar_high)
|
31
31
|
vanity_track_url_for("123", :sugar_high, :controller => "controller", :action => "action")
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def test_vanity_tracking_image
|
35
35
|
self.expects(:url_for).with(:controller => :vanity, :action => :image, :_identity => '123', :_track => :sugar_high).returns("/url")
|
36
36
|
assert_equal image_tag("/url", :width => "1px", :height => "1px", :alt => ""), vanity_tracking_image("123", :sugar_high, options = {})
|
37
37
|
end
|
38
|
+
|
39
|
+
def test_vanity_experiments
|
40
|
+
result = ab_test(:pie_or_cake)
|
41
|
+
test_description = ''
|
42
|
+
vanity_experiments.each do |name, alternative|
|
43
|
+
test_description += "Experiment #{name} chose #{alternative.value}"
|
44
|
+
end
|
45
|
+
assert_equal test_description, "Experiment pie_or_cake chose #{result}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_vanity_experiments_return_is_read_only
|
49
|
+
result = ab_test(:pie_or_cake)
|
50
|
+
vanity_experiments_returns = vanity_experiments
|
51
|
+
vanity_experiments_returns[:some_new_key] = 'some new value'
|
52
|
+
assert_equal vanity_experiments.keys.length, 1
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_vanity_experiments_returns_empty_hash_when_no_experiments
|
56
|
+
assert_equal vanity_experiments, {}
|
57
|
+
end
|
58
|
+
|
38
59
|
end
|
metadata
CHANGED
@@ -1,47 +1,46 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: vanity
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
5
|
-
prerelease:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.8.1
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- Assaf Arkin
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
|
12
|
+
date: 2013-10-05 00:00:00 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
|
17
|
-
|
18
|
-
requirements:
|
16
|
+
prerelease: false
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
19
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version:
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: "2.0"
|
22
22
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
23
|
+
version_requirements: *id001
|
24
|
+
- !ruby/object:Gem::Dependency
|
26
25
|
name: redis-namespace
|
27
|
-
|
28
|
-
|
29
|
-
requirements:
|
26
|
+
prerelease: false
|
27
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
30
29
|
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
30
|
+
- !ruby/object:Gem::Version
|
32
31
|
version: 1.0.0
|
33
32
|
type: :runtime
|
34
|
-
|
35
|
-
version_requirements: *70288496149580
|
33
|
+
version_requirements: *id002
|
36
34
|
description: Mirror, mirror on the wall ...
|
37
35
|
email: assaf@labnotes.org
|
38
|
-
executables:
|
36
|
+
executables:
|
39
37
|
- vanity
|
40
38
|
extensions: []
|
41
|
-
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
42
41
|
- README.rdoc
|
43
42
|
- CHANGELOG
|
44
|
-
files:
|
43
|
+
files:
|
45
44
|
- .autotest
|
46
45
|
- .gitignore
|
47
46
|
- .rvmrc
|
@@ -79,8 +78,6 @@ files:
|
|
79
78
|
- doc/metrics.textile
|
80
79
|
- doc/rails.textile
|
81
80
|
- doc/site.js
|
82
|
-
- gemfiles/rails2.gemfile
|
83
|
-
- gemfiles/rails2.gemfile.lock
|
84
81
|
- gemfiles/rails3.gemfile
|
85
82
|
- gemfiles/rails3.gemfile.lock
|
86
83
|
- gemfiles/rails31.gemfile
|
@@ -125,6 +122,7 @@ files:
|
|
125
122
|
- lib/vanity/templates/vanity.js
|
126
123
|
- lib/vanity/version.rb
|
127
124
|
- test/adapters/redis_adapter_test.rb
|
125
|
+
- test/cli_test.rb
|
128
126
|
- test/dummy/Rakefile
|
129
127
|
- test/dummy/app/controllers/application_controller.rb
|
130
128
|
- test/dummy/app/helpers/application_helper.rb
|
@@ -176,36 +174,39 @@ files:
|
|
176
174
|
- vanity.gemspec
|
177
175
|
homepage: http://vanity.labnotes.org
|
178
176
|
licenses: []
|
177
|
+
|
178
|
+
metadata: {}
|
179
|
+
|
179
180
|
post_install_message: To get started run vanity --help
|
180
|
-
rdoc_options:
|
181
|
+
rdoc_options:
|
181
182
|
- --title
|
182
|
-
- Vanity 1.8.
|
183
|
+
- Vanity 1.8.1
|
183
184
|
- --main
|
184
185
|
- README.rdoc
|
185
186
|
- --webcvs
|
186
187
|
- http://github.com/assaf/vanity
|
187
|
-
require_paths:
|
188
|
+
require_paths:
|
188
189
|
- lib
|
189
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
- !ruby/object:Gem::Version
|
190
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
194
|
version: 1.8.7
|
195
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
version: '0'
|
195
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: "0"
|
201
200
|
requirements: []
|
201
|
+
|
202
202
|
rubyforge_project:
|
203
|
-
rubygems_version: 1.
|
203
|
+
rubygems_version: 2.1.5
|
204
204
|
signing_key:
|
205
|
-
specification_version:
|
205
|
+
specification_version: 4
|
206
206
|
summary: Experience Driven Development framework for Ruby
|
207
|
-
test_files:
|
207
|
+
test_files:
|
208
208
|
- test/adapters/redis_adapter_test.rb
|
209
|
+
- test/cli_test.rb
|
209
210
|
- test/dummy/Rakefile
|
210
211
|
- test/dummy/app/controllers/application_controller.rb
|
211
212
|
- test/dummy/app/helpers/application_helper.rb
|
data/gemfiles/rails2.gemfile
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source :rubygems
|
4
|
-
|
5
|
-
gem "appraisal"
|
6
|
-
gem "garb"
|
7
|
-
gem "mocha"
|
8
|
-
gem "mongo"
|
9
|
-
gem "bson_ext"
|
10
|
-
gem "mysql"
|
11
|
-
gem "passenger", "~>2.0"
|
12
|
-
gem "pg"
|
13
|
-
gem "rack"
|
14
|
-
gem "shoulda"
|
15
|
-
gem "timecop"
|
16
|
-
gem "webmock"
|
17
|
-
gem "SystemTimer", "1.2.3", :platforms=>:mri_18
|
18
|
-
gem "rails", "2.3.14"
|
19
|
-
|
20
|
-
gemspec :path=>"../"
|
@@ -1,85 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: /Users/dougcole/workspace/vanity
|
3
|
-
specs:
|
4
|
-
vanity (1.8.0)
|
5
|
-
redis (~> 2.0)
|
6
|
-
redis-namespace (~> 1.0.0)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: http://rubygems.org/
|
10
|
-
specs:
|
11
|
-
SystemTimer (1.2.3)
|
12
|
-
actionmailer (2.3.14)
|
13
|
-
actionpack (= 2.3.14)
|
14
|
-
actionpack (2.3.14)
|
15
|
-
activesupport (= 2.3.14)
|
16
|
-
rack (~> 1.1.0)
|
17
|
-
activerecord (2.3.14)
|
18
|
-
activesupport (= 2.3.14)
|
19
|
-
activeresource (2.3.14)
|
20
|
-
activesupport (= 2.3.14)
|
21
|
-
activesupport (2.3.14)
|
22
|
-
addressable (2.2.7)
|
23
|
-
appraisal (0.4.1)
|
24
|
-
bundler
|
25
|
-
rake
|
26
|
-
bson (1.6.0)
|
27
|
-
bson_ext (1.6.0)
|
28
|
-
bson (= 1.6.0)
|
29
|
-
crack (0.3.1)
|
30
|
-
fastthread (1.0.7)
|
31
|
-
garb (0.9.1)
|
32
|
-
activesupport (>= 2.2.0)
|
33
|
-
crack (>= 0.1.6)
|
34
|
-
metaclass (0.0.1)
|
35
|
-
mocha (0.10.5)
|
36
|
-
metaclass (~> 0.0.1)
|
37
|
-
mongo (1.6.0)
|
38
|
-
bson (= 1.6.0)
|
39
|
-
mysql (2.8.1)
|
40
|
-
passenger (2.2.15)
|
41
|
-
fastthread (>= 1.0.1)
|
42
|
-
rack
|
43
|
-
rake (>= 0.8.1)
|
44
|
-
pg (0.13.2)
|
45
|
-
rack (1.1.3)
|
46
|
-
rails (2.3.14)
|
47
|
-
actionmailer (= 2.3.14)
|
48
|
-
actionpack (= 2.3.14)
|
49
|
-
activerecord (= 2.3.14)
|
50
|
-
activeresource (= 2.3.14)
|
51
|
-
activesupport (= 2.3.14)
|
52
|
-
rake (>= 0.8.3)
|
53
|
-
rake (0.9.2.2)
|
54
|
-
redis (2.2.2)
|
55
|
-
redis-namespace (1.0.3)
|
56
|
-
redis (< 3.0.0)
|
57
|
-
shoulda (3.0.1)
|
58
|
-
shoulda-context (~> 1.0.0)
|
59
|
-
shoulda-matchers (~> 1.0.0)
|
60
|
-
shoulda-context (1.0.0)
|
61
|
-
shoulda-matchers (1.0.0)
|
62
|
-
timecop (0.3.5)
|
63
|
-
webmock (1.8.0)
|
64
|
-
addressable (>= 2.2.7)
|
65
|
-
crack (>= 0.1.7)
|
66
|
-
|
67
|
-
PLATFORMS
|
68
|
-
ruby
|
69
|
-
|
70
|
-
DEPENDENCIES
|
71
|
-
SystemTimer (= 1.2.3)
|
72
|
-
appraisal
|
73
|
-
bson_ext
|
74
|
-
garb
|
75
|
-
mocha
|
76
|
-
mongo
|
77
|
-
mysql
|
78
|
-
passenger (~> 2.0)
|
79
|
-
pg
|
80
|
-
rack
|
81
|
-
rails (= 2.3.14)
|
82
|
-
shoulda
|
83
|
-
timecop
|
84
|
-
vanity!
|
85
|
-
webmock
|