reports_kit 0.2.0 → 0.3.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.travis.yml +20 -0
  4. data/README.md +17 -19
  5. data/app/assets/javascripts/reports_kit/lib/_init.js +2 -1
  6. data/app/assets/javascripts/reports_kit/lib/chart.js +25 -16
  7. data/app/assets/javascripts/reports_kit/lib/report.js +42 -25
  8. data/app/assets/javascripts/reports_kit/lib/table.js +37 -2
  9. data/app/assets/stylesheets/reports_kit/reports.css.sass +3 -0
  10. data/docs/dimensions.md +26 -34
  11. data/docs/display_options.md +12 -15
  12. data/docs/filters.md +54 -63
  13. data/docs/measures.md +3 -4
  14. data/lib/reports_kit.rb +12 -10
  15. data/lib/reports_kit/base_controller.rb +1 -2
  16. data/lib/reports_kit/configuration.rb +19 -4
  17. data/lib/reports_kit/entity.rb +3 -0
  18. data/lib/reports_kit/helper.rb +17 -21
  19. data/lib/reports_kit/model_configuration.rb +1 -1
  20. data/lib/reports_kit/report_builder.rb +11 -11
  21. data/lib/reports_kit/reports/{abstract_measure.rb → abstract_series.rb} +1 -1
  22. data/lib/reports_kit/reports/{composite_measure.rb → composite_series.rb} +12 -8
  23. data/lib/reports_kit/reports/data/add_table_aggregations.rb +105 -0
  24. data/lib/reports_kit/reports/data/{composite_aggregation.rb → aggregate_composite.rb} +28 -27
  25. data/lib/reports_kit/reports/data/{one_dimension.rb → aggregate_one_dimension.rb} +9 -7
  26. data/lib/reports_kit/reports/data/{two_dimensions.rb → aggregate_two_dimensions.rb} +9 -8
  27. data/lib/reports_kit/reports/data/chart_options.rb +6 -11
  28. data/lib/reports_kit/reports/data/format_one_dimension.rb +56 -36
  29. data/lib/reports_kit/reports/data/format_table.rb +65 -0
  30. data/lib/reports_kit/reports/data/format_two_dimensions.rb +10 -8
  31. data/lib/reports_kit/reports/data/generate.rb +51 -28
  32. data/lib/reports_kit/reports/data/generate_for_properties.rb +52 -30
  33. data/lib/reports_kit/reports/data/populate_one_dimension.rb +30 -12
  34. data/lib/reports_kit/reports/data/populate_two_dimensions.rb +31 -31
  35. data/lib/reports_kit/reports/data/utils.rb +28 -24
  36. data/lib/reports_kit/reports/dimension.rb +4 -0
  37. data/lib/reports_kit/reports/{dimension_with_measure.rb → dimension_with_series.rb} +8 -9
  38. data/lib/reports_kit/reports/filter.rb +4 -0
  39. data/lib/reports_kit/reports/filter_types/base.rb +4 -3
  40. data/lib/reports_kit/reports/filter_types/boolean.rb +4 -4
  41. data/lib/reports_kit/reports/filter_types/datetime.rb +13 -3
  42. data/lib/reports_kit/reports/filter_types/number.rb +5 -5
  43. data/lib/reports_kit/reports/{filter_with_measure.rb → filter_with_series.rb} +7 -7
  44. data/lib/reports_kit/reports/generate_autocomplete_results.rb +2 -2
  45. data/lib/reports_kit/reports/inferrable_configuration.rb +6 -6
  46. data/lib/reports_kit/reports/{measure.rb → series.rb} +28 -15
  47. data/lib/reports_kit/reports_controller.rb +25 -5
  48. data/lib/reports_kit/value.rb +3 -0
  49. data/lib/reports_kit/version.rb +1 -1
  50. data/spec/fixtures/generate_inputs.yml +116 -63
  51. data/spec/fixtures/generate_outputs.yml +64 -0
  52. data/spec/reports_kit/report_builder_spec.rb +10 -12
  53. data/spec/reports_kit/reports/data/generate_spec.rb +559 -140
  54. data/spec/reports_kit/reports/{dimension_with_measure_spec.rb → dimension_with_series_spec.rb} +5 -7
  55. data/spec/reports_kit/reports/{filter_with_measure_spec.rb → filter_with_series_spec.rb} +3 -3
  56. data/spec/spec_helper.rb +5 -5
  57. data/spec/support/config.rb +31 -1
  58. data/spec/support/helpers.rb +6 -2
  59. metadata +17 -14
  60. data/lib/reports_kit/reports/data/entity.rb +0 -7
  61. data/lib/reports_kit/reports/data/value.rb +0 -7
@@ -400,6 +400,70 @@
400
400
  - - foo/bar2
401
401
  - 0
402
402
  - 2
