active_reporter 0.6.1 → 0.6.5

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +9 -9
  3. data/lib/active_reporter/aggregator/array.rb +1 -1
  4. data/lib/active_reporter/aggregator/count.rb +2 -2
  5. data/lib/active_reporter/aggregator/count_if.rb +2 -2
  6. data/lib/active_reporter/aggregator/ratio.rb +1 -1
  7. data/lib/active_reporter/aggregator.rb +9 -9
  8. data/lib/active_reporter/calculator.rb +2 -2
  9. data/lib/active_reporter/dimension/base.rb +3 -3
  10. data/lib/active_reporter/dimension/bin/set.rb +3 -3
  11. data/lib/active_reporter/dimension/bin/table.rb +1 -1
  12. data/lib/active_reporter/dimension/bin.rb +23 -15
  13. data/lib/active_reporter/dimension/category.rb +1 -1
  14. data/lib/active_reporter/dimension/enum.rb +1 -1
  15. data/lib/active_reporter/dimension/number.rb +3 -3
  16. data/lib/active_reporter/dimension/time.rb +4 -4
  17. data/lib/active_reporter/dimension.rb +8 -8
  18. data/lib/active_reporter/evaluator.rb +2 -2
  19. data/lib/active_reporter/inflector.rb +1 -1
  20. data/lib/active_reporter/report/aggregation.rb +12 -12
  21. data/lib/active_reporter/report/definition.rb +6 -6
  22. data/lib/active_reporter/report/validation.rb +26 -15
  23. data/lib/active_reporter/report.rb +3 -3
  24. data/lib/active_reporter/serializer/base.rb +6 -6
  25. data/lib/active_reporter/serializer/csv.rb +2 -2
  26. data/lib/active_reporter/serializer/form_field.rb +5 -5
  27. data/lib/active_reporter/serializer/highcharts.rb +6 -6
  28. data/lib/active_reporter/serializer.rb +7 -7
  29. data/lib/active_reporter/tracker/base.rb +1 -1
  30. data/lib/active_reporter/tracker.rb +3 -3
  31. data/lib/active_reporter/version.rb +1 -1
  32. data/lib/active_reporter.rb +7 -3
  33. data/spec/acceptance/data_spec.rb +49 -49
  34. data/spec/active_reporter/aggregator_spec.rb +37 -37
  35. data/spec/active_reporter/dimension/base_spec.rb +29 -29
  36. data/spec/active_reporter/dimension/bin/set_spec.rb +29 -29
  37. data/spec/active_reporter/dimension/bin/table_spec.rb +7 -7
  38. data/spec/active_reporter/dimension/bin_spec.rb +12 -12
  39. data/spec/active_reporter/dimension/category_spec.rb +22 -22
  40. data/spec/active_reporter/dimension/enum_spec.rb +12 -12
  41. data/spec/active_reporter/dimension/number_spec.rb +11 -11
  42. data/spec/active_reporter/dimension/time_spec.rb +20 -20
  43. data/spec/active_reporter/report_spec.rb +162 -162
  44. data/spec/active_reporter/serializer/hash_table_spec.rb +13 -13
  45. data/spec/active_reporter/serializer/highcharts_spec.rb +30 -30
  46. data/spec/active_reporter/serializer/table_spec.rb +22 -22
  47. data/spec/dummy/Rakefile +1 -1
  48. data/spec/dummy/app/models/post_report.rb +1 -1
  49. data/spec/dummy/app/views/layouts/application.html.erb +2 -2
  50. data/spec/dummy/app/views/site/report.html.erb +5 -5
  51. data/spec/dummy/bin/bundle +2 -2
  52. data/spec/dummy/bin/rails +3 -3
  53. data/spec/dummy/bin/rake +2 -2
  54. data/spec/dummy/bin/setup +2 -2
  55. data/spec/dummy/config/application.rb +4 -4
  56. data/spec/dummy/config/boot.rb +3 -3
  57. data/spec/dummy/config/database.yml +3 -3
  58. data/spec/dummy/config/environment.rb +1 -1
  59. data/spec/dummy/config/environments/production.rb +4 -4
  60. data/spec/dummy/config/environments/test.rb +1 -1
  61. data/spec/dummy/config/initializers/assets.rb +1 -1
  62. data/spec/dummy/config/initializers/inflections.rb +4 -4
  63. data/spec/dummy/config/initializers/session_store.rb +1 -1
  64. data/spec/dummy/config/locales/en.yml +2 -2
  65. data/spec/dummy/config/routes.rb +9 -9
  66. data/spec/dummy/config.ru +1 -1
  67. data/spec/dummy/log/test.log +54769 -77257
  68. data/spec/spec_helper.rb +13 -13
  69. metadata +64 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 760b641c323ac15a10767901f91776f8060353366c74e00333a29f76c43a622f
