prosperity 0.0.1 → 0.0.2

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 (223) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/prosperity/application.js.coffee +5 -24
  3. data/app/assets/javascripts/prosperity/dashboards.js.coffee +17 -0
  4. data/app/assets/javascripts/prosperity/graph.js.coffee +89 -0
  5. data/app/assets/stylesheets/prosperity/application.css.scss +1 -1
  6. data/app/assets/stylesheets/prosperity/dashboards.css +4 -0
  7. data/app/assets/stylesheets/prosperity/graph.css +4 -0
  8. data/app/controllers/prosperity/application_controller.rb +30 -0
  9. data/app/controllers/prosperity/dashboard_graphs_controller.rb +24 -0
  10. data/app/controllers/prosperity/dashboards_controller.rb +33 -0
  11. data/app/controllers/prosperity/graphs_controller.rb +72 -0
  12. data/app/controllers/prosperity/metrics_controller.rb +57 -0
  13. data/app/helpers/prosperity/application_helper.rb +4 -0
  14. data/app/helpers/prosperity/dashboard_graphs_helper.rb +4 -0
  15. data/app/helpers/prosperity/dashboards_helper.rb +4 -0
  16. data/app/helpers/prosperity/graph_helper.rb +7 -0
  17. data/app/models/prosperity/dashboard.rb +8 -0
  18. data/app/models/prosperity/dashboard_graph.rb +6 -0
  19. data/app/models/prosperity/graph.rb +20 -0
  20. data/app/models/prosperity/graph_line.rb +8 -0
  21. data/app/views/layouts/prosperity/application.html.erb +56 -0
  22. data/app/views/prosperity/dashboards/edit.html.erb +24 -0
  23. data/app/views/prosperity/dashboards/index.html.erb +15 -0
  24. data/app/views/prosperity/dashboards/new.html.erb +8 -0
  25. data/app/views/prosperity/dashboards/show.html.erb +14 -0
  26. data/app/views/prosperity/graphs/edit.html.erb +41 -0
  27. data/app/views/prosperity/graphs/new.html.erb +15 -0
  28. data/app/views/prosperity/metrics/index.html.erb +8 -0
  29. data/app/views/prosperity/metrics/show.html.erb +23 -0
  30. data/app/views/prosperity/shared/_date_range.html.erb +9 -0
  31. data/config/routes.rb +12 -2
  32. data/db/migrate/20131127042251_dashboards.rb +34 -0
  33. data/lib/generators/metric/USAGE +8 -0
  34. data/lib/generators/metric/metric_generator.rb +7 -0
  35. data/lib/generators/metric/templates/metric.rb.erb +3 -0
  36. data/lib/prosperity/aggregate/aggregate_builder.rb +42 -0
  37. data/lib/prosperity/aggregate/average.rb +12 -0
  38. data/lib/prosperity/aggregate/base.rb +5 -0
  39. data/lib/prosperity/aggregate/count.rb +12 -0
  40. data/lib/prosperity/aggregate/maximum.rb +12 -0
  41. data/lib/prosperity/aggregate/minimum.rb +12 -0
  42. data/lib/prosperity/aggregate/sql.rb +12 -0
  43. data/lib/prosperity/aggregate/sum.rb +12 -0
  44. data/lib/prosperity/aggregate/with_column.rb +10 -0
  45. data/lib/prosperity/aggregate.rb +5 -0
  46. data/lib/prosperity/engine.rb +14 -0
  47. data/lib/prosperity/exception.rb +19 -1
  48. data/lib/prosperity/extractors/base.rb +33 -5
  49. data/lib/prosperity/extractors/change.rb +35 -0
  50. data/lib/prosperity/extractors/interval.rb +51 -0
  51. data/lib/prosperity/extractors/total.rb +23 -0
  52. data/lib/prosperity/helpers/time.rb +12 -0
  53. data/lib/prosperity/metric.rb +90 -5
  54. data/lib/prosperity/metric_finder.rb +10 -0
  55. data/lib/prosperity/metrics/option.rb +2 -0
  56. data/lib/prosperity/period.rb +4 -3
  57. data/lib/prosperity/periods.rb +13 -2
  58. data/lib/prosperity/version.rb +1 -1
  59. data/spec/controllers/prosperity/dashboard_graphs_controller_spec.rb +45 -0
  60. data/spec/controllers/prosperity/dashboards_controller_spec.rb +54 -0
  61. data/spec/controllers/prosperity/graphs_controller_spec.rb +145 -0
  62. data/spec/controllers/prosperity/metrics_controller_spec.rb +78 -0
  63. data/spec/dummy/app/models/user.rb +1 -0
  64. data/spec/dummy/app/prosperity/user_value_sum_metric.rb +4 -0
  65. data/spec/dummy/app/prosperity/user_value_sum_sql_metric.rb +4 -0
  66. data/spec/dummy/app/prosperity/users_metric.rb +8 -0
  67. data/spec/dummy/app/prosperity/users_sql_metric.rb +4 -0
  68. data/spec/dummy/config/database.yml +0 -8
  69. data/spec/dummy/config/routes.rb +1 -1
  70. data/spec/dummy/db/migrate/20140217005117_add_value_to_users.rb +5 -0
  71. data/spec/dummy/db/schema.rb +37 -1
  72. data/spec/dummy/db/seeds.rb +3 -1
  73. data/spec/dummy/log/development.log +76950 -0
  74. data/spec/dummy/log/test.log +111316 -0
  75. data/spec/dummy/tmp/cache/assets/development/sass/34a577735054231563e7022ea73e1468db9203ba/application.css.scssc +0 -0
  76. data/spec/dummy/tmp/cache/assets/development/sprockets/07e8fb2db7d85e29590a6b05160ca825 +0 -0
  77. data/spec/dummy/tmp/cache/assets/development/sprockets/1533bcf4a8f5a745dfda80cebd88d217 +0 -0
  78. data/spec/dummy/tmp/cache/assets/development/sprockets/1643e7f9f85637df140a850af6674f10 +0 -0
  79. data/spec/dummy/tmp/cache/assets/development/sprockets/197492ed379339e17a0f5d01d3b01b8c +0 -0
  80. data/spec/dummy/tmp/cache/assets/development/sprockets/1c55cf24465f311353197ce336df0178 +0 -0
  81. data/spec/dummy/tmp/cache/assets/development/sprockets/210050da208fb75a75b701bfa4e8470f +0 -0
  82. data/spec/dummy/tmp/cache/assets/development/sprockets/2733033a48e2e8a6fdd6e4ab371689ee +0 -0
  83. data/spec/dummy/tmp/cache/assets/development/sprockets/27a59e08207d3ae723f2b2b3d22264c3 +0 -0
  84. data/spec/dummy/tmp/cache/assets/development/sprockets/3e21790900d62ae3954585f08a1cb28a +0 -0
  85. data/spec/dummy/tmp/cache/assets/development/sprockets/3f76425644a701b85db3d385f077052d +0 -0
  86. data/spec/dummy/tmp/cache/assets/development/sprockets/448c1e44da04c20f27eaa31ad8c4391e +0 -0
  87. data/spec/dummy/tmp/cache/assets/development/sprockets/47df4fdca8a2ff6a43c18d7aa1ffd9c5 +0 -0
  88. data/spec/dummy/tmp/cache/assets/development/sprockets/566fbede2036fd06a20e7e52e30ddc7d +0 -0
  89. data/spec/dummy/tmp/cache/assets/development/sprockets/5f1aaf22720701db690538726e896a39 +0 -0
  90. data/spec/dummy/tmp/cache/assets/development/sprockets/647038c58f26163a9217646e1e5f09ae +0 -0
  91. data/spec/dummy/tmp/cache/assets/development/sprockets/6882b260ae69f1594eff540d803e5ac3 +0 -0
  92. data/spec/dummy/tmp/cache/assets/development/sprockets/69f4b83d363269ee4122bbbaaa1325d1 +0 -0
  93. data/spec/dummy/tmp/cache/assets/development/sprockets/6e1aee34907ba1ccdbfca2deb18a5adb +0 -0
  94. data/spec/dummy/tmp/cache/assets/development/sprockets/72c0d4a0eeedae5e79ae49abb24f6d32 +0 -0
  95. data/spec/dummy/tmp/cache/assets/development/sprockets/828a046f0e7dc2dad0eecfe49d31e14d +0 -0
  96. data/spec/dummy/tmp/cache/assets/development/sprockets/91ae0bd43f98b4f1f111e0bdc178302c +0 -0
  97. data/spec/dummy/tmp/cache/assets/development/sprockets/97d99b466bedb69706f4815fa26b69f3 +0 -0
  98. data/spec/dummy/tmp/cache/assets/development/sprockets/990cf740a7968767a327f6186313badb +0 -0
  99. data/spec/dummy/tmp/cache/assets/development/sprockets/a2b14d5c46db32da9183354fb3fcd0bf +0 -0
  100. data/spec/dummy/tmp/cache/assets/development/sprockets/a6d6196cfd275dea0718553a95f997a5 +0 -0
  101. data/spec/dummy/tmp/cache/assets/development/sprockets/bb1f5ffb0ccbeec2c6499044b356f7c6 +0 -0
  102. data/spec/dummy/tmp/cache/assets/development/sprockets/bc83340720a76d8208112f6aecbff08e +0 -0
  103. data/spec/dummy/tmp/cache/assets/development/sprockets/be67cef79122a71f7432c2f984f1f258 +0 -0
  104. data/spec/dummy/tmp/cache/assets/development/sprockets/c83e71ece967e80f8df838874c130431 +0 -0
  105. data/spec/dummy/tmp/cache/assets/development/sprockets/cad26971ff72bbf5aa5f4e6a469389eb +0 -0
  106. data/spec/dummy/tmp/cache/assets/development/sprockets/d0d5517256edcd1f83b11a13c6ca040f +0 -0
  107. data/spec/dummy/tmp/cache/assets/development/sprockets/d0f0c5e105bfb1d6e5cd7295fbd1f65d +0 -0
  108. data/spec/dummy/tmp/cache/assets/development/sprockets/d3087f7df919b7f0d8142ee163db6c79 +0 -0
  109. data/spec/dummy/tmp/cache/assets/development/sprockets/decc27a1fa9ea32fe0dcc18619e32587 +0 -0
  110. data/spec/dummy/tmp/cache/assets/development/sprockets/df796f7ea525be06a82ebc3a4f97ffec +0 -0
  111. data/spec/dummy/tmp/cache/assets/development/sprockets/e02b5049cf477b43a72b4a00e2fceb46 +0 -0
  112. data/spec/dummy/tmp/cache/assets/development/sprockets/e2a9bdd87a2d19256837fce6544a122c +0 -0
  113. data/spec/dummy/tmp/cache/assets/development/sprockets/e378dcebf3c529db0d6e57d0c8dc3904 +0 -0
  114. data/spec/dummy/tmp/cache/assets/development/sprockets/ee3031bd54230ddf2addb5fa5718c86b +0 -0
  115. data/spec/dummy/tmp/cache/assets/development/sprockets/f4648036e284d9aa3468f4f7b9bbb967 +0 -0
  116. data/spec/dummy/tmp/cache/assets/development/sprockets/f9bbf698d099ead559e5ba4a5a4c5538 +0 -0
  117. data/spec/dummy/tmp/cache/assets/development/sprockets/fb8d3825617fcc11dfa614a51effee0e +0 -0
  118. data/spec/dummy/tmp/cache/assets/test/sass/34a577735054231563e7022ea73e1468db9203ba/application.css.scssc +0 -0
  119. data/spec/dummy/tmp/cache/assets/test/sprockets/07e8fb2db7d85e29590a6b05160ca825 +0 -0
  120. data/spec/dummy/tmp/cache/assets/test/sprockets/0a40fa5e0d6c0de40a8a698dcd697305 +0 -0
  121. data/spec/dummy/tmp/cache/assets/test/sprockets/1533bcf4a8f5a745dfda80cebd88d217 +0 -0
  122. data/spec/dummy/tmp/cache/assets/test/sprockets/1643e7f9f85637df140a850af6674f10 +0 -0
  123. data/spec/dummy/tmp/cache/assets/test/sprockets/177ca1f3e92db4f8a8f6e7ad9786ebfc +0 -0
  124. data/spec/dummy/tmp/cache/assets/test/sprockets/197492ed379339e17a0f5d01d3b01b8c +0 -0
  125. data/spec/dummy/tmp/cache/assets/test/sprockets/1c55cf24465f311353197ce336df0178 +0 -0
  126. data/spec/dummy/tmp/cache/assets/test/sprockets/1cb94582c835e73b3fd3c276f9a7de56 +0 -0
  127. data/spec/dummy/tmp/cache/assets/test/sprockets/203047a4141cf08162077e7290421bbb +0 -0
  128. data/spec/dummy/tmp/cache/assets/test/sprockets/210050da208fb75a75b701bfa4e8470f +0 -0
  129. data/spec/dummy/tmp/cache/assets/test/sprockets/2733033a48e2e8a6fdd6e4ab371689ee +0 -0
  130. data/spec/dummy/tmp/cache/assets/test/sprockets/27a59e08207d3ae723f2b2b3d22264c3 +0 -0
  131. data/spec/dummy/tmp/cache/assets/test/sprockets/29a6c93aeb91d07a5533b3adba7697d0 +0 -0
  132. data/spec/dummy/tmp/cache/assets/test/sprockets/29ac2be474969468157245a7f8737fa4 +0 -0
  133. data/spec/dummy/tmp/cache/assets/test/sprockets/314e44d29ecc7449c9ca3b754329c245 +0 -0
  134. data/spec/dummy/tmp/cache/assets/test/sprockets/3162d1398d6940ee5e933b7ab4d2273d +0 -0
  135. data/spec/dummy/tmp/cache/assets/test/sprockets/3d80e2a5faaf2bd987d804c17aead745 +0 -0
  136. data/spec/dummy/tmp/cache/assets/test/sprockets/4155a156cc6ffb880b56dbc34346fbc0 +0 -0
  137. data/spec/dummy/tmp/cache/assets/test/sprockets/4166fe47cddf4ba18c53b843d69b4c5f +0 -0
  138. data/spec/dummy/tmp/cache/assets/test/sprockets/441f922b26aae90d40e319b6ed0a3bc8 +0 -0
  139. data/spec/dummy/tmp/cache/assets/test/sprockets/4432a4b71ce9551df8d4b3860f4b9be3 +0 -0
  140. data/spec/dummy/tmp/cache/assets/test/sprockets/448c1e44da04c20f27eaa31ad8c4391e +0 -0
  141. data/spec/dummy/tmp/cache/assets/test/sprockets/47df4fdca8a2ff6a43c18d7aa1ffd9c5 +0 -0
  142. data/spec/dummy/tmp/cache/assets/test/sprockets/5479c7b4fba9179d4d1dc59ae64964c1 +0 -0
  143. data/spec/dummy/tmp/cache/assets/test/sprockets/566fbede2036fd06a20e7e52e30ddc7d +0 -0
  144. data/spec/dummy/tmp/cache/assets/test/sprockets/5a3ab9afd151c265cf11c621c0ddbe00 +0 -0
  145. data/spec/dummy/tmp/cache/assets/test/sprockets/647038c58f26163a9217646e1e5f09ae +0 -0
  146. data/spec/dummy/tmp/cache/assets/test/sprockets/64e0150fafbd9aaa3822efa1abb0211d +0 -0
  147. data/spec/dummy/tmp/cache/assets/test/sprockets/65c2d908dbca1bc833ae0b552f6c27fa +0 -0
  148. data/spec/dummy/tmp/cache/assets/test/sprockets/6882b260ae69f1594eff540d803e5ac3 +0 -0
  149. data/spec/dummy/tmp/cache/assets/test/sprockets/69f4b83d363269ee4122bbbaaa1325d1 +0 -0
  150. data/spec/dummy/tmp/cache/assets/test/sprockets/6e1aee34907ba1ccdbfca2deb18a5adb +0 -0
  151. data/spec/dummy/tmp/cache/assets/test/sprockets/726d3f6850549a59954f0bf5584cfd9f +0 -0
  152. data/spec/dummy/tmp/cache/assets/test/sprockets/7ab9ac7cc2529219a4c68fd7854d5c0f +0 -0
  153. data/spec/dummy/tmp/cache/assets/test/sprockets/7bac3aca131c870ad5b07d8ccdc86e06 +0 -0
  154. data/spec/dummy/tmp/cache/assets/test/sprockets/80392355fc6e00cf69b2cd46978ebcbe +0 -0
  155. data/spec/dummy/tmp/cache/assets/test/sprockets/874b42463fefbb0bce47775722ebb4ae +0 -0
  156. data/spec/dummy/tmp/cache/assets/test/sprockets/87ef8ddd2847d19f22a16d726b88b433 +0 -0
  157. data/spec/dummy/tmp/cache/assets/test/sprockets/91ae0bd43f98b4f1f111e0bdc178302c +0 -0
  158. data/spec/dummy/tmp/cache/assets/test/sprockets/97d99b466bedb69706f4815fa26b69f3 +0 -0
  159. data/spec/dummy/tmp/cache/assets/test/sprockets/990cf740a7968767a327f6186313badb +0 -0
  160. data/spec/dummy/tmp/cache/assets/test/sprockets/9a690664139b0393787d6454b4697183 +0 -0
  161. data/spec/dummy/tmp/cache/assets/test/sprockets/a2b14d5c46db32da9183354fb3fcd0bf +0 -0
  162. data/spec/dummy/tmp/cache/assets/test/sprockets/a6d6196cfd275dea0718553a95f997a5 +0 -0
  163. data/spec/dummy/tmp/cache/assets/test/sprockets/bc83340720a76d8208112f6aecbff08e +0 -0
  164. data/spec/dummy/tmp/cache/assets/test/sprockets/c29c465933e7e86d6f6224f5e78c5baf +0 -0
  165. data/spec/dummy/tmp/cache/assets/test/sprockets/c975834a35907ecd2d314bbd6844ee88 +0 -0
  166. data/spec/dummy/tmp/cache/assets/test/sprockets/cad26971ff72bbf5aa5f4e6a469389eb +0 -0
  167. data/spec/dummy/tmp/cache/assets/test/sprockets/cf4affc50c6303e717d6514380d1f417 +0 -0
  168. data/spec/dummy/tmp/cache/assets/test/sprockets/d0d5517256edcd1f83b11a13c6ca040f +0 -0
  169. data/spec/dummy/tmp/cache/assets/test/sprockets/d3087f7df919b7f0d8142ee163db6c79 +0 -0
  170. data/spec/dummy/tmp/cache/assets/test/sprockets/d8b357d5741711da2dd710af0e15d268 +0 -0
  171. data/spec/dummy/tmp/cache/assets/test/sprockets/decc27a1fa9ea32fe0dcc18619e32587 +0 -0
  172. data/spec/dummy/tmp/cache/assets/test/sprockets/df796f7ea525be06a82ebc3a4f97ffec +0 -0
  173. data/spec/dummy/tmp/cache/assets/test/sprockets/e22a1b318499e7f06ea9274e18ab004f +0 -0
  174. data/spec/dummy/tmp/cache/assets/test/sprockets/e298cc3a8203ab1fb6978a90254f8926 +0 -0
  175. data/spec/dummy/tmp/cache/assets/test/sprockets/e378dcebf3c529db0d6e57d0c8dc3904 +0 -0
  176. data/spec/dummy/tmp/cache/assets/test/sprockets/e868f358fe87542c483951a2d9f532b6 +0 -0
  177. data/spec/dummy/tmp/cache/assets/test/sprockets/e8a6adf580ebd1942f4aabe6738678c2 +0 -0
  178. data/spec/dummy/tmp/cache/assets/test/sprockets/ed71f99e0a9653296abd5d6f501dd898 +0 -0
  179. data/spec/dummy/tmp/cache/assets/test/sprockets/efe6f2d16d3a1819817efb8734daf8af +0 -0
  180. data/spec/dummy/tmp/cache/assets/test/sprockets/f03e99bdb4159ae3485ca2858716e19b +0 -0
  181. data/spec/dummy/tmp/cache/assets/test/sprockets/f4648036e284d9aa3468f4f7b9bbb967 +0 -0
  182. data/spec/dummy/tmp/cache/assets/test/sprockets/f961f7434a28c0fe24bf4ffe6cba75fb +0 -0
  183. data/spec/dummy/tmp/cache/assets/test/sprockets/f9bbf698d099ead559e5ba4a5a4c5538 +0 -0
  184. data/spec/dummy/tmp/cache/assets/test/sprockets/fb8d3825617fcc11dfa614a51effee0e +0 -0
  185. data/spec/helpers/prosperity/dashboard_graphs_helper_spec.rb +6 -0
  186. data/spec/helpers/prosperity/dashboards_helper_spec.rb +6 -0
  187. data/spec/helpers/prosperity/{metrics_helper_spec.rb → graph_helper_spec.rb} +1 -1
  188. data/spec/lib/prosperity/aggregate/aggregate_builder_spec.rb +65 -0
  189. data/spec/lib/prosperity/aggregate/average_spec.rb +7 -0
  190. data/spec/lib/prosperity/aggregate/base_spec.rb +7 -0
  191. data/spec/lib/prosperity/aggregate/count_spec.rb +7 -0
  192. data/spec/lib/prosperity/aggregate/maximum_spec.rb +7 -0
  193. data/spec/lib/prosperity/aggregate/minimum_spec.rb +7 -0
  194. data/spec/lib/prosperity/aggregate/sql_spec.rb +7 -0
  195. data/spec/lib/prosperity/aggregate/sum_spec.rb +7 -0
  196. data/spec/lib/prosperity/aggregate/with_column_spec.rb +7 -0
  197. data/spec/lib/prosperity/aggregate_spec.rb +7 -0
  198. data/spec/lib/prosperity/extractors/base_spec.rb +27 -2
  199. data/spec/lib/prosperity/extractors/change_spec.rb +72 -0
  200. data/spec/lib/prosperity/extractors/interval_spec.rb +153 -0
  201. data/spec/lib/prosperity/extractors/total_spec.rb +79 -0
  202. data/spec/lib/prosperity/helpers/time_spec.rb +7 -0
  203. data/spec/lib/prosperity/metric_finder_spec.rb +7 -0
  204. data/spec/lib/prosperity/metric_spec.rb +126 -1
  205. data/spec/lib/prosperity/periods_spec.rb +14 -0
  206. data/spec/models/prosperity/dashboard_graph_spec.rb +6 -0
  207. data/spec/models/prosperity/dashboard_spec.rb +6 -0
  208. data/spec/models/prosperity/graph_line_spec.rb +6 -0
  209. data/spec/models/prosperity/graph_spec.rb +6 -0
  210. data/spec/spec_helper.rb +5 -2
  211. data/spec/support/shared/extractors.rb +64 -0
  212. data/spec/support/test_database.rb +1 -0
  213. data/vendor/assets/javascripts/highcharts.js +285 -0
  214. metadata +317 -62
  215. data/app/helpers/prosperity/metrics_helper.rb +0 -11
  216. data/app/views/layouts/prosperity/application.html.haml +0 -37
  217. data/app/views/prosperity/metrics/index.html.haml +0 -7
  218. data/db/migrate/20131026214127_test.rb +0 -4
  219. data/lib/prosperity/extractors/count.rb +0 -18
  220. data/lib/prosperity/extractors/group.rb +0 -23
  221. data/spec/lib/prosperity/extractors/count_spec.rb +0 -35
  222. data/spec/lib/prosperity/extractors/group_spec.rb +0 -34
  223. data/vendor/assets/javascripts/chart.js +0 -1426
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe Extractors::Interval do
5
+ let(:expected_data_size) { 14 }
6
+ it_behaves_like "an extractor"
7
+
8
+ let(:start_time) { 1.year.ago }
9
+ let(:end_time) { start_time + 1.year }
10
+ let(:period) { Periods::MONTH }
11
+ let(:data) { subject.to_a }
12
+
13
+ subject { Extractors::Interval.new(metric, 'default', start_time, end_time, period) }
14
+
15
+ before do
16
+ User.delete_all
17
+ [2.years.ago, 1.month.ago, 1.month.from_now].each do |time|
18
+ User.create created_at: time
19
+ end
20
+ User.create created_at: 1.week.ago
21
+ end
22
+
23
+ context "simple scope" do
24
+ let(:metric) { UsersMetric.new }
25
+
26
+ describe "#to_a" do
27
+ it "returns the one entry per period" do
28
+ data.size.should == expected_data_size
29
+ end
30
+
31
+ it "only returns models from that period" do
32
+ data.sum.should == 2
33
+ end
34
+ end
35
+ end
36
+
37
+ context "simple sql fragment" do
38
+ let(:metric) { UsersSqlMetric.new }
39
+
40
+ describe "#to_a" do
41
+ it "returns the one entry per period" do
42
+ data.size.should == expected_data_size
43
+ end
44
+
45
+ it "only returns models from that period" do
46
+ data.sum.should == 2
47
+ end
48
+ end
49
+
50
+ context "with weekly period" do
51
+ let(:period) { Periods::WEEK }
52
+
53
+ describe "#to_a" do
54
+ it "returns the one entry per period" do
55
+ [54, 53].should include(data.size)
56
+ end
57
+
58
+ it "only returns models from that period" do
59
+ data.sum.should == 2
60
+ end
61
+ end
62
+
63
+ context "with alternate start and end times" do
64
+ let(:start_time) { 2.weeks.ago }
65
+ let(:end_time) { start_time + 2.weeks }
66
+
67
+ describe "#to_a" do
68
+ it "returns the one entry per period" do
69
+ data.size.should == 4
70
+ end
71
+
72
+ it "only returns models from that period" do
73
+ data.sum.should == 1
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ context "sql fragment with nested WITH" do
81
+ let(:metric) do
82
+ Class.new(Metric) do
83
+ sql "WITH all_columns AS (SELECT * FROM users) SELECT name, created_at FROM users"
84
+ end.new
85
+ end
86
+
87
+ describe "#to_a" do
88
+ it "returns the one entry per period" do
89
+ data.size.should == expected_data_size
90
+ end
91
+
92
+ it "only returns models from that period" do
93
+ data.sum.should == 2
94
+ end
95
+ end
96
+ end
97
+
98
+ context "a metric with a sum aggregate" do
99
+ before do
100
+ User.create! value: 1
101
+ User.create! value: 3
102
+ end
103
+
104
+ context "a non sql metric" do
105
+ let(:metric) do
106
+ Class.new(Metric) do
107
+ scope { User }
108
+ aggregate { sum(:value) }
109
+ end.new
110
+ end
111
+
112
+ describe "#to_a" do
113
+ it "returns the one entry per period" do
114
+ data.size.should == expected_data_size
115
+ data[-2].should == User.all.sum(:value)
116
+ end
117
+ end
118
+ end
119
+
120
+ context "a sql metric" do
121
+ let(:metric) do
122
+ Class.new(Metric) do
123
+ sql "SELECT * FROM users"
124
+ aggregate { sum(:value) }
125
+ end.new
126
+ end
127
+
128
+ describe "#to_a" do
129
+ it "returns the one entry per period" do
130
+ data.size.should == expected_data_size
131
+ data[-2].should == User.all.sum(:value)
132
+ end
133
+ end
134
+ end
135
+
136
+ context "ruby block" do
137
+ let(:metric) do
138
+ Class.new(Metric) do
139
+ value_at do |time, period, *|
140
+ 10
141
+ end
142
+ end.new
143
+ end
144
+
145
+ describe "#to_a" do
146
+ it "delegates to the ruby block" do
147
+ data.should == [0] * expected_data_size
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe Extractors::Total do
5
+ it_behaves_like "an extractor"
6
+ let(:expected_data_size) { 14 }
7
+
8
+ let(:start_time) { 1.year.ago }
9
+ let(:end_time) { start_time + 12.months }
10
+ let(:period) { Periods::MONTH }
11
+
12
+ let(:data) { subject.to_a }
13
+ let(:metric) { UsersMetric.new }
14
+ let(:option) { 'default' }
15
+
16
+ subject { Extractors::Total.new(metric, option, start_time, end_time, period) }
17
+
18
+ before do
19
+ User.delete_all
20
+ [2.years.ago, 1.month.ago, 1.month.from_now].each do |time|
21
+ User.create created_at: time
22
+ end
23
+ end
24
+
25
+ context "simple scope" do
26
+ describe "#to_a" do
27
+ it "returns the one entry per period" do
28
+ data.size.should == expected_data_size
29
+ end
30
+
31
+ it "returns the counts at it increases" do
32
+ data[0].should == 1
33
+ data[-1].should == 2
34
+ end
35
+ end
36
+ end
37
+
38
+ context "simple sql fragment" do
39
+ let(:metric) { UsersSqlMetric.new }
40
+
41
+ describe "#to_a" do
42
+ it "returns the one entry per period" do
43
+ data.size.should == expected_data_size
44
+ end
45
+
46
+ it "returns the counts at it increases" do
47
+ data[0].should == 1
48
+ data[-1].should == 2
49
+ end
50
+ end
51
+ end
52
+
53
+ context "with an option" do
54
+ let(:option) { "no_results" }
55
+
56
+ describe "#to_a" do
57
+ it "only returns the results for that option block" do
58
+ data.all?(&:zero?).should be_true
59
+ end
60
+ end
61
+ end
62
+
63
+ context "ruby block" do
64
+ let(:metric) do
65
+ Class.new(Metric) do
66
+ value_at do |time, period, *|
67
+ 10
68
+ end
69
+ end.new
70
+ end
71
+
72
+ describe "#to_a" do
73
+ it "delegates to the ruby block" do
74
+ data.should == [10] * expected_data_size
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe Helpers::Time do
5
+
6
+ end
7
+ end
@@ -16,5 +16,12 @@ module Prosperity
16
16
  metrics.first.superclass.should == Metric