403
+ - :type: table
404
+ :report_options:
405
+ :aggregations:
406
+ - :from: columns
407
+ :operator: sum
408
+ :label: Total
409
+ :table_data:
410
+ - -
411
+ - Repo Issues
412
+ - Labels
413
+ - - foo/bar1
414
+ - 2
415
+ - 1
416
+ - - foo/bar2
417
+ - 0
418
+ - 2
419
+ - - Total
420
+ - 2
421
+ - 3
422
+ - :type: table
423
+ :report_options:
424
+ :aggregations:
425
+ - :from: rows
426
+ :operator: sum
427
+ :label: Total
428
+ :table_data:
429
+ - -
430
+ - Repo Issues
431
+ - Labels
432
+ - Total
433
+ - - foo/bar1
434
+ - 2
435
+ - 1
436
+ - 3
437
+ - - foo/bar2
438
+ - 0
439
+ - 2
440
+ - 2
441
+ - :type: table
442
+ :report_options:
443
+ :aggregations:
444
+ - :from: columns
445
+ :operator: sum
446
+ :label: Total
447
+ - :from: rows
448
+ :operator: sum
449
+ :label: Total
450
+ :table_data:
451
+ - -
452
+ - Repo Issues
453
+ - Labels
454
+ - Total
455
+ - - foo/bar1
456
+ - 2
457
+ - 1
458
+ - 3
459
+ - - foo/bar2
460
+ - 0
461
+ - 2
462
+ - 2
463
+ - - Total
464
+ - 2
465
+ - 3
466
+ - 5
403
467
  - :chart_data:
404
468
  :labels:
405
469
  - foo/bar1
@@ -6,23 +6,21 @@ describe ReportsKit::ReportBuilder do
6
6
  context 'with a datetime dimension' do
7
7
  let(:properties) do
8
8
  {
9
- measure: {
10
- key: 'issue',
11
- filters: [
12
- {
13
- key: 'opened_at',
14
- criteria: {
15
- operator: 'between',
16
- value: '-1w - now'
17
- }
9
+ measure: 'issue',
10
+ filters: [
11
+ {
12
+ key: 'opened_at',
13
+ criteria: {
14
+ operator: 'between',
15
+ value: '-1w - now'
18
16
  }
19
- ]
20
- }
17
+ }
18
+ ]
21
19
  }
22
20
  end
23
21
 
24
22
  it 'transforms the filter criteria' do
25
- expect(subject.date_range('opened_at')).to include("#{format_criteria_time(1.week.ago)} - #{format_criteria_time(Time.zone.now)}")
23
+ expect(subject.date_range('opened_at')).to include("#{format_configuration_time(1.week.ago)} - #{format_configuration_time(Time.zone.now)}")
26
24
  end
27
25
  end
28
26
  end
@@ -24,10 +24,8 @@ describe ReportsKit::Reports::Data::Generate do
24
24
  context 'with default granularity' do
25
25
  let(:properties) do
26
26
  {
27
- measure: {
28
- key: 'issue',
29
- dimensions: %w(opened_at)
30
- }
27
+ measure: 'issue',
28
+ dimensions: %w(opened_at)
31
29
  }
32
30
  end
33
31
  let!(:issues) do
@@ -58,22 +56,20 @@ describe ReportsKit::Reports::Data::Generate do
58
56
  })
59
57
  end
60
58
 
61
- context 'with a datetime filter' do
59
+ context 'with an absolute datetime filter' do
62
60
  let(:properties) do
63
61
  {
64
- measure: {
65
- key: 'issue',
66
- filters: [
67
- {
68
- key: 'opened_at',
69
- criteria: {
70
- operator: 'between',
71
- value: "#{format_criteria_time(now - 1.week)} - #{format_criteria_time(now)}"
72
- }
62
+ measure: 'issue',
63
+ filters: [
64
+ {
65
+ key: 'opened_at',
66
+ criteria: {
67
+ operator: 'between',
68
+ value: "#{format_configuration_time(now - 1.week)} - #{format_configuration_time(now)}"
73
69
  }
74
- ],
75
- dimensions: %w(opened_at)
76
- }
70
+ }
71
+ ],
72
+ dimensions: %w(opened_at)
77
73
  }
78
74
  end
79
75
 
@@ -82,29 +78,57 @@ describe ReportsKit::Reports::Data::Generate do
82
78
  labels: [format_week_offset(1), format_week_offset(0)],
83
79
  datasets: [
84
80
  {
85
- label: "Issues",
81
+ label: 'Issues',
86
82
  data: [0, 1]
87
83
  }
88
84
  ]
89
85
  })
90
86
  end
91
87
 
88
+ context 'with a old end date' do
89
+ let(:properties) do
90
+ {
91
+ measure: 'issue',
92
+ filters: [
93
+ {
94
+ key: 'opened_at',
95
+ criteria: {
96
+ operator: 'between',
97
+ value: "#{format_configuration_time(now - 2.weeks)} - #{format_configuration_time(now - 1.week)}"
98
+ }
99
+ }
100
+ ],
101
+ dimensions: %w(opened_at)
102
+ }
103
+ end
104
+
105
+ it 'returns the chart_data' do
106
+ expect(chart_data).to eq({
107
+ labels: [format_week_offset(2), format_week_offset(1)],
108
+ datasets: [
109
+ {
110
+ label: 'Issues',
111
+ data: [2, 0]
112
+ }
113
+ ]
114
+ })
115
+ end
116
+ end
117
+
92
118
  context 'with zero results' do
