mountain-goat 0.1.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/README.md +119 -48
  2. data/generators/mg/mg_generator.rb +17 -9
  3. data/generators/mg/templates/create_mountain_goat_tables.rb +61 -25
  4. data/generators/mg/templates/mg.rb +1 -0
  5. data/generators/mg/templates/mountain-goat.yml +22 -3
  6. data/generators/mg/templates/mountain_goat_reports.rake +17 -0
  7. data/generators/mg/templates/update_mountain_goat_tables.rb +104 -0
  8. data/lib/mountain-goat.rb +21 -12
  9. data/lib/mountain-goat/analytics.rb +134 -0
  10. data/lib/mountain-goat/controllers/{mountain_goat/mountain_goat_converts_controller.rb → mg/converts_controller.rb} +12 -11
  11. data/lib/mountain-goat/controllers/{mountain_goat/mountain_goat_metric_variants_controller.rb → mg/metric_variants_controller.rb} +6 -5
  12. data/lib/mountain-goat/controllers/{mountain_goat/mountain_goat_metrics_controller.rb → mg/metrics_controller.rb} +8 -6
  13. data/lib/mountain-goat/controllers/mg/mg.rb +47 -0
  14. data/lib/mountain-goat/controllers/{mountain_goat → mg}/mountain_goat_controller.rb +5 -42
  15. data/lib/mountain-goat/controllers/mg/playground_controller.rb +8 -0
  16. data/lib/mountain-goat/controllers/{mountain_goat/mountain_goat_rallies_controller.rb → mg/rallies_controller.rb} +4 -26
  17. data/lib/mountain-goat/controllers/mg/report_items_controller.rb +82 -0
  18. data/lib/mountain-goat/controllers/mg/reports_controller.rb +90 -0
  19. data/lib/mountain-goat/m_g.rb +64 -0
  20. data/lib/mountain-goat/metric_tracking.rb +192 -74
  21. data/lib/mountain-goat/models/mg/ci_meta.rb +10 -0
  22. data/lib/mountain-goat/models/mg/convert.rb +147 -0
  23. data/lib/mountain-goat/models/mg/convert_meta_type.rb +20 -0
  24. data/lib/mountain-goat/models/mg/cs_meta.rb +10 -0
  25. data/lib/mountain-goat/models/{metric.rb → mg/metric.rb} +3 -5
  26. data/lib/mountain-goat/models/mg/metric_variant.rb +25 -0
  27. data/lib/mountain-goat/models/mg/mountain_goat.rb +3 -0
  28. data/lib/mountain-goat/models/{rally.rb → mg/rally.rb} +4 -3
  29. data/lib/mountain-goat/models/mg/report.rb +11 -0
  30. data/lib/mountain-goat/models/mg/report_item.rb +24 -0
  31. data/lib/mountain-goat/models/mg/report_mailer.rb +18 -0
  32. data/lib/mountain-goat/public/g-bar-min.js +7 -0
  33. data/lib/mountain-goat/public/g-dot-min.js +7 -0
  34. data/lib/mountain-goat/public/g-line-min.js +7 -0
  35. data/lib/mountain-goat/public/g-pie-min.js +1 -0
  36. data/lib/mountain-goat/public/g-raphael-min.js +7 -0
  37. data/lib/mountain-goat/public/jqModel.css +41 -0
  38. data/lib/mountain-goat/public/jqModel.js +69 -0
  39. data/lib/mountain-goat/public/jquery.raphael.js +208 -0
  40. data/lib/mountain-goat/public/mg.css +135 -26
  41. data/lib/mountain-goat/public/mg.js +53 -1
  42. data/lib/mountain-goat/public/raphael-min.js +7 -0
  43. data/lib/mountain-goat/public/utils.js +520 -0
  44. data/lib/mountain-goat/switch_variant.rb +4 -4
  45. data/lib/mountain-goat/version.rb +1 -1
  46. data/lib/mountain-goat/views/mountain_goat/layouts/_pdf.html.erb +15 -0
  47. data/lib/mountain-goat/views/mountain_goat/layouts/mountain_goat.html.erb +17 -5
  48. data/lib/mountain-goat/views/mountain_goat/layouts/xhr.html.erb +2 -0
  49. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_converts → mg/converts}/.tmp_show.html.erb.4433~ +0 -0
  50. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_converts → mg/converts}/_convert_form.html.erb +0 -0
  51. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_converts → mg/converts}/_convert_meta_type_form.html.erb +0 -0
  52. data/lib/mountain-goat/views/mountain_goat/mg/converts/edit.html.erb +13 -0
  53. data/lib/mountain-goat/views/mountain_goat/mg/converts/index.html.erb +25 -0
  54. data/lib/mountain-goat/views/mountain_goat/mg/converts/new.html.erb +13 -0
  55. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_converts → mg/converts}/show.html.erb +3 -28
  56. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_metric_variants → mg/metric_variants}/_metric_variant_form.html.erb +0 -4
  57. data/lib/mountain-goat/views/mountain_goat/mg/metric_variants/edit.html.erb +13 -0
  58. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_metric_variants → mg/metric_variants}/index.html.erb +3 -3
  59. data/lib/mountain-goat/views/mountain_goat/mg/metric_variants/new.html.erb +15 -0
  60. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_metric_variants → mg/metric_variants}/show.html.erb +4 -5
  61. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_metrics → mg/metrics}/.tmp_show.html.erb.21270~ +0 -0
  62. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_metrics → mg/metrics}/_metric_form.html.erb +0 -2
  63. data/lib/mountain-goat/views/mountain_goat/mg/metrics/edit.html.erb +13 -0
  64. data/lib/mountain-goat/views/mountain_goat/mg/metrics/index.html.erb +14 -0
  65. data/lib/mountain-goat/views/mountain_goat/mg/metrics/new.html.erb +14 -0
  66. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_metrics → mg/metrics}/show.html.erb +7 -8
  67. data/lib/mountain-goat/views/mountain_goat/{mountain_goat → mg/mountain_goat}/login.html.erb +0 -0
  68. data/lib/mountain-goat/views/mountain_goat/mg/playground/test.html.erb +14 -0
  69. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_rallies → mg/rallies}/.tmp__rally.html.erb.40484~ +0 -0
  70. data/lib/mountain-goat/views/mountain_goat/mg/rallies/_rallies.html.erb +5 -0
  71. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_rallies → mg/rallies}/_rallies_form.html.erb +0 -0
  72. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_rallies → mg/rallies}/_rally.html.erb +0 -0
  73. data/lib/mountain-goat/views/mountain_goat/mg/rallies/edit.html.erb +13 -0
  74. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_rallies → mg/rallies}/index.html.erb +1 -1
  75. data/lib/mountain-goat/views/mountain_goat/mg/rallies/new.html.erb +13 -0
  76. data/lib/mountain-goat/views/mountain_goat/{mountain_goat_rallies → mg/rallies}/show.html.erb +1 -1
  77. data/lib/mountain-goat/views/mountain_goat/mg/report_items/_chart.html.erb +18 -0
  78. data/lib/mountain-goat/views/mountain_goat/mg/report_items/_report_item_form.html.erb +10 -0
  79. data/lib/mountain-goat/views/mountain_goat/mg/report_items/_report_item_pivot_form.html.erb +14 -0
  80. data/lib/mountain-goat/views/mountain_goat/mg/report_items/_show.html.erb +29 -0
  81. data/lib/mountain-goat/views/mountain_goat/mg/report_items/_svg_chart.html.erb +4 -0
  82. data/lib/mountain-goat/views/mountain_goat/mg/report_items/edit.html.erb +19 -0
  83. data/lib/mountain-goat/views/mountain_goat/mg/report_items/new.html.erb +17 -0
  84. data/lib/mountain-goat/views/mountain_goat/mg/report_mailer/report.html.erb +27 -0
  85. data/lib/mountain-goat/views/mountain_goat/mg/reports/_report.html.erb +22 -0
  86. data/lib/mountain-goat/views/mountain_goat/mg/reports/_report_form.html.erb +21 -0
  87. data/lib/mountain-goat/views/mountain_goat/mg/reports/_report_report_items.html.erb +5 -0
  88. data/lib/mountain-goat/views/mountain_goat/mg/reports/edit.html.erb +36 -0
  89. data/lib/mountain-goat/views/mountain_goat/mg/reports/index.html.erb +26 -0
  90. data/lib/mountain-goat/views/mountain_goat/mg/reports/new.html.erb +17 -0
  91. data/lib/mountain-goat/views/mountain_goat/mg/reports/show.html.erb +21 -0
  92. data/test/fixtures/{ci_metas.yml → mg_ci_metas.yml} +0 -0
  93. data/test/fixtures/{convert_meta_types.yml → mg_convert_meta_types.yml} +0 -0
  94. data/test/fixtures/{converts.yml → mg_converts.yml} +5 -0
  95. data/test/fixtures/{cs_metas.yml → mg_cs_metas.yml} +0 -0
  96. data/test/fixtures/mg_deliveries.yml +9 -0
  97. data/test/fixtures/{metric_variants.yml → mg_metric_variants.yml} +0 -0
  98. data/test/fixtures/{metrics.yml → mg_metrics.yml} +2 -3
  99. data/test/fixtures/{rallies.yml → mg_rallies.yml} +6 -2
  100. data/test/fixtures/mg_report_items.yml +13 -0
  101. data/test/fixtures/mg_reports.yml +15 -0
  102. data/test/mg_convert_test.rb +32 -0
  103. data/test/mg_converts_controller_test.rb +47 -0
  104. data/test/mg_metric_variants_controller_test.rb +46 -0
  105. data/test/mg_metrics_controller_test.rb +52 -0
  106. data/test/mg_mountain_goat_controller_test.rb +45 -0
  107. data/test/mg_mountain_goat_test.rb +392 -0
  108. data/test/mg_playground_controller_test.rb +11 -0
  109. data/test/mg_rallies_controller_test.rb +36 -0
  110. data/test/mg_report_item_test.rb +7 -0
  111. data/test/mg_report_items_controller_test.rb +31 -0
  112. data/test/mg_report_test.rb +18 -0
  113. data/test/mg_reports_controller_test.rb +50 -0
  114. data/test/test_helper.rb +203 -0
  115. metadata +108 -55
  116. data/lib/mountain-goat/models/ci_meta.rb +0 -9
  117. data/lib/mountain-goat/models/convert.rb +0 -70
  118. data/lib/mountain-goat/models/convert_meta_type.rb +0 -19
  119. data/lib/mountain-goat/models/cs_meta.rb +0 -9
  120. data/lib/mountain-goat/models/metric_variant.rb +0 -22
  121. data/lib/mountain-goat/views/mountain_goat/mountain_goat_converts/edit.html.erb +0 -13
  122. data/lib/mountain-goat/views/mountain_goat/mountain_goat_converts/index.html.erb +0 -48
  123. data/lib/mountain-goat/views/mountain_goat/mountain_goat_converts/new.html.erb +0 -13
  124. data/lib/mountain-goat/views/mountain_goat/mountain_goat_metric_variants/edit.html.erb +0 -13
  125. data/lib/mountain-goat/views/mountain_goat/mountain_goat_metric_variants/new.html.erb +0 -15
  126. data/lib/mountain-goat/views/mountain_goat/mountain_goat_metrics/edit.html.erb +0 -13
  127. data/lib/mountain-goat/views/mountain_goat/mountain_goat_metrics/index.html.erb +0 -14
  128. data/lib/mountain-goat/views/mountain_goat/mountain_goat_metrics/new.html.erb +0 -14
  129. data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/_rallies.html.erb +0 -5
  130. data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/edit.html.erb +0 -13
  131. data/lib/mountain-goat/views/mountain_goat/mountain_goat_rallies/new.html.erb +0 -13
  132. data/test/ocelot_converts_controller_test.rb +0 -45
  133. data/test/ocelot_metric_variants_controller_test.rb +0 -45
  134. data/test/ocelot_metrics_controller_test.rb +0 -45
  135. data/test/ocelot_rallies_controller_test.rb +0 -8
