mountain-goat 0.1.8 → 1.0.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.
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