4
- data.tar.gz: 12e2c7902056ec37e07a72c11d16261390c2aa8e56e1b7395d000d24b2617de8
3
+ metadata.gz: 723ed733317c2a8e7a9671f7df71388c7df0b8019824ef83a8455d1fc2358a26
4
+ data.tar.gz: 6897c073647fc646151861295592048449e80803ba000332a63b6a026942d770
5
5
  SHA512:
6
- metadata.gz: 94f9875a81ab72172e200920213ca1de4f307f6879dc7163101d7399c5ea0cb3ba80b4b724c4c3b62b0d32daee75fe11a43a68a72d00ed1aa787a43fb3c8e6b4
7
- data.tar.gz: 80d2ee5dc68fe12fc1239bab3305aa4c15ddccbb57daf74183e9e95bb05db7754b3045f927cf5eb2d673c113df1f3b6cd5d5c4b3412dd44cc9404ec891575e64
6
+ metadata.gz: 1d8eb39876e5f564fdf8b3522b9e1a6739052311b57f525baa4ac827fc0a3507a515c355a23f0b8d1e6280976a9f17dd654e80fb16e39278ceb82fed6fdb2d78
7
+ data.tar.gz: 89b76c59b8ef242536ed4758c7ff036fa35425703c57a56f1d212a72b642a5f5d24d919e2bc16c4907e93cac6e74e24d8500ca6f1d6ef2502c381cb4ab111fb0
data/Rakefile CHANGED
@@ -1,22 +1,22 @@
1
1
  begin
2
- require 'bundler/setup'
2
+ require "bundler/setup"
3
3
  rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
4
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
5
  end
6
6
 
7
- require 'rdoc/task'
7
+ require "rdoc/task"
8
8
 
9
9
  RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'ActiveReporter'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.rdoc')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
10
+ rdoc.rdoc_dir = "rdoc"
11
+ rdoc.title = "ActiveReporter"
12
+ rdoc.options << "--line-numbers"
13
+ rdoc.rdoc_files.include("README.rdoc")
14
+ rdoc.rdoc_files.include("lib/**/*.rb")
15
15
  end
16
16
 
17
17
  Bundler::GemHelper.install_tasks
18
18
 
19
- require 'rspec/core/rake_task'
19
+ require "rspec/core/rake_task"
20
20
 
21
21
  RSpec::Core::RakeTask.new(:spec)
22
22
 
@@ -2,7 +2,7 @@ module ActiveReporter
2
2
  module Aggregator
3
3
  class Array < ActiveReporter::Aggregator::Base
4
4
  def aggregate(groups)
5
- fail InvalidParamsError, 'array agg is only supported in Postgres' unless ActiveReporter.database_type == :postgres
5
+ fail InvalidParamsError, "array aggregator is only supported in Postgres" unless ActiveReporter.database_type == :postgres
6
6
  super
7
7
  end
8
8
 
@@ -2,7 +2,7 @@ module ActiveReporter
2
2
  module Aggregator
3
3
  class Count < ActiveReporter::Aggregator::Base
4
4
  def function
5
- "COUNT(#{'DISTINCT' if distinct} #{expression})"
5
+ "COUNT(#{"DISTINCT" if distinct} #{expression})"
6
6
  end
7
7
 
8
8
  def default_value
@@ -16,7 +16,7 @@ module ActiveReporter
16
16
  end
17
17
 
18
18
  def column
19
- opts.fetch(:column, 'id')
19
+ opts.fetch(:column, "id")
20
20
  end
21
21
  end
22
22
  end
@@ -2,7 +2,7 @@ module ActiveReporter
2
2
  module Aggregator
3
3
  class CountIf < ActiveReporter::Aggregator::Count
4
4
  def function
5
- "COUNT(#{expression} IN (#{values.map(&:to_s).join(',')}) OR NULL)"
5
+ "COUNT(#{expression} IN (#{values.map(&:to_s).join(",")}) OR NULL)"
6
6
  end
7
7
 
8
8
  def default_value
@@ -16,7 +16,7 @@ module ActiveReporter
16
16
  end
17
17
 
18
18
  def column
19
- super || 'id'
19
+ super || "id"
20
20
  end
21
21
  end
22
22
  end
@@ -4,7 +4,7 @@ module ActiveReporter
4
4
  attr_reader :numerator, :denominator
5
5
 