93
119
  let(:properties) do
94
120
  {
95
- measure: {
96
- key: 'tag',
97
- filters: [
98
- {
99
- key: 'created_at',
100
- criteria: {
101
- operator: 'between',
102
- value: "#{format_criteria_time(now - 1.week)} - #{format_criteria_time(now)}"
103
- }
121
+ measure: 'tag',
122
+ filters: [
123
+ {
124
+ key: 'created_at',
125
+ criteria: {
126
+ operator: 'between',
127
+ value: "#{format_configuration_time(now - 1.week)} - #{format_configuration_time(now)}"
104
128
  }
105
- ],
106
- dimensions: %w(created_at)
107
- }
129
+ }
130
+ ],
131
+ dimensions: %w(created_at)
108
132
  }
109
133
  end
110
134
 
@@ -124,7 +148,7 @@ describe ReportsKit::Reports::Data::Generate do
124
148
  end
125
149
  end
126
150
 
127
- context 'with multiple measures and datetime filters with different keys' do
151
+ context 'with multiple series and datetime filters with different keys' do
128
152
  let!(:tags) do
129
153
  [
130
154
  create(:tag, repo: repo, created_at: now - 1.weeks),
@@ -133,20 +157,20 @@ describe ReportsKit::Reports::Data::Generate do
133
157
  end
134
158
  let(:properties) do
135
159
  {
136
- measures: [
160
+ series: [
137
161
  {
138
- key: 'issue',
162
+ measure: 'issue',
139
163
  filters: %w(opened_at),
140
164
  dimensions: %w(opened_at)
141
165
  },
142
166
  {
143
- key: 'tag',
167
+ measure: 'tag',
144
168
  filters: %w(created_at),
145
169
  dimensions: %w(created_at)
146
170
  }
147
171
  ],
148
172
  ui_filters: {
149
- created_at: "#{format_criteria_time(now - 1.week)} - #{format_criteria_time(now)}"
173
+ created_at: "#{format_configuration_time(now - 1.week)} - #{format_configuration_time(now)}"
150
174
  }
151
175
  }
152
176
  end
@@ -156,11 +180,11 @@ describe ReportsKit::Reports::Data::Generate do
156
180
  labels: [format_week_offset(2), format_week_offset(1), format_week_offset(0)],
157
181
  datasets: [
158
182
  {
159
- label: "Issues",
183
+ label: 'Issues',
160
184
  data: [2, 0, 1]
161
185
  },
162
186
  {
163
- label: "Tags",
187
+ label: 'Tags',
164
188
  data: [0, 1, 1]
165
189
  }
166
190
  ]
@@ -168,15 +192,63 @@ describe ReportsKit::Reports::Data::Generate do
168
192
  end
169
193
  end
170
194
  end
195
+
196
+ context 'with a relative datetime filter' do
197
+ let(:properties) do
198
+ {
199
+ measure: 'issue',
200
+ filters: [
201
+ {
202
+ key: 'opened_at',
203
+ criteria: {
204
+ operator: 'between',
205
+ value: '-1w - now'
206
+ }
207
+ }
208
+ ],
209
+ dimensions: %w(opened_at)
210
+ }
211
+ end
212
+
213
+ it 'returns the chart_data' do
214
+ expect(chart_data).to eq({
215
+ labels: [format_week_offset(1), format_week_offset(0)],
216
+ datasets: [
217
+ {
218
+ label: 'Issues',
219
+ data: [0, 1]
220
+ }
221
+ ]
222
+ })
223
+ end
224
+
225
+ context 'when a record\'s timestamp is closer to the beginning of the week than the current date' do
226
+ let!(:issues) do
227
+ [
228
+ create(:issue, repo: repo, opened_at: Date.parse('2009-12-22'))
229
+ ]
230
+ end
231
+
232
+ it 'includes record' do
233
+ expect(chart_data).to eq({
234
+ labels: [format_week_offset(1), format_week_offset(0)],
235
+ datasets: [
236
+ {
237
+ label: 'Issues',
238
+ data: [1, 0]
239
+ }
240
+ ]
241
+ })
242
+ end
243
+ end
244
+ end
171
245
  end
172
246
 
173
247
  context 'with day granularity' do
174
248
  let(:properties) do
175
249
  {
176
- measure: {
177
- key: 'issue',
178
- dimensions: [{ key: 'opened_at', granularity: 'day' }]
179
- }
250
+ measure: 'issue',
251
+ dimensions: [{ key: 'opened_at', granularity: 'day' }]
180
252
  }
181
253
  end
182
254
  let!(:issues) do
@@ -207,10 +279,8 @@ describe ReportsKit::Reports::Data::Generate do
207
279
  context 'with an association dimension' do
208
280
  let(:properties) do
209
281
  {
210
- measure: {
211
- key: 'issue',
212
- dimensions: %w(repo)
213
- }
282
+ measure: 'issue',
283
+ dimensions: %w(repo)
214
284
  }
215
285
  end
216
286
  let!(:issues) do
@@ -234,7 +304,24 @@ describe ReportsKit::Reports::Data::Generate do
234
304
  it 'returns the chart_data' do
235
305
  expect(chart_data).to eq({
236
306
  labels: [repo.to_s],
237
- datasets: [{ label: "Issues", data: [2.0] }]
307
+ datasets: [{ label: 'Issues', data: [2.0] }]
308
+ })
309
+ end
310
+ end
311
+
312
+ context 'with a limit' do
313
+ let(:properties) do
314
+ {
315
+ measure: 'issue',
316
+ dimensions: %w(repo),
317
+ limit: 1
318
+ }
319
+ end
320
+
321
+ it 'returns the chart_data' do
322
+ expect(chart_data).to eq({
323
+ labels: [repo.to_s],
324
+ datasets: [{ label: 'Issues', data: [2] }]
238
325
  })
239
326
  end
240
327
  end
@@ -242,10 +329,8 @@ describe ReportsKit::Reports::Data::Generate do
242
329
  context 'with a dimension limit' do
243
330
  let(:properties) do
244
331
  {
245
- measure: {
246
- key: 'issue',
247
- dimensions: [{ key: 'repo', limit: 1 }]
248
- }
332
+ measure: 'issue',
333
+ dimensions: [{ key: 'repo', limit: 1 }]
249
334
  }
250
335
  end
251
336
 
@@ -263,9 +348,9 @@ describe ReportsKit::Reports::Data::Generate do
263
348
  measure: {
264
349
  key: 'issue',
265
350
  name: 'Average Durations',
266
- aggregation: 'average_duration',
267
- dimensions: %w(repo)
268
- }
351
+ aggregation: 'average_duration'
352
+ },
353
+ dimensions: %w(repo)
269
354
  }
270
355
  end
271
356
  let!(:issues) do
@@ -287,26 +372,24 @@ describe ReportsKit::Reports::Data::Generate do
287
372
  context 'with a belongs_to association filter' do
288
373
  let(:properties) do
289
374
  {
290
- measure: {
291
- key: 'issue',
292
- filters: [
293
- {
294
- key: 'repo',
295
- criteria: {
296
- operator: 'include',
297
- value: [repo.id]
298
- }
375
+ measure: 'issue',
376
+ filters: [
377
+ {
378
+ key: 'repo',
379
+ criteria: {
380
+ operator: 'include',
381
+ value: [repo.id]
299
382
  }
300
- ],
301
- dimensions: %w(repo)
302
- }
383
+ }
384
+ ],
385
+ dimensions: %w(repo)
303
386
  }
304
387
  end
305
388
 
306
389
  it 'returns the chart_data' do
307
390
  expect(chart_data).to eq({
308
391
  labels: [repo.to_s],
309
- datasets: [{ label: "Issues", data: [2.0] }]
392
+ datasets: [{ label: 'Issues', data: [2.0] }]
310
393
  })
311
394
  end
312
395
  end
@@ -314,19 +397,17 @@ describe ReportsKit::Reports::Data::Generate do
314
397
  context 'with a has_many association filter' do
315
398
  let(:properties) do
316
399
  {
317
- measure: {
318
- key: 'issue',
319
- filters: [
320
- {
321
- key: 'tags',
322
- criteria: {
323
- operator: 'include',
324
- value: [tag.id]
325
- }
400
+ measure: 'issue',
401
+ filters: [
402
+ {
403
+ key: 'tags',
404
+ criteria: {
405
+ operator: 'include',
406
+ value: [tag.id]
326
407
  }
327
- ],
328
- dimensions: %w(repo)
329
- }
408
+ }
409
+ ],
410
+ dimensions: %w(repo)
330
411
  }
331
412
  end
332
413
  let(:tag) { create(:tag) }
@@ -338,7 +419,7 @@ describe ReportsKit::Reports::Data::Generate do
338
419
  chart_data
339
420
  expect(chart_data).to eq({
340
421
  labels: [repo.to_s],
341
- datasets: [{ label: "Issues", data: [1.0] }]
422
+ datasets: [{ label: 'Issues', data: [1.0] }]
342
423
  })
343
424
  end
344
425
  end
@@ -346,19 +427,17 @@ describe ReportsKit::Reports::Data::Generate do
346
427
  context 'with a has_many :through association filter' do
347
428
  let(:properties) do
348
429
  {
349
- measure: {
350
- key: 'issue',
351
- filters: [
352
- {
353
- key: 'labels',
354
- criteria: {
355
- operator: 'include',
356
- value: [label.id]
357
- }
430
+ measure: 'issue',
431
+ filters: [
432
+ {
433
+ key: 'labels',
434
+ criteria: {
435
+ operator: 'include',
436
+ value: [label.id]
358
437
  }
359
- ],
360
- dimensions: %w(repo)
361
- }
438
+ }
439
+ ],
440
+ dimensions: %w(repo)
362
441
  }
363
442
  end
364
443
  let(:label) { create(:label) }
@@ -369,7 +448,7 @@ describe ReportsKit::Reports::Data::Generate do
369
448
  it 'returns the chart_data' do
370
449
  expect(chart_data).to eq({
371
450
  labels: [repo.to_s],
372
- datasets: [{ label: "Issues", data: [1.0] }]
451
+ datasets: [{ label: 'Issues', data: [1.0] }]
373
452
  })
374
453
  end
375
454
  end
@@ -378,10 +457,8 @@ describe ReportsKit::Reports::Data::Generate do
378
457
  context 'with a boolean dimension' do
379
458
  let(:properties) do
380
459
  {
381
- measure: {
382
- key: 'issue',
383
- dimensions: %w(locked)
384
- }
460
+ measure: 'issue',
461
+ dimensions: %w(locked)
385
462
  }
386
463
  end
387
464
  let!(:issues) do
@@ -403,13 +480,11 @@ describe ReportsKit::Reports::Data::Generate do
403
480
  context 'with datetime and association dimensions' do
404
481
  let(:properties) do
405
482
  {
406
- measure: {
407
- key: 'issue',
408
- dimensions: [
409
- { key: 'opened_at', label: nil },
410
- { key: 'repo' }
411
- ]
412
- }
483
+ measure: 'issue',
484
+ dimensions: [
485
+ { key: 'opened_at', label: nil },
486
+ { key: 'repo' }
487
+ ]
413
488
  }
414
489
  end
415
490
  let!(:issues) do
@@ -436,6 +511,84 @@ describe ReportsKit::Reports::Data::Generate do
436
511
  })
437
512
  end
438
513
 
514
+ context "with format: 'csv'" do
515
+ subject { described_class.new(properties.merge(format: 'csv'), context_record: context_record).perform }
516
+
517
+ it 'returns the table_data' do
518
+ expect(table_data).to eq([
519
+ [nil, repo.to_s, repo2.to_s],
520
+ [format_csv_week_offset(2), 1, 0],
521
+ [format_csv_week_offset(1), 0, 0],
522
+ [format_csv_week_offset(0), 1, 1]
523
+ ])
524
+ end
525
+
526
+ context 'with a data_format_method that adds HTML tags' do
527
+ subject { described_class.new(properties.merge(format: 'csv', report_options: { data_format_method: 'add_label_link' }), context_record: context_record).perform }
528
+
529
+ it 'returns the table_data without the HTML tags' do
530
+ expect(table_data).to eq([
531
+ [nil, repo.to_s, repo2.to_s],
532
+ ["#{format_csv_week_offset(2)} Bar", 1, 0],
533
+ ["#{format_csv_week_offset(1)} Bar", 0, 0],
534
+ ["#{format_csv_week_offset(0)} Bar", 1, 1]
535
+ ])
536
+ end
537
+ end
538
+
539
+ context 'with a csv_data_format_method' do
540
+ subject { described_class.new(properties.merge(format: 'csv', report_options: { csv_data_format_method: 'prepend_column' }), context_record: context_record).perform }
541
+
542
+ it 'returns the table_data' do
543
+ expect(table_data).to eq([
544
+ [nil, 'Day of Month', repo.to_s, repo2.to_s],
545
+ [format_csv_week_offset(2), 13, 1, 0],
546
+ [format_csv_week_offset(1), 20, 0, 0],
547
+ [format_csv_week_offset(0), 27, 1, 1]
548
+ ])
549
+ end
550
+ end
551
+
552
+ context 'with both a data_format_method and a csv_data_format_method' do
553
+ subject { described_class.new(properties.merge(format: 'csv', report_options: { data_format_method: 'add_label_link', csv_data_format_method: 'prepend_column' }), context_record: context_record).perform }
554
+
555
+ it 'returns the table_data' do
556
+ expect(table_data).to eq([
557
+ [nil, 'Day of Month', repo.to_s, repo2.to_s],
558
+ ["#{format_csv_week_offset(2)} Bar", 13, 1, 0],
559
+ ["#{format_csv_week_offset(1)} Bar", 20, 0, 0],
560
+ ["#{format_csv_week_offset(0)} Bar", 27, 1, 1]
561
+ ])
562
+ end
563
+ end
564
+
565
+ context 'with a csv_data_format_method and aggregations' do
566
+ subject { described_class.new(properties.merge(format: 'csv', report_options: report_options), context_record: context_record).perform }
567
+ let(:report_options) do
568
+ {
569
+ csv_data_format_method: 'prepend_column',
570
+ aggregations: [
571
+ {
572
+ from: 'columns',
573
+ operator: 'sum',
574
+ label: 'Total'
575
+ }
576
+ ]
577
+ }
578
+ end
579
+
580
+ it 'returns the table_data' do
581
+ expect(table_data).to eq([
582
+ [nil, 'Day of Month', repo.to_s, repo2.to_s],
583
+ [format_csv_week_offset(2), 13, 1, 0],
584
+ [format_csv_week_offset(1), 20, 0, 0],
585
+ [format_csv_week_offset(0), 27, 1, 1],
586
+ ['Total', nil, 2, 1]
587
+ ])
588
+ end
589
+ end
590
+ end
591
+
439
592
  context "with format: 'table'" do
440
593
  subject { described_class.new(properties.merge(format: 'table'), context_record: context_record).perform }
441
594
 
@@ -447,10 +600,23 @@ describe ReportsKit::Reports::Data::Generate do
447
600
  [format_week_offset(0), 1, 1]
448
601
  ])
