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