google_data_source 0.7.6

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 (64) hide show
  1. data/.document +5 -0
  2. data/.gitignore +7 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +25 -0
  6. data/Rakefile +31 -0
  7. data/google_data_source.gemspec +32 -0
  8. data/lib/assets/images/google_data_source/chart_bar_add.png +0 -0
  9. data/lib/assets/images/google_data_source/chart_bar_delete.png +0 -0
  10. data/lib/assets/images/google_data_source/loader.gif +0 -0
  11. data/lib/assets/javascripts/google_data_source/data_source_init.js +3 -0
  12. data/lib/assets/javascripts/google_data_source/extended_data_table.js +76 -0
  13. data/lib/assets/javascripts/google_data_source/filter_form.js +180 -0
  14. data/lib/assets/javascripts/google_data_source/google_visualization/combo_table.js.erb +113 -0
  15. data/lib/assets/javascripts/google_data_source/google_visualization/table.js +116 -0
  16. data/lib/assets/javascripts/google_data_source/google_visualization/timeline.js +13 -0
  17. data/lib/assets/javascripts/google_data_source/google_visualization/visualization.js.erb +141 -0
  18. data/lib/assets/javascripts/google_data_source/index.js +7 -0
  19. data/lib/dummy_engine.rb +5 -0
  20. data/lib/google_data_source.rb +33 -0
  21. data/lib/google_data_source/base.rb +281 -0
  22. data/lib/google_data_source/column.rb +31 -0
  23. data/lib/google_data_source/csv_data.rb +23 -0
  24. data/lib/google_data_source/data_date.rb +17 -0
  25. data/lib/google_data_source/data_date_time.rb +17 -0
  26. data/lib/google_data_source/helper.rb +69 -0
  27. data/lib/google_data_source/html_data.rb +6 -0
  28. data/lib/google_data_source/invalid_data.rb +14 -0
  29. data/lib/google_data_source/json_data.rb +78 -0
  30. data/lib/google_data_source/railtie.rb +36 -0
  31. data/lib/google_data_source/sql/models.rb +266 -0
  32. data/lib/google_data_source/sql/parser.rb +239 -0
  33. data/lib/google_data_source/sql_parser.rb +82 -0
  34. data/lib/google_data_source/template_handler.rb +31 -0
  35. data/lib/google_data_source/test_helper.rb +26 -0
  36. data/lib/google_data_source/version.rb +3 -0
  37. data/lib/google_data_source/xml_data.rb +25 -0
  38. data/lib/locale/de.yml +5 -0
  39. data/lib/reporting/action_controller_extension.rb +19 -0
  40. data/lib/reporting/grouped_set.rb +58 -0
  41. data/lib/reporting/helper.rb +110 -0
  42. data/lib/reporting/reporting.rb +352 -0
  43. data/lib/reporting/reporting_adapter.rb +27 -0
  44. data/lib/reporting/reporting_entry.rb +147 -0
  45. data/lib/reporting/sql_reporting.rb +220 -0
  46. data/test/lib/empty_reporting.rb +2 -0
  47. data/test/lib/test_reporting.rb +33 -0
  48. data/test/lib/test_reporting_b.rb +9 -0
  49. data/test/lib/test_reporting_c.rb +3 -0
  50. data/test/locales/en.models.yml +6 -0
  51. data/test/locales/en.reportings.yml +5 -0
  52. data/test/rails/reporting_renderer_test.rb +47 -0
  53. data/test/test_helper.rb +50 -0
  54. data/test/units/base_test.rb +340 -0
  55. data/test/units/csv_data_test.rb +36 -0
  56. data/test/units/grouped_set_test.rb +60 -0
  57. data/test/units/json_data_test.rb +68 -0
  58. data/test/units/reporting_adapter_test.rb +20 -0
  59. data/test/units/reporting_entry_test.rb +149 -0
  60. data/test/units/reporting_test.rb +374 -0
  61. data/test/units/sql_parser_test.rb +111 -0
  62. data/test/units/sql_reporting_test.rb +307 -0
  63. data/test/units/xml_data_test.rb +32 -0
  64. metadata +286 -0
