i_wonder 0.0.9 → 0.1.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.
- data/README.rdoc +1 -1
- data/app/models/i_wonder/ab_test.rb +37 -4
- data/app/models/i_wonder/ab_test_goal.rb +9 -1
- data/app/views/i_wonder/ab_tests/index.html.erb +1 -1
- data/app/views/i_wonder/ab_tests/show.html.erb +3 -3
- data/lib/i_wonder/engine.rb +2 -3
- data/lib/i_wonder/version.rb +1 -1
- data/test/dummy/log/development.log +21 -0
- data/test/dummy/log/test.log +69398 -0
- data/test/factories/ab_test_factory.rb +15 -0
- data/test/functional/ab_controller_mixins_test.rb +20 -6
- data/test/integration/i_wonder/ab_tests_controller_test.rb +46 -0
- data/test/unit/i_wonder/ab_test_test.rb +20 -11
- data/test/unit/i_wonder/loader_test.rb +3 -3
- metadata +26 -22
data/README.rdoc
CHANGED
|
@@ -6,7 +6,7 @@ module IWonder
|
|
|
6
6
|
|
|
7
7
|
has_many :test_group_memberships, :dependent => :destroy, :foreign_key => "ab_test_sym", :primary_key => :sym
|
|
8
8
|
|
|
9
|
-
has_many :ab_test_goals, :dependent => :destroy, :foreign_key => "ab_test_sym", :primary_key =>
|
|
9
|
+
has_many :ab_test_goals, :dependent => :destroy, :foreign_key => "ab_test_sym", :primary_key => "sym"
|
|
10
10
|
accepts_nested_attributes_for :ab_test_goals, :allow_destroy => true
|
|
11
11
|
|
|
12
12
|
hash_accessor :options, :test_group_names, :type => :array, :reject_blanks => true
|
|
@@ -18,6 +18,31 @@ module IWonder
|
|
|
18
18
|
validates_uniqueness_of :sym, :on => :create, :message => "must be unique"
|
|
19
19
|
validates_inclusion_of :test_applies_to, :in => %w( session user account ), :on => :create, :message => "extension %s is not included in the list"
|
|
20
20
|
|
|
21
|
+
|
|
22
|
+
# ----------------------------------------------------------------------------------------------------------------------------------------
|
|
23
|
+
# These two methods should NOT be needed. For some reason the accepts_nested_attributes_for is not autosaving or deleting associated goals
|
|
24
|
+
|
|
25
|
+
def ab_test_goals_attributes=(hash)
|
|
26
|
+
hash.each{|key,value|
|
|
27
|
+
goal = self.ab_test_goals.detect{|tg| tg.id == value["id"].to_i}
|
|
28
|
+
goal ||= self.ab_test_goals.build
|
|
29
|
+
goal.attributes = value
|
|
30
|
+
|
|
31
|
+
if value["_destroy"] =~ /true|1/ or value["_destroy"].is_a?(TrueClass)
|
|
32
|
+
goal.mark_for_destruction
|
|
33
|
+
end
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
before_save :remove_deleted_test_goals
|
|
37
|
+
def remove_deleted_test_goals
|
|
38
|
+
ab_test_goals.select(&:marked_for_destruction?).each(&:destroy)
|
|
39
|
+
ab_test_goals.each(&:save)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ----------------------------------------------------------------------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
|
|
21
46
|
validate :has_two_groups_and_a_goal
|
|
22
47
|
def has_two_groups_and_a_goal
|
|
23
48
|
unless test_group_names.length >= 2
|
|
@@ -30,7 +55,7 @@ module IWonder
|
|
|
30
55
|
end
|
|
31
56
|
|
|
32
57
|
after_save :save_to_file
|
|
33
|
-
def save_to_file
|
|
58
|
+
def save_to_file
|
|
34
59
|
AbTesting::Loader.save_ab_test(self)
|
|
35
60
|
end
|
|
36
61
|
|
|
@@ -47,7 +72,13 @@ module IWonder
|
|
|
47
72
|
if(current_group = get_current_group(current_controller))
|
|
48
73
|
return current_group.test_group_name
|
|
49
74
|
else
|
|
50
|
-
|
|
75
|
+
begin
|
|
76
|
+
test_group = add_to_test_group(randomly_chosen_test_group, current_controller)
|
|
77
|
+
rescue Exception => e
|
|
78
|
+
# If there is some error, just return a randome option. Better not to crash
|
|
79
|
+
# TODO: this should warn developer somehow
|
|
80
|
+
return randomly_chosen_test_group
|
|
81
|
+
end
|
|
51
82
|
return test_group.test_group_name
|
|
52
83
|
end
|
|
53
84
|
end
|
|
@@ -71,7 +102,9 @@ module IWonder
|
|
|
71
102
|
|
|
72
103
|
scoped_groups_with_goal_events = ab_test_goal.add_goal_to_query(scoped_groups_with_events)
|
|
73
104
|
|
|
74
|
-
scoped_groups_with_goal_events.
|
|
105
|
+
scoped_groups_with_goal_events = scoped_groups_with_goal_events.select("COUNT(DISTINCT i_wonder_events.#{event_membership_key}) as count_all")
|
|
106
|
+
|
|
107
|
+
AbTest.connection.execute(scoped_groups_with_goal_events.to_sql)[0]["count_all"].to_i
|
|
75
108
|
end
|
|
76
109
|
|
|
77
110
|
def from_xml(xml)
|
|
@@ -14,6 +14,14 @@ module IWonder
|
|
|
14
14
|
validates_presence_of :event_type, :if => :tracks_event?
|
|
15
15
|
validates_presence_of :page_view_controller, :if => :tracks_page_view?
|
|
16
16
|
|
|
17
|
+
before_validation :clean_up_controller
|
|
18
|
+
def clean_up_controller
|
|
19
|
+
if tracks_page_view?
|
|
20
|
+
page_view_controller.gsub!("Controller", "")
|
|
21
|
+
page_view_controller.downcase!
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
17
25
|
def tracks_event?
|
|
18
26
|
goal_type == "Event"
|
|
19
27
|
end
|
|
@@ -26,7 +34,7 @@ module IWonder
|
|
|
26
34
|
if tracks_event?
|
|
27
35
|
sc = scoped_statement.where("i_wonder_events.event_type = ?", event_type)
|
|
28
36
|
else
|
|
29
|
-
sc = scoped_statement.where("i_wonder_events.event_type = ? AND controller = ?", "hit", page_view_controller)
|
|
37
|
+
sc = scoped_statement.where("i_wonder_events.event_type = ? AND i_wonder_events.controller = ?", "hit", page_view_controller)
|
|
30
38
|
|
|
31
39
|
if page_view_action.present?
|
|
32
40
|
sc = sc.where("i_wonder_events.action = ?", page_view_action)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<div class="show">
|
|
2
|
-
<% if Rails.env.
|
|
3
|
-
<span class="description">No Modifying tests in production</span>
|
|
4
|
-
<% else %>
|
|
2
|
+
<% if Rails.env.development? %>
|
|
5
3
|
<p>
|
|
6
4
|
<%= link_to "Edit", edit_ab_test_path(@ab_test) %>
|
|
7
5
|
|
|
|
8
6
|
<%= link_to "Delete", @ab_test, :method => :delete, :confirm => "Are you sure?" %>
|
|
9
7
|
</p>
|
|
8
|
+
<% else %>
|
|
9
|
+
<span class="description">No Modifying tests in production</span>
|
|
10
10
|
<% end %>
|
|
11
11
|
|
|
12
12
|
<h2>I wonder <%= @ab_test.name%>?</h2>
|
data/lib/i_wonder/engine.rb
CHANGED
|
@@ -5,8 +5,7 @@ module IWonder
|
|
|
5
5
|
|
|
6
6
|
initializer "i_wonder.loading_tests" do |app|
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
unless ( File.basename($0) == "rake" && ARGV.include?("db:migrate") )
|
|
8
|
+
unless File.basename($0) == "rake" # don't run on rake tasks (migration and asset:precompile have cause lot's of problems)
|
|
10
9
|
ActiveRecord::Base.send :include, HashAccessor # this is to avoid load order issues from a required gem
|
|
11
10
|
AbTesting::Loader.load_all
|
|
12
11
|
end
|
|
@@ -28,7 +27,7 @@ class Railtie < Rails::Railtie
|
|
|
28
27
|
ApplicationController.send :include, IWonder::Logging::ActionControllerMixins
|
|
29
28
|
ApplicationController.send :include, IWonder::AbTesting::ActionControllerMixins
|
|
30
29
|
|
|
31
|
-
ActiveRecord.send :include, IWonder::Logging::ActiveRecordMixins
|
|
30
|
+
ActiveRecord::Base.send :include, IWonder::Logging::ActiveRecordMixins
|
|
32
31
|
end
|
|
33
32
|
|
|
34
33
|
end
|
data/lib/i_wonder/version.rb
CHANGED
|
@@ -67879,3 +67879,24 @@ Served asset /i_wonder/reports.js - 304 Not Modified (0ms)
|
|
|
67879
67879
|
|
|
67880
67880
|
Started GET "/assets/i_wonder/application.js?body=1" for 127.0.0.1 at 2011-10-31 11:41:44 -0700
|
|
67881
67881
|
Served asset /i_wonder/application.js - 304 Not Modified (0ms)
|
|
67882
|
+
[1m[36mIWonder::AbTest Load (1.4ms)[0m [1mSELECT "i_wonder_ab_tests".* FROM "i_wonder_ab_tests" WHERE "i_wonder_ab_tests"."sym" = 'unique_sym_1' LIMIT 1[0m
|
|
67883
|
+
WARNING: Can't mass-assign protected attributes: ab_test_goals
|
|
67884
|
+
WARNING: Can't mass-assign protected attributes: type, ab_test_sym
|
|
67885
|
+
[1m[35m (0.1ms)[0m BEGIN
|
|
67886
|
+
[1m[36m (0.4ms)[0m [1mSELECT 1 FROM "i_wonder_ab_tests" WHERE "i_wonder_ab_tests"."name" = 'Unique Test 1' LIMIT 1[0m
|
|
67887
|
+
[1m[35m (0.2ms)[0m SELECT 1 FROM "i_wonder_ab_tests" WHERE "i_wonder_ab_tests"."sym" = 'unique_sym_1' LIMIT 1
|
|
67888
|
+
[1m[36mSQL (3.3ms)[0m [1mINSERT INTO "i_wonder_ab_tests" ("created_at", "description", "name", "options", "sym", "test_applies_to", "test_group_data", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m [["created_at", Tue, 01 Nov 2011 01:12:12 UTC +00:00], ["description", nil], ["name", "Unique Test 1"], ["options", "--- \n:test_group_names: \n- Options 1\n- Options 2\n"], ["sym", "unique_sym_1"], ["test_applies_to", "session"], ["test_group_data", "--- {}\n\n"], ["updated_at", Tue, 01 Nov 2011 01:12:12 UTC +00:00]]
|
|
67889
|
+
[1m[35mSQL (0.7ms)[0m INSERT INTO "i_wonder_ab_test_goals" ("ab_test_sym", "options") VALUES ($1, $2) RETURNING "id" [["ab_test_sym", "unique_sym_1"], ["options", "--- \n:event_type: success\n:goal_type: Event\n"]]
|
|
67890
|
+
[1m[36m (0.6ms)[0m [1mCOMMIT[0m
|
|
67891
|
+
PGError: ERROR: column "member_id" does not exist
|
|
67892
|
+
LINE 1: SELECT DISTINCT(member_id), COUNT(*) FROM "i_wonder_events"
|
|
67893
|
+
^
|
|
67894
|
+
: SELECT DISTINCT(member_id), COUNT(*) FROM "i_wonder_events"
|
|
67895
|
+
PGError: ERROR: column "i_wonder_events.session_id" must appear in the GROUP BY clause or be used in an aggregate function
|
|
67896
|
+
LINE 1: SELECT DISTINCT(session_id), COUNT(*) FROM "i_wonder_events"...
|
|
67897
|
+
^
|
|
67898
|
+
: SELECT DISTINCT(session_id), COUNT(*) FROM "i_wonder_events"
|
|
67899
|
+
PGError: ERROR: column "i_wonder_events.id" must appear in the GROUP BY clause or be used in an aggregate function
|
|
67900
|
+
LINE 1: SELECT "i_wonder_events".* FROM "i_wonder_events" GROUP BY ...
|
|
67901
|
+
^
|
|
67902
|
+
: SELECT "i_wonder_events".* FROM "i_wonder_events" GROUP BY session_id
|