active_reporter 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +14 -0
  3. data/README.md +436 -0
  4. data/Rakefile +23 -0
  5. data/lib/active_reporter.rb +26 -0
  6. data/lib/active_reporter/aggregator.rb +9 -0
  7. data/lib/active_reporter/aggregator/array.rb +14 -0
  8. data/lib/active_reporter/aggregator/average.rb +9 -0
  9. data/lib/active_reporter/aggregator/base.rb +73 -0
  10. data/lib/active_reporter/aggregator/count.rb +23 -0
  11. data/lib/active_reporter/aggregator/count_if.rb +23 -0
  12. data/lib/active_reporter/aggregator/max.rb +9 -0
  13. data/lib/active_reporter/aggregator/min.rb +9 -0
  14. data/lib/active_reporter/aggregator/ratio.rb +23 -0
  15. data/lib/active_reporter/aggregator/sum.rb +13 -0
  16. data/lib/active_reporter/calculator.rb +2 -0
  17. data/lib/active_reporter/calculator/base.rb +19 -0
  18. data/lib/active_reporter/calculator/ratio.rb +9 -0
  19. data/lib/active_reporter/dimension.rb +8 -0
  20. data/lib/active_reporter/dimension/base.rb +150 -0
  21. data/lib/active_reporter/dimension/bin.rb +123 -0
  22. data/lib/active_reporter/dimension/bin/set.rb +162 -0
  23. data/lib/active_reporter/dimension/bin/table.rb +43 -0
  24. data/lib/active_reporter/dimension/category.rb +29 -0
  25. data/lib/active_reporter/dimension/enum.rb +32 -0
  26. data/lib/active_reporter/dimension/number.rb +51 -0
  27. data/lib/active_reporter/dimension/time.rb +93 -0
  28. data/lib/active_reporter/evaluator.rb +2 -0
  29. data/lib/active_reporter/evaluator/base.rb +17 -0
  30. data/lib/active_reporter/evaluator/block.rb +15 -0
  31. data/lib/active_reporter/inflector.rb +8 -0
  32. data/lib/active_reporter/invalid_params_error.rb +4 -0
  33. data/lib/active_reporter/report.rb +102 -0
  34. data/lib/active_reporter/report/aggregation.rb +297 -0
  35. data/lib/active_reporter/report/definition.rb +195 -0
  36. data/lib/active_reporter/report/metrics.rb +75 -0
  37. data/lib/active_reporter/report/validation.rb +106 -0
  38. data/lib/active_reporter/serializer.rb +7 -0
  39. data/lib/active_reporter/serializer/base.rb +103 -0
  40. data/lib/active_reporter/serializer/csv.rb +22 -0
  41. data/lib/active_reporter/serializer/form_field.rb +134 -0
  42. data/lib/active_reporter/serializer/hash_table.rb +12 -0
  43. data/lib/active_reporter/serializer/highcharts.rb +200 -0
  44. data/lib/active_reporter/serializer/nested_hash.rb +11 -0
  45. data/lib/active_reporter/serializer/table.rb +21 -0
  46. data/lib/active_reporter/tracker.rb +2 -0
  47. data/lib/active_reporter/tracker/base.rb +15 -0
  48. data/lib/active_reporter/tracker/delta.rb +9 -0
  49. data/lib/active_reporter/version.rb +3 -0
  50. data/lib/tasks/active_reporter_tasks.rake +4 -0
  51. data/spec/acceptance/data_spec.rb +381 -0
  52. data/spec/active_reporter/aggregator_spec.rb +102 -0
  53. data/spec/active_reporter/dimension/base_spec.rb +102 -0
  54. data/spec/active_reporter/dimension/bin/set_spec.rb +83 -0
  55. data/spec/active_reporter/dimension/bin/table_spec.rb +47 -0
  56. data/spec/active_reporter/dimension/bin_spec.rb +77 -0
  57. data/spec/active_reporter/dimension/category_spec.rb +60 -0
  58. data/spec/active_reporter/dimension/enum_spec.rb +94 -0
  59. data/spec/active_reporter/dimension/number_spec.rb +71 -0
  60. data/spec/active_reporter/dimension/time_spec.rb +61 -0
  61. data/spec/active_reporter/report_spec.rb +597 -0
  62. data/spec/active_reporter/serializer/hash_table_spec.rb +45 -0
  63. data/spec/active_reporter/serializer/highcharts_spec.rb +113 -0
  64. data/spec/active_reporter/serializer/table_spec.rb +62 -0
  65. data/spec/dummy/README.rdoc +28 -0
  66. data/spec/dummy/Rakefile +6 -0
  67. data/spec/dummy/app/assets/config/manifest.js +0 -0
  68. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  69. data/spec/dummy/app/assets/stylesheets/application.css +26 -0
  70. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  71. data/spec/dummy/app/controllers/site_controller.rb +11 -0
  72. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  73. data/spec/dummy/app/models/author.rb +4 -0
  74. data/spec/dummy/app/models/comment.rb +4 -0
  75. data/spec/dummy/app/models/data_builder.rb +112 -0
  76. data/spec/dummy/app/models/post.rb +6 -0
  77. data/spec/dummy/app/models/post_report.rb +14 -0
  78. data/spec/dummy/app/views/layouts/application.html.erb +17 -0
  79. data/spec/dummy/app/views/site/report.html.erb +73 -0
  80. data/spec/dummy/bin/bundle +3 -0
  81. data/spec/dummy/bin/rails +4 -0
  82. data/spec/dummy/bin/rake +4 -0
  83. data/spec/dummy/bin/setup +29 -0
  84. data/spec/dummy/config.ru +4 -0
  85. data/spec/dummy/config/application.rb +26 -0
  86. data/spec/dummy/config/boot.rb +5 -0
  87. data/spec/dummy/config/database.yml +22 -0
  88. data/spec/dummy/config/environment.rb +5 -0
  89. data/spec/dummy/config/environments/development.rb +41 -0
  90. data/spec/dummy/config/environments/production.rb +79 -0
  91. data/spec/dummy/config/environments/test.rb +42 -0
  92. data/spec/dummy/config/initializers/assets.rb +11 -0
  93. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  94. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  95. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  96. data/spec/dummy/config/initializers/inflections.rb +16 -0
  97. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  98. data/spec/dummy/config/initializers/session_store.rb +3 -0
  99. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  100. data/spec/dummy/config/locales/en.yml +23 -0
  101. data/spec/dummy/config/routes.rb +57 -0
  102. data/spec/dummy/config/secrets.yml +22 -0
  103. data/spec/dummy/db/migrate/20150714202319_add_dummy_models.rb +25 -0
  104. data/spec/dummy/db/schema.rb +43 -0
  105. data/spec/dummy/db/seeds.rb +1 -0
  106. data/spec/dummy/log/test.log +37033 -0
  107. data/spec/dummy/public/404.html +67 -0
  108. data/spec/dummy/public/422.html +67 -0
  109. data/spec/dummy/public/500.html +66 -0
  110. data/spec/dummy/public/favicon.ico +0 -0
  111. data/spec/factories/factories.rb +29 -0
  112. data/spec/spec_helper.rb +40 -0
  113. data/spec/support/float.rb +8 -0
  114. metadata +385 -0
