reports_kit 0.1.0 → 0.2.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -5
  3. data/app/assets/javascripts/reports_kit/lib/chart.js +33 -8
  4. data/app/assets/javascripts/reports_kit/lib/report.js +27 -26
  5. data/app/assets/javascripts/reports_kit/lib/table.js +58 -0
  6. data/app/assets/javascripts/reports_kit/vendor/jquery.tablesorter.min.js +4 -0
  7. data/app/assets/stylesheets/reports_kit/reports.css.sass +20 -0
  8. data/config/initializers/mime_types.rb +1 -0
  9. data/docs/dimensions.md +34 -26
  10. data/docs/display_options.md +15 -12
  11. data/docs/filters.md +2 -2
  12. data/docs/measures.md +4 -3
  13. data/gemfiles/mysql.gemfile.lock +14 -1
  14. data/gemfiles/postgresql.gemfile.lock +14 -1
  15. data/lib/reports_kit.rb +15 -0
  16. data/lib/reports_kit/cache.rb +37 -0
  17. data/lib/reports_kit/configuration.rb +13 -1
  18. data/lib/reports_kit/helper.rb +54 -3
  19. data/lib/reports_kit/model_configuration.rb +6 -1
  20. data/lib/reports_kit/order.rb +33 -0
  21. data/lib/reports_kit/relative_time.rb +42 -0
  22. data/lib/reports_kit/report_builder.rb +34 -15
  23. data/lib/reports_kit/reports/abstract_measure.rb +9 -0
  24. data/lib/reports_kit/reports/adapters/mysql.rb +8 -1
  25. data/lib/reports_kit/reports/adapters/postgresql.rb +8 -1
  26. data/lib/reports_kit/reports/composite_measure.rb +43 -0
  27. data/lib/reports_kit/reports/data/chart_options.rb +5 -0
  28. data/lib/reports_kit/reports/data/composite_aggregation.rb +96 -0
  29. data/lib/reports_kit/reports/data/entity.rb +7 -0
  30. data/lib/reports_kit/reports/data/format_one_dimension.rb +120 -0
  31. data/lib/reports_kit/reports/data/format_two_dimensions.rb +141 -0
  32. data/lib/reports_kit/reports/data/generate.rb +72 -25
  33. data/lib/reports_kit/reports/data/generate_for_properties.rb +75 -0
  34. data/lib/reports_kit/reports/data/one_dimension.rb +15 -49
  35. data/lib/reports_kit/reports/data/populate_one_dimension.rb +36 -0
  36. data/lib/reports_kit/reports/data/populate_two_dimensions.rb +104 -0
  37. data/lib/reports_kit/reports/data/two_dimensions.rb +15 -110
  38. data/lib/reports_kit/reports/data/utils.rb +77 -12
  39. data/lib/reports_kit/reports/data/value.rb +7 -0
  40. data/lib/reports_kit/reports/dimension.rb +4 -110
  41. data/lib/reports_kit/reports/dimension_with_measure.rb +137 -0
  42. data/lib/reports_kit/reports/filter.rb +5 -64
  43. data/lib/reports_kit/reports/filter_types/base.rb +1 -1
  44. data/lib/reports_kit/reports/filter_types/boolean.rb +9 -7
  45. data/lib/reports_kit/reports/filter_types/datetime.rb +7 -5
  46. data/lib/reports_kit/reports/filter_types/number.rb +2 -0
  47. data/lib/reports_kit/reports/filter_with_measure.rb +84 -0
  48. data/lib/reports_kit/reports/generate_autocomplete_results.rb +1 -1
  49. data/lib/reports_kit/reports/inferrable_configuration.rb +32 -13
  50. data/lib/reports_kit/reports/measure.rb +48 -12
  51. data/lib/reports_kit/reports_controller.rb +42 -3
  52. data/lib/reports_kit/version.rb +1 -1
  53. data/reports_kit.gemspec +2 -0
  54. data/spec/fixtures/generate_inputs.yml +146 -21
  55. data/spec/fixtures/generate_outputs.yml +768 -17
  56. data/spec/reports_kit/relative_time_spec.rb +29 -0
  57. data/spec/reports_kit/report_builder_spec.rb +28 -0
  58. data/spec/reports_kit/reports/data/generate_spec.rb +614 -27
  59. data/spec/reports_kit/reports/dimension_with_measure_spec.rb +69 -0
  60. data/spec/reports_kit/reports/{filter_spec.rb → filter_with_measure_spec.rb} +4 -3
  61. data/spec/spec_helper.rb +7 -2
  62. data/spec/support/config.rb +11 -0
  63. data/spec/support/helpers.rb +3 -3
  64. data/spec/support/models/issue.rb +7 -0
  65. metadata +53 -4
  66. data/spec/reports_kit/reports/dimension_spec.rb +0 -54
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReportsKit::Reports::DimensionWithMeasure do
4
+ subject { described_class.new(dimension: dimension, measure: measure) }
5
+ let(:dimension) { ReportsKit::Reports::Dimension.new(properties) }
6
+ let(:measure) { ReportsKit::Reports::Measure.new(key: 'issue', dimensions: [properties]) }
7
+
8
+ describe 'settings' do
9
+ context 'with a datetime dimension' do
10
+ let(:properties) { 'opened_at' }
11
+
12
+ it 'returns the settings' do
13
+ expect(subject.settings).to eq({ column: 'issues.opened_at', group: database_adapter.truncate_to_week('issues.opened_at') })
14
+ end
15
+ end
16
+
17
+ context 'with a string dimension' do
18
+ let(:properties) { 'title' }
19
+
20
+ it 'returns the settings' do
21
+ expect(subject.settings).to eq({ column: 'issues.title', group: "issues.title" })
22
+ end
23
+ end
24
+
25
+ context 'with a text dimension' do
26
+ let(:properties) { 'description' }
27
+
28
+ it 'returns the settings' do
29
+ expect(subject.settings).to eq({ column: 'issues.description', group: "issues.description" })
30
+ end
31
+ end
32
+
33
+ context 'with a belongs_to association dimension' do
34
+ let(:properties) { 'repo' }
35
+
36
+ it 'returns the settings' do
37
+ expect(subject.settings).to eq({ column: 'issues.repo_id', group: 'issues.repo_id' })
38
+ end
39
+ end
40
+
41
+ context 'with a has_many association dimension' do
42
+ let(:properties) { 'tags' }
43
+
44
+ it 'returns the settings' do
45
+ expect(subject.settings).to eq({ joins: :tags, column: 'tags.id', group: 'issues.issue_id' })
46
+ end
47
+ end
48
+
49
+ context 'with a has_many :through association dimension' do
50
+ let(:properties) { 'labels' }
51
+
52
+ it 'returns the settings' do
53
+ expect(subject.settings).to eq({ joins: :issues_labels, column: 'issues_labels.label_id', group: 'issues_labels.label_id' })
54
+ end
55
+ end
56
+
57
+ describe ':key_to_label setting' do
58
+ context 'with a Proc' do
59
+ let(:properties) { 'titleized_state' }
60
+
61
+ it 'returns the result of the Proc' do
62
+ expect(subject.key_to_label('foo')).to eq('Foo')
63
+ end
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -1,8 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ReportsKit::Reports::Filter do
4
- subject { described_class.new(properties, measure: measure) }
5
- let(:measure) { ReportsKit::Reports::Measure.new('issue') }
3
+ describe ReportsKit::Reports::FilterWithMeasure do
4
+ subject { described_class.new(filter: filter, measure: measure) }
5
+ let(:filter) { ReportsKit::Reports::Filter.new(properties) }
6
+ let(:measure) { ReportsKit::Reports::Measure.new(key: 'issue', dimensions: %w(repo)) }
6
7
 