6
6
  def function
7
- "(#{numerator}/NULLIF(#{denominator},0))"
7
+ "(#{numerator}/NULLIF(#{denominator},0)::FLOAT)"
8
8
  end
9
9
 
10
10
  private
@@ -1,9 +1,9 @@
1
- require 'active_reporter/aggregator/base'
2
- require 'active_reporter/aggregator/array'
3
- require 'active_reporter/aggregator/average'
4
- require 'active_reporter/aggregator/count'
5
- require 'active_reporter/aggregator/count_if'
6
- require 'active_reporter/aggregator/max'
7
- require 'active_reporter/aggregator/min'
8
- require 'active_reporter/aggregator/ratio'
9
- require 'active_reporter/aggregator/sum'
1
+ require "active_reporter/aggregator/base"
2
+ require "active_reporter/aggregator/array"
3
+ require "active_reporter/aggregator/average"
4
+ require "active_reporter/aggregator/count"
5
+ require "active_reporter/aggregator/count_if"
6
+ require "active_reporter/aggregator/max"
7
+ require "active_reporter/aggregator/min"
8
+ require "active_reporter/aggregator/ratio"
9
+ require "active_reporter/aggregator/sum"
@@ -1,2 +1,2 @@
1
- require 'active_reporter/calculator/base'
2
- require 'active_reporter/calculator/ratio'
1
+ require "active_reporter/calculator/base"
2
+ require "active_reporter/calculator/ratio"
@@ -71,7 +71,7 @@ module ActiveReporter
71
71
  end
72
72
 
73
73
  def order(relation)
74
- relation.order("#{order_expression} #{sort_order} #{null_order}")
74
+ relation.order(Arel.sql("#{order_expression} #{sort_order} #{null_order}"))
75
75
  end
76
76
 
77
77
  def sort_desc?
@@ -79,7 +79,7 @@ module ActiveReporter
79
79
  end
80
80
 
81
81
  def sort_order
82
- sort_desc? ? 'DESC' : 'ASC'
82
+ sort_desc? ? "DESC" : "ASC"
83
83
  end
84
84
 
85
85
  def nulls_last?
@@ -90,7 +90,7 @@ module ActiveReporter
90
90
 
91
91
  def null_order
92
92
  return unless ActiveReporter.database_type == :postgres
93
- nulls_last? ? 'NULLS LAST' : 'NULLS FIRST'
93
+ nulls_last? ? "NULLS LAST" : "NULLS FIRST"
94
94
  end
95
95
 
96
96
  def params
@@ -21,7 +21,7 @@ module ActiveReporter
21
21
  when /^([^,]+),(.+)$/ then new($1, $2)
22
22
  when /^([^,]+),$/ then new($1, nil)
23
23
  when /^,(.+)$/ then new(nil, $1)
24
- when ',', nil then new(nil, nil)
24
+ when ",", nil then new(nil, nil)
25
25
  else
26
26
  raise "Unexpected SQL bin format #{value}"
27
27
  end
@@ -104,8 +104,8 @@ module ActiveReporter
104
104
 
105
105
  def [](key)
106
106
  case key.to_s
107
- when 'min' then min
108
- when 'max' then max
107
+ when "min" then min
108
+ when "max" then max
109
109
  end
110
110
  end
111
111
 
@@ -35,7 +35,7 @@ module ActiveReporter
35
35
  end
36
36
 
37
37
  def any_contain(expr)
38
- map { |bin| bin.contains_sql(expr) }.join(' OR ')
38
+ map { |bin| bin.contains_sql(expr) }.join(" OR ")
39
39
  end
40
40
  end
41
41
  end
@@ -1,4 +1,4 @@
1
- require 'active_reporter/dimension/base'
1
+ require "active_reporter/dimension/base"
2
2
 
3
3
  module ActiveReporter
4
4
  module Dimension
@@ -9,15 +9,34 @@ module ActiveReporter
9
9
  self.class::MAX_BINS
10
10
  end
11
11
 
12
+ # report values are greater than or equal to min, grouped by bin_width
12
13
  def min
13
14
  @min ||= filter_min || report.records.minimum(expression)
14
15
  end
15
16
  alias bin_start min
16
17
 
18
+ # report values are less than max, grouped by bin_width
17
19
  def max
18
20
  @max ||= filter_max || report.records.maximum(expression)
19
21
  end
20
22
 
