make_exportable 1.0.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.
- data/Gemfile +12 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +187 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/lib/make_exportable.rb +19 -0
- data/lib/make_exportable/core.rb +309 -0
- data/lib/make_exportable/errors.rb +7 -0
- data/lib/make_exportable/exportable_format.rb +33 -0
- data/lib/make_exportable/exportable_formats/csv.rb +34 -0
- data/lib/make_exportable/exportable_formats/excel.rb +39 -0
- data/lib/make_exportable/exportable_formats/html.rb +39 -0
- data/lib/make_exportable/exportable_formats/json.rb +36 -0
- data/lib/make_exportable/exportable_formats/tsv.rb +34 -0
- data/lib/make_exportable/exportable_formats/xml.rb +43 -0
- data/lib/make_exportable/make_exportable_helper.rb +27 -0
- data/lib/make_exportable/version.rb +9 -0
- data/rails/init.rb +1 -0
- data/spec/database.yml +10 -0
- data/spec/database.yml.sample +10 -0
- data/spec/make_exportable/formats_spec.rb +81 -0
- data/spec/make_exportable/make_exportable_helper_spec.rb +31 -0
- data/spec/make_exportable/make_exportable_spec.rb +510 -0
- data/spec/models.rb +44 -0
- data/spec/schema.rb +16 -0
- data/spec/spec_helper.rb +55 -0
- metadata +98 -0
@@ -0,0 +1,510 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "Make Exportable" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
clean_database!
|
7
|
+
end
|
8
|
+
|
9
|
+
describe MakeExportable do
|
10
|
+
|
11
|
+
# For simply having MakeExportable loaded as a gem/plugin
|
12
|
+
describe "mattr_accessor :exportable_classes" do
|
13
|
+
|
14
|
+
it "should be a hash" do
|
15
|
+
MakeExportable.exportable_classes.class.should == Hash
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be readable and writable" do
|
19
|
+
MakeExportable.exportable_classes[:testkey] = 'testvalue'
|
20
|
+
MakeExportable.exportable_classes[:testkey].should == 'testvalue'
|
21
|
+
MakeExportable.exportable_classes.delete(:testkey)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "mattr_accessor :exportable_formats" do
|
26
|
+
|
27
|
+
it "should be a hash" do
|
28
|
+
MakeExportable.exportable_classes.class.should == Hash
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be readable and writable" do
|
32
|
+
MakeExportable.exportable_formats[:testkey] = 'testvalue'
|
33
|
+
MakeExportable.exportable_formats[:testkey].should == 'testvalue'
|
34
|
+
MakeExportable.exportable_formats.delete(:testkey)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should contain keys for the supported format types" do
|
38
|
+
MakeExportable.exportable_formats.should_not be_nil
|
39
|
+
MakeExportable.exportable_formats.key?(:csv ).should be_true
|
40
|
+
MakeExportable.exportable_formats.key?(:xls ).should be_true
|
41
|
+
MakeExportable.exportable_formats.key?(:html).should be_true
|
42
|
+
MakeExportable.exportable_formats.key?(:json).should be_true
|
43
|
+
MakeExportable.exportable_formats.key?(:tsv ).should be_true
|
44
|
+
MakeExportable.exportable_formats.key?(:xml ).should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have the correct format class as a value for each key" do
|
48
|
+
MakeExportable.exportable_formats[:csv ].should == MakeExportable::CSV
|
49
|
+
MakeExportable.exportable_formats[:xls ].should == MakeExportable::Excel
|
50
|
+
MakeExportable.exportable_formats[:html].should == MakeExportable::HTML
|
51
|
+
MakeExportable.exportable_formats[:json].should == MakeExportable::JSON
|
52
|
+
MakeExportable.exportable_formats[:tsv ].should == MakeExportable::TSV
|
53
|
+
MakeExportable.exportable_formats[:xml ].should == MakeExportable::XML
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "extenstions to ActiveRecord's class methods" do
|
59
|
+
|
60
|
+
it "should include MakeExportable's ActiveRecordBaseMethods" do
|
61
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
62
|
+
ActiveRecord::Base.methods.include?(:exportable?).should be_true
|
63
|
+
ActiveRecord::Base.methods.include?(:make_exportable).should be_true
|
64
|
+
else
|
65
|
+
ActiveRecord::Base.methods.include?('exportable?').should be_true
|
66
|
+
ActiveRecord::Base.methods.include?('make_exportable').should be_true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# Once classes add MakeExportable's functionality
|
74
|
+
describe "classes declaring make_exportable" do
|
75
|
+
|
76
|
+
before(:each) do
|
77
|
+
class User
|
78
|
+
make_exportable
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should be included in MakeExportable.exportable_tables" do
|
83
|
+
MakeExportable.exportable_classes['User'].should == User
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should have MakeExportable's ClassMethods" do
|
87
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
88
|
+
User.methods.include?(:exportable?).should be_true
|
89
|
+
User.methods.include?(:to_export).should be_true
|
90
|
+
User.methods.include?(:get_export_data).should be_true
|
91
|
+
User.methods.include?(:create_report).should be_true
|
92
|
+
else
|
93
|
+
User.methods.include?("exportable?").should be_true
|
94
|
+
User.methods.include?("to_export").should be_true
|
95
|
+
User.methods.include?("get_export_data").should be_true
|
96
|
+
User.methods.include?("create_report").should be_true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should not expose MakeExportable's ClassMethods which are private" do
|
101
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
102
|
+
User.methods.include?(:find_export_data).should be_false
|
103
|
+
User.methods.include?(:map_export_data).should be_false
|
104
|
+
User.methods.include?(:validate_export_format).should be_false
|
105
|
+
User.methods.include?(:validate_export_data_lengths).should be_false
|
106
|
+
else
|
107
|
+
User.methods.include?("find_export_data").should be_false
|
108
|
+
User.methods.include?("map_export_data").should be_false
|
109
|
+
User.methods.include?("validate_export_format").should be_false
|
110
|
+
User.methods.include?("validate_export_data_lengths").should be_false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should have MakeExportable's InstanceMethods" do
|
115
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
116
|
+
User.instance_methods.include?(:export_attribute).should be_true
|
117
|
+
else
|
118
|
+
User.instance_methods.include?("export_attribute").should be_true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should have an inheritable class accessor for exportable_options" do
|
123
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
124
|
+
User.instance_methods.include?(:exportable_options).should be_true
|
125
|
+
else
|
126
|
+
User.instance_methods.include?("exportable_options").should be_true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "dynamically-named methods" do
|
131
|
+
|
132
|
+
describe 'create_#{format}_report' do
|
133
|
+
|
134
|
+
MakeExportable.exportable_formats.map do |format, v|
|
135
|
+
it "should define the method create_#{format}_report" do
|
136
|
+
User.should_receive(:create_report).with(format.to_s)
|
137
|
+
User.send("create_#{format}_report")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should return NoMethodError if the format is not supported" do
|
142
|
+
lambda do
|
143
|
+
User.create_xyz_report
|
144
|
+
end.should raise_error(NoMethodError)
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'to_#{format}_export' do
|
150
|
+
|
151
|
+
MakeExportable.exportable_formats.map do |format, v|
|
152
|
+
it "should define the method to_#{format}_export" do
|
153
|
+
User.should_receive(:to_export).with(format.to_s)
|
154
|
+
User.class_eval("to_#{format}_export")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should return NoMethodError if the format is not supported" do
|
159
|
+
lambda do
|
160
|
+
User.to_xyz_export
|
161
|
+
end.should raise_error(NoMethodError)
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "not passing in options" do
|
169
|
+
|
170
|
+
it "should set default values for key options" do
|
171
|
+
User.exportable_options.keys.map(&:to_s).sort.should == ["columns", "formats", "scopes"]
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should set :columns to all database columns" do
|
175
|
+
User.exportable_options[:columns].should == [:id, :first_name, :last_name, :password, :email, :is_admin, :created_at, :updated_at]
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should set :formats to all supported formats" do
|
179
|
+
User.exportable_options[:formats].map(&:to_s).sort.should == ["csv", "html", "json", "tsv", "xls", "xml"]
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should set :scopes to an empty array" do
|
183
|
+
User.exportable_options[:scopes].should == []
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "passing in options" do
|
189
|
+
|
190
|
+
it "should toss out invalid options" do
|
191
|
+
|
192
|
+
class Post < ActiveRecord::Base
|
193
|
+
make_exportable :nonsense => "this should not be included", :offset => 20
|
194
|
+
end
|
195
|
+
|
196
|
+
# valid_options = [:as, :only, :except, :scopes, :conditions, :order, :include,
|
197
|
+
# :group, :having, :limit, :offset, :joins]
|
198
|
+
Post.exportable_options.include?(:nonsense).should be_false
|
199
|
+
Post.exportable_options.include?(:offset).should be_true
|
200
|
+
end
|
201
|
+
|
202
|
+
describe ":only/:except options" do
|
203
|
+
|
204
|
+
it "should not appear in exportable_options" do
|
205
|
+
# these get removed and converted into :columns
|
206
|
+
class Post < ActiveRecord::Base
|
207
|
+
make_exportable :only => [:this, :that, :another], :except => [:title]
|
208
|
+
end
|
209
|
+
Post.exportable_options.include?(:only).should be_false
|
210
|
+
Post.exportable_options.include?(:except).should be_false
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should allow column names to be either strings or symbols" do
|
214
|
+
class Post < ActiveRecord::Base
|
215
|
+
make_exportable :only => ["full_name", :symbol_method]
|
216
|
+
end
|
217
|
+
Post.exportable_options[:columns].should == [:full_name, :symbol_method]
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should allow a single column name or an array of names" do
|
221
|
+
class Post < ActiveRecord::Base
|
222
|
+
make_exportable :only => "full_name"
|
223
|
+
end
|
224
|
+
Post.exportable_options[:columns].should == [:full_name]
|
225
|
+
end
|
226
|
+
|
227
|
+
# unique for :only option
|
228
|
+
it "should allow attributes/methods which are not database columns" do
|
229
|
+
|
230
|
+
class Post < ActiveRecord::Base
|
231
|
+
make_exportable :only => ["a_method_name", "another_method"]
|
232
|
+
end
|
233
|
+
|
234
|
+
Post.exportable_options[:columns].should == [:a_method_name, :another_method]
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should replace the default columns saved in exportable_options[:columns]" do
|
239
|
+
|
240
|
+
class Post < ActiveRecord::Base
|
241
|
+
make_exportable :only => ["a_method_name", "another_method"]
|
242
|
+
end
|
243
|
+
|
244
|
+
Post.exportable_options[:columns].should == [:a_method_name, :another_method]
|
245
|
+
end
|
246
|
+
|
247
|
+
# unless we add a check for this
|
248
|
+
it "should not try to catch bogus attribute/method names" do
|
249
|
+
class Post < ActiveRecord::Base
|
250
|
+
make_exportable :only => ["full_name", "another_method"]
|
251
|
+
end
|
252
|
+
Post.exportable_options[:columns].should == [:full_name, :another_method]
|
253
|
+
end
|
254
|
+
|
255
|
+
# unique for :except option
|
256
|
+
it "should subtract from the default columns saved in exportable_options[:columns]" do
|
257
|
+
|
258
|
+
class Post < ActiveRecord::Base
|
259
|
+
make_exportable :except => [:created_at, :updated_at]
|
260
|
+
end
|
261
|
+
|
262
|
+
Post.exportable_options[:columns].should == [:id, :title, :content, :approved]
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should ignore bogus attribute/method names" do
|
266
|
+
class Post < ActiveRecord::Base
|
267
|
+
make_exportable :except => [:created_at, :updated_at, :bogus]
|
268
|
+
end
|
269
|
+
Post.exportable_options[:columns].should == [:id, :title, :content, :approved]
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
describe ":as option" do
|
275
|
+
|
276
|
+
it "should not appear in exportable_options" do
|
277
|
+
class Post < ActiveRecord::Base
|
278
|
+
make_exportable :as => [:csv, "xml"]
|
279
|
+
end
|
280
|
+
Post.exportable_options.include?(:as).should be_false
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should allow format names to be either strings or symbols" do
|
284
|
+
class Post < ActiveRecord::Base
|
285
|
+
make_exportable :as => [:csv, "xml"]
|
286
|
+
end
|
287
|
+
Post.exportable_options[:formats].map(&:to_s).sort.should == ["csv", "xml"]
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should allow a single format name or an array of names" do
|
291
|
+
class Post < ActiveRecord::Base
|
292
|
+
make_exportable :as => :json
|
293
|
+
end
|
294
|
+
Post.exportable_options[:formats].should == [:json]
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should ignore formats not in the supported formats" do
|
298
|
+
class Post < ActiveRecord::Base
|
299
|
+
make_exportable :as => [:csv, "unsupported"]
|
300
|
+
end
|
301
|
+
Post.exportable_options[:formats].should == [:csv]
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should raise an error if only unsupported formats are passed in" do
|
305
|
+
lambda do
|
306
|
+
class Post < ActiveRecord::Base
|
307
|
+
make_exportable :as => "unsupported"
|
308
|
+
end
|
309
|
+
end.should raise_error(MakeExportable::FormatNotFound)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
describe ":scopes option" do
|
314
|
+
it "should be saved unchanged in exportable_options[:scopes]" do
|
315
|
+
Post.class_eval("make_exportable :scopes => [:scope1, :scope2]")
|
316
|
+
Post.exportable_options[:scopes].should == [:scope1, :scope2]
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
describe "finder options" do
|
321
|
+
[:conditions, :order, :include, :group, :having, :limit, :offset, :joins].each do |opt|
|
322
|
+
it "should save :#{opt} unchanged in exportable_options[:#{opt}]" do
|
323
|
+
Post.class_eval("make_exportable :#{opt} => 'accepts anything trusting the user'")
|
324
|
+
Post.exportable_options[opt].should == "accepts anything trusting the user"
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
describe "MakeExportable::ClassMethods" do
|
334
|
+
|
335
|
+
before(:each) do
|
336
|
+
class User
|
337
|
+
make_exportable
|
338
|
+
end
|
339
|
+
clean_database!
|
340
|
+
User.create(:first_name => "user_1", :last_name => "Doe", :created_at => Time.at(0), :updated_at => Time.at(0))
|
341
|
+
User.create(:first_name => "user_2", :last_name => "Doe", :created_at => Time.at(0), :updated_at => Time.at(0))
|
342
|
+
end
|
343
|
+
|
344
|
+
describe "exportable?" do
|
345
|
+
|
346
|
+
it "should be false for regular ActiveRecord classes" do
|
347
|
+
Unexportable.exportable?.should be_false
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should be true for classes that call make_exportable" do
|
351
|
+
User.exportable?.should be_true
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should be true when the argument value is an allowed format for this class" do
|
355
|
+
User.exportable?("csv").should be_true
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should be false when the argument value is not an allowed format for this class" do
|
359
|
+
User.exportable?("unsupported").should be_false
|
360
|
+
end
|
361
|
+
|
362
|
+
end
|
363
|
+
|
364
|
+
describe "to_export" do
|
365
|
+
|
366
|
+
it "should use default headers if no :header option is sent"
|
367
|
+
|
368
|
+
it "should use :headers option for headers if sent"
|
369
|
+
|
370
|
+
it "should use no headers if :headers is false"
|
371
|
+
|
372
|
+
end
|
373
|
+
|
374
|
+
describe "get_export_data" do
|
375
|
+
|
376
|
+
context "scopes and find options" do
|
377
|
+
# Test how :scopes and find options are merged and applied
|
378
|
+
# (testing the private method :find_export_data)
|
379
|
+
it "should chainable on named_scopes" do
|
380
|
+
User.a_limiter.get_export_data(:only => [:first_name, :last_name]).should == [["first_name", "last_name"],["user_1", "Doe"]]
|
381
|
+
end
|
382
|
+
|
383
|
+
it "should allow a scope to be sent" do
|
384
|
+
User.get_export_data(:only => [:first_name, :last_name], :scopes => ['a_limiter']).should == [["first_name", "last_name"], ["user_1", "Doe"]]
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should allow multiple scopes to be sent" do
|
388
|
+
User.get_export_data(:only =>[:first_name, :last_name], :scopes => ['a_limiter', "order_by"]).should == [["first_name", "last_name"], ["user_2", "Doe"]]
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should find records using :conditions option" do
|
392
|
+
if ActiveRecord::VERSION::MAJOR < 3
|
393
|
+
User.get_export_data(:only => [:first_name, :last_name], :conditions => {:first_name => "user_1"} ).should == [["first_name", "last_name"], ["user_1", "Doe"]]
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
it "should sort records using :order option" do
|
398
|
+
if ActiveRecord::VERSION::MAJOR < 3
|
399
|
+
User.get_export_data(:only => [:first_name, :last_name], :order => "id DESC").should == [["first_name", "last_name"], ["user_2", "Doe"], ["user_1", "Doe"]]
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
it "should limit records using :limit option" do
|
404
|
+
if ActiveRecord::VERSION::MAJOR < 3
|
405
|
+
User.get_export_data(:only => [:first_name, :last_name], :limit => 1, :order => "id ASC" ).should == [["first_name", "last_name"], ["user_1", "Doe"]]
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
# TODO: Test how :scopes and find options get merged when there are default options
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
context "column selection" do
|
414
|
+
# Test how :only/:except are merged and selected
|
415
|
+
# (testing the private method :map_export_data)
|
416
|
+
it "should export the default columns by default" do
|
417
|
+
time = User.first.created_at.to_s
|
418
|
+
User.get_export_data().should == [["id", "first_name", "last_name", "password", "email", "is_admin", "created_at", "updated_at"], ["1", "user_1", "Doe", "", "", "false", Time.at(0).to_s, Time.at(0).to_s], ["2", "user_2", "Doe", "", "", "false", Time.at(0).to_s, Time.at(0).to_s]]
|
419
|
+
end
|
420
|
+
|
421
|
+
it "should export only the columns given by :only" do
|
422
|
+
User.get_export_data(:only => [:first_name, :last_name]).should == [["first_name", "last_name"], ["user_1", "Doe"], ["user_2", "Doe"]]
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should export the default columns minus those given by :except" do
|
426
|
+
User.get_export_data(:except => [:id, :created_at, :updated_at, :password, :is_admin]).should == [["first_name", "last_name", "email"], ["user_1", "Doe", ""], ["user_2", "Doe", ""]]
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should raise an error if no columns are passed" do
|
430
|
+
lambda do
|
431
|
+
User.nothing.get_export_data(:except =>["id", "first_name", "last_name", "password", "email", "is_admin", "created_at", "updated_at"])
|
432
|
+
end.should raise_error(MakeExportable::ExportFault)
|
433
|
+
end
|
434
|
+
|
435
|
+
# TODO: Test how :only/:except get merged when there are default options
|
436
|
+
|
437
|
+
end
|
438
|
+
|
439
|
+
end
|
440
|
+
|
441
|
+
describe "create_report" do
|
442
|
+
|
443
|
+
it "should raise an FormatNotFound if the format is not supported" do
|
444
|
+
lambda do
|
445
|
+
User.create_report("NONSUPPORTED", "")
|
446
|
+
end.should raise_error(MakeExportable::FormatNotFound)
|
447
|
+
end
|
448
|
+
|
449
|
+
it 'should export an array of header and array of arrays of rows in the specified format' do
|
450
|
+
User.create_report("csv", [[ "data", 'lovely data'],["", "more lovely data"]], :headers => ["Title", "Another Title"]).should == ["Title,Another Title\ndata,lovely data\n\"\",more lovely data\n", "text/csv; charset=utf-8; header=present"]
|
451
|
+
end
|
452
|
+
|
453
|
+
it 'should export array of arrays of rows in the specified format if header is set to true with header set as present' do
|
454
|
+
User.create_report("csv", [["Title", "Another Title"],[ "data", 'lovely data'],["", "more lovely data"]], :headers => true).should == ["Title,Another Title\ndata,lovely data\n\"\",more lovely data\n", "text/csv; charset=utf-8; header=present"]
|
455
|
+
end
|
456
|
+
|
457
|
+
it 'should export array of arrays of rows in the specified format if header is set to false' do
|
458
|
+
User.create_report("csv", [[ "data", 'lovely data'],["", "more lovely data"]], :headers => false).should == ["data,lovely data\n\"\",more lovely data\n", "text/csv; charset=utf-8; header=absent"]
|
459
|
+
end
|
460
|
+
|
461
|
+
it "should raise an ExportFault if the datasets are not all the same size" do
|
462
|
+
lambda do
|
463
|
+
User.create_report("xml", [[ "data", 'lovely data'],["more lovely data"]], :headers =>["Title", "Another Title"])
|
464
|
+
end.should raise_error(MakeExportable::ExportFault)
|
465
|
+
end
|
466
|
+
|
467
|
+
end
|
468
|
+
|
469
|
+
end
|
470
|
+
|
471
|
+
describe "MakeExportable::InstanceMethods" do
|
472
|
+
|
473
|
+
describe "#export_attribute" do
|
474
|
+
|
475
|
+
before(:each) do
|
476
|
+
class User
|
477
|
+
make_exportable
|
478
|
+
end
|
479
|
+
@user = User.create(:first_name => "Carl", :last_name => "Joans")
|
480
|
+
end
|
481
|
+
|
482
|
+
it "should return attribute values" do
|
483
|
+
@user.export_attribute('is_admin').should == "false"
|
484
|
+
end
|
485
|
+
|
486
|
+
it 'should allow #{method}_export to override the original method' do
|
487
|
+
class User < ActiveRecord::Base
|
488
|
+
def is_admin_export
|
489
|
+
return "I'm not an Admin I'm a monkey"
|
490
|
+
end
|
491
|
+
end
|
492
|
+
@user.export_attribute('is_admin').should == "I'm not an Admin I'm a monkey"
|
493
|
+
end
|
494
|
+
|
495
|
+
# TODO: Would it be better behavior to raise an error?
|
496
|
+
it "should return an empty string if the attribute doesn't exist" do
|
497
|
+
@user.export_attribute('ful_name').should == ""
|
498
|
+
end
|
499
|
+
|
500
|
+
it "should be able to call methods as attributes during exporting" do
|
501
|
+
@user.export_attribute('full_name').should == "Carl Joans"
|
502
|
+
end
|
503
|
+
|
504
|
+
end
|
505
|
+
|
506
|
+
end
|
507
|
+
|
508
|
+
end
|
509
|
+
|
510
|
+
end
|