7
8
  context 'with a datetime filter' do
8
9
  let(:properties) { 'opened_at' }
@@ -2,19 +2,20 @@ require 'reports_kit'
2
2
 
3
3
  require 'database_cleaner'
4
4
  require 'pry'
5
+ require 'pry-byebug'
5
6
  require 'timecop'
6
7
  require 'support/factory_girl'
7
8
  require 'support/helpers'
8
9
 
9
10
  directory = File.dirname(File.absolute_path(__FILE__))
10
11
  Dir.glob("#{directory}/factories/*.rb") { |file| require file }
11
- Dir.glob("#{directory}/support/models/*.rb") { |file| require file }
12
12
 
13
13
  Time.zone = ActiveSupport::TimeZone.new('UTC')
14
14
  ActiveRecord::Base.default_timezone = :utc
15
15
 
16
16
  if Gem.loaded_specs.has_key?('mysql2')
17
17
  REPORTS_KIT_DATABASE_ADAPTER = ReportsKit::Reports::Adapters::Mysql
18
+ REPORTS_KIT_DATABASE_TYPE = :mysql
18
19
  ActiveRecord::Base.establish_connection(
19
20
  adapter: 'mysql2',
20
21
  host: 'localhost',
@@ -23,6 +24,7 @@ if Gem.loaded_specs.has_key?('mysql2')
23
24
  )