449
602
  end
603
+
604
+ context 'with a data_format_method that adds HTML tags' do
605
+ subject { described_class.new(properties.merge(format: 'table', report_options: { data_format_method: 'add_label_link' }), context_record: context_record).perform }
606
+
607
+ it 'returns the table_data with the HTML tags' do
608
+ expect(table_data).to eq([
609
+ [nil, repo.to_s, repo2.to_s],
610
+ ["<a href='#'>#{format_week_offset(2)}</a> Bar", 1, 0],
611
+ ["<a href='#'>#{format_week_offset(1)}</a> Bar", 0, 0],
612
+ ["<a href='#'>#{format_week_offset(0)}</a> Bar", 1, 1]
613
+ ])
614
+ end
615
+ end
450
616
  end
451
617
 
452
- context "with a data_format_method" do
453
- subject { described_class.new(properties.merge(data_format_method: 'add_label_suffix'), context_record: context_record).perform }
618
+ context 'with a data_format_method' do
619
+ subject { described_class.new(properties.merge(report_options: { data_format_method: 'add_label_suffix' }), context_record: context_record).perform }
454
620
 
455
621
  it 'returns the chart_data' do
456
622
  expect(chart_data).to eq({
@@ -467,21 +633,79 @@ describe ReportsKit::Reports::Data::Generate do
467
633
  ]
468
634
  })