23
+ def bin_end
24
+ @bin_end ||= if max.blank? || min.blank? || min > max
25
+ nil
26
+ else
27
+ bin_edge = bin_start + bin_width
28
+
29
+ loop do
30
+ break if bin_edge >= max
31
+ bin_edge += bin_width
32
+ end
33
+
34
+ bin_edge += bin_width unless filter_values_for(:max).present? # # # figure out why we need this??
35
+
36
+ bin_edge
37
+ end
38
+ end
39
+
21
40
  def filter_min
22
41
  filter_values_for(:min).min
23
42
  end
@@ -95,23 +114,12 @@ module ActiveReporter
95
114
  end
96
115
 
97
116
  def autopopulate_bins
98
- return [] if bin_start.blank? || max.blank?
99
-
100
- bin_max = filter_values_for(:max).present? ? (max - bin_width) : max
117
+ return [] if bin_start.blank? || bin_end.blank?
101
118
 
102
- bin_count = (bin_max - bin_start)/(bin_width)
119
+ bin_count = ((bin_end - bin_start)/(bin_width)).to_i
103
120
  invalid_param!(:bin_width, "is too small for the domain; would generate #{bin_count.to_i} bins") if bin_count > max_bins
104
121
 
105
- bin_edge = bin_start
106
- bins = []
107
-
108
- loop do
109
- break if bin_edge > bin_max
110
-
111
- bin = { min: bin_edge, max: bin_edge + bin_width }
112
- bins << bin
113
- bin_edge = bin[:max]
114
- end
122
+ bins = bin_count.times.map { |i| { min: (bin_start + (bin_width*i)), max: (bin_start + (bin_width*i.next)) } }
115
123
 
116
124
  bins.reverse! if sort_desc?
117
125
  ( nulls_last? ? bins.push(nil) : bins.unshift(nil) ) if data_contains_nil?
@@ -1,4 +1,4 @@
1
- require 'active_reporter/dimension/base'
1
+ require "active_reporter/dimension/base"
2
2
 
3
3
  module ActiveReporter
4
4
  module Dimension
@@ -1,4 +1,4 @@
1
- require 'active_reporter/dimension/category'
1
+ require "active_reporter/dimension/category"
2
2
 
3
3
  module ActiveReporter
4
4
  module Dimension
@@ -1,4 +1,4 @@
1
- require 'active_reporter/dimension/bin'
1
+ require "active_reporter/dimension/bin"
2
2
 
3
3
  module ActiveReporter
4
4
  module Dimension
@@ -9,8 +9,8 @@ module ActiveReporter
9
9
  super
10
10
 
11
11
  if params.key?(:bin_width)
12
- invalid_param!(:bin_width, 'must be numeric') unless ActiveReporter.numeric?(params[:bin_width])
13
- invalid_param!(:bin_width, 'must be greater than 0') unless params[:bin_width].to_f > 0
12
+ invalid_param!(:bin_width, "must be numeric") unless ActiveReporter.numeric?(params[:bin_width])
13
+ invalid_param!(:bin_width, "must be greater than 0") unless params[:bin_width].to_f > 0
14
14
  end
15
15
  end
16
16
 
@@ -1,12 +1,12 @@
1
- require 'active_reporter/inflector'
2
- require 'active_reporter/dimension/bin'
1
+ require "active_reporter/inflector"
2
+ require "active_reporter/dimension/bin"
3
3
 
4
4
  module ActiveReporter
5
5
  module Dimension
6
6
  class Time < Bin
7
7
  STEPS = %i(seconds minutes hours days weeks months years)
8
8
  BIN_STEPS = (STEPS - [:seconds]).map { |step| step.to_s.singularize(:_gem_active_reporter) }