@@ -0,0 +1,381 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'more complicated case' do
4
+ let(:report_model) do
5
+ Class.new(ActiveReporter::Report) do
6
+ report_on :Post
7
+
8
+ time_dimension :published_at
9
+ number_dimension :likes
10
+ category_dimension :author, model: :author, attribute: :name, relation: ->(r) { r.left_outer_joins(:author) }
11
+
12
+ count_aggregator :count
13
+ sum_aggregator :total_likes, attribute: :likes
14
+ average_aggregator :mean_likes, attribute: :likes
15
+ min_aggregator :min_likes, attribute: :likes
16
+ max_aggregator :max_likes, attribute: :likes
17
+ end
18
+ end
19
+
20
+ def data_by(groupers, g_params = nil)
21
+ groupers = Array.wrap(groupers)
22
+ dimension_params = {}
23
+ if g_params
24
+ g_params = Array.wrap(g_params)
25
+ groupers.zip(g_params).each do |grouper, params|
26
+ dimension_params[grouper] = params
27
+ end
28
+ end
29
+
30
+ report = report_model.new(groupers: groupers, dimensions: dimension_params)
31
+ report.data
32
+ end
33
+
34
+ def expect_equal(h1, h2)
35
+ # sqlite uses Float instead of BigDecimal, we need to normalize the JSON objects to use the
36
+ # same data type so the values match. We also round these at 9 decimal places to account for
37
+ # rounding discrepencies between the two data types
38
+
39
+ h1_json = JSON.parse(h1.to_json).map do |a|
40
+ a.deep_transform_values do |v|
41
+ case v
42
+ when String
43
+ BigDecimal(v).round(9) rescue v
44
+ else
45
+ v
46
+ end
47
+ end
48
+ end
49
+
50
+ h2_json = JSON.parse(h2.to_json).map do |a|
51
+ a.deep_transform_values do |v|
52
+ case v
53
+ when String
54
+ BigDecimal(v).round(9) rescue v
55
+ else
56
+ v
57
+ end
58
+ end
59
+ end
60
+
61
+ expect(h1_json).to eq h2_json
62
+ end
63
+
64
+ let(:joyce) { create(:author, name: 'James Joyce') }
65
+ let(:woolf) { create(:author, name: 'Virginia Woolf') }
66
+
67
+ let(:oct_1) { Time.zone.parse('2015-10-01') }
68
+ let(:nov_1) { Time.zone.parse('2015-11-01') }
69
+ let(:dec_1) { Time.zone.parse('2015-12-01') }
70
+
71
+ let(:oct) { { min: oct_1, max: nov_1 } }
72
+ let(:nov) { { min: nov_1, max: dec_1 } }
73
+
74
+ let!(:post_1) { create(:post, author: joyce.name, published_at: oct_1, likes: 1) }
75
+ let!(:post_2) { create(:post, author: joyce.name, published_at: oct_1, likes: 2) }
76
+ let!(:post_3) { create(:post, author: joyce.name, published_at: nov_1, likes: 1) }
77
+ let!(:post_4) { create(:post, author: joyce.name, likes: 3).tap { |p| p.update!(published_at: nil) } }
78
+
79
+ let!(:post_5) { create(:post, author: woolf.name, published_at: oct_1, likes: 2) }
80
+ let!(:post_6) { create(:post, author: woolf.name, published_at: nov_1, likes: 3) }
81
+ let!(:post_7) { create(:post, author: woolf.name, likes: 3).tap { |p| p.update!(published_at: nil) } }
82
+
83
+ let!(:post_8) { create(:post, author: nil, published_at: oct_1, likes: 2) }
84
+ let!(:post_9) { create(:post, author: nil, published_at: nov_1, likes: 3) }
85
+
86
+ specify 'basic grouping, 1 grouper, no filters' do
87
+ expect_equal data_by(:author), [
88
+ { key: nil, values: [
89
+ { key: :count, value: 2 },
90
+ { key: :total_likes, value: 5 },
91
+ { key: :mean_likes, value: '2.5' },
92
+ { key: :min_likes, value: 2 },
93
+ { key: :max_likes, value: 3 }
94
+ ] },
95
+ { key: joyce.name, values: [
96
+ { key: :count, value: 4 },
97
+ { key: :total_likes, value: 7 },
98
+ { key: :mean_likes, value: '1.75' },
99
+ { key: :min_likes, value: 1 },
100
+ { key: :max_likes, value: 3 }
101
+ ] },
102
+ { key: woolf.name, values: [
103
+ { key: :count, value: 3 },
104
+ { key: :total_likes, value: 8 },
105
+ { key: :mean_likes, value: '2.6666666666666667' },
106
+ { key: :min_likes, value: 2 },
107
+ { key: :max_likes, value: 3 }
108
+ ] }
109
+ ]
110
+
111
+ expect_equal data_by(:published_at, bin_width: '1 month'), [
112
+ { key: nil, values: [
113
+ { key: :count, value: 2 },
114
+ { key: :total_likes, value: 6 },
115
+ { key: :mean_likes, value: '3.0' },
116
+ { key: :min_likes, value: 3 },
117
+ { key: :max_likes, value: 3 }
118
+ ] },
119
+ { key: oct, values: [
120
+ { key: :count, value: 4 },
121
+ { key: :total_likes, value: 7 },
122
+ { key: :mean_likes, value: '1.75' },
123
+ { key: :min_likes, value: 1 },
124
+ { key: :max_likes, value: 2 }
125
+ ] },
126
+ { key: nov, values: [
127
+ { key: :count, value: 3 },
128
+ { key: :total_likes, value: 7 },
129
+ { key: :mean_likes, value: '2.3333333333333333' },
130
+ { key: :min_likes, value: 1 },
131
+ { key: :max_likes, value: 3 }
132
+ ] }
133
+ ]
134
+
135
+ expect_equal data_by(:likes, bin_width: 1), [
136
+ { key: { min: 1, max: 2 }, values: [
137
+ { key: :count, value: 2 },
138
+ { key: :total_likes, value: 2 },
139
+ { key: :mean_likes, value: '1.0' },
140
+ { key: :min_likes, value: 1 },
141
+ { key: :max_likes, value: 1 }
142
+ ] },
143
+ { key: { min: 2, max: 3 }, values: [
144
+ { key: :count, value: 3 },
145
+ { key: :total_likes, value: 6 },
146
+ { key: :mean_likes, value: '2.0' },
147
+ { key: :min_likes, value: 2 },
148
+ { key: :max_likes, value: 2 }
149
+ ] },
150
+ { key: { min: 3, max: 4 }, values: [
151
+ { key: :count, value: 4 },
152
+ { key: :total_likes, value: 12 },
153
+ { key: :mean_likes, value: '3.0' },
154
+ { key: :min_likes, value: 3 },
155
+ { key: :max_likes, value: 3 }
156
+ ] }
157
+ ]
158
+ end
159
+
160
+ specify 'basic grouping, >=2 groupers, no filters' do
161
+ expect_equal data_by([:published_at, :author], bin_width: { months: 1 }), [
162
+ { key: nil, values: [
163
+ { key: nil, values: [
164
+ { key: :count, value: 0 },
165
+ { key: :total_likes, value: 0 },
166
+ { key: :mean_likes, value: nil },
167
+ { key: :min_likes, value: nil },
168
+ { key: :max_likes, value: nil }
169
+ ] },
170
+ { key: oct, values: [
171
+ { key: :count, value: 1 },
172
+ { key: :total_likes, value: 2 },
173
+ { key: :mean_likes, value: '2.0' },
174
+ { key: :min_likes, value: 2 },
175
+ { key: :max_likes, value: 2 }
176
+ ] },
177
+ { key: nov, values: [
178
+ { key: :count, value: 1 },
179
+ { key: :total_likes, value: 3 },
180
+ { key: :mean_likes, value: '3.0' },
181
+ { key: :min_likes, value: 3 },
182
+ { key: :max_likes, value: 3 }
183
+ ] }
184
+ ] },
185
+ { key: joyce.name, values: [
186
+ { key: nil, values: [
187
+ { key: :count, value: 1 },
188
+ { key: :total_likes, value: 3 },
189
+ { key: :mean_likes, value: '3.0' },
190
+ { key: :min_likes, value: 3 },
191
+ { key: :max_likes, value: 3 }
192
+ ] },
193
+ { key: oct, values: [
194
+ { key: :count, value: 2 },
195
+ { key: :total_likes, value: 3 },
196
+ { key: :mean_likes, value: '1.5' },
197
+ { key: :min_likes, value: 1 },
198
+ { key: :max_likes, value: 2 }
199
+ ] },
200
+ { key: nov, values: [
201
+ { key: :count, value: 1 },
202
+ { key: :total_likes, value: 1 },
203
+ { key: :mean_likes, value: '1.0' },
204
+ { key: :min_likes, value: 1 },
205
+ { key: :max_likes, value: 1 }
206
+ ] }
207
+ ] },
208
+ { key: woolf.name, values: [
209
+ { key: nil, values: [
210
+ { key: :count, value: 1 },
211
+ { key: :total_likes, value: 3 },
212
+ { key: :mean_likes, value: '3.0' },
213
+ { key: :min_likes, value: 3 },
214
+ { key: :max_likes, value: 3 }
215
+ ] },
216
+ { key: oct, values: [
217
+ { key: :count, value: 1 },
218
+ { key: :total_likes, value: 2 },
219
+ { key: :mean_likes, value: '2.0' },
220
+ { key: :min_likes, value: 2 },
221
+ { key: :max_likes, value: 2 }
222
+ ] },
223
+ { key: nov, values: [
224
+ { key: :count, value: 1 },
225
+ { key: :total_likes, value: 3 },
226
+ { key: :mean_likes, value: '3.0' },
227
+ { key: :min_likes, value: 3 },
228
+ { key: :max_likes, value: 3 }
229
+ ] }
230
+ ] }
231
+ ]
232
+ end
233
+
234
+ specify 'sorting with nulls (1 grouper)' do
235
+ expect_equal data_by(:author, sort_desc: true), [
236
+ { key: woolf.name, values: [
237
+ { key: :count, value: 3 },
238
+ { key: :total_likes, value: 8 },
239
+ { key: :mean_likes, value: '2.6666666666666667' },
240
+ { key: :min_likes, value: 2 },
241
+ { key: :max_likes, value: 3 }
242
+ ] },
243
+ { key: joyce.name, values: [
244
+ { key: :count, value: 4 },
245
+ { key: :total_likes, value: 7 },
246
+ { key: :mean_likes, value: '1.75' },
247
+ { key: :min_likes, value: 1 },
248
+ { key: :max_likes, value: 3 }
249
+ ] },
250
+ { key: nil, values: [
251
+ {key: :count, value: 2 },
252
+ {key: :total_likes, value: 5 },
253
+ {key: :mean_likes, value: '2.5' },
254
+ {key: :min_likes, value: 2 },
255
+ {key: :max_likes, value: 3 }
256
+ ] }
257
+ ]
258
+
259
+ expect_equal data_by(:published_at, bin_width: '1 month', sort_desc: true), [
260
+ { key: nov, values: [
261
+ { key: :count, value: 3 },
262
+ { key: :total_likes, value: 7 },
263
+ { key: :mean_likes, value: '2.3333333333333333' },
264
+ { key: :min_likes, value: 1 },
265
+ { key: :max_likes, value: 3 }
266
+ ] },
267
+ { key: oct, values: [
268
+ { key: :count, value: 4 },
269
+ { key: :total_likes, value: 7 },
270
+ { key: :mean_likes, value: '1.75' },
271
+ { key: :min_likes, value: 1 },
272
+ { key: :max_likes, value: 2 }
273
+ ] },
274
+ { key: nil, values: [
275
+ { key: :count, value: 2 },
276
+ { key: :total_likes, value: 6 },
277
+ { key: :mean_likes, value: '3.0' },
278
+ { key: :min_likes, value: 3 },
279
+ { key: :max_likes, value: 3 }
280
+ ] }
281
+ ]
282
+
283
+ if ActiveReporter.database_type == :postgres
284
+ expect_equal data_by(:author, nulls_last: true), [
285
+ { key: joyce.name, values: [
286
+ { key: :count, value: 4 },
287
+ { key: :total_likes, value: 7 },
288
+ { key: :mean_likes, value: '1.75' },
289
+ { key: :min_likes, value: 1 },
290
+ { key: :max_likes, value: 3 }
291
+ ] },
292
+ { key: woolf.name, values: [
293
+ { key: :count, value: 3 },
294
+ { key: :total_likes, value: 8 },
295
+ { key: :mean_likes, value: '2.6666666666666667' },
296
+ { key: :min_likes, value: 2 },
297
+ { key: :max_likes, value: 3 }
298
+ ] },
299
+ { key: nil, values: [
300
+ { key: :count, value: 2 },
301
+ { key: :total_likes, value: 5 },
302
+ { key: :mean_likes, value: '2.5' },
303
+ { key: :min_likes, value: 2 },
304
+ { key: :max_likes, value: 3 }
305
+ ] }
306
+ ]
307
+
308
+ expect_equal data_by(:author, sort_desc: true, nulls_last: true), [
309
+ { key: nil, values: [
310
+ { key: :count, value: 2 },
311
+ { key: :total_likes, value: 5 },
312
+ { key: :mean_likes, value: '2.5' },
313
+ { key: :min_likes, value: 2 },
314
+ { key: :max_likes, value: 3 }
315
+ ] },
316
+ { key: woolf.name, values: [
317
+ { key: :count, value: 3 },
318
+ { key: :total_likes, value: 8 },
319
+ { key: :mean_likes, value: '2.6666666666666667' },
320
+ { key: :min_likes, value: 2 },
321
+ { key: :max_likes, value: 3 }
322
+ ] },
323
+ { key: joyce.name, values: [
324
+ { key: :count, value: 4 },
325
+ { key: :total_likes, value: 7 },
326
+ { key: :mean_likes, value: '1.75' },
327
+ { key: :min_likes, value: 1 },
328
+ { key: :max_likes, value: 3 }
329
+ ] }
330
+ ]
331
+
332
+ expect_equal data_by(:published_at, bin_width: '1 month', nulls_last: true), [
333
+ { key: oct, values: [
334
+ { key: :count, value: 4 },
335
+ { key: :total_likes, value: 7 },
336
+ { key: :mean_likes, value: '1.75' },
337
+ { key: :min_likes, value: 1 },
338
+ { key: :max_likes, value: 2 }
339
+ ] },
340
+ { key: nov, values: [
341
+ { key: :count, value: 3 },
342
+ { key: :total_likes, value: 7 },
343
+ { key: :mean_likes, value: '2.3333333333333333' },
344
+ { key: :min_likes, value: 1 },
345
+ { key: :max_likes, value: 3 }
346
+ ] },
347
+ { key: nil, values: [
348
+ { key: :count, value: 2 },
349
+ { key: :total_likes, value: 6 },
350
+ { key: :mean_likes, value: '3.0' },
351
+ { key: :min_likes, value: 3 },
352
+ { key: :max_likes, value: 3 }
353
+ ] }
354
+ ]
355
+
356
+ expect_equal data_by(:published_at, bin_width: '1 month', sort_desc: true, nulls_last: true), [
357
+ { key: nil, values: [
358
+ { key: :count, value: 2 },
359
+ { key: :total_likes, value: 6 },
360
+ { key: :mean_likes, value: '3.0' },
361
+ { key: :min_likes, value: 3 },
362
+ { key: :max_likes, value: 3 }
363
+ ] },
364
+ { key: nov, values: [
365
+ { key: :count, value: 3 },
366
+ { key: :total_likes, value: 7 },
367
+ { key: :mean_likes, value: '2.3333333333333333' },
368
+ { key: :min_likes, value: 1 },
369
+ { key: :max_likes, value: 3 }
370
+ ] },
371
+ { key: oct, values: [
372
+ { key: :count, value: 4 },
373
+ { key: :total_likes, value: 7 },
374
+ { key: :mean_likes, value: '1.75' },
375
+ { key: :min_likes, value: 1 },
376
+ { key: :max_likes, value: 2 }
377
+ ] }
378
+ ]
379
+ end
380
+ end
381
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveReporter::Aggregator do
4
+ let(:report_model) do
5
+ Class.new(ActiveReporter::Report) do
6
+ report_on :Post
7
+ category_dimension :author, model: :author, attribute: :name, relation: ->(r) { r.left_outer_joins(:author) }
8
+ enum_dimension :status, attribute: :status
9
+ count_aggregator :count
10
+ sum_aggregator :total_likes, attribute: :likes
11
+ average_aggregator :mean_likes, attribute: :likes
12
+ min_aggregator :min_likes, attribute: :likes
13
+ max_aggregator :max_likes, attribute: :likes
14
+ array_aggregator :post_ids, attribute: :id
15
+ end
16
+ end
17
+
18
+ let(:report) { report_model.new(aggregators: aggregators, groupers: [:author, :status]) }
19
+
20
+ let!(:post_1) { create(:post, likes: 3, author: 'Alice') }
21
+ let!(:post_2) { create(:post, likes: 2, author: 'Alice') }
22
+ let!(:post_3) { create(:post, likes: 4, author: 'Bob') }
23
+ let!(:post_4) { create(:post, likes: 1, author: 'Bob') }
24
+ let!(:post_5) { create(:post, likes: 5, author: 'Bob') }
25
+ let!(:post_6) { create(:post, likes: 10, author: 'Chester') }
26
+
27
+ context 'aggregating post_ids' do
28
+ let(:aggregators) { :post_ids }
29
+
30
+ it 'should return post_ids values' do
31
+ if ActiveReporter.database_type == :postgres
32
+ expect(report.raw_data).to eq({
33
+ ['Alice', 'published', 'post_ids'] => [post_1.id, post_2.id],
34
+ ['Bob', 'published', 'post_ids'] => [post_3.id, post_4.id, post_5.id],
35
+ ['Chester', 'published', 'post_ids'] => [post_6.id],
36
+ })
37
+ else
38
+ expect { report.raw_data }.to raise_error(ActiveReporter::InvalidParamsError)
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'aggregating max_likes' do
44
+ let(:aggregators) { :max_likes }
45
+
46
+ it 'should return max_likes values' do
47
+ expect(report.raw_data).to eq({
48
+ ['Alice', 'published', 'max_likes'] => 3,
49
+ ['Bob', 'published', 'max_likes'] => 5,
50
+ ['Chester', 'published', 'max_likes'] => 10,
51
+ })
52
+ end
53
+ end
54
+
55
+ context 'aggregating min_likes' do
56
+ let(:aggregators) { :min_likes }
57
+
58
+ it 'should return min_likes values' do
59
+ expect(report.raw_data).to eq({
60
+ ['Alice', 'published', 'min_likes'] => 2,
61
+ ['Bob', 'published', 'min_likes'] => 1,
62
+ ['Chester', 'published', 'min_likes'] => 10
63
+ })
64
+ end
65
+ end
66
+
67
+ context 'aggregating mean_likes' do
68
+ let(:aggregators) { :mean_likes }
69
+
70
+ it 'should return mean_likes values' do
71
+ expect(report.raw_data.collect{ |k,v| [k, v.round(2)] }.to_h).to eq({
72
+ ['Alice', 'published', 'mean_likes'] => 2.50,
73
+ ['Bob', 'published', 'mean_likes'] => 3.33,
74
+ ['Chester', 'published', 'mean_likes'] => 10.00,
75
+ })
76
+ end
77
+ end
78
+
79
+ context 'aggregating total_likes' do
80
+ let(:aggregators) { :total_likes }
81
+
82
+ it 'should return total_likes values' do
83
+ expect(report.raw_data).to eq({
84
+ ['Alice', 'published', 'total_likes'] => 5,
85
+ ['Bob', 'published', 'total_likes'] => 10,
86
+ ['Chester', 'published', 'total_likes'] => 10
87
+ })
88
+ end
89
+ end
90
+
91
+ context 'aggregating count' do
92
+ let(:aggregators) { :count }
93
+
94
+ it 'should return count values' do
95
+ expect(report.raw_data).to eq({
96
+ ['Alice', 'published', 'count'] => 2,
97
+ ['Bob', 'published', 'count'] => 3,
98
+ ['Chester', 'published', 'count'] => 1
99
+ })
100
+ end
101
+ end
102
+ end