469
635
  end
636
+
637
+ context 'with dependence on the context_record' do
638
+ subject { described_class.new(properties.merge(report_options: { data_format_method: 'add_context_record_suffix' }), context_record: context_record).perform }
639
+ let(:context_record) { repo }
640
+
641
+ it 'returns the chart_data' do
642
+ expect(chart_data).to eq({
643
+ labels: ["#{format_week_offset(2)} #{context_record}", "#{format_week_offset(1)} #{context_record}", "#{format_week_offset(0)} #{context_record}"],
644
+ datasets: [
645
+ {
646
+ label: repo.to_s,
647
+ data: [1, 0, 1]
648
+ }
649
+ ]
650
+ })
651
+ end
652
+ end
653
+ end
654
+
655
+ context 'with an edit_relation_method' do
656
+ subject { described_class.new(properties.merge(report_options: { edit_relation_method: 'empty_result_set_for_relation' }), context_record: context_record).perform }
657
+
658
+ it 'returns the chart_data' do
659
+ expect(chart_data).to eq({
660
+ labels: [],
661
+ datasets: [
662
+ {
663
+ label: 'Issues',
664
+ data: []
665
+ }
666
+ ]
667
+ })
668
+ end
470
669
  end
471
670
  end
472
671
 
473
- context 'with two measures' do
672
+ context 'with a dimension with a blank label' do
474
673
  let(:properties) do
