vanity 2.0.0.beta3 → 2.0.0.beta4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vanity (2.0.0.beta3)
4
+ vanity (2.0.0.beta4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/bin/vanity CHANGED
@@ -16,7 +16,6 @@ opts = OptionParser.new("", 24, " ") do |opts|
16
16
  opts.banner << "Commands:\n"
17
17
  opts.banner << " list List all experiments and metrics\n"
18
18
  opts.banner << " report Report on all running experiments/metrics\n"
19
- opts.banner << " upgrade Upgrade your database when deploying new release\n"
20
19
 
21
20
  opts.separator ""
22
21
  opts.separator "Reporting options:"
@@ -29,13 +28,9 @@ opts = OptionParser.new("", 24, " ") do |opts|
29
28
  opts.on "--load_path PATH", "Path to experiments directory (default: #{playground.load_path})" do |path|
30
29
  playground.load_path = path
31
30
  end
32
- opts.on "-d", "--database url", "Database connection URL (e.g. redis:/localhost:6379)" do |conn|
31
+ opts.on "-d", "--database url", "Database connection URL (e.g. redis://localhost:6379)" do |conn|
33
32
  playground.establish_connection conn
34
33
  end
35
- opts.on "--redis HOST:PORT:DB", "DEPRECATED: Redis server host (default: localhost:6379)" do |redis|
36
- host, port, db = redis.split(":")
37
- playground.establish_connection "redis:/#{host}:#{port}/#{db}"
38
- end
39
34
  opts.on_tail "-h", "--help", "Show this message" do
40
35
  puts opts.to_s.gsub(/^.*DEPRECATED.*$/s, '')
41
36
  exit
@@ -60,9 +55,6 @@ ARGV.each do |cmd|
60
55
  when "list"
61
56
  require "vanity/commands/list"
62
57
  Vanity::Commands.list
63
- when "upgrade"
64
- require "vanity/commands/upgrade"
65
- Vanity::Commands.upgrade
66
58
  else puts "No such command: #{cmd}"
67
59
  end
68
60
  end
@@ -15,7 +15,7 @@
15
15
  </div>
16
16
  <div id="links">
17
17
  <a href="http://github.com/assaf/vanity">Source code</a> |
18
- <a href="http://groups.google.com/group/vanity-talk" title="vanity-talk google group">Google Group</a> |
18
+ <a href="http://stackoverflow.com/questions/tagged/vanity" title="stackoverflow vanity tag">StackOverflow Tag</a> |
19
19
  <a href="http://rdoc.info/gems/vanity">API reference</a>
20
20
  </div>
21
21
  <div id="sidebar">
@@ -15,7 +15,7 @@ By all means.
15
15
 
16
16
  h3(#contributing). How To Contribute
17
17
 
18
- Pick on an "open issue":http://github.com/assaf/vanity/issues, "experimental feature":experimental.html, suggestion from the "Google Group":http://groups.google.com/group/vanity-talk, or whatever you feel like contributing.
18
+ Pick on an "open issue":http://github.com/assaf/vanity/issues, "experimental feature":experimental.html, or whatever you feel like contributing.
19
19
 
20
20
  To contribute new code/changes:
21
21
  # "Fork the project":http://github.com/assaf/vanity
@@ -68,7 +68,7 @@ h3(#doc). Documentation
68
68
 
69
69
  Documentation is written in "Textile":http://redcloth.org/textile/writing-paragraph-text/, and converted to HTML using "Jekyll":http://jekyllrb.com/.
70
70
 
71
- API reference is "RDoc":http://rdoc.sourceforge.net/doc/index.html, converted to HTML using "Yardoc":http://yardoc.org/.
71
+ API reference is "RDoc":http://rdoc.sourceforge.net/doc/index.html, converted to HTML using "Yardoc":http://yardoc.org/.
72
72
 
73
73
  To build and view documentation:
74
74
 
data/doc/index.textile CHANGED
@@ -21,7 +21,7 @@ Also:
21
21
  * "Experiment Driven Development(Introduction to EDD and Vanity)":http://blog.labnotes.org/2009/11/19/vanity-experiment-driven-development-for-rails/
22
22
  * "Get the code(Official Github repository)":http://github.com/assaf/vanity
23
23
  * "API reference":api/index.html
24
- * "Join vanity-talk list":http://groups.google.com/group/vanity-talk
24
+ * "Ask questions on StackOverflow":http://stackoverflow.com/questions/tagged/vanity
25
25
  * "Contributing to Vanity":contributing.html
26
26
 
27
27
  h3(#intro). Introduction & setup
@@ -7,7 +7,7 @@ GIT
7
7
  PATH
8
8
  remote: ..
9
9
  specs:
10
- vanity (2.0.0.beta3)
10
+ vanity (2.0.0.beta4)
11
11
 
12
12
  GEM
13
13
  remote: https://rubygems.org/
@@ -7,7 +7,7 @@ GIT
7
7
  PATH
8
8
  remote: ..
9
9
  specs:
10
- vanity (2.0.0.beta3)
10
+ vanity (2.0.0.beta4)
11
11
 
12
12
  GEM
13
13
  remote: https://rubygems.org/
@@ -25,14 +25,6 @@ module Vanity
25
25
  send :"find_or_create_by_#{method}", value
26
26
  end
27
27
  end
28
-
29
- def self.rails_agnostic_find_first(conditions)
30
- if respond_to? :where
31
- where(conditions).first
32
- else
33
- find(:first, :conditions => conditions)
34
- end
35
- end
36
28
  end
37
29
 
38
30
  # Schema model
@@ -103,7 +95,7 @@ module Vanity
103
95
  # passed then this will be passed to create if creating, or will be
104
96
  # used to update the found participant.
105
97
  def self.retrieve(experiment, identity, create = true, update_with = nil)
106
- if record = VanityParticipant.rails_agnostic_find_first(:experiment_id=>experiment.to_s, :identity=>identity.to_s)
98
+ if record = VanityParticipant.where(:experiment_id=>experiment.to_s, :identity=>identity.to_s).first
107
99
  record.update_attributes(update_with) if update_with
108
100
  elsif create
109
101
  record = VanityParticipant.create({ :experiment_id=>experiment.to_s, :identity=>identity.to_s }.merge(update_with || {}))
@@ -220,7 +212,7 @@ module Vanity
220
212
  record = VanityExperiment.retrieve(experiment)
221
213
  participants = VanityParticipant.where(:experiment_id => experiment.to_s, :seen => alternative).count
222
214
  converted = VanityParticipant.where(:experiment_id => experiment.to_s, :converted => alternative).count
223
- conversions = record.vanity_conversions.sum(:conversions, :conditions => {:alternative => alternative})
215
+ conversions = record.vanity_conversions.where(:alternative => alternative).sum(:conversions)
224
216
 
225
217
  {
226
218
  :participants => participants,
@@ -39,15 +39,19 @@ module Vanity
39
39
  class_or_scope = class_or_scope.constantize if class_or_scope.is_a?(String)
40
40
  options = options || {}
41
41
  conditions = options.delete(:conditions)
42
- @ar_scoped = conditions ? class_or_scope.scoped(:conditions=>conditions) : class_or_scope
42
+
43
+ @ar_scoped = conditions ? class_or_scope.where(conditions) : class_or_scope
43
44
  @ar_aggregate = AGGREGATES.find { |key| options.has_key?(key) }
44
45
  @ar_column = options.delete(@ar_aggregate)
45
46
  fail "Cannot use multiple aggregates in a single metric" if AGGREGATES.find { |key| options.has_key?(key) }
47
+
46
48
  @ar_timestamp = options.delete(:timestamp) || :created_at
47
49
  @ar_timestamp, @ar_timestamp_table = @ar_timestamp.to_s.split('.').reverse
48
50
  @ar_timestamp_table ||= @ar_scoped.table_name
51
+
49
52
  fail "Unrecognized options: #{options.keys * ", "}" unless options.empty?
50
- @ar_scoped.after_create self
53
+
54
+ @ar_scoped.after_create(self)
51
55
  extend ActiveRecord
52
56
  end
53
57
  end
@@ -65,9 +69,16 @@ module Vanity
65
69
  sdate = sdate + difference
66
70
  edate = edate + difference
67
71
 
68
- query = { :conditions=> { @ar_timestamp_table => { @ar_timestamp => (sdate.to_time...(edate + 1).to_time) } },
69
- :group=>"date(#{@ar_scoped.quoted_table_name}.#{@ar_scoped.connection.quote_column_name @ar_timestamp})" }
70
- grouped = @ar_column ? @ar_scoped.send(@ar_aggregate, @ar_column, query) : @ar_scoped.count(query)
72
+ grouped = @ar_scoped
73
+ .where(@ar_timestamp_table => { @ar_timestamp => (sdate.to_time...(edate + 1).to_time) })
74
+ .group("date(#{@ar_scoped.quoted_table_name}.#{@ar_scoped.connection.quote_column_name(@ar_timestamp)})")
75
+
76
+ if @ar_column
77
+ grouped = grouped.send(@ar_aggregate, @ar_column)
78
+ else
79
+ grouped = grouped.count
80
+ end
81
+
71
82
  grouped = Hash[grouped.map {|k,v| [k.to_date, v] }]
72
83
  (sdate..edate).inject([]) { |ordered, date| ordered << (grouped[date] || 0) }
73
84
  end
@@ -79,6 +90,7 @@ module Vanity
79
90
  end
80
91
 
81
92
  def last_update_at
93
+ # SELECT created_at FROM "skies" ORDER BY created_at DESC LIMIT 1
82
94
  record = @ar_scoped.find(:first, :order=>"#@ar_timestamp DESC", :limit=>1, :select=>@ar_timestamp)
83
95
  record && record.send(@ar_timestamp)
84
96
  end
@@ -1,5 +1,5 @@
1
1
  module Vanity
2
- VERSION = "2.0.0.beta3"
2
+ VERSION = "2.0.0.beta4"
3
3
 
4
4
  module Version
5
5
  version = VERSION.to_s.split(".").map { |i| i.to_i }
data/test/cli_test.rb CHANGED
@@ -37,10 +37,10 @@ describe "bin/vanity" do
37
37
  end
38
38
 
39
39
  it "responds to unknown commands" do
40
- require "vanity/commands/upgrade"
41
- Vanity::Commands.expects(:upgrade)
42
- ARGV.clear
43
- ARGV << 'upgrade'
44
- load "bin/vanity"
40
+ assert_output("No such command: upgrade\n") do
41
+ ARGV.clear
42
+ ARGV << 'upgrade'
43
+ load "bin/vanity"
44
+ end
45
45
  end
46
46
  end
@@ -5,3 +5,4 @@
5
5
  # Make sure the secret is at least 30 characters and all random,
6
6
  # no regular words or you'll be exposed to dictionary attacks.
7
7
  Dummy::Application.config.secret_token = '33ccbc9a29f3b02e87c08904505b1c9a3a1e97dd01f02e598e65ee9e7b96fff2ca4a6d0dd7c4a8d3682d8c64f84d372661e141264e70697dc576c722c72d80d0'
8
+ Dummy::Application.config.secret_key_base = 'secret' if Dummy::Application.config.respond_to?(:secret_key_base=)
@@ -1,23 +1,22 @@
1
1
  require "test_helper"
2
2
 
3
3
  class Sky < ActiveRecord::Base
4
- if connected?
5
- connection.drop_table :skies if table_exists?
6
- connection.create_table :skies do |t|
4
+ scope :high, lambda { where("height >= 4") }
5
+ end
6
+
7
+ if ENV["DB"] == "active_record"
8
+
9
+ describe Vanity::Metric::ActiveRecord do
10
+
11
+ before do
12
+ Sky.connection.create_table(:skies) do |t|
7
13
  t.integer :height
8
14
  t.timestamps
9
15
  end
10
16
  end
11
17
 
12
- scope :high, lambda { { :conditions=>"height >= 4" } }
13
- end
14
-
15
- if ActiveRecord::Base.connected?
16
-
17
- describe "ActiveRecord Metric" do
18
-
19
18
  after do
20
- Sky.delete_all
19
+ Sky.connection.drop_table(:skies) if Sky.connection.table_exists?(Sky.table_name)
21
20
  Sky.reset_callbacks(:create)
22
21
  Sky.reset_callbacks(:save)
23
22
  end
@@ -236,7 +235,7 @@ describe "ActiveRecord Metric" do
236
235
  assert_equal 2, times
237
236
  end
238
237
 
239
- it "do it youself" do
238
+ it "do it yourself" do
240
239
  File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
241
240
  f.write <<-RUBY
242
241
  metric "Sky is limit" do
@@ -49,13 +49,15 @@ describe Vanity::Playground do
49
49
  end
50
50
  end
51
51
 
52
- describe "autoconnect" do
53
- it "reconnects with existing connection" do
52
+ describe "reconnect!" do
53
+ it "reconnects with the same configuration" do
54
54
  Vanity.playground.establish_connection "mock:/"
55
55
  Vanity.playground.reconnect!
56
56
  assert_equal Vanity.playground.connection.to_s, "mock:/"
57
57
  end
58
+ end
58
59
 
60
+ describe "autoconnect" do
59
61
  it "establishes connection by default with connection" do
60
62
  instance = Vanity::Playground.new(:connection=>"mock:/")
61
63
  assert instance.connected?
data/test/test_helper.rb CHANGED
@@ -70,7 +70,7 @@ module VanityTestHelpers
70
70
  # or reload an experiment (saved by the previous playground).
71
71
  def new_playground
72
72
  Vanity.playground = Vanity::Playground.new(:logger=>$logger, :load_path=>"tmp/experiments")
73
- Vanity.playground.establish_connection(DATABASE)
73
+ Vanity.playground.establish_connection(DATABASE) unless Vanity.playground.connected?
74
74
  end
75
75
 
76
76
  # Defines the specified metrics (one or more names). Returns metric, or array
@@ -107,7 +107,7 @@ module VanityTestHelpers
107
107
  end
108
108
 
109
109
  def dummy_request
110
- defined?(ActionDispatch) ? ActionDispatch::TestRequest.new() : ActionController::TestRequest.new()
110
+ ActionDispatch::TestRequest.new()
111
111
  end
112
112
 
113
113
  # Defining setup/tear down in a module and including it below doesn't
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vanity
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta3
4
+ version: 2.0.0.beta4
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-19 00:00:00.000000000 Z
12
+ date: 2014-08-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -104,7 +104,6 @@ files:
104
104
  - lib/vanity/backport.rb
105
105
  - lib/vanity/commands/list.rb
106
106
  - lib/vanity/commands/report.rb
107
- - lib/vanity/commands/upgrade.rb
108
107
  - lib/vanity/experiment/ab_test.rb
109
108
  - lib/vanity/experiment/alternative.rb
110
109
  - lib/vanity/experiment/base.rb
@@ -163,11 +162,6 @@ files:
163
162
  - test/dummy/script/rails
164
163
  - test/experiment/ab_test.rb
165
164
  - test/experiment/base_test.rb
166
- - test/experiments/age_and_zipcode.rb
167
- - test/experiments/metrics/cheers.rb
168
- - test/experiments/metrics/signups.rb
169
- - test/experiments/metrics/yawns.rb
170
- - test/experiments/null_abc.rb
171
165
  - test/frameworks/rails/action_controller_test.rb
172
166
  - test/frameworks/rails/action_mailer_test.rb
173
167
  - test/frameworks/rails/action_view_test.rb
@@ -187,7 +181,7 @@ licenses:
187
181
  post_install_message: To get started run vanity --help
188
182
  rdoc_options:
189
183
  - --title
190
- - Vanity 2.0.0.beta3
184
+ - Vanity 2.0.0.beta4
191
185
  - --main
192
186
  - README.rdoc
193
187
  - --webcvs
@@ -244,11 +238,6 @@ test_files:
244
238
  - test/dummy/script/rails
245
239
  - test/experiment/ab_test.rb
246
240
  - test/experiment/base_test.rb
247
- - test/experiments/age_and_zipcode.rb
248
- - test/experiments/metrics/cheers.rb
249
- - test/experiments/metrics/signups.rb
250
- - test/experiments/metrics/yawns.rb
251
- - test/experiments/null_abc.rb
252
241
  - test/frameworks/rails/action_controller_test.rb
253
242
  - test/frameworks/rails/action_mailer_test.rb
254
243
  - test/frameworks/rails/action_view_test.rb
@@ -1,34 +0,0 @@
1
- module Vanity
2
- module Commands
3
- class << self
4
- # Upgrade to newer version of Vanity (this usually means doing magic in
5
- # the database)
6
- def upgrade
7
- if Vanity.playground.connection.respond_to?(:redis)
8
- redis = Vanity.playground.connection.redis
9
- # Upgrade metrics from 1.3 to 1.4
10
- keys = redis.keys("metrics:*")
11
- if keys.empty?
12
- puts "No metrics to upgrade"
13
- else
14
- puts "Updating #{keys.map { |name| name.split(":")[1] }.uniq.length} metrics"
15
- keys.each do |key|
16
- key << ":value:0" if key[/\d{4}-\d{2}-\d{2}$/]
17
- redis.renamenx key, "vanity:#{key}"
18
- end
19
- end
20
- # Upgrade experiments from 1.3 to 1.4
21
- keys = redis.keys("vanity:1:*")
22
- if keys.empty?
23
- puts "No experiments to upgrade"
24
- else
25
- puts "Updating #{keys.map { |name| name.split(":")[2] }.uniq.length} experiments"
26
- keys.each do |key|
27
- redis.renamenx key, key.gsub(":1:", ":experiments:")
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,19 +0,0 @@
1
- ab_test "Age and Zipcode" do
2
- description <<-TEXT
3
- Testing new registration form that asks for age and zipcode. Option A presents
4
- the existing form, and option B adds age and zipcode fields.
5
-
6
- We know option B will convert less, but higher quality leads. If we lose less
7
- than 20% conversions, we're going to switch to option B.
8
- TEXT
9
- metrics :signups
10
-
11
- complete_if do
12
- alternatives.all? { |alt| alt.participants > 100 }
13
- end
14
- outcome_is do
15
- one_field = alternative(false)
16
- three_fields = alternative(true)
17
- three_fields.conversion_rate >= 0.8 * one_field.conversion_rate ? three_fields : one_field
18
- end
19
- end
@@ -1,3 +0,0 @@
1
- metric "Cheers" do
2
- description "They love us, don't they?"
3
- end
@@ -1,2 +0,0 @@
1
- metric "Signups" do
2
- end
@@ -1,3 +0,0 @@
1
- metric "Yawns" do
2
- description "How many yawns/sec can our video-sharing micro-blogging social network elicit?"
3
- end
@@ -1,5 +0,0 @@
1
- ab_test "Null/ABC" do
2
- description "Testing three alternatives"
3
- alternatives nil, :red, :green, :blue
4
- metrics :signups
5
- end