17
17
  end
18
18
  end
19
+
20
+ describe ".find_by_name" do
21
+ it "finds a metric by name" do
22
+ metric = described_class.find_by_name('UsersMetric')
23
+ metric.should be < Metric
24
+ end
25
+ end
19
26
  end
20
27
  end
@@ -16,6 +16,72 @@ module Prosperity
16
16
  it "gets the scope" do
17
17
  subject.scope.should == User
18
18
  end
19
+
20
+ it "should not be sql" do
21
+ subject.should_not be_sql
22
+ end
23
+
24
+ it "should have the default aggregate" do
25
+ subject.aggregate.should be_an(Aggregate::Count)
26
+ end
27
+ end
28
+
29
+ context "A raw sql metric" do
30
+ context "From a string" do
31
+ subject do
32
+ Class.new(Metric) do
33
+ sql "SELECT name, created_at FROM users"
34
+ end.new
35
+ end
36
+
37
+ it "groups by created_at by default" do
38
+ subject.group_by.should == :created_at
39
+ end
40
+
41
+ it "gets the scope" do
42
+ subject.sql.should == "SELECT name, created_at FROM users"
43
+ end
44
+
45
+ it "raises an exception when adding an option" do
46
+ expect {
47
+ subject.class.option "active" do |scope|
48
+ scope.active
49
+ end
50
+ }.to raise_exception(SqlMetricCannotHaveOption)
51
+ end
52
+
53
+ it "should be sql" do
54
+ subject.should be_sql
55
+ end
56
+ end
57
+
58
+ context "From a block" do
59
+ subject do
60
+ Class.new(Metric) do
61
+ sql { "SELECT name, created_at FROM users" }
62
+ end.new
63
+ end
64
+
65
+ it "groups by created_at by default" do
66
+ subject.group_by.should == :created_at
67
+ end
68
+
69
+ it "gets the scope" do
70
+ subject.sql.should == "SELECT name, created_at FROM users"
71
+ end
72
+
73
+ it "raises an exception when adding an option" do
74
+ expect {
75
+ subject.class.option "active" do |scope|
76
+ scope.active
77
+ end
78
+ }.to raise_exception(SqlMetricCannotHaveOption)
79
+ end
80
+
81
+ it "should be sql" do
82
+ subject.should be_sql
83
+ end
84
+ end
19
85
  end