475
674
  {
476
- measures: [
675
+ measure: 'issue',
676
+ dimensions: %w(repo)
677
+ }
678
+ end
679
+
680
+ before do
681
+ allow_any_instance_of(Repo).to receive(:to_s).and_return(nil)
682
+ end
683
+
684
+ it 'hides the dimension' do
685
+ expect(chart_data).to eq({
686
+ labels: [],
687
+ datasets: [
477
688
  {
478
- key: 'issue',
689
+ label: 'Issues',
690
+ data: []
691
+ }
692
+ ]
693
+ })
694
+ end
695
+ end
696
+
697
+ context 'with two series' do
698
+ let(:properties) do
699
+ {
700
+ series: [
701
+ {
702
+ measure: 'issue',
479
703
  dimensions: [{ key: 'created_at', label: nil }]
480
704
  },
481
705
  {
482
- key: 'tag',
706
+ measure: 'tag',
483
707
  dimensions: %w(created_at)
484
- },
708
+ }
485
709
  ]
486
710
  }
487
711
  end
@@ -515,6 +739,67 @@ describe ReportsKit::Reports::Data::Generate do
515
739
  })
516
740
  end
517
741
 
742
+ context 'with edit_dimension_keys_method and a dimension without data' do
743
+ let(:properties) do
744
+ {
745
+ series: [
746
+ {
747
+ measure: 'issue',
748
+ dimensions: %w(repo)
749
+ },
750
+ {
751
+ measure: 'tag',
752
+ dimensions: %w(repo)
753
+ }
754
+ ],
755
+ report_options: {
756
+ edit_dimension_keys_method: 'all_repo_ids'
757
+ }
758
+ }
759
+ end
760
+ let!(:repo3) { create(:repo) }
761
+
762
+ it 'returns the chart_data' do
763
+ expect(chart_data).to eq({
764
+ labels: [repo, repo2, repo3].map(&:to_s),
765
+ datasets: [
766
+ {
767
+ label: 'Issues',
768
+ data: [2, 1, 0]
769
+ },
770
+ {
771
+ label: 'Tags',
772
+ data: [2, 0, 0]
773
+ }
774
+ ]
775
+ })
776
+ end
777
+ end
778
+
779
+ context 'with concurrent queries enabled' do
780
+ around :each do |example|
781
+ ReportsKit.configuration.use_concurrent_queries = true
782
+ example.run
783
+ ReportsKit.configuration.use_concurrent_queries = false
784
+ end
785
+
786
+ it 'returns the chart_data' do
787
+ expect(chart_data).to eq({
788
+ labels: [format_week_offset(2), format_week_offset(1), format_week_offset(0)],
789
+ datasets: [
790
+ {
791
+ label: 'Issues',
792
+ data: [1, 0, 2]
793
+ },
794
+ {
795
+ label: 'Tags',
796
+ data: [1, 1, 0]
797
+ }
798
+ ]
799
+ })
800
+ end
801
+ end
802
+
518
803
  context "with format: 'table'" do
