reports_kit 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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