20
86
 
21
87
  context "a metric missing the scope" do
@@ -29,11 +95,22 @@ module Prosperity
29
95
  end
30
96
  end
31
97
 
98
+ context "a metric missing the sql" do
99
+ subject do
100
+ Class.new(Metric) do
101
+ end
102
+ end
103
+
104
+ it "raises an exception when accessing the sql" do
105
+ expect { subject.sql }.to raise_exception(MissingSql)
106
+ end
107
+ end
108
+
32
109
  context "A simple scope metric with multiple options" do
33
110
  subject do
34
111
  Class.new(Metric) do
35
112
  scope { User }
36
- options "active" do |scope|
113
+ option "active" do |scope|
37
114
  scope.active
38
115
  end
39
116
  end.new
@@ -45,5 +122,53 @@ module Prosperity
45
122
  subject.options['active'].should be_present
46
123
  end
47
124
  end
125
+
126
+ context "A metric with a custom group by" do
127
+ subject do
128
+ Class.new(Metric) do
129
+ scope { User }
130
+ group_by "users.created_at"
131
+ end.new
132
+ end
133
+
134
+ its(:group_by) { should == 'users.created_at' }
135
+ end
136
+
137
+ context "A metric with a a sum aggregate" do
138
+ subject do
139
+ Class.new(Metric) do
140
+ scope { User }
141
+ aggregate { sum(:some_column) }
142
+ end.new
143
+ end
144
+
145
+ let(:aggregate) { subject.aggregate }
146
+
147
+ it "has the correct aggregate info" do
148
+ aggregate.should be_an(Aggregate::Sum)
149
+ aggregate.column.should == :some_column
150
+ end
151
+ end
152
+
153
+ context "a ruby code metric" do
154
+ subject do
155
+ Class.new(Metric) do
156
+ value_at do |time, period, option|
157
+ :expected
158
+ end
159
+ end.new
160
+ end
161
+
162
+ it "has the correct value_at info" do
163
+ subject.value_at.call.should == :expected
164
+ end
165
+
166
+ describe ".ruby?" do
167
+ it "should be true" do
168
+ subject.class.ruby?.should == true
169
+ subject.ruby?.should == true
170
+ end
171
+ end
172
+ end
48
173
  end