519
804
  subject { described_class.new(properties.merge(format: 'table'), context_record: context_record).perform }
520
805
 
@@ -535,9 +820,9 @@ describe ReportsKit::Reports::Data::Generate do
535
820
  {
536
821
  measure: {
537
822
  key: 'issue',
538
- aggregation: 'average_duration',
539
- dimensions: %w(repo created_at)
540
- }
823
+ aggregation: 'average_duration'
824
+ },
825
+ dimensions: %w(repo created_at)
541
826
  }
542
827
  end
543
828
  let!(:issues) do
@@ -557,19 +842,53 @@ describe ReportsKit::Reports::Data::Generate do
557
842
  end
558
843
  end
559
844
 
845
+ describe 'configuration' do
846
+ let(:properties) do
847
+ {
848
+ measure: 'issue',
849
+ dimensions: %w(repo)
850
+ }
851
+ end
852
+ let!(:issues) do
853
+ [
854
+ create(:issue, repo: repo),
855
+ create(:issue, repo: repo),
856
+ create(:issue, repo: repo2)
857
+ ]
858
+ end
859
+
860
+ context 'with default_properties' do
861
+ around :each do |example|
862
+ ReportsKit.configuration.default_properties = {
863
+ chart: {
864
+ options: {
865
+ foo: 'bar'
866
+ }
867
+ }
868
+ }
869
+ example.run
870
+ ReportsKit.configuration.default_properties = nil
871
+ end
872
+
873
+ it 'returns the chart_data' do
874
+ expect(subject[:chart_data][:options][:foo]).to eq('bar')
875
+ end
876
+ end
877
+ end
878
+
560
879
  describe 'composite aggregations' do
561
- context 'with two measures' do
880
+ context 'with two series' do
562
881
  let(:properties) do
