abingo 1.1.0

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.
@@ -0,0 +1,11 @@
1
+ require 'find'
2
+ require 'fileutils'
3
+ def find_and_delete(path, pattern)
4
+ Find.find(path) do |f|
5
+ if !File.file?(f) and f[pattern]
6
+ FileUtils.rm_rf(f)
7
+ end
8
+ end
9
+ end
10
+ # print all the ruby files
11
+ find_and_delete(".", /\.svn$/)
@@ -0,0 +1,187 @@
1
+ require 'test_helper'
2
+
3
+ class AbingoTest < ActiveSupport::TestCase
4
+
5
+ #Wipes cache, D/B prior to doing a test run.
6
+ Abingo.cache.clear
7
+ Abingo::Experiment.delete_all
8
+ Abingo::Alternative.delete_all
9
+
10
+ test "identity automatically assigned" do
11
+ assert Abingo.identity != nil
12
+ end
13
+
14
+ test "alternative parsing" do
15
+ array = %w{a b c}
16
+ assert_equal array, Abingo.parse_alternatives(array)
17
+ assert_equal 65, Abingo.parse_alternatives(65).size
18
+ assert_equal 4, Abingo.parse_alternatives(2..5).size
19
+ assert !(Abingo.parse_alternatives(2..5).include? 1)
20
+ end
21
+
22
+ test "experiment creation" do
23
+ assert_equal 0, Abingo::Experiment.count
24
+ assert_equal 0, Abingo::Alternative.count
25
+ alternatives = %w{A B}
26
+ alternative_selected = Abingo.test("unit_test_sample_A", alternatives)
27
+ assert_equal 1, Abingo::Experiment.count
28
+ assert_equal 2, Abingo::Alternative.count
29
+ assert alternatives.include?(alternative_selected)
30
+ end
31
+
32
+ test "exists works right" do
33
+ Abingo.test("exist works right", %w{does does_not})
34
+ assert Abingo::Experiment.exists?("exist works right")
35
+ end
36
+
37
+ test "alternatives picked consistently" do
38
+ alternative_picked = Abingo.test("consistency_test", 1..100)
39
+ 100.times do
40
+ assert_equal alternative_picked, Abingo.test("consistency_test", 1..100)
41
+ end
42
+ end
43
+
44
+ test "participation works" do
45
+ new_tests = %w{participationA participationB participationC}
46
+ new_tests.map do |test_name|
47
+ Abingo.test(test_name, 1..5)
48
+ end
49
+
50
+ participating_tests = Abingo.cache.read("Abingo::participating_tests::#{Abingo.identity}") || []
51
+
52
+ new_tests.map do |test_name|
53
+ assert participating_tests.include? test_name
54
+ end
55
+ end
56
+
57
+ test "participants counted" do
58
+ test_name = "participants_counted_test"
59
+ alternative = Abingo.test(test_name, %w{a b c})
60
+
61
+ ex = Abingo::Experiment.find_by_test_name(test_name)
62
+ lookup = Abingo::Alternative.calculate_lookup(test_name, alternative)
63
+ chosen_alt = Abingo::Alternative.find_by_lookup(lookup)
64
+ assert_equal 1, ex.participants
65
+ assert_equal 1, chosen_alt.participants
66
+ end
67
+
68
+ test "conversion tracking by test name" do
69
+ test_name = "conversion_test_by_name"
70
+ alternative = Abingo.test(test_name, %w{a b c})
71
+ Abingo.bingo!(test_name)
72
+ ex = Abingo::Experiment.find_by_test_name(test_name)
73
+ lookup = Abingo::Alternative.calculate_lookup(test_name, alternative)
74
+ chosen_alt = Abingo::Alternative.find_by_lookup(lookup)
75
+ assert_equal 1, ex.conversions
76
+ assert_equal 1, chosen_alt.conversions
77
+ Abingo.bingo!(test_name)
78
+
79
+ #Should still only have one because this conversion should not be double counted.
80
+ #We haven't specified that in the test options.
81
+ assert_equal 1, Abingo::Experiment.find_by_test_name(test_name).conversions
82
+ end
83
+
84
+ test "conversion tracking by conversion name" do
85
+ conversion_name = "purchase"
86
+ tests = %w{conversionTrackingByConversionNameA conversionTrackingByConversionNameB conversionTrackingByConversionNameC}
87
+ tests.map do |test_name|
88
+ Abingo.test(test_name, %w{A B}, :conversion => conversion_name)
89
+ end
90
+
91
+ Abingo.bingo!(conversion_name)
92
+ tests.map do |test_name|
93
+ assert_equal 1, Abingo::Experiment.find_by_test_name(test_name).conversions
94
+ end
95
+ end
96
+
97
+ test "short circuiting works" do
98
+ conversion_name = "purchase"
99
+ test_name = "short circuit test"
100
+ alt_picked = Abingo.test(test_name, %w{A B}, :conversion => conversion_name)
101
+ ex = Abingo::Experiment.find_by_test_name(test_name)
102
+ alt_not_picked = (%w{A B} - [alt_picked]).first
103
+
104
+ ex.end_experiment!(alt_not_picked, conversion_name)
105
+
106
+ ex.reload
107
+ assert_equal "Finished", ex.status
108
+
109
+ Abingo.bingo!(test_name) #Should not be counted, test is over.
110
+ assert_equal 0, ex.conversions
111
+
112
+ old_identity = Abingo.identity
113
+ Abingo.identity = "shortCircuitTestNewIdentity"
114
+ Abingo.test(test_name, %w{A B}, :conversion => conversion_name)
115
+ Abingo.identity = old_identity
116
+ ex.reload
117
+ assert_equal 1, ex.participants #Original identity counted, new identity not counted b/c test stopped
118
+ end
119
+
120
+ test "proper experiment creation in high concurrency" do
121
+ conversion_name = "purchase"
122
+ test_name = "high_concurrency_test"
123
+ alternatives = %w{foo bar}
124
+
125
+ threads = []
126
+ 5.times do
127
+ threads << Thread.new do
128
+ Abingo.test(test_name, alternatives, conversion_name)
129
+ 1
130
+ end
131
+ end
132
+ sleep(10)
133
+ assert_equal 1, Abingo::Experiment.count_by_sql(["select count(id) from experiments where test_name = ?", test_name])
134
+ end
135
+
136
+ test "non-humans are ignored for participation and conversions if not explicitly counted" do
137
+ Abingo.options[:count_humans_only] = true
138
+ Abingo.options[:expires_in] = 1.hour
139
+ Abingo.options[:expires_in_for_bots] = 3.seconds
140
+ first_identity = Abingo.identity = "unsure_if_human#{Time.now.to_i}"
141
+ test_name = "are_you_a_human"
142
+ Abingo.test(test_name, %w{does_not matter})
143
+
144
+ assert_false Abingo.is_human?, "Identity not marked as human yet."
145
+
146
+ ex = Abingo::Experiment.find_by_test_name(test_name)
147
+ Abingo.bingo!(test_name)
148
+ assert_equal 0, ex.participants, "Not human yet, so should have no participants."
149
+ assert_equal 0, ex.conversions, "Not human yet, so should have no conversions."
150
+
151
+ Abingo.human!
152
+
153
+ #Setting up second participant who doesn't convert.
154
+ Abingo.identity = "unsure_if_human_2_#{Time.now.to_i}"
155
+ Abingo.test(test_name, %w{does_not matter})
156
+ Abingo.human!
157
+
158
+ ex = Abingo::Experiment.find_by_test_name(test_name)
159
+ assert_equal 2, ex.participants, "Now that we're human, our participation should matter."
160
+ assert_equal 1, ex.conversions, "Now that we're human, our conversions should matter, but only one of us converted."
161
+ end
162
+
163
+ test "Participating tests for a given identity" do
164
+ Abingo.identity = "test_participant"
165
+ test_names = (1..3).map {|t| "participating_test_test_name #{t}"}
166
+ test_alternatives = %w{yes no}
167
+ test_names.each {|test_name| Abingo.test(test_name, test_alternatives)}
168
+ ex = Abingo::Experiment.last
169
+ ex.end_experiment!("no") #End final of 3 tests, leaving 2 presently running
170
+
171
+ assert_equal 2, Abingo.participating_tests.size #Pairs for two tests
172
+ Abingo.participating_tests.each do |key, value|
173
+ assert test_names.include? key
174
+ assert test_alternatives.include? value
175
+ end
176
+
177
+ assert_equal 3, Abingo.participating_tests(false).size #pairs for three tests
178
+ Abingo.participating_tests(false).each do |key, value|
179
+ assert test_names.include? key
180
+ assert test_alternatives.include? value
181
+ end
182
+
183
+ Abingo.identity = "test_nonparticipant"
184
+ assert_equal({}, Abingo.participating_tests)
185
+ end
186
+
187
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'rails'
3
+
4
+ if Rails::VERSION::MAJOR.to_i >= 3
5
+ require 'rails/all'
6
+ require 'test/unit'
7
+
8
+ require 'active_support'
9
+ require 'active_support/railtie'
10
+ require 'active_support/core_ext'
11
+ require 'active_support/test_case'
12
+
13
+ require 'action_controller'
14
+ require 'action_controller/caching'
15
+ require 'active_record'
16
+ require 'active_record/base'
17
+
18
+ require 'rails'
19
+ require 'rails/application'
20
+
21
+ require 'rails/railtie'
22
+
23
+ #We need to load the whole Rails application to properly initialize Rails.cache and other constants. Oh boy.
24
+ #We're going to parse it out of RAILS_PATH/config.ru using a little metaprogramming magic.
25
+ require ::File.expand_path('../../../../../config/environment', __FILE__)
26
+ lines = File.open(::File.expand_path('../../../../../config.ru', __FILE__)).readlines.select {|a| a =~ /::Application/}
27
+ application_name = lines.first[/[^ ]*::/].gsub(":", "")
28
+ Kernel.const_get(application_name).const_get("Application").initialize!
29
+ else
30
+ #Rails 2 testing
31
+ require 'active_support'
32
+ require 'active_support/test_case'
33
+ end
34
+
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: abingo
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Glenn Gillen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70225544745500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70225544745500
25
+ description: A split testing framework for Rails 3.x.x
26
+ email:
27
+ - me@glenngillen.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Gemfile.lock
35
+ - MIT-LICENSE
36
+ - README
37
+ - Rakefile
38
+ - abingo.gemspec
39
+ - generators/abingo_migration/abingo_migration_generator.rb
40
+ - generators/abingo_migration/templates/abingo_migration.rb
41
+ - lib/abingo.rb
42
+ - lib/abingo/alternative.rb
43
+ - lib/abingo/controller/dashboard.rb
44
+ - lib/abingo/conversion_rate.rb
45
+ - lib/abingo/experiment.rb
46
+ - lib/abingo/rails/controller/dashboard.rb
47
+ - lib/abingo/statistics.rb
48
+ - lib/abingo/version.rb
49
+ - lib/abingo/views/dashboard/_experiment.erb
50
+ - lib/abingo/views/dashboard/index.erb
51
+ - lib/abingo_sugar.rb
52
+ - lib/abingo_view_helper.rb
53
+ - strip.rb
54
+ - test/abingo_test.rb
55
+ - test/test_helper.rb
56
+ - uninstall.rb
57
+ homepage: https://github.com/glenngillen/abingo
58
+ licenses: []
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ segments:
70
+ - 0
71
+ hash: -3437429555840451377
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ segments:
79
+ - 0
80
+ hash: -3437429555840451377
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.15
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: The ABingo split testing framework for Rails 3.x.x from Patrick McKenzie
87
+ test_files:
88
+ - test/abingo_test.rb
89
+ - test/test_helper.rb