49
174
  end
@@ -2,6 +2,20 @@ require 'spec_helper'
2
2
 
3
3
  module Prosperity
4
4
  describe Periods do
5
+ subject { Periods::DAY }
5
6
 
7
+ describe "#each_period" do
8
+ it "iterates until the end time" do
9
+ times = []
10
+ start_time = DateTime.new(2012, 01, 01)
11
+ end_time = DateTime.new(2012, 01, 05)
12
+
13
+ subject.each_period(start_time, end_time) do |start_time|
14
+ times << start_time
15
+ end
16
+
17
+ times.should == Array.new(6) { |i| DateTime.new(2012, 01, i + 1) }
18
+ end
19
+ end
6
20
  end
7
21
  end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe DashboardGraph do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe Dashboard do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe GraphLine do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe Graph do
5
+ end
6
+ end
data/spec/spec_helper.rb CHANGED
@@ -5,10 +5,13 @@ require 'rspec/rails'
5
5
  require 'rspec/autorun'
6
6
  require 'pry-debugger'
7
7
 
8
- Dir[File.join(__dir__, "support/**/*.rb")].each {|f| require f }
9
- TEST_FILES = File.join(__dir__, "test_files")
8
+ PROSPERITY_ROOT = File.expand_path("..", __FILE__)
9
+
10
+ Dir[File.join(PROSPERITY_ROOT, "support/**/*.rb")].each {|f| require f }
11
+ TEST_FILES = File.join(PROSPERITY_ROOT, "test_files")
10
12
 