563
882
  {
564
883
  name: name,
565
884
  composite_operator: composite_operator,
566
- measures: [
885
+ series: [
567
886
  {
568
- key: 'issue',
887
+ measure: 'issue',
569
888
  dimensions: %w(created_at)
570
889
  },
571
890
  {
572
- key: 'tag',
891
+ measure: 'tag',
573
892
  dimensions: %w(created_at)
574
893
  }
575
894
  ]
@@ -630,13 +949,13 @@ describe ReportsKit::Reports::Data::Generate do
630
949
  name: name,
631
950
  composite_operator: composite_operator,
632
951
  value_format_method: 'format_percentage',
633
- measures: [
952
+ series: [
634
953
  {
635
- key: 'issue',
954
+ measure: 'issue',
636
955
  dimensions: %w(created_at)
637
956
  },
638
957
  {
639
- key: 'tag',
958
+ measure: 'tag',
640
959
  dimensions: %w(created_at)
641
960
  }
642
961
  ]
@@ -656,6 +975,106 @@ describe ReportsKit::Reports::Data::Generate do
656
975
  end
657
976
  end
658
977
 
978
+ context 'with a limit' do
979
+ let(:properties) do
980
+ {
981
+ name: name,
982
+ composite_operator: '+',
983
+ limit: 1,
984
+ series: [
985
+ {
986
+ measure: 'issue',
987
+ dimensions: %w(repo)
988
+ },
989
+ {
990
+ measure: 'tag',
991
+ dimensions: %w(repo)
992
+ }
993
+ ]
994
+ }
995
+ end
996
+
997
+ it 'returns the chart_data' do
998
+ expect(chart_data).to eq({
999
+ labels: [repo.to_s],
1000
+ datasets: [
1001
+ {
1002
+ label: name,
1003
+ data: [5]
1004
+ }
1005
+ ]
1006
+ })
1007
+ end
1008
+ end
1009
+
1010
+ context 'with a limit and an order' do
1011
+ context 'with an ascending order' do
1012
+ let(:properties) do
1013
+ {
1014
+ name: name,
1015
+ composite_operator: '%',
1016
+ limit: 1,
1017
+ order: '1',
1018
+ series: [
1019
+ {
1020
+ measure: 'issue',
1021
+ dimensions: %w(repo)
1022
+ },
1023
+ {
1024
+ measure: 'tag',
1025
+ dimensions: %w(repo)
1026
+ }
1027
+ ]
1028
+ }
1029
+ end
1030
+
1031
+ it 'returns the chart_data' do
1032
+ expect(chart_data).to eq({
1033
+ labels: [repo2.to_s],
1034
+ datasets: [
1035
+ {
1036
+ label: name,
1037
+ data: [0]
1038
+ }
1039
+ ]
1040
+ })
1041
+ end
1042
+ end
1043
+
1044
+ context 'with a descending order' do
1045
+ let(:properties) do
1046
+ {
1047
+ name: name,
1048
+ composite_operator: '%',
1049
+ limit: 1,
1050
+ order: '1 desc',
1051
+ series: [
1052
+ {
1053
+ measure: 'issue',
1054
+ dimensions: %w(repo)
1055
+ },
1056
+ {
1057
+ measure: 'tag',
1058
+ dimensions: %w(repo)
1059
+ }
1060
+ ]
1061
+ }
1062
+ end
1063
+
1064
+ it 'returns the chart_data' do
1065
+ expect(chart_data).to eq({
1066
+ labels: [repo.to_s],
1067
+ datasets: [
1068
+ {
1069
+ label: name,
1070
+ data: [66.7]
1071
+ }
1072
+ ]
1073
+ })
1074
+ end
1075
+ end
1076
+ end
1077
+
659
1078
  context 'with a boolean dimension' do
660
1079
  let!(:issues) do
661
1080
  [
@@ -669,13 +1088,13 @@ describe ReportsKit::Reports::Data::Generate do
669
1088
  {
670
1089
  name: name,
671
1090
  composite_operator: composite_operator,
672
- measures: [
1091
+ series: [
673
1092
  {
674
- key: 'issue',
1093
+ measure: 'issue',
675
1094
  dimensions: %w(locked)
676
1095
  },
677
1096
  {
678
- key: 'issue',
1097
+ measure: 'issue',
679
1098
  dimensions: %w(locked)
680
1099
  }
681
1100
  ]
@@ -698,27 +1117,27 @@ describe ReportsKit::Reports::Data::Generate do
698
1117
  context 'with a nested composite aggregation' do
699
1118
  let(:properties) do
700
1119
  {
701
- measures: [
1120
+ series: [
702
1121
  {
703
1122
  name: name,
704
1123
  composite_operator: '+',
705
- measures: [
1124
+ series: [
706
1125
  {
707
- key: 'issue',
1126
+ measure: 'issue',
708
1127
  dimensions: %w(created_at)
709
1128
  },
710
1129
  {
711
- key: 'tag',
1130
+ measure: 'tag',
712
1131
  dimensions: %w(created_at)
713
1132
  }
714
1133
  ]
715
1134
  },
716
1135
  {
717
- key: 'issue',
1136
+ measure: 'issue',
718
1137
  dimensions: %w(created_at)
719
1138
  },
720
1139
  {
721
- key: 'tag',
1140
+ measure: 'tag',
722
1141
  dimensions: %w(created_at)
723
1142
  }
724
1143
  ]
@@ -748,36 +1167,36 @@ describe ReportsKit::Reports::Data::Generate do
748
1167
  context 'with ui_filters' do
749
1168
  let(:properties) do
750
1169
  {
751
- measures: [
1170
+ series: [
752
1171
  {
753
1172
  name: name,
754
1173
  composite_operator: '+',
755
- measures: [
1174
+ series: [
756
1175
  {
757
- key: 'issue',
1176
+ measure: 'issue',
758
1177
  filters: %w(created_at),
759
1178
  dimensions: %w(created_at)
760
1179
  },
761
1180
  {
762
- key: 'tag',
1181
+ measure: 'tag',
763
1182
  filters: %w(created_at),
764
1183
  dimensions: %w(created_at)
765
1184
  }
766
1185
  ]
767
1186
  },
768
1187
  {
769
- key: 'issue',
1188
+ measure: 'issue',
770
1189
  filters: %w(created_at),
771
1190
  dimensions: %w(created_at)
772
1191
  },
773
1192
  {
774
- key: 'tag',
1193
+ measure: 'tag',
775
1194
  filters: %w(created_at),
776
1195
  dimensions: %w(created_at)
777
1196
  }
778
1197
  ],
779
1198
  ui_filters: {
780
- created_at: "#{format_criteria_time(now - 1.week)} - #{format_criteria_time(now)}"
1199
+ created_at: "#{format_configuration_time(now - 1.week)} - #{format_configuration_time(now)}"
781
1200
  }
782
1201
  }
783
1202
  end
@@ -806,17 +1225,17 @@ describe ReportsKit::Reports::Data::Generate do
806
1225
  context 'with two dimensions' do
807
1226
  let(:properties) do
808
1227
  {
809
- measures: [
1228
+ series: [
810
1229
  {
811
1230
  name: name,
812
1231
  composite_operator: '+',
813
- measures: [
1232
+ series: [
814
1233
  {
815
- key: 'issue',
1234
+ measure: 'issue',
816
1235
  dimensions: %w(created_at repo)
817
1236
  },
818
1237
  {
819
- key: 'tag',
1238
+ measure: 'tag',
820
1239
  dimensions: %w(created_at repo)
821
1240
  }
822
1241
  ]