@@ -0,0 +1,47 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class Mg::ConvertsControllerTest < ActionController::TestCase
4
+ #index, show, new, edit, create, update, destroy
5
+
6
+ test "should get index" do
7
+ get :index, {}, logged_in
8
+ assert_response :success
9
+ assert_not_nil assigns(:converts)
10
+ end
11
+
12
+ test "should get new" do
13
+ get :new, {}, logged_in
14
+ assert_response :success
15
+ end
16
+
17
+ test "should create convert" do
18
+ assert_difference('Mg::Convert.count') do
19
+ post :create, { :convert => { :name => 'my next convert', :convert_type => 'convert_type_3' } }, logged_in
20
+ end
21
+
22
+ assert_redirected_to mg_convert_url assigns(:convert)
23
+ end
24
+
25
+ test "should show convert" do
26
+ get :show, { :id => mg_converts(:one).to_param }, logged_in
27
+ assert_response :success
28
+ end
29
+
30
+ test "should get edit" do
31
+ get :edit, { :id => mg_converts(:one).to_param }, logged_in
32
+ assert_response :success
33
+ end
34
+
35
+ test "should update convert" do
36
+ put :update, { :id => mg_converts(:one).to_param, :convert => { } }, logged_in
37
+ assert_redirected_to mg_convert_url assigns(:convert)
38
+ end
39
+
40
+ test "should destroy convert" do
41
+ assert_difference('Mg::Convert.count', -1) do
42
+ delete :destroy, { :id => mg_converts(:one).to_param }, logged_in
43
+ end
44
+
45
+ assert_redirected_to mg_converts_url
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class Mg::MetricVariantsControllerTest < ActionController::TestCase
4
+
5
+ test "should get index" do
6
+ get :index, {}, logged_in
7
+ assert_response :success
8
+ assert_not_nil assigns(:metric_variants)
9
+ end
10
+
11
+ test "should get new" do
12
+ get :new, { :metric_id => mg_metrics(:two).id }, logged_in
13
+ assert_response :success
14
+ end
15
+
16
+ test "should create metric_variant" do
17
+ assert_difference('Mg::MetricVariant.count') do
18
+ post :create, { :metric_variant => { :metric_id => mg_metrics(:two).id, :name => 'var', :value => 'cool' } }, logged_in
19
+ end
20
+
21
+ assert_redirected_to mg_metric_url mg_metrics(:two)
22
+ end
23
+
24
+ test "should show metric_variant" do
25
+ get :show, { :id => mg_metric_variants(:one).to_param }, logged_in
26
+ assert_response :success
27
+ end
28
+
29
+ test "should get edit" do
30
+ get :edit, { :id => mg_metric_variants(:one).to_param }, logged_in
31
+ assert_response :success
32
+ end
33
+
34
+ test "should update metric_variant" do
35
+ put :update, { :id => mg_metric_variants(:one).to_param, :metric_variant => { } }, logged_in
36
+ assert_redirected_to mg_metric_url assigns(:metric_variant).metric
37
+ end
38
+
39
+ test "should destroy metric_variant" do
40
+ assert_difference('Mg::MetricVariant.count', -1) do
41
+ delete :destroy, { :id => mg_metric_variants(:one).to_param }, logged_in
42
+ end
43
+
44
+ assert_redirected_to mg_metric_variants_url
45
+ end
46
+ end
@@ -0,0 +1,52 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class Mg::MetricsControllerTest < ActionController::TestCase
4
+
5
+ test "should test fresh metrics" do
6
+ @request.env["HTTP_REFERER"] = "http://test.host/hi"
7
+ put :fresh_metrics, { }, logged_in #this clears cookies.. meh
8
+ assert_redirected_to "http://test.host/hi"
9
+ end
10
+
11
+ test "should get index" do
12
+ get :index, {}, logged_in
13
+ assert_response :success
14
+ assert_not_nil assigns(:metrics)
15
+ end
16
+
17
+ test "should get new" do
18
+ get :new, { }, logged_in
19
+ assert_response :success
20
+ end
21
+
22
+ test "should create metric" do
23
+ assert_difference('Mg::Metric.count') do
24
+ post :create, { :metric => { :metric_type => 'geoff', :title => 'hayes' } }, logged_in
25
+ end
26
+
27
+ assert_redirected_to mg_metric_url :id => assigns(:metric).id
28
+ end
29
+
30
+ test "should show metric" do
31
+ get :show, { :id => mg_metrics(:one).to_param }, logged_in
32
+ assert_response :success
33
+ end
34
+
35
+ test "should get edit" do
36
+ get :edit, { :id => mg_metrics(:one).to_param }, logged_in
37
+ assert_response :success
38
+ end
39
+
40
+ test "should update metric" do
41
+ put :update, { :id => mg_metrics(:one).to_param, :metric => { } }, logged_in
42
+ assert_redirected_to mg_metric_url :id => assigns(:metric).id
43
+ end
44
+
45
+ test "should destroy metric" do
46
+ assert_difference('Mg::Metric.count', -1) do
47
+ delete :destroy, { :id => mg_metrics(:one).to_param }, logged_in
48
+ end
49
+
50
+ assert_redirected_to mg_metrics_url
51
+ end
52
+ end
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class Mg::MountainGoatControllerTest < ActionController::TestCase
4
+
5
+ #fetch, login, login_create
6
+
7
+ test "fetch file" do
8
+ #Double __ could theoretically become a .., let's just stem this off
9
+ assert_raise ArgumentError do
10
+ get :fetch, { :file => 'hi__png' }
11
+ end
12
+
13
+ assert_raise ArgumentError do
14
+ get :fetch, { :file => 'hi/png' }
15
+ end
16
+
17
+ assert_raise ArgumentError do
18
+ get :fetch, { :file => 'hi.png' }
19
+ end
20
+
21
+ assert_raise ArgumentError do
22
+ get :fetch, { :file => '__/analytics_rb' }
23
+ end
24
+
25
+ get :fetch, { :file => 'mgnew_css' }
26
+ assert_response :not_found
27
+
28
+ get :fetch, { :file => 'mg_css' }
29
+ assert_response :success
30
+ end
31
+
32
+ test "login" do
33
+ get :login
34
+ assert_response :success
35
+ assert flash[:error].blank?
36
+ end
37
+
38
+ test "login - create" do
39
+ post :login_create, { :password => '123' }
40
+ assert_response :success #invalid
41
+
42
+ post :login_create, { :password => 'husky' }
43
+ assert_redirected_to '/mg' #valid
44
+ end
45
+ end
@@ -0,0 +1,392 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class Mg::MountainGoatTest < ActiveRecord::TestCase
4
+ include MetricTracking::Controller
5
+
6
+ class FakeSession
7
+
8
+ def []=(key, value)
9
+ @data = {}.with_indifferent_access if @data.nil?
10
+ @data[key] = value.is_a?(Hash) ? value[:value] : value
11
+ end
12
+
13
+ def [](key)
14
+ return @data[key] if !@data.nil? && @data.has_key?(key)
15
+ return nil
16
+ end
17
+ end
18
+
19
+ test "mountain goat tests" do
20
+ @mg_strategy = 'e-greedy'
21
+ @mg_storage = FakeSession.new
22
+
23
+ #Let's start by adding a few tests, checking to see if storage is correct
24
+ assert_equal 'a', bd(:test, 'a')
25
+ assert_equal 'a', bd(:test, 'a')
26
+ metric = Mg::Metric.find_by_metric_type(:test.to_s)
27
+ a = metric.metric_variants.find_by_name('a')
28
+ assert_equal 1, metric.metric_variants.count
29
+ assert_equal 2, a.served
30
+ assert_equal a.id, @mg_storage[:metric_test_variant]
31
+ assert_equal 0, a.reward
32
+
33
+ rw(:jimbo, 10) #score a reward
34
+ a.reload
35
+ assert_equal 10, a.reward
36
+ assert_equal 1, a.conversions
37
+ rw(:jimbo, 20) #score a reward
38
+ a.reload
39
+ assert_equal 30, a.reward
40
+ assert_equal 2, a.conversions
41
+
42
+ metric.metric_variants.create!( :value => 'b', :name => 'b' )
43
+ b = metric.metric_variants.find_by_name('b')
44
+
45
+ assert_equal 2, metric.metric_variants.count
46
+ assert_nil b.reward
47
+
48
+ #This is coming from session - let's test "tally each serve"
49
+ metric.update_attribute(:tally_each_serve, false)
50
+ metric.reload
51
+
52
+ assert_equal 'a', bd(:test, 'a')
53
+ a.reload
54
+ assert_equal 2, a.served #this comes from "tally each serve"
55
+ assert_equal 30, a.reward
56
+
57
+ metric.update_attribute(:tally_each_serve, true)
58
+ metric.reload
59
+ assert_equal 'a', bd(:test, 'a')
60
+ a.reload
61
+
62
+ assert_equal 3, a.served
63
+ assert_equal 30, a.reward
64
+ @mg_storage = FakeSession.new #clear "session"
65
+
66
+ b.reload
67
+ assert_equal 0, b.served #Let's see if b gets served since it has zero
68
+ #when random comes into play, it's going to be hard to test, so let's stray away
69
+
70
+ assert_equal 'b', bd(:test, 'a') #this should serve b since it has a reward of 0 and a has a reward of 30
71
+ b.reload
72
+ assert_equal 1, b.served
73
+ assert_equal 0, b.reward
74
+ assert_equal 0, b.conversions
75
+
76
+ #Let's just check repeats
77
+ assert_equal 'b', bd(:test, 'a')
78
+ b.reload
79
+ assert_equal 2, b.served
80
+ assert_equal 0, b.reward
81
+ assert_equal 0, b.conversions
82
+
83
+ @mg_storage = FakeSession.new #clear "session"
84
+
85
+ #We should still get a since it's the winner
86
+ assert_equal 'a', bd(:test, 'a')
87
+ a.reload
88
+ assert_equal 4, a.served
89
+ assert_equal 30, a.reward
90
+ assert_equal 2, a.conversions
91
+
92
+ #Since we can't get b served without fudging (later), let's make a new variant
93
+ metric.metric_variants.create!( :value => 'c', :name => 'c' )
94
+ c = metric.metric_variants.find_by_name('c')
95
+
96
+ #Let's just check repeats
97
+ assert_equal 'a', bd(:test, 'a')
98
+ a.reload
99
+ assert_equal 5, a.served
100
+ assert_equal 30, a.reward
101
+ assert_equal 2, a.conversions
102
+
103
+ @mg_storage = FakeSession.new #clear "session"
104
+ assert_equal 'c', bd(:test, 'a')
105
+ c.reload
106
+ assert_equal 1, c.served
107
+ assert_equal 0, c.reward
108
+ assert_equal 0, c.conversions
109
+
110
+ #Make c the new winner
111
+ rw(:jimbo, 40) #score a reward
112
+ c.reload
113
+ assert_equal 40, c.reward
114
+ assert_equal 1, c.conversions
115
+
116
+ #Now, let's see if he peaks his head out
117
+ @mg_storage = FakeSession.new #clear "session"
118
+ assert_equal 'c', bd(:test, 'a')
119
+ c.reload
120
+ assert_equal 2, c.served
121
+ assert_equal 40, c.reward
122
+ assert_equal 1, c.conversions
123
+
124
+ #Okay, we now can be fairly confident we are serving the best usually
125
+ #We need to test serving "random"-- this is going to be hard even with fake random
126
+ #The end-all-be-all should be 'id'.. maybe
127
+ @mg_i = 0
128
+ @mg_storage = FakeSession.new #clear "session"
129
+ assert_equal 'a', bd(:test, 'a')
130
+ a.reload
131
+ assert_equal 6, a.served
132
+
133
+ #Now, back to the winner
134
+ @mg_i = 1
135
+ @mg_storage = FakeSession.new #clear "session"
136
+ assert_equal 'c', bd(:test, 'a')
137
+ c.reload
138
+ assert_equal 3, c.served
139
+
140
+ #Deeper reward tests
141
+ @mg_storage = FakeSession.new #clear "session"
142
+ rw(:jimbo, 15) #should go to nothing
143
+ a.reload; b.reload; c.reload;
144
+ assert_equal 30, a.reward
145
+ assert_equal 0, b.reward
146
+ assert_equal 40, c.reward
147
+
148
+ #Let's regrab c (winner) and new metric test2 with 'j'
149
+ assert_equal 'c', bd(:test, 'a')
150
+ assert_equal 'j', bd(:test2, 'j')
151
+ metric2 = Mg::Metric.find_by_metric_type(:test2.to_s)
152
+ j = metric2.metric_variants.find_by_name('j')
153
+
154
+ rw(:jimbo, 15) #should go to both c and j
155
+ j.reload; a.reload; b.reload; c.reload;
156
+ assert_equal 55, c.reward
157
+ assert_equal 15, j.reward
158
+
159
+ #Create a new variant 'k' for test2 metric
160
+ metric2.metric_variants.create!( :value => 'k', :name => 'k' )
161
+ k = metric2.metric_variants.find_by_name('k')
162
+
163
+ @mg_storage = FakeSession.new #clear "session"
164
+ assert_equal 'c', bd(:test, 'a')
165
+ assert_equal 'k', bd(:test2, 'j') #this should be 'unexplored'
166
+
167
+ rw(:jimbo, 15) #should go to c and k (not j)
168
+ j.reload; k.reload; a.reload; b.reload; c.reload;
169
+ assert_equal 30, a.reward
170
+ assert_equal 0, b.reward
171
+ assert_equal 70, c.reward
172
+ assert_equal 15, j.reward
173
+ assert_equal 15, k.reward
174
+
175
+ #c = 70 / 6 = ~12, a = 30 / 6 = 5.. 70 / 14 = 5
176
+ #let's make sure winners aren't winners if they are over-served
177
+ @mg_storage = FakeSession.new #clear "session"
178
+ assert_equal 'c', bd(:test, 'a') # / 6
179
+ @mg_storage = FakeSession.new #clear "session"
180
+ assert_equal 'c', bd(:test, 'a')# / 7
181
+ @mg_storage = FakeSession.new #clear "session"
182
+ assert_equal 'c', bd(:test, 'a')# / 8
183
+ @mg_storage = FakeSession.new #clear "session"
184
+ assert_equal 'c', bd(:test, 'a')# / 9
185
+ @mg_storage = FakeSession.new #clear "session"
186
+ assert_equal 'c', bd(:test, 'a')# / 10
187
+ @mg_storage = FakeSession.new #clear "session"
188
+ assert_equal 'c', bd(:test, 'a')# / 11
189
+ @mg_storage = FakeSession.new #clear "session"
190
+ assert_equal 'c', bd(:test, 'a')# / 12
191
+ @mg_storage = FakeSession.new #clear "session"
192
+ assert_equal 'c', bd(:test, 'a')# / 13
193
+ @mg_storage = FakeSession.new #clear "session"
194
+ assert_equal 'c', bd(:test, 'a')# / 14
195
+ @mg_storage = FakeSession.new #clear "session"
196
+ assert_equal 'a', bd(:test, 'a')# / 15 !!
197
+ @mg_storage = FakeSession.new #clear "session"
198
+ assert_equal 'c', bd(:test, 'a')# 70 / 15 ~ 30 / 7
199
+ end
200
+
201
+ test "mountain goat tests - bandit switch" do
202
+ @mg_strategy = 'e-greedy'
203
+ @mg_storage = FakeSession.new
204
+
205
+ #Let's start by adding a few tests, checking to see if storage is correct
206
+ @var = 0
207
+ assert_difference('Mg::MetricVariant.count', 2) do
208
+ bds(:test) do |variant|
209
+ variant.a do
210
+ logger.warn "TRTTTu - In a"
211
+ @var = 1
212
+ end
213
+
214
+ variant.b do
215
+ logger.warn "TRTTTu - In b"
216
+ @var = 2
217
+ end
218
+ end
219
+ end
220
+
221
+ metric = Mg::Metric.find_by_metric_type(:test.to_s)
222
+ a = metric.metric_variants.find_by_name('a')
223
+ b = metric.metric_variants.find_by_name('b')
224
+
225
+ assert_equal a.id, @mg_storage[:metric_test_variant]
226
+
227
+ assert_equal 1, @var
228
+ assert_equal 1, a.served
229
+ assert_equal 0, a.reward
230
+ rw(:jimbo, 15) #should go to a
231
+ a.reload
232
+ assert_equal 15, a.reward
233
+
234
+ rw(:jimbo, 10) #should go to a
235
+ a.reload
236
+ assert_equal 25, a.reward
237
+
238
+ #should serve a since we haven't reset cookies
239
+ assert_no_difference('Mg::MetricVariant.count') do
240
+ bds(:test) do |variant|
241
+ variant.a do
242
+ @var = 1
243
+ end
244
+
245
+ variant.b do
246
+ @var = 2
247
+ end
248
+ end
249
+ end
250
+
251
+ a.reload; b.reload
252
+
253
+ assert_equal 1, @var
254
+ assert_equal 2, a.served
255
+
256
+ #should serve b since it has no serves
257
+ @mg_storage = FakeSession.new
258
+ assert_no_difference('Mg::MetricVariant.count') do
259
+ bds(:test) do |variant|
260
+ variant.a do
261
+ @var = 1
262
+ end
263
+
264
+ variant.b do
265
+ @var = 2
266
+ end
267
+ end
268
+ end
269
+
270
+ a.reload; b.reload
271
+
272
+ assert_equal 2, @var
273
+ assert_equal 2, a.served
274
+ assert_equal 1, b.served
275
+ assert_equal 0, b.reward
276
+ rw(:jimbo, 15) #should go to b
277
+ b.reload
278
+ assert_equal 15, b.reward
279
+
280
+ #should serve c since it has no serves
281
+ @mg_storage = FakeSession.new
282
+ assert_difference('Mg::MetricVariant.count') do
283
+ bds(:test) do |variant|
284
+ variant.a do
285
+ @var = 1
286
+ end
287
+
288
+ variant.b do
289
+ @var = 2
290
+ end
291
+
292
+ variant.c do
293
+ @var = 3
294
+ end
295
+ end
296
+ end
297
+
298
+ assert_equal 3, @var
299
+ end
300
+
301
+ test "mountain goat tests - e-greedy-decreasing" do
302
+ @mg_strategy = 'e-greedy-decreasing'
303
+ @mg_storage = FakeSession.new
304
+
305
+ #Let's start by adding a few tests, checking to see if storage is correct
306
+ assert_equal 'a', bd(:test, 'a')
307
+ assert_equal 'a', bd(:test, 'a')
308
+ metric = Mg::Metric.find_by_metric_type(:test.to_s)
309
+ a = metric.metric_variants.find_by_name('a')
310
+ assert_equal 1, metric.metric_variants.count
311
+ assert_equal 2, a.served
312
+ assert_equal a.id, @mg_storage[:metric_test_variant]
313
+ assert_equal 0, a.reward
314
+
315
+ rw(:jimbo, 10) #score a reward
316
+ a.reload
317
+ assert_equal 10, a.reward
318
+ assert_equal 1, a.conversions
319
+ rw(:jimbo, 20) #score a reward
320
+ a.reload
321
+ assert_equal 30, a.reward
322
+ assert_equal 2, a.conversions
323
+
324
+ metric.metric_variants.create!( :value => 'b', :name => 'b' )
325
+ b = metric.metric_variants.find_by_name('b')
326
+
327
+ assert_equal 2, metric.metric_variants.count
328
+ assert_nil b.reward
329
+
330
+ #Should serve 'b' for exploration of 0-serves
331
+ @mg_storage = FakeSession.new
332
+ assert_equal 'b', bd(:test, 'a')
333
+ rw(:jimbo, 100) #a is still the winner
334
+
335
+ @mg_storage = FakeSession.new
336
+ #So far 3 serves, should serve random "a" when random < 0.1 / 3, "b" the winner otherwise
337
+ @mg_storage = FakeSession.new
338
+ @mg_i = 0.032
339
+ assert_equal 'a', bd(:test, 'a')
340
+
341
+ #So far 4 serves, should serve random "a" when random < 0.1 / 4, "b" the winner otherwise
342
+ @mg_storage = FakeSession.new
343
+ @mg_i = 0.025
344
+ assert_equal 'b', bd(:test, 'a') #strictly less than
345
+
346
+ #So far 5 serves, should serve random "a" when random < 0.1 / 5, "b" the winner otherwise
347
+ @mg_storage = FakeSession.new
348
+ @mg_i = 0.019
349
+ assert_equal 'a', bd(:test, 'a')
350
+
351
+ #So far 6 serves, should serve random "a" when random < 0.1 / 6, "b" the winner otherwise
352
+ @mg_storage = FakeSession.new
353
+ @mg_i = 0.017
354
+ assert_equal 'b', bd(:test, 'a')
355
+ end
356
+
357
+ test "mountain goat tests - a/b" do
358
+ @mg_strategy = 'a/b'
359
+ @mg_storage = FakeSession.new
360
+
361
+ #Let's start by adding a few tests, checking to see if storage is correct
362
+ assert_equal 'a', bd(:test, 'a')
363
+ assert_equal 'a', bd(:test, 'a')
364
+ metric = Mg::Metric.find_by_metric_type(:test.to_s)
365
+ a = metric.metric_variants.find_by_name('a')
366
+ assert_equal 1, metric.metric_variants.count
367
+ assert_equal 2, a.served
368
+ assert_equal a.id, @mg_storage[:metric_test_variant]
369
+ assert_equal 0, a.reward
370
+
371
+ rw(:jimbo, 10) #score a reward
372
+ a.reload
373
+ assert_equal 10, a.reward
374
+ assert_equal 1, a.conversions
375
+ rw(:jimbo, 20) #score a reward
376
+ a.reload
377
+ assert_equal 30, a.reward
378
+ assert_equal 2, a.conversions
379
+
380
+ metric.metric_variants.create!( :value => 'b', :name => 'b' )
381
+ b = metric.metric_variants.find_by_name('b')
382
+
383
+ assert_equal 2, metric.metric_variants.count
384
+ assert_nil b.reward
385
+
386
+ #Since we aren't using rand.. we'll not likely be able to bypass 'a' in our 'randomness'
387
+ assert_equal 'a', bd(:test, 'a')
388
+
389
+ @mg_storage = FakeSession.new
390
+ assert_equal 'a', bd(:test, 'a')
391
+ end
392
+ end