11
13
  RSpec.configure do |config|
14
+ config.render_views
12
15
  config.treat_symbols_as_metadata_keys_with_true_values = true
13
16
  config.run_all_when_everything_filtered = true
14
17
  config.filter_run :focus
@@ -0,0 +1,64 @@
1
+ shared_examples "an extractor" do
2
+ AGGREGATES = [:sum, :minimum, :maximum, :average]
3
+ let(:expected_data_size) { 14 }
4
+
5
+ ["sql", "normal"].each do |type|
6
+ AGGREGATES.each do |agg|
7
+ context "a #{type} metric with aggregate #{agg}" do
8
+ let(:metric) do
9
+ Class.new(Prosperity::Metric) do
10
+ if type == 'sql'
11
+ sql "SELECT * FROM users"
12
+ else
13
+ scope { User }
14
+ end
15
+ aggregate { send(agg, :value) }
16
+ end.new
17
+ end
18
+
19
+ describe "#to_a" do
20
+ let(:data) { subject.to_a }
21
+ it "returns the one entry per period" do
22
+ data.size.should == expected_data_size
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ context "a sql metric with default aggregat" do
29
+ let(:metric) do
30
+ Class.new(Prosperity::Metric) do
31
+ if type == 'sql'
32
+ sql "SELECT * FROM users"
33
+ else
34
+ scope { User }
35
+ end
36
+ end.new
37
+ end
38
+
39
+ describe "#to_a" do
40
+ let(:data) { subject.to_a }
41
+ it "returns the one entry per period" do
42
+ data.size.should == expected_data_size
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ context "a full SQL metric" do
49
+ let(:metric) do
50
+ Class.new(Prosperity::Metric) do
51
+ sql "SELECT * FROM users"
52
+ group_by "created_at"
53
+ aggregate { "SUM(value)" }
54
+ end.new
55
+ end
56
+
57
+ describe "#to_a" do
58
+ let(:data) { subject.to_a }
59
+ it "returns the one entry per period" do
60
+ data.size.should == expected_data_size
61
+ end
62
+ end
63
+ end
64
+ end
@@ -12,6 +12,7 @@ RSpec.configure do |config|
12
12
  m.create_table :users do |t|
13
13
  t.string :email
14
14
  t.string :name
15
+ t.integer :value
15
16
  t.timestamps
16
17
  end
17
18
  end