24
25
  else
25
26
  REPORTS_KIT_DATABASE_ADAPTER = ReportsKit::Reports::Adapters::Postgresql
27
+ REPORTS_KIT_DATABASE_TYPE = :postgresql
26
28
  ActiveRecord::Base.establish_connection(
27
29
  adapter: 'postgresql',
28
30
  host: 'localhost',
@@ -30,6 +32,8 @@ else
30
32
  username: 'postgres'
31
33
  )
32
34
  end
35
+ Dir.glob("#{directory}/support/models/*.rb") { |file| require file }
36
+ require 'support/config'
33
37
  require 'support/schema'
34
38
 
35
39
  RSpec.configure do |config|
@@ -47,8 +51,9 @@ RSpec.configure do |config|
47
51
  # --seed 1234
48
52
  config.order = 'random'
49
53
 
54
+ TIMECOP_TIME = Time.utc(2010)
50
55
  config.before(:each) do
51
- Timecop.freeze(Time.utc(2010))
56
+ Timecop.freeze(TIMECOP_TIME)
52
57
  end
53
58
  config.after(:each) do
54
59
  Timecop.return
@@ -0,0 +1,11 @@
1
+ ReportsKit.configure do |config|
2
+ config.custom_methods = {
3
+ format_percentage: -> (value) { "#{value.round(0)}%" },
4
+ add_label_suffix: -> (data) {
5
+ data[:entities].each do |entity|
6
+ entity.label = "#{entity.label} Foo" if entity.label
7
+ end
8
+ data
9
+ }
10
+ }
11
+ end
@@ -7,15 +7,15 @@ module Helpers
7
7
  REPORTS_KIT_DATABASE_ADAPTER
8
8
  end
9
9
 
10
- def date_string_for_filter(time)
10
+ def format_criteria_time(time)
11
11
  time.strftime('%b %-d, %Y')
12
12
  end
13
13
 
14
14
  def format_day_offset(day_offset)
15
- ReportsKit::Reports::Data::Utils.format_time((now - day_offset.days))
15
+ ReportsKit::Reports::Data::Utils.format_display_time((now - day_offset.days))
16
16
  end
17
17
 
18
18
  def format_week_offset(week_offset)
19
- ReportsKit::Reports::Data::Utils.format_time((now - week_offset.weeks).beginning_of_week)
19
+ ReportsKit::Reports::Data::Utils.format_display_time((now - week_offset.weeks).beginning_of_week(ReportsKit.configuration.first_day_of_week))
20
20
  end
21
21
  end