@@ -0,0 +1,6 @@
1
+ en:
2
+ models:
3
+ attributes:
4
+ test_reporting:
5
+ address: AddressModels
6
+ age: AgeModels
@@ -0,0 +1,5 @@
1
+ en:
2
+ reportings:
3
+ test_reporting:
4
+ name: NameReportings
5
+ age: AgeReportings
@@ -0,0 +1,47 @@
1
+ require "#{File.expand_path(File.dirname(__FILE__))}/../test_helper"
2
+
3
+
4
+ # require 'rails'
5
+ # require 'google_data_source/railtie'
6
+ # GoogleDataSource::Railtie.run_initializers
7
+
8
+
9
+ class ReportingRendererTest < Test::Unit::TestCase
10
+
11
+
12
+ # test "render" do
13
+ # class TestController < ActionController::Base
14
+ # def params
15
+ # {}
16
+ # end
17
+
18
+ # def test(reporting)
19
+ # render :reporting => reporting
20
+ # end
21
+
22
+ # def regular
23
+ # render :text => "foo"
24
+ # end
25
+ # end
26
+
27
+ # class TestReporting < ::Reporting
28
+ # end
29
+
30
+ # reporting = TestReporting.new
31
+ # controller = TestController.new
32
+ # datasource = GoogleDataSource::DataSource::Base.from_params(:reqId => 123)
33
+
34
+ # # stubs
35
+ # controller.stubs(:render_for_text).returns('')
36
+ # GoogleDataSource::DataSource::Base.stubs(:from_params).returns(datasource)
37
+
38
+ # # regular rendering should still work
39
+ # controller.expects(:render_without_reporting).with({:text => "foo"})
40
+
41
+ # # the response of the data source has to be generated
42
+ # datasource.expects(:response).returns("")
43
+
44
+ # controller.test(reporting)
45
+ # controller.regular
46
+ # end
47
+ end
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'bundler/setup'
4
+
5
+ # TODO: move to rr?
6
+ require 'mocha'
7
+
8
+ require 'test/unit'
9
+ require 'shoulda'
10
+
11
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+
15
+ require 'google_data_source'
16
+
17
+ class Test::Unit::TestCase
18
+ end
19
+
20
+
21
+ # Setup I18n stuff
22
+ I18n.load_path << Dir[File.join(File.expand_path(File.dirname(__FILE__)), 'locales', '*.yml')]
23
+ I18n.default_locale = :en
24
+
25
+ # Setup Database and Models
26
+ ActiveRecord::Base.establish_connection(
27
+ :adapter => "sqlite3",
28
+ :database => ":memory:"
29
+ )
30
+
31
+ def setup_db
32
+ ActiveRecord::Migration.verbose = false
33
+ ActiveRecord::Schema.define do
34
+ create_table "items", :force => true do |t|
35
+ t.column "name", :string
36
+ t.column "description", :text
37
+ t.column "number", :integer
38
+ t.column "datetime", :datetime
39
+ t.column "date", :date
40
+ end
41
+ end
42
+ end
43
+
44
+ def teardown_db
45
+ ActiveRecord::Base.connection.tables.each do |table|
46
+ ActiveRecord::Base.connection.drop_table(table)
47
+ end
48
+ end
49
+
50
+ class Item < ActiveRecord::Base; end
@@ -0,0 +1,340 @@
1
+ require "#{File.expand_path(File.dirname(__FILE__))}/../test_helper"
2
+ require 'test_reporting'
3
+ require 'test_reporting_b'
4
+
5
+ class TestReportingForBaseTest < Reporting
6
+ column :name, :type => :string
7
+ column :age, :type => :number
8
+
9
+ def aggregate
10
+ [
11
+ { :name => "John", :age => 20 },
12
+ { :name => "Jim", :age => 30 }
13
+ ]
14
+ end
15
+
16
+ def select
17
+ %w(name age)
18
+ end
19
+ end
20
+
21
+ class TestAggregator
22
+ attr_reader :columns
23
+ attr_writer :valid
24
+
25
+ def initialize(data, columns)
26
+ @valid = true
27
+ @data = data
28
+ @columns = columns
29
+ end
30
+
31
+ def data(options = {})
32
+ @data
33
+ end
34
+
35
+ def callback
36
+ "alert('foo');"
37
+ end
38
+
39
+ def valid?
40
+ @valid
41
+ end
42
+ end
43
+
44
+ class BaseTest < ActiveSupport::TestCase
45
+ include GoogleDataSource::DataSource
46
+
47
+ def setup
48
+ setup_db
49
+ @reporting = TestReportingForBaseTest.new
50
+ @datasource = Base.from_params({})
51
+ end
52
+
53
+ def teardown
54
+ teardown_db
55
+ end
56
+
57
+ test "from_params should parse the tqx parameter" do
58
+ datasource = Base.from_params({ :tqx => 'reqId:123;out:csv;version:0.5' })
59
+ assert_equal '123', datasource[:reqId]
60
+ assert_equal 'csv', datasource[:out]
61
+ assert_equal '0.5', datasource[:version]
62
+ end
63
+
64
+ test "the tqx should be settable via []=" do
65
+ @datasource[:reqId] = '123'
66
+ assert_equal '123', response_hash(@datasource)['reqId']
67
+ end
68
+
69
+ test "response should include the right reqId" do
70
+ datasource = GoogleDataSource::DataSource::Base.from_params({ :tqx => 'reqId:123' })
71
+ response = response_hash(datasource)
72
+ assert_equal '123', response['reqId']
73
+ end
74
+
75
+ test "from_params should consider the out parameter" do
76
+ datasource = Base.from_gdata_params({ :out => 'csv' })
77
+ assert datasource.is_a?(CsvData)
78
+ datasource = Base.from_gdata_params({ :out => 'html' })
79
+ assert datasource.is_a?(HtmlData)
80
+ datasource = Base.from_gdata_params({ :out => 'json' })
81
+ assert datasource.is_a?(JsonData)
82
+ datasource = Base.from_gdata_params({ :out => '' })
83
+ assert datasource.is_a?(InvalidData)
84
+ end
85
+
86
+ test "should return the right format" do
87
+ datasource = Base.from_gdata_params({ :out => 'csv' })
88
+ assert_equal 'csv', datasource.format
89
+ datasource = Base.from_gdata_params({ :out => 'json' })
90
+ assert_equal 'json', datasource.format
91
+ datasource = Base.from_gdata_params({ :out => 'html' })
92
+ assert_equal 'html', datasource.format
93
+ end
94
+
95
+ test "should be invalid if an error is added" do
96
+ assert @datasource.valid?
97
+ @datasource.add_error(:foo, 'bar')
98
+ assert !@datasource.valid?
99
+ end
100
+
101
+ test "should be invalid if no reqId is given" do
102
+ datasource = Base.from_params({:tqx => "out:csv"})
103
+ datasource.validate
104
+ assert !datasource.valid?
105
+ end
106
+
107
+ test "invalidity if version is not supported" do
108
+ datasource = Base.from_params({:tqx => "reqId:0;version:0.5"})
109
+ datasource.validate
110
+ assert !datasource.valid?
111
+ end
112
+
113
+ test "invalidity if output format is not supported" do
114
+ datasource = Base.from_params({:tqx => "reqId:0;out:pdf"})
115
+ datasource.validate
116
+ assert !datasource.valid?
117
+ end
118
+
119
+ test "guess_columns" do
120
+ items = [Item.create(:name => "name", :description => "description", :number => 0)]
121
+ columns = @datasource.guess_columns(items)
122
+
123
+ col_name = columns.select{|c| c.id == :name}.first
124
+ col_description = columns.select{|c| c.id == :description}.first
125
+ col_number = columns.select{|c| c.id == :number}.first
126
+
127
+ assert !col_name.nil?
128
+ assert !col_description.nil?
129
+ assert !col_number.nil?
130
+
131
+ # TODO check types
132
+ end
133
+
134
+ test "columns setter should convert hashes to Column objects" do
135
+ @datasource.columns = [
136
+ { :id => 'foo', :type => :string }
137
+ ]
138
+ assert_equal 1, @datasource.columns.size
139
+ assert_kind_of Column, @datasource.columns.first
140
+ end
141
+
142
+ test "throw exception on invalid column type" do
143
+ assert_raise ArgumentError do
144
+ @datasource.columns = [
145
+ { :id => 'foo', :type => :bar }
146
+ ]
147
+ end
148
+ end
149
+
150
+ test "set with array as data and columns array" do
151
+ @datasource.set(test_data, test_columns)
152
+ raw_data = @datasource.instance_variable_get(:@raw_data)
153
+ assert_equal test_data, raw_data
154
+ assert_equal 2, @datasource.columns.size
155
+ assert_equal :name, @datasource.columns.first.id
156
+ assert_equal :age, @datasource.columns.last.id
157
+ end
158
+
159
+ test "set with an aggregator class" do
160
+ @datasource.set(test_aggregator)
161
+
162
+ # check for columns
163
+ assert_equal 2, @datasource.columns.size
164
+ assert_equal :name, @datasource.columns.first.id
165
+
166
+ # check for data
167
+ assert_equal "John", @datasource.data.first[0]
168
+ assert_equal 20, @datasource.data.first[1]
169
+ end
170
+
171
+ test "simple response" do
172
+ @datasource.set(test_aggregator)
173
+ result = response_hash(@datasource)
174
+ assert_equal '0.6', result['version']
175
+ assert_equal 2, result['table']['cols'].size
176
+ assert_equal 'name', result['table']['cols'].first['id']
177
+ assert_equal 'string',result['table']['cols'].first['type']
178
+ assert_equal 'John', result['table']['rows'].first['c'].first['v']
179
+ end
180
+
181
+ test "formatter" do
182
+ @datasource.set(test_aggregator)
183
+ @datasource.formatter :name do |row|
184
+ "<strong>#{row.name}</strong>"
185
+ end
186
+ data = response_data(@datasource)
187
+ assert_equal "John", data.first[0]['v']
188
+ assert_equal "<strong>John</strong>", data.first[0]['f']
189
+ end
190
+
191
+ test "formatter should add required columns" do
192
+ aggregator = TestAggregator.new(test_data, [{ :id => :name, :type => :string }])
193
+ @datasource.set(aggregator)
194
+ # should only require name column
195
+ assert_equal 1, @datasource.required_columns.size
196
+
197
+ # should also require age column
198
+ @datasource.formatter :name, :requires => [:age] do |row|
199
+ "foo"
200
+ end
201
+ assert_equal 2, @datasource.required_columns.size
202
+ assert @datasource.required_columns.include?('name')
203
+ assert @datasource.required_columns.include?('age')
204
+ end
205
+
206
+ test "has_formatter?" do
207
+ assert ! @datasource.has_formatter?(:name)
208
+ @datasource.formatter :name do |row|
209
+ "foo"
210
+ end
211
+ assert @datasource.has_formatter?(:name)
212
+ end
213
+
214
+ test "column_ids" do
215
+ @datasource.set(test_aggregator)
216
+ assert_equal %w(name age).collect(&:to_sym), @datasource.column_ids
217
+ end
218
+
219
+ test "virtual_column" do
220
+ aggregator = TestAggregator.new(test_data, [{ :id => :summary, :type => :string }])
221
+ @datasource.set(aggregator)
222
+ @datasource.virtual_column :summary do |row|
223
+ "#{row.name} - #{row.age}"
224
+ end
225
+
226
+ data = response_data(@datasource)
227
+ assert_equal "John - 20", data[0][0]['v']
228
+ assert_equal "Jim - 30", data[1][0]['v']
229
+ end
230
+
231
+ test "is_virtual_column?" do
232
+ assert ! @datasource.is_virtual_column?(:summary)
233
+ @datasource.virtual_column :summary do |row|
234
+ "foo"
235
+ end
236
+ assert @datasource.is_virtual_column?(:summary)
237
+ end
238
+
239
+ test "virtual_column should add required columns if given as option" do
240
+ aggregator = TestAggregator.new(test_data, [{ :id => :name, :type => :string }, { :id => :summary }])
241
+ @datasource.set(aggregator)
242
+
243
+ assert_equal 2, @datasource.required_columns.size
244
+ @datasource.virtual_column :summary, :requires => [:age] do |row|
245
+ "foo"
246
+ end
247
+ assert_equal 3, @datasource.required_columns.size
248
+ end
249
+
250
+ test "virtual_column should try to inform the aggregator about the column definition, virtual_column first" do
251
+ aggregator = test_aggregator
252
+ aggregator.expects(:add_virtual_column).with(:summary, :string)
253
+
254
+ @datasource.virtual_column :summary do |row|
255
+ "#{row.name} - #{row.age}"
256
+ end
257
+ @datasource.set(aggregator)
258
+ end
259
+
260
+ test "virtual_column should try to inform the aggregator about the column definition, set first" do
261
+ aggregator = test_aggregator
262
+ aggregator.expects(:add_virtual_column).with(:summary, :string)
263
+
264
+ @datasource.set(aggregator)
265
+ @datasource.virtual_column :summary do |row|
266
+ "#{row.name} - #{row.age}"
267
+ end
268
+ end
269
+
270
+ test "set column label" do
271
+ @datasource.set(test_aggregator)
272
+ @datasource.column_labels = {
273
+ :name => "Name"
274
+ }
275
+ columns = response_columns(@datasource)
276
+ #puts columns.inspect
277
+ assert_equal "Name", columns.first['label']
278
+ end
279
+
280
+ test "should turn invalid if aggregator is invalid" do
281
+ aggregator = test_aggregator
282
+ @datasource.set(aggregator)
283
+ @datasource.data
284
+ assert @datasource.valid?
285
+
286
+ aggregator.valid = false
287
+ @datasource.set(aggregator)
288
+ @datasource.data
289
+ assert ! @datasource.valid?
290
+ end
291
+
292
+ test "should render error if invalid" do
293
+ aggregator = test_aggregator
294
+ aggregator.valid = false
295
+ @datasource.set(aggregator)
296
+ response = response_hash(@datasource)
297
+ #puts response.inspect
298
+ assert_equal 'error', response['status']
299
+ end
300
+
301
+ test "should correctly set columns in hierarchy" do
302
+ # verify that the class_inheritable_accessor stuff is migrated correctly
303
+ assert_equal %w{name age address fullname fullfullname circle_a circle_b}.sort,
304
+ TestReporting.datasource_columns.keys.sort
305
+ assert_equal %w{name age address fullname fullfullname circle_a circle_b name_b age_b}.sort,
306
+ TestReportingB.datasource_columns.keys.sort
307
+ end
308
+
309
+ def test_data
310
+ [
311
+ { :name => "John", :age => 20},
312
+ { :name => "Jim", :age => 30}
313
+ ]
314
+ end
315
+
316
+ def test_columns
317
+ [
318
+ { :id => :name, :type => :string },
319
+ { :id => 'age', :type => :number}
320
+ ]
321
+ end
322
+
323
+ def test_aggregator
324
+ TestAggregator.new(test_data, test_columns)
325
+ end
326
+
327
+ def response_hash(datasource)
328
+ json = datasource.response.match(/setResponse\(({.*})\)/)[1]
329
+ ActiveSupport::JSON.decode(json)
330
+ end
331
+
332
+ def response_columns(datasource)
333
+ response_hash(datasource)['table']['cols']
334
+ end
335
+
336
+ def response_data(datasource)
337
+ response_hash(datasource)['table']['rows'].collect { |r| r['c'] }
338
+ end
339
+
340
+ end