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.
- data/.document +5 -0
- data/.gitignore +7 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +25 -0
- data/Rakefile +31 -0
- data/google_data_source.gemspec +32 -0
- data/lib/assets/images/google_data_source/chart_bar_add.png +0 -0
- data/lib/assets/images/google_data_source/chart_bar_delete.png +0 -0
- data/lib/assets/images/google_data_source/loader.gif +0 -0
- data/lib/assets/javascripts/google_data_source/data_source_init.js +3 -0
- data/lib/assets/javascripts/google_data_source/extended_data_table.js +76 -0
- data/lib/assets/javascripts/google_data_source/filter_form.js +180 -0
- data/lib/assets/javascripts/google_data_source/google_visualization/combo_table.js.erb +113 -0
- data/lib/assets/javascripts/google_data_source/google_visualization/table.js +116 -0
- data/lib/assets/javascripts/google_data_source/google_visualization/timeline.js +13 -0
- data/lib/assets/javascripts/google_data_source/google_visualization/visualization.js.erb +141 -0
- data/lib/assets/javascripts/google_data_source/index.js +7 -0
- data/lib/dummy_engine.rb +5 -0
- data/lib/google_data_source.rb +33 -0
- data/lib/google_data_source/base.rb +281 -0
- data/lib/google_data_source/column.rb +31 -0
- data/lib/google_data_source/csv_data.rb +23 -0
- data/lib/google_data_source/data_date.rb +17 -0
- data/lib/google_data_source/data_date_time.rb +17 -0
- data/lib/google_data_source/helper.rb +69 -0
- data/lib/google_data_source/html_data.rb +6 -0
- data/lib/google_data_source/invalid_data.rb +14 -0
- data/lib/google_data_source/json_data.rb +78 -0
- data/lib/google_data_source/railtie.rb +36 -0
- data/lib/google_data_source/sql/models.rb +266 -0
- data/lib/google_data_source/sql/parser.rb +239 -0
- data/lib/google_data_source/sql_parser.rb +82 -0
- data/lib/google_data_source/template_handler.rb +31 -0
- data/lib/google_data_source/test_helper.rb +26 -0
- data/lib/google_data_source/version.rb +3 -0
- data/lib/google_data_source/xml_data.rb +25 -0
- data/lib/locale/de.yml +5 -0
- data/lib/reporting/action_controller_extension.rb +19 -0
- data/lib/reporting/grouped_set.rb +58 -0
- data/lib/reporting/helper.rb +110 -0
- data/lib/reporting/reporting.rb +352 -0
- data/lib/reporting/reporting_adapter.rb +27 -0
- data/lib/reporting/reporting_entry.rb +147 -0
- data/lib/reporting/sql_reporting.rb +220 -0
- data/test/lib/empty_reporting.rb +2 -0
- data/test/lib/test_reporting.rb +33 -0
- data/test/lib/test_reporting_b.rb +9 -0
- data/test/lib/test_reporting_c.rb +3 -0
- data/test/locales/en.models.yml +6 -0
- data/test/locales/en.reportings.yml +5 -0
- data/test/rails/reporting_renderer_test.rb +47 -0
- data/test/test_helper.rb +50 -0
- data/test/units/base_test.rb +340 -0
- data/test/units/csv_data_test.rb +36 -0
- data/test/units/grouped_set_test.rb +60 -0
- data/test/units/json_data_test.rb +68 -0
- data/test/units/reporting_adapter_test.rb +20 -0
- data/test/units/reporting_entry_test.rb +149 -0
- data/test/units/reporting_test.rb +374 -0
- data/test/units/sql_parser_test.rb +111 -0
- data/test/units/sql_reporting_test.rb +307 -0
- data/test/units/xml_data_test.rb +32 -0
- metadata +286 -0
@@ -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
|
data/test/test_helper.rb
ADDED
@@ -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
|