@@ -1,6 +1,13 @@
1
1
  class Issue < ActiveRecord::Base
2
+ include ReportsKit::Model
3
+
2
4
  belongs_to :repo
3
5
  has_many :issues_labels
4
6
  has_many :labels, through: :issues_labels
5
7
  has_many :tags
8
+
9
+ reports_kit do
10
+ aggregation :average_duration, [:average, REPORTS_KIT_DATABASE_TYPE == :mysql ? 'DATEDIFF(closed_at, opened_at)' : '(closed_at::date - opened_at::date)']
11
+ dimension :titleized_state, group: 'issues.state', key_to_label: -> (state) { state.try(:titleize) }
12
+ end
6
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reports_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Benner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-05 00:00:00.000000000 Z
11
+ date: 2017-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: spreadsheet
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: appraisal
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,20 @@ dependencies:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry-byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: timecop
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -141,8 +169,10 @@ files:
141
169
  - app/assets/javascripts/reports_kit/lib/_init.js
142
170
  - app/assets/javascripts/reports_kit/lib/chart.js
143
171
  - app/assets/javascripts/reports_kit/lib/report.js
172
+ - app/assets/javascripts/reports_kit/lib/table.js
144
173
  - app/assets/javascripts/reports_kit/vendor/chart.js
145
174
  - app/assets/javascripts/reports_kit/vendor/daterangepicker.js
175
+ - app/assets/javascripts/reports_kit/vendor/jquery.tablesorter.min.js
146
176
  - app/assets/javascripts/reports_kit/vendor/moment.js
147
177
  - app/assets/javascripts/reports_kit/vendor/select2.full.js
148
178
  - app/assets/stylesheets/reports_kit/application.css.scss
@@ -151,6 +181,7 @@ files:
151
181
  - app/assets/stylesheets/reports_kit/vendor/daterangepicker.css
152
182
  - app/assets/stylesheets/reports_kit/vendor/select2-bootstrap.css
153
183
  - app/assets/stylesheets/reports_kit/vendor/select2.css
184
+ - config/initializers/mime_types.rb
154
185
  - config/routes.rb
155
186
  - docs/README.md
156
187
  - docs/dimensions.md
@@ -190,20 +221,34 @@ files:
190
221
  - gemfiles/postgresql.gemfile.lock
191
222
  - lib/reports_kit.rb
192
223
  - lib/reports_kit/base_controller.rb
224
+ - lib/reports_kit/cache.rb
193
225
  - lib/reports_kit/configuration.rb
194
226
  - lib/reports_kit/engine.rb
195
227
  - lib/reports_kit/helper.rb
196
228
  - lib/reports_kit/model.rb
197
229
  - lib/reports_kit/model_configuration.rb
230
+ - lib/reports_kit/order.rb
231
+ - lib/reports_kit/relative_time.rb
198
232
  - lib/reports_kit/report_builder.rb
233
+ - lib/reports_kit/reports/abstract_measure.rb
199
234
  - lib/reports_kit/reports/adapters/mysql.rb
200
235
  - lib/reports_kit/reports/adapters/postgresql.rb
236
+ - lib/reports_kit/reports/composite_measure.rb
201
237
  - lib/reports_kit/reports/data/chart_options.rb
238
+ - lib/reports_kit/reports/data/composite_aggregation.rb
239
+ - lib/reports_kit/reports/data/entity.rb
240
+ - lib/reports_kit/reports/data/format_one_dimension.rb
241
+ - lib/reports_kit/reports/data/format_two_dimensions.rb
202
242
  - lib/reports_kit/reports/data/generate.rb
243
+ - lib/reports_kit/reports/data/generate_for_properties.rb
203
244
  - lib/reports_kit/reports/data/one_dimension.rb
245
+ - lib/reports_kit/reports/data/populate_one_dimension.rb
246
+ - lib/reports_kit/reports/data/populate_two_dimensions.rb
204
247
  - lib/reports_kit/reports/data/two_dimensions.rb
