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