9
- DURATION_PATTERN = /\A\d+ (?:#{STEPS.map{ |step| "#{step}?" }.join('|')})\z/
9
+ DURATION_PATTERN = /\A\d+ (?:#{STEPS.map{ |step| "#{step}?" }.join("|")})\z/
10
10
 
11
11
  def validate_params!
12
12
  super
@@ -78,7 +78,7 @@ module ActiveReporter
78
78
 
79
79
  class Set < Bin::Set
80
80
  def parse(value)
81
- ::Time.zone.parse(value.to_s.gsub('"', ''))
81
+ ::Time.zone.parse(value.to_s.gsub('"', ""))
82
82
  end
83
83
 
84
84
  def cast(value)
@@ -1,8 +1,8 @@
1
- require 'active_reporter/dimension/base'
2
- require 'active_reporter/dimension/bin'
3
- require 'active_reporter/dimension/bin/set'
4
- require 'active_reporter/dimension/bin/table'
5
- require 'active_reporter/dimension/time'
6
- require 'active_reporter/dimension/number'
7
- require 'active_reporter/dimension/category'
8
- require 'active_reporter/dimension/enum'
1
+ require "active_reporter/dimension/base"
2
+ require "active_reporter/dimension/bin"
3
+ require "active_reporter/dimension/bin/set"
4
+ require "active_reporter/dimension/bin/table"
5
+ require "active_reporter/dimension/time"
6
+ require "active_reporter/dimension/number"
7
+ require "active_reporter/dimension/category"
8
+ require "active_reporter/dimension/enum"
@@ -1,2 +1,2 @@
1
- require 'active_reporter/evaluator/base'
2
- require 'active_reporter/evaluator/block'
1
+ require "active_reporter/evaluator/base"
2
+ require "active_reporter/evaluator/block"
@@ -4,5 +4,5 @@ ActiveSupport::Inflector.inflections(:_gem_active_reporter) do |inflect|
4
4
  inflect.instance_variable_set("@#{var}", sys_inflect.send(var).dup)
5
5
  end
6
6
 
7
- inflect.uncountable 'delta'
7
+ inflect.uncountable "delta"
8
8
  end
@@ -29,7 +29,6 @@ module ActiveReporter
29
29
 
30
30
  def source_data
31
31
  @source_data ||= aggregators.values.reduce(groups) do |relation, aggregator|
32
- # append each aggregator into the base relation (groups)
33
32
  relation.merge(aggregator.aggregate(base_relation))
34
33
  end
35
34
  end
@@ -39,12 +38,11 @@ module ActiveReporter
39
38
  def aggregate
40
39
  tracker_dimension_key = :_tracker_dimension
41
40
 
42
- if trackable? && trackers.any?
41
+ if trackable? && trackers.any? && prior_bin_report.source_data.present?
43
42
  prior_obj = prior_bin_report.source_data.first
44
43
  prior_row = prior_bin_report.hashed_data.first.with_indifferent_access
45
44
 
46
- results_key_prefix = groupers.map { |g| g.extract_sql_value(prior_obj) }
47
- prior_row[tracker_dimension_key] = results_key_prefix[0..-2]
45
+ prior_row[tracker_dimension_key] = groupers.without(tracker_dimension).map { |g| g.extract_sql_value(prior_obj) }
48
46
  else
49
47
  prior_obj = nil
50
48
  prior_row = {}
@@ -87,7 +85,7 @@ module ActiveReporter
87
85
  # "author.id" value (bin) changes the tracker is reset so we do not track changes from the last day of each
88
86
  # "author.id" to the first day of the next "author.id".
89
87
  if trackable?
90
- current_row[tracker_dimension_key] = results_key_prefix[0..-2]
88
+ current_row[tracker_dimension_key] = groupers.without(tracker_dimension).map { |g| g.extract_sql_value(current_obj) }
91
89
 
92
90
  if current_row[tracker_dimension_key] == prior_row[tracker_dimension_key] && bins_are_adjacent?(current_obj, prior_obj)
93
91
  trackers.each do |name, tracker|
@@ -199,11 +197,11 @@ module ActiveReporter
199
197
 
200
198
  results.deep_merge!(results.collect do |row, value|
201
199
  calculators.collect do |name, calculator|
202
- row_data = hash_raw_row(row, value, ['totals'])
200
+ row_data = hash_raw_row(row, value, ["totals"])
203
201
  calc_report = parent_report.total_report
204
202
 
205
203
  parent_row = match_parent_row_for_calculator(row_data, calc_report, calculator)
206
- [['totals', name.to_s], calculator.calculate(row_data, parent_row)] unless parent_row.nil?
204
+ [["totals", name.to_s], calculator.calculate(row_data, parent_row)] unless parent_row.nil?
207
205
  end
208
206
  end.flatten(1).to_h) unless parent_report.nil?
209
207
 
@@ -241,9 +239,9 @@ module ActiveReporter
241
239
  # tracker? Even if there is a "correct" method for one report it may not be correct for a different report. The
242
240
  # same problem applies to strings. Which character is after "z"? The ASCII hex value is "{", which would work
243
241
  # fine for ordering, but maybe not for determining when a tracker should be reset. Additionally, we need to
244
- # deal with strings of different lengths. Alphabetically you could order 'A', 'AA', 'AAA', 'B' but how do know
245
- # when to reset the tracker? If we get a new value of 'AAAA' we have entirelly new values used to calculate the
246
- # tracker value for the 'B' row, effectivally making the tracker values irrelevent.
242
+ # deal with strings of different lengths. Alphabetically you could order "A", "AA", "AAA", "B" but how do know
243
+ # when to reset the tracker? If we get a new value of "AAAA" we have entirelly new values used to calculate the
244
+ # tracker value for the "B" row, effectivally making the tracker values irrelevent.
247
245
  # Even going back to the integer example, the value allowed to be stored increments by 1, but there is no
248
246
  # guerentee that these are the actual values being used in the field.
249
247
  # For these reasons we will not attempt to track any dimension that does not specifically specify a bin width.
@@ -270,7 +268,7 @@ module ActiveReporter
270
268
  end
271
269
 
272
270
  def trackable?
273
- @trackable ||= tracker_dimension.is_a?(ActiveReporter::Dimension::Bin) && tracker_dimension.min.present?
271
+ @trackable ||= tracker_dimension&.min.present?
274
272
  end
275
273
 
276
274
  def evaluatable?
@@ -278,7 +276,9 @@ module ActiveReporter
278
276
  end
279
277
 
280
278
  def tracker_dimension
281
- @tracker_dimension ||= groupers.last
279
+ @tracker_dimension ||= (groupers.reverse + dimensions.values).detect do |dimension|
280
+ dimension.is_a?(ActiveReporter::Dimension::Bin) && %i[min max bin_width].all? { |a| dimension.try(a).present? }
281
+ end
282
282
  end
283
283
 
284
284
  def prior_bin_report
@@ -1,4 +1,4 @@
1
- require 'active_reporter/inflector'
1
+ require "active_reporter/inflector"
2
2
 
3
3
  module ActiveReporter
4
4
  class Report
@@ -6,7 +6,7 @@ module ActiveReporter
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  METRICS = %i[aggregator calculator dimension tracker evaluator].collect do |type|
9
- metrics = Dir.glob(File.join(__dir__, '..', type.to_s, '*.rb')).collect { |file| File.basename(file, '.rb') }.without(*%w[base bin]).collect(&:to_sym).sort.freeze
9
+ metrics = Dir.glob(File.join(__dir__, "..", type.to_s, "*.rb")).collect { |file| File.basename(file, ".rb") }.without(*%w[base bin]).collect(&:to_sym).sort.freeze
10
10
  [type, const_set(type.to_s.upcase, metrics)]
11
11
  end.to_h.sort.freeze
12
12
 
@@ -102,7 +102,7 @@ module ActiveReporter
102
102
 
103
103
  # block_evaluator(:chargeback_ratio) { |row| supplemental_report_data.detect { |data| data[:id] == row[:id] }[:count] / row[:count] }
104
104
  def evaluator(name, evaluator_class, opts = {})
105
- raise 'needs block' unless opts.include?(:block)
105
+ raise "needs block" unless opts.include?(:block)
106
106
  evaluators[name.to_sym] = { axis_class: evaluator_class, opts: opts }
107
107
  end
108
108
 
@@ -124,20 +124,20 @@ module ActiveReporter
124
124
  class_eval <<-METRIC_HELPERS, __FILE__, __LINE__ + 1
125
125
  def #{mertic}_#{type}(name, opts = {}, &block)
126
126
  opts[:block] = block if block_given?
127
- #{type}(name, #{(type.to_s + '/' + mertic.to_s.singularize(:_gem_active_reporter)).camelize.sub(/.*\./, "")}, opts)
127
+ #{type}(name, #{(type.to_s + "/" + mertic.to_s.singularize(:_gem_active_reporter)).camelize.sub(/.*\./, "")}, opts)
128
128
  end
129
129
  METRIC_HELPERS
130
130
  end
131
131
  end
132
132
 
133
133
  def default_report_model
134
- name.demodulize.sub(/Report$/, '').constantize
134
+ name.demodulize.sub(/Report$/, "").constantize
135
135
  rescue NameError
136
136
  raise $!, "#{$!} cannot be used as `report_on` class, please configure `report_on` in the report class", $!.backtrace
137
137
  end
138
138
 
139
139
  def default_model
140
- name.demodulize.sub(/Report$/, '').constantize
140
+ name.demodulize.sub(/Report$/, "").constantize
141
141
  end
142
142
 
143
143
  def report_model
@@ -1,5 +1,5 @@
1
- require 'active_reporter/inflector'
2
- require 'active_reporter/invalid_params_error'
1
+ require "active_reporter/inflector"
2
+ require "active_reporter/invalid_params_error"
3
3
 
4
4
  module ActiveReporter
5
5
  class Report
@@ -19,11 +19,11 @@ module ActiveReporter
19
19
  end
20
20
 
21
21
  def validate_configuration!
22
- incomplete_message = ['You must declare at least one aggregator or tracker, and at lease one dimension to initialize a report', 'See the README for more details']
22
+ incomplete_message = ["You must declare at least one aggregator or tracker, and at lease one dimension to initialize a report", "See the README for more details"]
23
23
 
24
24
  raise ActiveReporter::InvalidParamsError, ["#{self.class.name} does not declare any aggregators or trackers"].concat(incomplete_message).join(". ") if aggregators.empty?
25
25
  raise ActiveReporter::InvalidParamsError, ["#{self.class.name} does not declare any dimensions"].concat(incomplete_message).join(". ") if dimensions.except(:totals).empty?
26
- raise ActiveReporter::InvalidParamsError, 'parent_report must be included in order to process calculations' if calculators.any? && parent_report.nil?
26
+ raise ActiveReporter::InvalidParamsError, "parent_report must be included in order to process calculations" if calculators.any? && parent_report.nil?
27
27
  end
28
28
 
29
29
  def validate_aggregators!
@@ -38,10 +38,13 @@ module ActiveReporter
38
38
  end
39
39
 
40
40
  calculators.values.each do |calculator|
41
- if calculator.aggregator.nil?
41
+ case
42
+ when calculator.aggregator.nil?
42
43
  add_invalid_param_error(:calculator, ":#{calculator.name} must define an aggregator (should be in #{self.class.aggregator.keys})")
43
- elsif aggregators.exclude?(calculator.aggregator)
44
+ when self.class.aggregators.exclude?(calculator.aggregator)
44
45
  add_invalid_param_error(:calculator, ":#{calculator.name} defines an invalid aggregator :#{calculator.aggregator} (should be in #{self.class.aggregators.keys})")
46
+ when params.include?(:aggregators) && aggregators.exclude?(calculator.aggregator)
47
+ params[:aggregators].push(calculator.aggregator)
45
48
  end
46
49
  end
47
50
  end
@@ -52,14 +55,22 @@ module ActiveReporter
52
55
  end
53
56
 
54
57
  trackers.values.each do |tracker|
55
- if tracker.aggregator.nil?
58
+ case
59
+ when tracker.aggregator.nil?
56
60
  add_invalid_param_error(:tracker, ":#{tracker.name} must define an aggregator (should be in #{self.class.aggregator.keys})")
57
- elsif aggregators.exclude?(tracker.aggregator)
61
+ when self.class.aggregators.exclude?(tracker.aggregator)
58
62
  add_invalid_param_error(:tracker, ":#{tracker.name} defines an invalid aggregator :#{tracker.aggregator} (should be in #{self.class.aggregators.keys})")
63
+ when params.include?(:aggregators) && aggregators.exclude?(tracker.aggregator)
64
+ params[:aggregators].push(tracker.aggregator)
59
65
  end
60
66
 
61
- if tracker.prior_aggregator.present? && aggregators.exclude?(tracker.prior_aggregator)
62
- add_invalid_param_error(:tracker, ":#{tracker.name} defines an invalid prior aggregator :#{tracker.prior_aggregator} (should be in #{self.class.aggregators.keys})")
67
+ if tracker.opts.include?(:prior_aggregator)
68
+ case
69
+ when self.class.aggregators.exclude?(tracker.prior_aggregator)
70
+ add_invalid_param_error(:tracker, ":#{tracker.name} defines an invalid prior aggregator :#{tracker.prior_aggregator} (should be in #{self.class.aggregators.keys})")
71
+ when params.include?(:aggregators) && aggregators.exclude?(tracker.prior_aggregator)
72
+ params[:aggregators].push(tracker.prior_aggregator)
73
+ end
63
74
  end
64
75
  end
65
76
  end
@@ -70,8 +81,8 @@ module ActiveReporter
70
81
  invalid_groupers_message = [
71
82
  [
72
83
  invalid_groupers.to_sentence,
73
- (invalid_groupers.one? ? 'is not a' : 'are not'), 'valid', 'dimension'.pluralize(invalid_groupers.count, :_gem_active_reporter)
74
- ].join(' '),
84
+ (invalid_groupers.one? ? "is not a" : "are not"), "valid", "dimension".pluralize(invalid_groupers.count, :_gem_active_reporter)
85
+ ].join(" "),
75
86
  "declared dimension include #{dimensions.keys.to_sentence}"
76
87
  ].join(". ")
77
88
  add_invalid_param_error(:groupers, invalid_groupers_message)
@@ -79,11 +90,11 @@ module ActiveReporter
79
90
  end
80
91
 
81
92
  def validate_parent_report!
82
- add_invalid_param_error(:parent_report, 'must be an instance of ActiveReporter::Report') unless parent_report.nil? || parent_report.kind_of?(ActiveReporter::Report)
93
+ add_invalid_param_error(:parent_report, "must be an instance of ActiveReporter::Report") unless parent_report.nil? || parent_report.kind_of?(ActiveReporter::Report)
83
94
  end
84
95
 
85
96
  def validate_total_report!
86
- add_invalid_param_error(:total_report, 'must be an instance of ActiveReporter::Report') unless @total_report.nil? || @total_report.kind_of?(ActiveReporter::Report)
97
+ add_invalid_param_error(:total_report, "must be an instance of ActiveReporter::Report") unless @total_report.nil? || @total_report.kind_of?(ActiveReporter::Report)
87
98
  end
88
99
 
89
100
  private
@@ -103,7 +114,7 @@ module ActiveReporter
103
114
  end
104
115
 
105
116
  def error_message
106
- (["The report configuration contains the following #{'error'.pluralize(errors.count, :_gem_active_reporter)}:"] + errors).join("\n - ")
117
+ (["The report configuration contains the following #{"error".pluralize(errors.count, :_gem_active_reporter)}:"] + errors).join("\n - ")
107
118
  end
108
119
  end
109
120
  end
@@ -1,4 +1,4 @@
1
- Dir.glob(File.join(__dir__, 'report', '*.rb')).each { |file| require file }
1
+ Dir.glob(File.join(__dir__, "report", "*.rb")).each { |file| require file }
2
2
 
3
3
  module ActiveReporter
4
4
  class Report
@@ -18,8 +18,8 @@ module ActiveReporter
18
18
  # When using a Calculator you may need the parent report data. Pass in a ActiveReporter::Report object when
19
19
  # instantiating a new ActiveReporter::Report instance as :parent_report. This will allow you to calculate a data
20
20
  # based on the #total_report of this passed :parent_report. For example, if the parent report includes a sum
21
- # aggregated 'views' column, the child report can use Report::Calculator::Ratio to caluclate the ratio of 'views'
22
- # on a given row versus the total 'views' from the parent report.
21
+ # aggregated "views" column, the child report can use Report::Calculator::Ratio to caluclate the ratio of "views"
22
+ # on a given row versus the total "views" from the parent report.
23
23
  @parent_report = @params.delete(:parent_report)
24
24
  @parent_groupers = @params.delete(:parent_groupers) || ( grouper_names & Array(parent_report&.grouper_names) )
25
25
 
@@ -1,4 +1,4 @@
1
- require 'active_reporter/inflector'
1
+ require "active_reporter/inflector"
2
2
 
3
3
  module ActiveReporter
4
4
  module Serializer
@@ -13,7 +13,7 @@ module ActiveReporter
13
13
  # on the aggregators or dimension name.
14
14
 
15
15
  def human_aggregator_label(aggregators)
16
- aggregators.keys.collect { |aggregator| aggregator.to_s.humanize }.join(' ')
16
+ aggregators.keys.collect { |aggregator| aggregator.to_s.humanize }.join(" ")
17
17
  end
18
18
 
19
19
  def human_dimension_label(dimension)
@@ -62,8 +62,8 @@ module ActiveReporter
62
62
 
63
63
  def time_formats
64
64
  {
65
- minutes: '%F %k:%M', hours: '%F %k', days: '%F',
66
- weeks: 'week of %F', months: '%Y-%m', years: '%Y'
65
+ minutes: "%F %k:%M", hours: "%F %k", days: "%F",
66
+ weeks: "week of %F", months: "%Y-%m", years: "%Y"
67
67
  }
68
68
  end
69
69
 
@@ -95,8 +95,8 @@ module ActiveReporter
95
95
  report.filters.flat_map do |dimension|
96
96
  human_dimension_label(dimension) + " = " + dimension.filter_values.map do |value|
97
97
  human_dimension_value_label(dimension, value)
98
- end.to_sentence(last_word_connector: ', or ')
99
- end.join('; ')
98
+ end.to_sentence(last_word_connector: ", or ")
99
+ end.join("; ")
100
100
  end
101
101
  end
102
102
  end
@@ -1,4 +1,4 @@
1
- require 'csv'
1
+ require "csv"
2
2
 
3
3
  module ActiveReporter
4
4
  module Serializer
@@ -11,7 +11,7 @@ module ActiveReporter
11
11
  end
12
12
 
13
13
  def save(filename = self.filename)
14
- File.open(filename, 'w') { |f| f.write data }
14
+ File.open(filename, "w") { |f| f.write data }
15
15
  end
16
16
 
17
17
  def filename