205
248
  - lib/reports_kit/reports/data/utils.rb
249
+ - lib/reports_kit/reports/data/value.rb
206
250
  - lib/reports_kit/reports/dimension.rb
251
+ - lib/reports_kit/reports/dimension_with_measure.rb
207
252
  - lib/reports_kit/reports/filter.rb
208
253
  - lib/reports_kit/reports/filter_types/base.rb
209
254
  - lib/reports_kit/reports/filter_types/boolean.rb
@@ -211,6 +256,7 @@ files:
211
256
  - lib/reports_kit/reports/filter_types/number.rb
212
257
  - lib/reports_kit/reports/filter_types/records.rb
213
258
  - lib/reports_kit/reports/filter_types/string.rb
259
+ - lib/reports_kit/reports/filter_with_measure.rb
214
260
  - lib/reports_kit/reports/generate_autocomplete_results.rb
215
261
  - lib/reports_kit/reports/inferrable_configuration.rb
216
262
  - lib/reports_kit/reports/measure.rb
@@ -225,10 +271,13 @@ files:
225
271
  - spec/factories/tag_factory.rb
226
272
  - spec/fixtures/generate_inputs.yml
227
273
  - spec/fixtures/generate_outputs.yml
274
+ - spec/reports_kit/relative_time_spec.rb
275
+ - spec/reports_kit/report_builder_spec.rb
228
276
  - spec/reports_kit/reports/data/generate_spec.rb
229
- - spec/reports_kit/reports/dimension_spec.rb
230
- - spec/reports_kit/reports/filter_spec.rb
277
+ - spec/reports_kit/reports/dimension_with_measure_spec.rb
278
+ - spec/reports_kit/reports/filter_with_measure_spec.rb
231
279
  - spec/spec_helper.rb
280
+ - spec/support/config.rb
232
281
  - spec/support/factory_girl.rb
233
282
  - spec/support/helpers.rb
234
283
  - spec/support/models/issue.rb
@@ -1,54 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ReportsKit::Reports::Dimension do
4
- subject { described_class.new(properties, measure: measure) }
5
- let(:measure) { ReportsKit::Reports::Measure.new('issue') }
6
-
7
- context 'with a datetime dimension' do
8
- let(:properties) { 'opened_at' }
9
-
10
- it 'returns the settings' do
11
- expect(subject.settings).to eq({ column: 'issues.opened_at', group: database_adapter.truncate_to_week('issues.opened_at') })
12
- end
13
- end
14
-
15
- context 'with a string dimension' do
16
- let(:properties) { 'title' }
17
-
18
- it 'returns the settings' do
19
- expect(subject.settings).to eq({ column: 'issues.title', group: "issues.title" })
20
- end
21
- end
22
-
23
- context 'with a text dimension' do
24
- let(:properties) { 'description' }
25
-
26
- it 'returns the settings' do
27
- expect(subject.settings).to eq({ column: 'issues.description', group: "issues.description" })
28
- end
29
- end
30
-
31
- context 'with a belongs_to association dimension' do
32
- let(:properties) { 'repo' }
33
-
34
- it 'returns the settings' do
35
- expect(subject.settings).to eq({ column: 'issues.repo_id', group: 'issues.repo_id' })
36
- end
37
- end
38
-
39
- context 'with a has_many association dimension' do
40
- let(:properties) { 'tags' }
41
-
42
- it 'returns the settings' do
43
- expect(subject.settings).to eq({ joins: :tags, column: 'tags.id', group: 'issues.issue_id' })
44
- end
45
- end
46
-
47
- context 'with a has_many :through association dimension' do
48
- let(:properties) { 'labels' }
49
-
50
- it 'returns the settings' do
51
- expect(subject.settings).to eq({ joins: :issues_labels, column: 'issues_labels.label_id', group: 'issues.label_id' })
52
- end
53
- end
54
- end