uploadcolumn 0.3.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/.gitignore +3 -0
- data/CHANGELOG +123 -0
- data/LICENSE +22 -0
- data/README.rdoc +206 -0
- data/Rakefile +90 -0
- data/VERSION +1 -0
- data/init.rb +15 -0
- data/lib/upload_column/active_record_extension.rb +154 -0
- data/lib/upload_column/configuration.rb +49 -0
- data/lib/upload_column/magic_columns.rb +50 -0
- data/lib/upload_column/manipulators/image_science.rb +86 -0
- data/lib/upload_column/manipulators/rmagick.rb +75 -0
- data/lib/upload_column/rails/action_controller_extension.rb +61 -0
- data/lib/upload_column/rails/asset_tag_extension.rb +17 -0
- data/lib/upload_column/rails/upload_column_helper.rb +45 -0
- data/lib/upload_column/sanitized_file.rb +176 -0
- data/lib/upload_column/uploaded_file.rb +299 -0
- data/lib/upload_column.rb +12 -0
- data/spec/active_record_extension_spec.rb +514 -0
- data/spec/custom_matchers.rb +148 -0
- data/spec/fixtures/animated.gif +0 -0
- data/spec/fixtures/animated_solarized.gif +0 -0
- data/spec/fixtures/invalid-image.jpg +1 -0
- data/spec/fixtures/kerb.jpg +0 -0
- data/spec/fixtures/kerb_solarized.jpg +0 -0
- data/spec/fixtures/netscape.gif +0 -0
- data/spec/fixtures/skanthak.png +0 -0
- data/spec/image_science_manipulator_spec.rb +195 -0
- data/spec/integration_spec.rb +668 -0
- data/spec/magic_columns_spec.rb +120 -0
- data/spec/rmagick_manipulator_spec.rb +186 -0
- data/spec/sanitized_file_spec.rb +496 -0
- data/spec/spec_helper.rb +90 -0
- data/spec/upload_column_spec.rb +65 -0
- data/spec/uploaded_file_spec.rb +1053 -0
- metadata +108 -0
@@ -0,0 +1,514 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
gem 'activerecord'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
require File.join(File.dirname(__FILE__), '../lib/upload_column')
|
7
|
+
|
8
|
+
class Entry < ActiveRecord::Base; end # setup a basic AR class for testing
|
9
|
+
|
10
|
+
describe "an ActiveRecord class" do
|
11
|
+
|
12
|
+
include UploadColumnSpecHelper
|
13
|
+
|
14
|
+
it "should respond to upload_column" do
|
15
|
+
Entry.should respond_to(:upload_column)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should reflect on upload_columns" do
|
19
|
+
Entry.send(:reset_upload_columns)
|
20
|
+
|
21
|
+
Entry.upload_column(:avatar)
|
22
|
+
|
23
|
+
Entry.reflect_on_upload_columns[:avatar].should be_an_instance_of(UploadColumn::Column)
|
24
|
+
Entry.reflect_on_upload_columns[:monkey].should == nil
|
25
|
+
|
26
|
+
Entry.upload_column(:monkey)
|
27
|
+
|
28
|
+
Entry.reflect_on_upload_columns[:avatar].should be_an_instance_of(UploadColumn::Column)
|
29
|
+
Entry.reflect_on_upload_columns[:monkey].should be_an_instance_of(UploadColumn::Column)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should reset upload columns" do
|
33
|
+
Entry.upload_column(:avatar)
|
34
|
+
|
35
|
+
Entry.reflect_on_upload_columns[:avatar].should be_an_instance_of(UploadColumn::Column)
|
36
|
+
|
37
|
+
Entry.send(:reset_upload_columns)
|
38
|
+
|
39
|
+
Entry.reflect_on_upload_columns[:avatar].should == nil
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "an Active Record class with an upload_column" do
|
45
|
+
|
46
|
+
include UploadColumnSpecHelper
|
47
|
+
|
48
|
+
it "should add accessor methods" do
|
49
|
+
# use a name that hasn't been used before!
|
50
|
+
entry = disconnected_model(Entry)
|
51
|
+
entry.should_not respond_to(:llama)
|
52
|
+
entry.should_not respond_to(:llama_temp)
|
53
|
+
entry.should_not respond_to(:llama=)
|
54
|
+
entry.should_not respond_to(:llama_temp=)
|
55
|
+
|
56
|
+
Entry.upload_column(:llama)
|
57
|
+
|
58
|
+
entry = disconnected_model(Entry)
|
59
|
+
|
60
|
+
entry.should respond_to(:llama)
|
61
|
+
entry.should respond_to(:llama_temp)
|
62
|
+
entry.should respond_to(:llama=)
|
63
|
+
entry.should respond_to(:llama_temp=)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should save the name of the column to be reflected upon" do
|
67
|
+
Entry.upload_column(:walruss)
|
68
|
+
Entry.reflect_on_upload_columns[:walruss].name.should == :walruss
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should save the options to be reflected upon" do
|
72
|
+
options = { :donkey => true }
|
73
|
+
|
74
|
+
Entry.upload_column(:walruss, options)
|
75
|
+
|
76
|
+
Entry.reflect_on_upload_columns[:walruss].options.should == options
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "an Active Record with no upload_column" do
|
81
|
+
|
82
|
+
before(:all) do
|
83
|
+
class Monkey < ActiveRecord::Base; end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should have no uploads_column" do
|
87
|
+
Monkey.reflect_on_upload_columns.should == {}
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be instantiable" do
|
91
|
+
Monkey.stub!(:columns).and_return([])
|
92
|
+
Monkey.new
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "uploading a file" do
|
98
|
+
|
99
|
+
include UploadColumnSpecHelper
|
100
|
+
|
101
|
+
before do
|
102
|
+
setup_standard_mocking
|
103
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should pass it to UploadedFile and remember it" do
|
107
|
+
@entry.avatar.should == nil
|
108
|
+
@entry.avatar = @file
|
109
|
+
@entry.avatar.should == @uploaded_file
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should set the attribute on the ActiveRecord" do
|
113
|
+
@entry.should_receive(:[]=).with(:avatar, 'monkey.png')
|
114
|
+
@entry.avatar = @file
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "uploading an empty String" do
|
120
|
+
|
121
|
+
include UploadColumnSpecHelper
|
122
|
+
|
123
|
+
before do
|
124
|
+
setup_standard_mocking
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should do nothing" do
|
128
|
+
UploadColumn::UploadedFile.should_receive(:upload).with("", @entry, :avatar, @options).and_return(nil)
|
129
|
+
@entry.avatar.should == nil
|
130
|
+
@entry.avatar = ""
|
131
|
+
@entry.avatar.should == nil
|
132
|
+
end
|
133
|
+
|
134
|
+
it "shouldn't affect an already uploaded file" do
|
135
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
136
|
+
@entry.avatar = @file
|
137
|
+
@entry.avatar.should == @uploaded_file
|
138
|
+
|
139
|
+
UploadColumn::UploadedFile.should_receive(:upload).with("", @entry, :avatar, @options).and_return(nil)
|
140
|
+
@entry.avatar = ""
|
141
|
+
@entry.avatar.should == @uploaded_file
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "setting nil explicitly" do
|
147
|
+
|
148
|
+
include UploadColumnSpecHelper
|
149
|
+
|
150
|
+
before do
|
151
|
+
setup_standard_mocking
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should reset the column" do
|
155
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
156
|
+
@entry.avatar = @file
|
157
|
+
@entry.avatar.should == @uploaded_file
|
158
|
+
|
159
|
+
@entry.avatar = nil
|
160
|
+
@entry.avatar.should == nil
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "an upload_column with a value stored in the database and no uploaded_file" do
|
165
|
+
|
166
|
+
include UploadColumnSpecHelper
|
167
|
+
|
168
|
+
before do
|
169
|
+
@options = mock('options', :null_object => true)
|
170
|
+
Entry.upload_column(:avatar, @options)
|
171
|
+
|
172
|
+
@entry = disconnected_model(Entry)
|
173
|
+
@entry.stub!(:inspect).and_return('<#Entry>')
|
174
|
+
@string = mock('some string')
|
175
|
+
@entry.should_receive(:[]).with(:avatar).at_least(:once).and_return(@string)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should retrieve the file from the database" do
|
179
|
+
uploaded_file = mock('uploaded file')
|
180
|
+
|
181
|
+
UploadColumn::UploadedFile.should_receive(:retrieve).with(@string, @entry, :avatar, @options).and_return(uploaded_file)
|
182
|
+
|
183
|
+
@entry.avatar.should == uploaded_file
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "saving uploaded files" do
|
188
|
+
|
189
|
+
include UploadColumnSpecHelper
|
190
|
+
|
191
|
+
before do
|
192
|
+
setup_standard_mocking
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should call save on the uploaded file if they are temporary files" do
|
196
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
197
|
+
|
198
|
+
@uploaded_file.should_receive(:tempfile?).and_return(true)
|
199
|
+
@uploaded_file.should_receive(:save)
|
200
|
+
@entry.avatar = @file
|
201
|
+
|
202
|
+
@entry.send(:save_uploaded_files)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should not call save on the uploaded file if they are not temporary files" do
|
206
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
207
|
+
|
208
|
+
@uploaded_file.should_receive(:tempfile?).and_return(false)
|
209
|
+
@uploaded_file.should_not_receive(:save)
|
210
|
+
@entry.avatar = @file
|
211
|
+
|
212
|
+
@entry.send(:save_uploaded_files)
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should happen automatically" do
|
216
|
+
# TODO: hmmm, how to test this? do we have to rely on an integration test?
|
217
|
+
#@entry.should_receive(:save_uploaded_files)
|
218
|
+
#@entry.save
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
describe "fetching a temp value" do
|
224
|
+
|
225
|
+
include UploadColumnSpecHelper
|
226
|
+
|
227
|
+
setup do
|
228
|
+
setup_standard_mocking
|
229
|
+
|
230
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
231
|
+
|
232
|
+
@temp_value = '12345.1234.12345/somewhere.png'
|
233
|
+
|
234
|
+
@uploaded_file.should_receive(:temp_value).and_return(@temp_value)
|
235
|
+
@entry.avatar = @file
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should fetch the value from the uploaded file" do
|
239
|
+
@entry.avatar_temp.should == @temp_value
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
describe "assigning a tempfile" do
|
245
|
+
|
246
|
+
include UploadColumnSpecHelper
|
247
|
+
|
248
|
+
setup do
|
249
|
+
setup_standard_mocking
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should not override a new file" do
|
253
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
254
|
+
@uploaded_file.stub!(:new_file?).and_return(true)
|
255
|
+
@entry.avatar = @file
|
256
|
+
|
257
|
+
temp_value = '12345.1234.12345/somewhere.png'
|
258
|
+
|
259
|
+
UploadColumn::UploadedFile.should_not_receive(:retrieve_temp)
|
260
|
+
@entry.avatar_temp = temp_value
|
261
|
+
|
262
|
+
@entry.avatar.should == @uploaded_file
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should override a file that is not new" do
|
266
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
267
|
+
@uploaded_file.stub!(:new_file?).and_return(false)
|
268
|
+
@entry.avatar = @file
|
269
|
+
|
270
|
+
temp_value = '12345.1234.12345/somewhere.png'
|
271
|
+
|
272
|
+
retrieved_file = mock('a retrieved file')
|
273
|
+
retrieved_file.should_receive(:actual_filename).and_return('walruss.png')
|
274
|
+
UploadColumn::UploadedFile.should_receive(:retrieve_temp).with(temp_value, @entry, :avatar, @options).and_return(retrieved_file)
|
275
|
+
@entry.should_receive(:[]=).with(:avatar, 'walruss.png')
|
276
|
+
|
277
|
+
@entry.avatar_temp = temp_value
|
278
|
+
|
279
|
+
@entry.avatar.should == retrieved_file
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should set the file if there is none" do
|
283
|
+
|
284
|
+
temp_value = '12345.1234.12345/somewhere.png'
|
285
|
+
|
286
|
+
retrieved_file = mock('a retrieved file')
|
287
|
+
retrieved_file.should_receive(:actual_filename).and_return('walruss.png')
|
288
|
+
UploadColumn::UploadedFile.should_receive(:retrieve_temp).with(temp_value, @entry, :avatar, @options).and_return(retrieved_file)
|
289
|
+
@entry.should_receive(:[]=).with(:avatar, 'walruss.png')
|
290
|
+
|
291
|
+
@entry.avatar_temp = temp_value
|
292
|
+
|
293
|
+
@entry.avatar.should == retrieved_file
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
describe "assigning nil to temp" do
|
299
|
+
|
300
|
+
include UploadColumnSpecHelper
|
301
|
+
|
302
|
+
before(:each) do
|
303
|
+
setup_standard_mocking
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should do nothing" do
|
307
|
+
UploadColumn::UploadedFile.stub!(:upload).and_return(@uploaded_file)
|
308
|
+
@uploaded_file.stub!(:new_file?).and_return(false)
|
309
|
+
@entry.avatar = @file
|
310
|
+
|
311
|
+
UploadColumn::UploadedFile.should_not_receive(:retrieve_temp)
|
312
|
+
@entry.should_not_receive(:[]=)
|
313
|
+
|
314
|
+
lambda {
|
315
|
+
@entry.avatar_temp = nil
|
316
|
+
}.should_not change(@entry, :avatar)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
describe "assigning a blank string to temp" do
|
321
|
+
|
322
|
+
include UploadColumnSpecHelper
|
323
|
+
|
324
|
+
before(:each) do
|
325
|
+
setup_standard_mocking
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should do nothing" do
|
329
|
+
UploadColumn::UploadedFile.should_receive(:upload).with(@file, @entry, :avatar, @options).and_return(@uploaded_file)
|
330
|
+
@uploaded_file.stub!(:new_file?).and_return(false)
|
331
|
+
@entry.avatar = @file
|
332
|
+
|
333
|
+
UploadColumn::UploadedFile.should_not_receive(:retrieve_temp)
|
334
|
+
@entry.should_not_receive(:[]=)
|
335
|
+
|
336
|
+
lambda {
|
337
|
+
@entry.avatar_temp = ""
|
338
|
+
}.should_not change(@entry, :avatar)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "an upload column with no file" do
|
343
|
+
|
344
|
+
include UploadColumnSpecHelper
|
345
|
+
|
346
|
+
before(:each) do
|
347
|
+
setup_standard_mocking
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should return no value" do
|
351
|
+
@entry.avatar.should be_nil
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should return no temp_value" do
|
355
|
+
@entry.avatar_temp.should be_nil
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should return nothing in the _public_path method" do
|
359
|
+
@entry.avatar_public_path.should == nil
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should return nothing in the _path method" do
|
363
|
+
@entry.avatar_path.should == nil
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
describe "an upload column with an uploaded file" do
|
368
|
+
|
369
|
+
include UploadColumnSpecHelper
|
370
|
+
|
371
|
+
before(:each) do
|
372
|
+
setup_standard_mocking
|
373
|
+
UploadColumn::UploadedFile.stub!(:upload).and_return(@uploaded_file)
|
374
|
+
@entry.avatar = @file
|
375
|
+
end
|
376
|
+
|
377
|
+
it "should delegate the _public_path method to the column" do
|
378
|
+
@uploaded_file.should_receive(:public_path).and_return('/url/to/file.exe')
|
379
|
+
@entry.avatar_public_path.should == '/url/to/file.exe'
|
380
|
+
end
|
381
|
+
|
382
|
+
it "should delegate the _path method to the column" do
|
383
|
+
@uploaded_file.should_receive(:path).and_return('/path/to/file.exe')
|
384
|
+
@entry.avatar_path.should == '/path/to/file.exe'
|
385
|
+
end
|
386
|
+
|
387
|
+
end
|
388
|
+
|
389
|
+
describe "an upload column with different versions and no uploaded file" do
|
390
|
+
|
391
|
+
include UploadColumnSpecHelper
|
392
|
+
|
393
|
+
before(:each) do
|
394
|
+
setup_version_mocking # sets up a column with thumb and large versions
|
395
|
+
end
|
396
|
+
|
397
|
+
it "should return nil for the _thumb method" do
|
398
|
+
@entry.avatar_thumb.should == nil
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should return nil for the _large method" do
|
402
|
+
@entry.avatar_large.should == nil
|
403
|
+
end
|
404
|
+
|
405
|
+
it "should return nil for the _thumb_url method" do
|
406
|
+
@entry.avatar_thumb_public_path.should == nil
|
407
|
+
end
|
408
|
+
|
409
|
+
it "should return nil for the _large_path method" do
|
410
|
+
@entry.avatar_large_path.should == nil
|
411
|
+
end
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
describe "an upload column with different versions and an uploaded file" do
|
416
|
+
|
417
|
+
include UploadColumnSpecHelper
|
418
|
+
|
419
|
+
before(:each) do
|
420
|
+
setup_version_mocking # sets up a column with thumb and large versions
|
421
|
+
UploadColumn::UploadedFile.stub!(:upload).and_return(@uploaded_file)
|
422
|
+
@entry.avatar = @file
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should delegate the _thumb method to the column" do
|
426
|
+
thumb = mock('thumb')
|
427
|
+
@uploaded_file.should_receive(:thumb).and_return(thumb)
|
428
|
+
@entry.avatar_thumb.should == thumb
|
429
|
+
end
|
430
|
+
|
431
|
+
it "should delegate the _large method to the column" do
|
432
|
+
large = mock('large')
|
433
|
+
@uploaded_file.should_receive(:large).and_return(large)
|
434
|
+
@entry.avatar_large.should == large
|
435
|
+
end
|
436
|
+
|
437
|
+
it "should delegate the _thumb_url method to the column" do
|
438
|
+
thumb = mock('thumb')
|
439
|
+
thumb.should_receive(:public_path).and_return('/url/to/file.exe')
|
440
|
+
@uploaded_file.should_receive(:thumb).and_return(thumb)
|
441
|
+
|
442
|
+
@entry.avatar_thumb_public_path.should == '/url/to/file.exe'
|
443
|
+
end
|
444
|
+
|
445
|
+
it "should delegate the _large_path method to the column" do
|
446
|
+
large = mock('large')
|
447
|
+
large.should_receive(:path).and_return('/path/to/file.exe')
|
448
|
+
@uploaded_file.should_receive(:large).and_return(large)
|
449
|
+
|
450
|
+
@entry.avatar_large_path.should == '/path/to/file.exe'
|
451
|
+
end
|
452
|
+
|
453
|
+
end
|
454
|
+
|
455
|
+
describe "uploading a file that fails an integrity check" do
|
456
|
+
|
457
|
+
include UploadColumnSpecHelper
|
458
|
+
|
459
|
+
before(:all) do
|
460
|
+
Entry.validates_integrity_of :avatar
|
461
|
+
end
|
462
|
+
|
463
|
+
before(:each) do
|
464
|
+
setup_standard_mocking
|
465
|
+
end
|
466
|
+
|
467
|
+
it "should set the column to nil" do
|
468
|
+
UploadColumn::UploadedFile.should_receive(:upload).and_raise(UploadColumn::IntegrityError.new('something'))
|
469
|
+
@entry.avatar = @file
|
470
|
+
|
471
|
+
@entry.avatar.should be_nil
|
472
|
+
end
|
473
|
+
|
474
|
+
it "should fail an integrity validation" do
|
475
|
+
UploadColumn::UploadedFile.should_receive(:upload).and_raise(UploadColumn::IntegrityError.new('something'))
|
476
|
+
@entry.avatar = @file
|
477
|
+
|
478
|
+
@entry.should_not be_valid
|
479
|
+
@entry.errors.on(:avatar).should == 'something'
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
describe UploadColumn::ActiveRecordExtension::ClassMethods, ".image_column" do
|
484
|
+
|
485
|
+
include UploadColumnSpecHelper
|
486
|
+
|
487
|
+
before(:each) do
|
488
|
+
@class = Class.new(ActiveRecord::Base)
|
489
|
+
@class.send(:include, UploadColumn)
|
490
|
+
end
|
491
|
+
|
492
|
+
it "should call an upload column with some specialized options" do
|
493
|
+
@class.should_receive(:upload_column).with(:sicada,
|
494
|
+
:manipulator => UploadColumn::Manipulators::RMagick,
|
495
|
+
:root_dir => File.join(RAILS_ROOT, 'public', 'images'),
|
496
|
+
:web_root => '/images',
|
497
|
+
:monkey => 'blah',
|
498
|
+
:extensions => UploadColumn.image_extensions
|
499
|
+
)
|
500
|
+
@class.image_column(:sicada, :monkey => 'blah')
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
describe UploadColumn::ActiveRecordExtension::ClassMethods, ".validate_integrity" do
|
505
|
+
|
506
|
+
include UploadColumnSpecHelper
|
507
|
+
|
508
|
+
it "should change the options for this upload_column" do
|
509
|
+
Entry.upload_column :avatar
|
510
|
+
Entry.reflect_on_upload_columns[:avatar].options[:validate_integrity].should be_nil
|
511
|
+
Entry.validates_integrity_of :avatar
|
512
|
+
Entry.reflect_on_upload_columns[:avatar].options[:validate_integrity].should == true
|
513
|
+
end
|
514
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
class BeIdenticalWith
|
2
|
+
def initialize(expected)
|
3
|
+
@expected = expected
|
4
|
+
end
|
5
|
+
def matches?(actual)
|
6
|
+
@actual = actual
|
7
|
+
FileUtils.identical?(@actual, @expected)
|
8
|
+
end
|
9
|
+
def failure_message
|
10
|
+
"expected #{@actual.inspect} to be identical with #{@expected.inspect}"
|
11
|
+
end
|
12
|
+
def negative_failure_message
|
13
|
+
"expected #{@actual.inspect} to not be identical with #{@expected.inspect}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def be_identical_with(expected)
|
18
|
+
BeIdenticalWith.new(expected)
|
19
|
+
end
|
20
|
+
|
21
|
+
class ExistsPredicate
|
22
|
+
|
23
|
+
def matches?(actual)
|
24
|
+
actual.exists?
|
25
|
+
end
|
26
|
+
def failure_message
|
27
|
+
"expected #{@actual.inspect} to exist, it doesn't."
|
28
|
+
end
|
29
|
+
def negative_failure_message
|
30
|
+
"expected #{@actual.inspect} to not exist, yet it does."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def be_in_existence
|
35
|
+
ExistsPredicate.new
|
36
|
+
end
|
37
|
+
|
38
|
+
class MatchPath
|
39
|
+
def initialize(*expected)
|
40
|
+
if(expected.size < 2)
|
41
|
+
@expected = File.expand_path(expected.first)
|
42
|
+
else
|
43
|
+
@expected = expected.map {|e| e.is_a?(Regexp) ? e.to_s : Regexp.escape(e)}
|
44
|
+
@expected = File.expand_path(File.join(*@expected), RAILS_ROOT)
|
45
|
+
@expected = %r(^#{@expected}$)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
def matches?(actual)
|
49
|
+
@actual = actual
|
50
|
+
if @expected.is_a?(Regexp)
|
51
|
+
File.expand_path(actual) =~ @expected
|
52
|
+
else
|
53
|
+
File.expand_path(actual) == @expected
|
54
|
+
end
|
55
|
+
end
|
56
|
+
def failure_message
|
57
|
+
"expected #{@actual.inspect} to match #{@expected}."
|
58
|
+
end
|
59
|
+
def negative_failure_message
|
60
|
+
"expected #{@actual.inspect} to not match #{@expected}, yet it does."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Match a path without bothering whether they are formatted the same way.
|
65
|
+
# can also take several parameters, any number of which may be regexes
|
66
|
+
def match_path(*expected)
|
67
|
+
MatchPath.new(*expected)
|
68
|
+
end
|
69
|
+
|
70
|
+
class HavePermissions
|
71
|
+
def initialize(expected)
|
72
|
+
@expected = expected
|
73
|
+
end
|
74
|
+
|
75
|
+
def matches?(actual)
|
76
|
+
@actual = actual
|
77
|
+
# Satisfy expectation here. Return false or raise an error if it's not met.
|
78
|
+
(File.stat(@actual.path).mode & 0777) == @expected
|
79
|
+
end
|
80
|
+
|
81
|
+
def failure_message
|
82
|
+
"expected #{@actual.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def negative_failure_message
|
86
|
+
"expected #{@actual.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def have_permissions(expected)
|
91
|
+
HavePermissions.new(expected)
|
92
|
+
end
|
93
|
+
|
94
|
+
class BeNoLargerThan
|
95
|
+
def initialize(width, height)
|
96
|
+
@width, @height = width, height
|
97
|
+
end
|
98
|
+
|
99
|
+
def matches?(actual)
|
100
|
+
@actual = actual
|
101
|
+
# Satisfy expectation here. Return false or raise an error if it's not met.
|
102
|
+
require 'RMagick'
|
103
|
+
img = ::Magick::Image.read(@actual.path).first
|
104
|
+
@actual_width = img.columns
|
105
|
+
@actual_height = img.rows
|
106
|
+
@actual_width <= @width && @actual_height <= @height
|
107
|
+
end
|
108
|
+
|
109
|
+
def failure_message
|
110
|
+
"expected #{@actual.inspect} to be no larger than #{@width} by #{@height}, but it was #{@actual_height} by #{@actual_width}."
|
111
|
+
end
|
112
|
+
|
113
|
+
def negative_failure_message
|
114
|
+
"expected #{@actual.inspect} to be larger than #{@width} by #{@height}, but it wasn't."
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def be_no_larger_than(width, height)
|
119
|
+
BeNoLargerThan.new(width, height)
|
120
|
+
end
|
121
|
+
|
122
|
+
class HaveTheExactDimensionsOf
|
123
|
+
def initialize(width, height)
|
124
|
+
@width, @height = width, height
|
125
|
+
end
|
126
|
+
|
127
|
+
def matches?(actual)
|
128
|
+
@actual = actual
|
129
|
+
# Satisfy expectation here. Return false or raise an error if it's not met.
|
130
|
+
require 'RMagick'
|
131
|
+
img = ::Magick::Image.read(@actual.path).first
|
132
|
+
@actual_width = img.columns
|
133
|
+
@actual_height = img.rows
|
134
|
+
@actual_width == @width && @actual_height == @height
|
135
|
+
end
|
136
|
+
|
137
|
+
def failure_message
|
138
|
+
"expected #{@actual.inspect} to have an exact size of #{@width} by #{@height}, but it was #{@actual_height} by #{@actual_width}."
|
139
|
+
end
|
140
|
+
|
141
|
+
def negative_failure_message
|
142
|
+
"expected #{@actual.inspect} not to have an exact size of #{@width} by #{@height}, but it did."
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def have_the_exact_dimensions_of(width, height)
|
147
|
+
HaveTheExactDimensionsOf.new(width, height)
|
148
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
this is certainly not a JPEG image
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|