report_cat 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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +147 -0
- data/Rakefile +24 -0
- data/app/assets/javascripts/report_cat/application.js +13 -0
- data/app/assets/stylesheets/report_cat/application.css +13 -0
- data/app/controllers/report_cat/reports_controller.rb +43 -0
- data/app/helpers/report_cat/reports_helper.rb +132 -0
- data/app/models/report_cat/date_range.rb +94 -0
- data/app/views/report_cat/reports/_google_charts.html.erb +61 -0
- data/app/views/report_cat/reports/index.html.erb +2 -0
- data/app/views/report_cat/reports/show.html.erb +15 -0
- data/config/locales/en.yml +26 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20130918075200_create_date_ranges.rb +13 -0
- data/lib/report_cat/config.rb +30 -0
- data/lib/report_cat/core/chart.rb +50 -0
- data/lib/report_cat/core/column.rb +70 -0
- data/lib/report_cat/core/param.rb +35 -0
- data/lib/report_cat/core/report.rb +127 -0
- data/lib/report_cat/engine.rb +11 -0
- data/lib/report_cat/matchers/have_chart.rb +58 -0
- data/lib/report_cat/matchers/have_column.rb +45 -0
- data/lib/report_cat/matchers/have_param.rb +52 -0
- data/lib/report_cat/reports/cohort_report.rb +113 -0
- data/lib/report_cat/reports/date_range_report.rb +66 -0
- data/lib/report_cat/version.rb +3 -0
- data/lib/report_cat.rb +39 -0
- data/lib/tasks/report_cat.rake +4 -0
- data/spec/controllers/report_cat/reports_controller_spec.rb +100 -0
- data/spec/coverage_spec.rb +18 -0
- data/spec/data/helpers/report_charts.html +1 -0
- data/spec/data/helpers/report_charts.html.tmp +1 -0
- data/spec/data/helpers/report_form.html +63 -0
- data/spec/data/helpers/report_form.html.tmp +63 -0
- data/spec/data/helpers/report_form_param.html +1 -0
- data/spec/data/helpers/report_form_param.html.tmp +1 -0
- data/spec/data/helpers/report_list.html +1 -0
- data/spec/data/helpers/report_list.html.tmp +1 -0
- data/spec/data/helpers/report_param_checkbox.html +1 -0
- data/spec/data/helpers/report_param_checkbox.html.tmp +1 -0
- data/spec/data/helpers/report_param_date.html +60 -0
- data/spec/data/helpers/report_param_date.html.tmp +60 -0
- data/spec/data/helpers/report_param_hidden.html +1 -0
- data/spec/data/helpers/report_param_hidden.html.tmp +1 -0
- data/spec/data/helpers/report_param_select.html +3 -0
- data/spec/data/helpers/report_param_select.html.tmp +3 -0
- data/spec/data/helpers/report_param_text_field.html +1 -0
- data/spec/data/helpers/report_param_text_field.html.tmp +1 -0
- data/spec/data/helpers/report_table.html +1 -0
- data/spec/data/helpers/report_table.html.tmp +1 -0
- data/spec/data/helpers/report_table_hidden.html +1 -0
- data/spec/data/helpers/report_table_hidden.html.tmp +1 -0
- data/spec/data/lib/chart_columns.json +1 -0
- data/spec/data/lib/chart_columns.json.tmp +1 -0
- data/spec/data/lib/chart_data.json +1 -0
- data/spec/data/lib/chart_data.json.tmp +1 -0
- data/spec/data/lib/date_range_report_where.sql +6 -0
- data/spec/data/lib/date_range_report_where.sql.tmp +6 -0
- data/spec/data/lib/report.csv +3 -0
- data/spec/data/lib/report.csv.tmp +3 -0
- data/spec/data/lib/report.sql +1 -0
- data/spec/data/lib/report.sql.tmp +1 -0
- data/spec/data/models/sql_intersect.sql +5 -0
- data/spec/data/models/sql_intersect.sql.tmp +5 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +21 -0
- data/spec/dummy/app/controllers/root_controller.rb +20 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +13 -0
- data/spec/dummy/app/models/visit.rb +16 -0
- data/spec/dummy/app/reports/retention_cohort_report.rb +19 -0
- data/spec/dummy/app/reports/retention_report.rb +30 -0
- data/spec/dummy/app/reports/user_report.rb +23 -0
- data/spec/dummy/app/views/layouts/admin.html.erb +19 -0
- data/spec/dummy/app/views/layouts/application.html.erb +19 -0
- data/spec/dummy/app/views/root/index.html.erb +8 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +30 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +31 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/report_cat.rb +15 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +38 -0
- data/spec/dummy/config/routes.rb +13 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +26 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +61 -0
- data/spec/dummy/log/test.log +26478 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/helpers/report_cat/reports_helper_spec.rb +224 -0
- data/spec/lib/report_cat/config_spec.rb +96 -0
- data/spec/lib/report_cat/core/chart_spec.rb +67 -0
- data/spec/lib/report_cat/core/column_spec.rb +156 -0
- data/spec/lib/report_cat/core/param_spec.rb +95 -0
- data/spec/lib/report_cat/core/report_spec.rb +342 -0
- data/spec/lib/report_cat/engine_spec.rb +9 -0
- data/spec/lib/report_cat/matchers/have_chart_spec.rb +36 -0
- data/spec/lib/report_cat/matchers/have_column_spec.rb +30 -0
- data/spec/lib/report_cat/matchers/have_param_spec.rb +33 -0
- data/spec/lib/report_cat/reports/cohort_report_spec.rb +215 -0
- data/spec/lib/report_cat/reports/date_range_report_spec.rb +125 -0
- data/spec/lib/report_cat/version_spec.rb +11 -0
- data/spec/lib/report_cat_spec.rb +62 -0
- data/spec/lib/tasks/report_cat.rake_spec.rb +13 -0
- data/spec/models/report_cat/date_range_spec.rb +144 -0
- data/spec/rails_helper.rb +49 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/setup_reports.rb +28 -0
- data/spec/views/report_cat/reports/index.html.erb_spec.rb +16 -0
- data/spec/views/report_cat/reports/show.html.erb_spec.rb +19 -0
- metadata +489 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module ReportCat
|
|
4
|
+
module Reports
|
|
5
|
+
|
|
6
|
+
describe CohortReport do
|
|
7
|
+
|
|
8
|
+
before( :each ) do
|
|
9
|
+
@cohort = DateRangeReport.new
|
|
10
|
+
@cohort.add_column( :total, :integer, :sql => '0' )
|
|
11
|
+
@cohort.add_param( :foo, :integer )
|
|
12
|
+
@cohort.add_param( :bar, :string )
|
|
13
|
+
|
|
14
|
+
@period = :weekly
|
|
15
|
+
@start_date = Date.civil( 2013, 1, 1 )
|
|
16
|
+
@stop_date = Date.civil( 2013, 1, 31 )
|
|
17
|
+
|
|
18
|
+
@report = CohortReport.new( :cohort => @cohort )
|
|
19
|
+
@report.param( :start_date ).value = @start_date
|
|
20
|
+
@report.param( :stop_date ).value = @stop_date
|
|
21
|
+
@report.param( :period ).value = @period
|
|
22
|
+
|
|
23
|
+
@range = DateRange.range( @period, @start_date, @stop_date )
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#############################################################################
|
|
27
|
+
# initialize
|
|
28
|
+
|
|
29
|
+
describe '#initialize' do
|
|
30
|
+
|
|
31
|
+
it 'uses a default name' do
|
|
32
|
+
expect( @report.name ).to eql( :cohort_report )
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'adds a total column' do
|
|
36
|
+
expect( @report ).to have_column( :total ).with_type( :integer )
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'merges in any non-duplicate params from the cohort report' do
|
|
40
|
+
expect( @report ).to have_param( :foo ).with_type( :integer )
|
|
41
|
+
expect( @report ).to have_param( :bar ).with_type( :string )
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'defaults cohort_column to :total' do
|
|
45
|
+
expect( @report.cohort_column ).to eql( :total )
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'accepts cohort_column as an attribute' do
|
|
49
|
+
@report = CohortReport.new( :cohort_column => :test )
|
|
50
|
+
expect( @report.cohort_column ).to eql( :test )
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#############################################################################
|
|
55
|
+
# query
|
|
56
|
+
|
|
57
|
+
describe '#query' do
|
|
58
|
+
|
|
59
|
+
it 'adds columns for each date range' do
|
|
60
|
+
@report.query
|
|
61
|
+
expect( @report.columns.size ).to eql( 4 + @range.size )
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'adds rows for each date range' do
|
|
65
|
+
@report.query
|
|
66
|
+
expect( @report.rows.size ).to eql( @range.size )
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'adds a line chart of all its columns' do
|
|
70
|
+
@report.query
|
|
71
|
+
expect( @report.charts.size ).to eql( 1 )
|
|
72
|
+
expect( @report ).to have_chart( :cohort_line ).with_type( :line )
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'adds an link column' do
|
|
76
|
+
expect( @report.column( :link ) ).to be_nil
|
|
77
|
+
@report.query
|
|
78
|
+
expect( @report.column( :link ) ).to be_present
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#############################################################################
|
|
83
|
+
# add_row
|
|
84
|
+
|
|
85
|
+
describe '#add_row' do
|
|
86
|
+
|
|
87
|
+
before( :each ) do
|
|
88
|
+
DateRange.generate( @period, @start_date, @stop_date )
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'returns the generates row' do
|
|
92
|
+
expect( @report.add_row( @range.first, @range ) ).to be_an_instance_of( Array )
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'generates the report for this cohort' do
|
|
96
|
+
expect( @report ).to receive( :generate_cohort )
|
|
97
|
+
@report.add_row( @range.first, @range )
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'sets the first three columns to start, stop, total' do
|
|
101
|
+
@report.add_row( @range.first, @range )
|
|
102
|
+
expect( @report.columns[ 0 ].name ).to eql( :start_date )
|
|
103
|
+
expect( @report.columns[ 1 ].name ).to eql( :stop_date )
|
|
104
|
+
expect( @report.columns[ 2 ].name ).to eql( :total )
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'fills in the columns by date range' do
|
|
108
|
+
row = @report.add_row( @range.first, @range )
|
|
109
|
+
expect( row ).to be_an_instance_of( Array )
|
|
110
|
+
expect( row.size ).to eql( @range.size + 3 )
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'fills nil when there is no data' do
|
|
114
|
+
allow( @report.cohort ).to receive( :rows ).and_return( [] )
|
|
115
|
+
row = @report.add_row( @range.first, @range )
|
|
116
|
+
expect( row[ 3 ] ).to be_nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'fills with the total value' do
|
|
120
|
+
allow( @report.cohort ).to receive( :rows ).and_return( [ [ '', '', 30 ], [ '', '', 20 ], [ '', '', 10 ] ] )
|
|
121
|
+
row = @report.add_row( @range.first, @range )
|
|
122
|
+
expect( row[ 3 ] ).to eql( 30.0 )
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'tolerates total being 0' do
|
|
126
|
+
allow( @report.cohort ).to receive( :rows ).and_return( [ [ '', '', 0 ], [ '', '', 20 ], [ '', '', 10 ] ] )
|
|
127
|
+
row = @report.add_row( @range.first, @range )
|
|
128
|
+
expect( row[ 3 ] ).to eql( 0.0 )
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#############################################################################
|
|
134
|
+
# generate_cohort
|
|
135
|
+
|
|
136
|
+
describe '#generate_cohort' do
|
|
137
|
+
|
|
138
|
+
before( :each ) do
|
|
139
|
+
DateRange.generate( @period, @start_date, @stop_date )
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'initializes the start, stop, and period of the cohort report' do
|
|
143
|
+
@report.cohort.param( :period ).value = :monthly
|
|
144
|
+
@report.cohort.param( :start_date ).value = Date.civil( 2012, 1, 1)
|
|
145
|
+
@report.cohort.param( :stop_date ).value = Date.civil( 2012, 1, 1)
|
|
146
|
+
|
|
147
|
+
@report.generate_cohort( @range.first )
|
|
148
|
+
|
|
149
|
+
expect( @report.cohort.param( :period ).value ).to eql( @report.param( :period ).value )
|
|
150
|
+
expect( @report.cohort.param( :start_date ).value ).to eql( @range.first.start_date )
|
|
151
|
+
expect( @report.cohort.param( :stop_date ).value ).to eql( @report.param( :stop_date ).value )
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'generates the cohort report' do
|
|
155
|
+
expect( @report.cohort ).to receive( :generate )
|
|
156
|
+
@report.generate_cohort( @range.first )
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
#############################################################################
|
|
162
|
+
# add_link_column
|
|
163
|
+
|
|
164
|
+
describe '#add_link_column' do
|
|
165
|
+
|
|
166
|
+
before( :each ) do
|
|
167
|
+
allow( @report ).to receive( :rows ).and_return( [ [ Date.parse( '2014-04-22' ), nil, nil ] ] )
|
|
168
|
+
@report.add_link_column
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'adds a link column' do
|
|
172
|
+
expect( @report ).to have_column( :link ).with_type( :report )
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it 'populates the link column' do
|
|
176
|
+
i_link = @report.column_index( :link )
|
|
177
|
+
i_start = @report.column_index( :start_date )
|
|
178
|
+
|
|
179
|
+
@report.rows.each do |row|
|
|
180
|
+
start_date = row[ i_start ]
|
|
181
|
+
expect( row[ i_link ] ).to eql( @report.cohort_link( start_date ) )
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
#############################################################################
|
|
188
|
+
# cohort_link
|
|
189
|
+
|
|
190
|
+
describe '#cohort_link' do
|
|
191
|
+
|
|
192
|
+
it 'gets the cohort attributes as a hash' do
|
|
193
|
+
start_date = @report.param( :start_date ).value
|
|
194
|
+
cohort_link = @report.cohort_link( start_date )
|
|
195
|
+
|
|
196
|
+
expect( cohort_link[ :name ] ).to eql( @report.cohort.name )
|
|
197
|
+
expect( cohort_link[ :id ] ).to eql( @report.cohort.name )
|
|
198
|
+
expect( cohort_link[ :start_date ] ).to eql( start_date )
|
|
199
|
+
expect( cohort_link[ :stop_date ] ).to eql( @report.param( :stop_date ).value )
|
|
200
|
+
expect( cohort_link[ :period ] ).to eql( @report.param( :period ).value )
|
|
201
|
+
expect( cohort_link[ :back ] ).to eql( @report.attributes )
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it 'accepts link attributes to override the report values' do
|
|
205
|
+
link_attributes = { :period => :foobar }
|
|
206
|
+
start_date = @report.param( :start_date ).value
|
|
207
|
+
cohort_link = @report.cohort_link( start_date, link_attributes )
|
|
208
|
+
expect( cohort_link[ :period ] ).to eql( :foobar )
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module ReportCat
|
|
4
|
+
module Reports
|
|
5
|
+
|
|
6
|
+
describe DateRangeReport do
|
|
7
|
+
|
|
8
|
+
before( :each ) do
|
|
9
|
+
@report = DateRangeReport.new
|
|
10
|
+
|
|
11
|
+
@table_name = ReportCat::DateRange.table_name
|
|
12
|
+
@defaults = {
|
|
13
|
+
:name => :date_range_report,
|
|
14
|
+
:from => @table_name,
|
|
15
|
+
:order_by => "#{@table_name}.start_date asc",
|
|
16
|
+
:group_by => "#{@table_name}.start_date, #{@table_name}.stop_date"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@period = :weekly
|
|
20
|
+
@start_date = Date.civil( 2013, 9, 1 )
|
|
21
|
+
@stop_date = Date.civil( 2013, 9, 18 )
|
|
22
|
+
|
|
23
|
+
@report.param( :period ).value = @period
|
|
24
|
+
@report.param( :start_date ).value = @start_date
|
|
25
|
+
@report.param( :stop_date ).value = @stop_date
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'defines supported time periods' do
|
|
29
|
+
expected = [ :daily, :weekly, :monthly, :quarterly, :yearly ]
|
|
30
|
+
expect( DateRangeReport::PERIODS ).to eql( expected )
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#############################################################################
|
|
34
|
+
# defaults
|
|
35
|
+
|
|
36
|
+
describe '#defaults' do
|
|
37
|
+
|
|
38
|
+
it 'defines default report values' do
|
|
39
|
+
expect( @report.defaults ).to eql( @defaults )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#############################################################################
|
|
45
|
+
# initialize
|
|
46
|
+
|
|
47
|
+
describe '#initialize' do
|
|
48
|
+
|
|
49
|
+
it 'merges default values' do
|
|
50
|
+
name = :test
|
|
51
|
+
@report = DateRangeReport.new( :name => name )
|
|
52
|
+
expect( @report.name ).to be( name )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'defines params' do
|
|
56
|
+
expect( @report.params.size ).to eql( 3 )
|
|
57
|
+
expect( @report ).to have_param( :start_date ).with_type( :date ).with_value( @start_date )
|
|
58
|
+
expect( @report ).to have_param( :stop_date ).with_type( :date ).with_value( @stop_date )
|
|
59
|
+
expect( @report ).to have_param( :period ).with_type( :select ).with_value( :weekly ).with_options( :values => DateRangeReport::PERIODS )
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'defines columns' do
|
|
63
|
+
expect( @report.columns.size ).to eql( 2 )
|
|
64
|
+
expect( @report ).to have_column( :start_date ).with_type( :date ).with_options( :sql => "report_cat_date_ranges.start_date" )
|
|
65
|
+
expect( @report ).to have_column( :stop_date ).with_type( :date ).with_options( :sql => "report_cat_date_ranges.stop_date" )
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#############################################################################
|
|
71
|
+
# query
|
|
72
|
+
|
|
73
|
+
describe '#query' do
|
|
74
|
+
|
|
75
|
+
it 'generates the required date ranges' do
|
|
76
|
+
expect( DateRange ).to receive( :generate ).with( @period, @start_date, @stop_date )
|
|
77
|
+
@report.query
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'calls query on its super' do
|
|
81
|
+
expect( @report ).to receive( :to_sql ).and_return( 'select 1' )
|
|
82
|
+
@report.query
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
#############################################################################
|
|
88
|
+
# where
|
|
89
|
+
|
|
90
|
+
describe '#where' do
|
|
91
|
+
|
|
92
|
+
it 'generates sql' do
|
|
93
|
+
expect( @report.where ).to eql_file( 'spec/data/lib/date_range_report_where.sql')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'includes the preconfigured where clause' do
|
|
97
|
+
where = '1 = 1'
|
|
98
|
+
@report = DateRangeReport.new( :where => where )
|
|
99
|
+
expect( @report.where ).to include( where )
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
#############################################################################
|
|
105
|
+
# accessors
|
|
106
|
+
|
|
107
|
+
describe 'accessors' do
|
|
108
|
+
|
|
109
|
+
it 'has param accessors' do
|
|
110
|
+
expect( @report.period ).to eql( @report.param( :period ).value.to_sym )
|
|
111
|
+
expect( @report.start_date ).to eql( @report.param( :start_date ).value )
|
|
112
|
+
expect( @report.stop_date ).to eql( @report.param( :stop_date ).value )
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'has a first_period accessor' do
|
|
116
|
+
expected = ReportCat::DateRange.range( @report.period, @report.start_date, @report.stop_date ).first
|
|
117
|
+
expect( @report.first_period ).to eql( expected )
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'version' do
|
|
4
|
+
|
|
5
|
+
it 'has a version constant' do
|
|
6
|
+
expect( ReportCat::VERSION ).to_not be_nil
|
|
7
|
+
expect( ReportCat::VERSION ).to be_an_instance_of( String )
|
|
8
|
+
expect( ReportCat::VERSION ).to match( /\d+\.\d+\.\d+/ )
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
include ReportCat
|
|
4
|
+
|
|
5
|
+
describe ReportCat do
|
|
6
|
+
|
|
7
|
+
it 'requires the engine' do
|
|
8
|
+
expect( ReportCat::Engine ).to_not be_nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'defines the ReportCat module' do
|
|
12
|
+
expect( ReportCat ).to_not be_nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
#############################################################################
|
|
16
|
+
# config
|
|
17
|
+
|
|
18
|
+
describe '::config' do
|
|
19
|
+
|
|
20
|
+
it 'returns the configuration' do
|
|
21
|
+
expect( ReportCat.config ).to be_an_instance_of( ReportCat::Config )
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#############################################################################
|
|
27
|
+
# configure
|
|
28
|
+
|
|
29
|
+
describe '::configure' do
|
|
30
|
+
|
|
31
|
+
it 'yields the configuration' do
|
|
32
|
+
yielded = false
|
|
33
|
+
ReportCat.configure do |config|
|
|
34
|
+
expect( config ).to be_an_instance_of( ReportCat::Config )
|
|
35
|
+
yielded = true
|
|
36
|
+
end
|
|
37
|
+
expect( yielded ).to be( true )
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#############################################################################
|
|
43
|
+
# reports
|
|
44
|
+
|
|
45
|
+
describe '::reports' do
|
|
46
|
+
|
|
47
|
+
it 'returns a HashWithIndifferentAccess' do
|
|
48
|
+
expect( ReportCat.reports ).to be_an_instance_of( HashWithIndifferentAccess )
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'adds Report subclasses to the hash' do
|
|
52
|
+
reports = ReportCat.reports
|
|
53
|
+
|
|
54
|
+
Report.descendants.each do |klass|
|
|
55
|
+
report = klass.new
|
|
56
|
+
expect( reports[ report.name.to_sym ] ).to_not be_nil
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module ReportCat
|
|
4
|
+
|
|
5
|
+
describe DateRange do
|
|
6
|
+
|
|
7
|
+
before( :each ) do
|
|
8
|
+
@period = :daily
|
|
9
|
+
@start_date = Date.civil( 2013, 9, 15 )
|
|
10
|
+
@stop_date = Date.civil( 2013, 9, 18 )
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
#############################################################################
|
|
14
|
+
# ::generate
|
|
15
|
+
|
|
16
|
+
describe '::generate' do
|
|
17
|
+
|
|
18
|
+
it 'iterates the periods in the date range' do
|
|
19
|
+
expect( DateRange ).to receive( :iterate ).with( @period, @start_date, @stop_date )
|
|
20
|
+
DateRange.generate( @period, @start_date, @stop_date )
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'creates entries for each period' do
|
|
24
|
+
expected = ( @stop_date - @start_date ).to_i + 1
|
|
25
|
+
|
|
26
|
+
expect( DateRange.count ).to eql( 0 )
|
|
27
|
+
DateRange.generate( @period, @start_date, @stop_date )
|
|
28
|
+
expect( DateRange.count ).to eql( expected )
|
|
29
|
+
|
|
30
|
+
(@start_date..@stop_date).each do |date|
|
|
31
|
+
date_range = DateRange.where( :period => @period, :start_date => date, :stop_date => date ).first
|
|
32
|
+
expect( date_range ).to be_present
|
|
33
|
+
expect( date_range.period ).to eql( @period.to_s )
|
|
34
|
+
expect( date_range.start_date ).to eql( date )
|
|
35
|
+
expect( date_range.stop_date ).to eql( date )
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'does not create entries that already exist' do
|
|
40
|
+
DateRange.generate( @period, @start_date, @stop_date )
|
|
41
|
+
expect( DateRange ).to_not receive( :create )
|
|
42
|
+
DateRange.generate( @period, @start_date, @stop_date )
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#############################################################################
|
|
48
|
+
# ::iterate
|
|
49
|
+
|
|
50
|
+
describe '::iterate' do
|
|
51
|
+
|
|
52
|
+
it 'iterates the requests date range and yields the start and stop times for each period' do
|
|
53
|
+
expected = @stop_date - @start_date + 1
|
|
54
|
+
expect { |b| DateRange.iterate( @period, @start_date, @stop_date, &b) }.to yield_control.exactly( expected ).times
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'iterates daily' do
|
|
58
|
+
expect { |b| DateRange.iterate( :daily, '2013-01-01', '2013-12-31', &b) }.to yield_control.exactly( 365 ).times
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'iterates weekly' do
|
|
62
|
+
expect { |b| DateRange.iterate( :weekly, '2013-01-01', '2013-12-31', &b) }.to yield_control.exactly( 53 ).times
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'iterates monthly' do
|
|
66
|
+
expect { |b| DateRange.iterate( :monthly, '2013-01-01', '2013-12-31', &b) }.to yield_control.exactly( 12 ).times
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'iterates quarterly' do
|
|
70
|
+
expect { |b| DateRange.iterate( :quarterly, '2013-01-01', '2013-12-31', &b) }.to yield_control.exactly( 4 ).times
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'iterates yearly' do
|
|
74
|
+
expect { |b| DateRange.iterate( :yearly, '2013-01-01', '2013-12-31', &b) }.to yield_control.exactly( 1 ).times
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'raises an except for an unknown period' do
|
|
78
|
+
expect { |b| DateRange.iterate( :hourly, '2013-01-01', '2013-12-31', &b) }.to raise_error( 'Unknown date range: hourly' )
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#############################################################################
|
|
84
|
+
# ::join_*
|
|
85
|
+
|
|
86
|
+
describe 'joins' do
|
|
87
|
+
|
|
88
|
+
before( :each ) do
|
|
89
|
+
@table = 'users'
|
|
90
|
+
@column = 'created_at'
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe '::join_to' do
|
|
94
|
+
|
|
95
|
+
it 'generates a join string' do
|
|
96
|
+
expected = "join users on date( users.created_at ) between report_cat_date_ranges.start_date and report_cat_date_ranges.stop_date"
|
|
97
|
+
expect( DateRange.join_to( @table, @column ) ).to eql( expected )
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe '::join_before' do
|
|
103
|
+
|
|
104
|
+
it 'generates a join string' do
|
|
105
|
+
expected = "join users on date( users.created_at ) <= report_cat_date_ranges.stop_date"
|
|
106
|
+
expect( DateRange.join_before( @table, @column ) ).to eql( expected )
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe '::join_after' do
|
|
112
|
+
|
|
113
|
+
it 'generates a join string' do
|
|
114
|
+
expected = "join users on date( users.created_at ) > report_cat_date_ranges.stop_date"
|
|
115
|
+
expect( DateRange.join_after( @table, @column ) ).to eql( expected )
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#############################################################################
|
|
123
|
+
# ::sql_*
|
|
124
|
+
|
|
125
|
+
describe '::sql_intersect' do
|
|
126
|
+
|
|
127
|
+
it 'generates date intersection sql' do
|
|
128
|
+
expect( DateRange.sql_intersect( '2013-09-01', '2013-09-18' ) ).to eql_file( 'spec/data/models/sql_intersect.sql')
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
describe '::sql_period' do
|
|
134
|
+
|
|
135
|
+
it 'generate query sql' do
|
|
136
|
+
expected = "report_cat_date_ranges.period = 'weekly'"
|
|
137
|
+
expect( DateRange.sql_period( :weekly ) ).to eql( expected )
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
require 'spec_helper'
|
|
6
|
+
require File.expand_path('../dummy/config/environment', __FILE__)
|
|
7
|
+
require 'rspec/rails'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
ENGINE_ROOT = File.join(File.dirname(__FILE__), '..')
|
|
11
|
+
|
|
12
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
|
13
|
+
# in spec/support/ and its subdirectories.
|
|
14
|
+
Dir[File.join(ENGINE_ROOT, 'spec/support/**/*.rb')].each {|f| require f }
|
|
15
|
+
|
|
16
|
+
# Checks for pending migrations before tests are run.
|
|
17
|
+
# If you are not using ActiveRecord, you can remove this line.
|
|
18
|
+
ActiveRecord::Migration.maintain_test_schema!
|
|
19
|
+
|
|
20
|
+
RSpec.configure do |config|
|
|
21
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
|
22
|
+
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
|
23
|
+
|
|
24
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
|
25
|
+
# examples within a transaction, remove the following line or assign false
|
|
26
|
+
# instead of true.
|
|
27
|
+
config.use_transactional_fixtures = true
|
|
28
|
+
|
|
29
|
+
# If true, the base class of anonymous controllers will be inferred
|
|
30
|
+
# automatically. This will be the default behavior in future versions of
|
|
31
|
+
# rspec-rails.
|
|
32
|
+
# config.infer_base_class_for_anonymous_controllers = false
|
|
33
|
+
|
|
34
|
+
# RSpec Rails can automatically mix in different behaviours to your tests
|
|
35
|
+
# based on their file location, for example enabling you to call `get` and
|
|
36
|
+
# `post` in specs under `spec/controllers`.
|
|
37
|
+
#
|
|
38
|
+
# You can disable this behaviour by removing the line below, and instead
|
|
39
|
+
# explicitly tag your specs with their type, e.g.:
|
|
40
|
+
#
|
|
41
|
+
# RSpec.describe UsersController, :type => :controller do
|
|
42
|
+
# # ...
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# The different available types are documented in the features, such as in
|
|
46
|
+
# https://relishapp.com/rspec/rspec-rails/docs
|
|
47
|
+
config.infer_spec_type_from_file_location!
|
|
48
|
+
|
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_cat'
|
|
2
|
+
|
|
3
|
+
require 'simplecov'
|
|
4
|
+
require 'coveralls'
|
|
5
|
+
|
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
|
7
|
+
SimpleCov::Formatter::HTMLFormatter,
|
|
8
|
+
Coveralls::SimpleCov::Formatter
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
SimpleCov.start 'rails' do
|
|
12
|
+
add_filter '/vendor/'
|
|
13
|
+
add_filter '/spec/'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
RSpec.configure do |config|
|
|
17
|
+
|
|
18
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
19
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
20
|
+
# the seed, which is printed after each run.
|
|
21
|
+
# --seed 1234
|
|
22
|
+
config.order = 'random'
|
|
23
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module SetupReports
|
|
2
|
+
|
|
3
|
+
include ReportCat::Core
|
|
4
|
+
|
|
5
|
+
def setup_reports
|
|
6
|
+
@report = Report.new( :name => :test )
|
|
7
|
+
|
|
8
|
+
@report.add_param( :check_box_test, :check_box, false )
|
|
9
|
+
@report.add_param( :date_test, :date, Date.civil( 2013, 9, 16 ) )
|
|
10
|
+
@report.add_param( :hidden_test, :check_box, true, :hidden => true )
|
|
11
|
+
@report.add_param( :select_test, :select, 1, :values => [ 1, 2, 3 ] )
|
|
12
|
+
@report.add_param( :text_field_test, :text_field )
|
|
13
|
+
|
|
14
|
+
@report.add_column( :day, :date )
|
|
15
|
+
@report.add_column( :total, :integer )
|
|
16
|
+
|
|
17
|
+
@report.add_chart( :pie_test, :pie, :day, :total )
|
|
18
|
+
@report.add_chart( :bar_test, :bar, :day, :total )
|
|
19
|
+
@report.add_chart( :line_test, :line, :day, :total )
|
|
20
|
+
|
|
21
|
+
@report.rows[ 0 ] = [ '2013-09-17', 27 ]
|
|
22
|
+
@report.rows[ 1 ] = [ '2013-09-18', 270 ]
|
|
23
|
+
|
|
24
|
+
@reports = HashWithIndifferentAccess.new
|
|
25
|
+
@reports[ @report.name.to_sym ] = @report
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|