paperclip 2.8.0 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of paperclip might be problematic. Click here for more details.

Files changed (94) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +9 -7
  3. data/Appraisals +6 -12
  4. data/Gemfile +2 -0
  5. data/NEWS +24 -0
  6. data/README.md +53 -21
  7. data/Rakefile +7 -2
  8. data/UPGRADING +14 -0
  9. data/features/basic_integration.feature +8 -8
  10. data/features/rake_tasks.feature +1 -1
  11. data/features/step_definitions/attachment_steps.rb +11 -2
  12. data/features/step_definitions/rails_steps.rb +17 -79
  13. data/features/support/env.rb +3 -0
  14. data/features/support/file_helpers.rb +24 -0
  15. data/features/support/rails.rb +3 -3
  16. data/gemfiles/{rails3_1.gemfile → 3.0.gemfile} +3 -1
  17. data/gemfiles/{rails2.gemfile → 3.1.gemfile} +3 -1
  18. data/gemfiles/{rails3.gemfile → 3.2.gemfile} +3 -1
  19. data/images.rake +21 -0
  20. data/lib/generators/paperclip/paperclip_generator.rb +1 -2
  21. data/lib/paperclip.rb +48 -319
  22. data/lib/paperclip/attachment.rb +33 -81
  23. data/lib/paperclip/attachment_options.rb +0 -1
  24. data/lib/paperclip/callbacks.rb +30 -0
  25. data/lib/paperclip/errors.rb +27 -0
  26. data/lib/paperclip/geometry.rb +6 -4
  27. data/lib/paperclip/glue.rb +15 -0
  28. data/lib/paperclip/helpers.rb +71 -0
  29. data/lib/paperclip/instance_methods.rb +35 -0
  30. data/lib/paperclip/interpolations.rb +2 -2
  31. data/lib/paperclip/io_adapters/attachment_adapter.rb +62 -0
  32. data/lib/paperclip/io_adapters/file_adapter.rb +81 -0
  33. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  34. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  35. data/lib/paperclip/io_adapters/registry.rb +32 -0
  36. data/lib/paperclip/io_adapters/stringio_adapter.rb +64 -0
  37. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +63 -0
  38. data/lib/paperclip/locales/en.yml +17 -0
  39. data/lib/paperclip/logger.rb +21 -0
  40. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +1 -1
  41. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -2
  42. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +7 -7
  43. data/lib/paperclip/processor.rb +32 -17
  44. data/lib/paperclip/railtie.rb +10 -15
  45. data/lib/paperclip/storage/filesystem.rb +5 -14
  46. data/lib/paperclip/storage/fog.rb +2 -21
  47. data/lib/paperclip/storage/s3.rb +12 -29
  48. data/lib/paperclip/tempfile.rb +41 -0
  49. data/lib/paperclip/thumbnail.rb +2 -3
  50. data/lib/paperclip/validators.rb +45 -0
  51. data/lib/paperclip/validators/attachment_content_type_validator.rb +47 -0
  52. data/lib/paperclip/validators/attachment_presence_validator.rb +26 -0
  53. data/lib/paperclip/validators/attachment_size_validator.rb +102 -0
  54. data/lib/paperclip/version.rb +1 -1
  55. data/lib/tasks/paperclip.rake +3 -11
  56. data/paperclip.gemspec +15 -5
  57. data/test/adapter_registry_test.rb +32 -0
  58. data/test/attachment_adapter_test.rb +48 -0
  59. data/test/attachment_options_test.rb +0 -13
  60. data/test/attachment_test.rb +27 -55
  61. data/test/file_adapter_test.rb +43 -0
  62. data/test/generator_test.rb +78 -0
  63. data/test/geometry_test.rb +5 -5
  64. data/test/helper.rb +9 -11
  65. data/test/identity_adapter_test.rb +8 -0
  66. data/test/integration_test.rb +39 -94
  67. data/test/interpolations_test.rb +8 -1
  68. data/test/matchers/validate_attachment_size_matcher_test.rb +16 -2
  69. data/test/nil_adapter_test.rb +25 -0
  70. data/test/paperclip_test.rb +30 -189
  71. data/test/storage/filesystem_test.rb +0 -14
  72. data/test/storage/fog_test.rb +0 -14
  73. data/test/storage/s3_live_test.rb +22 -9
  74. data/test/storage/s3_test.rb +70 -34
  75. data/test/stringio_adapter_test.rb +42 -0
  76. data/test/style_test.rb +10 -16
  77. data/test/thumbnail_test.rb +16 -10
  78. data/test/uploaded_file_adapter_test.rb +98 -0
  79. data/test/validators/attachment_content_type_validator_test.rb +140 -0
  80. data/test/validators/attachment_presence_validator_test.rb +85 -0
  81. data/test/validators/attachment_size_validator_test.rb +207 -0
  82. data/test/validators_test.rb +25 -0
  83. metadata +152 -30
  84. data/gemfiles/rails3_2.gemfile +0 -9
  85. data/generators/paperclip/USAGE +0 -5
  86. data/generators/paperclip/paperclip_generator.rb +0 -27
  87. data/generators/paperclip/templates/paperclip_migration.rb.erb +0 -19
  88. data/init.rb +0 -4
  89. data/lib/paperclip/callback_compatibility.rb +0 -61
  90. data/lib/paperclip/iostream.rb +0 -45
  91. data/lib/paperclip/upfile.rb +0 -64
  92. data/rails/init.rb +0 -2
  93. data/test/iostream_test.rb +0 -71
  94. data/test/upfile_test.rb +0 -53
@@ -117,30 +117,30 @@ class GeometryTest < Test::Unit::TestCase
117
117
 
118
118
  should "not generate from a bad file" do
119
119
  file = "/home/This File Does Not Exist.omg"
120
- assert_raise(Paperclip::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
120
+ assert_raise(Paperclip::Errors::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
121
121
  end
122
122
 
123
123
  should "not generate from a blank filename" do
124
124
  file = ""
125
- assert_raise(Paperclip::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
125
+ assert_raise(Paperclip::Errors::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
126
126
  end
127
127
 
128
128
  should "not generate from a nil file" do
129
129
  file = nil
130
- assert_raise(Paperclip::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
130
+ assert_raise(Paperclip::Errors::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
131
131
  end
132
132
 
133
133
  should "not generate from a file with no path" do
134
134
  file = mock("file", :path => "")
135
135
  file.stubs(:respond_to?).with(:path).returns(true)
136
- assert_raise(Paperclip::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
136
+ assert_raise(Paperclip::Errors::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
137
137
  end
138
138
 
139
139
  should "let us know when a command isn't found versus a processing error" do
140
140
  old_path = ENV['PATH']
141
141
  begin
142
142
  ENV['PATH'] = ''
143
- assert_raises(Paperclip::CommandNotFoundError) do
143
+ assert_raises(Paperclip::Errors::CommandNotFoundError) do
144
144
  file = File.join(File.dirname(__FILE__), "fixtures", "5k.png")
145
145
  @geo = Paperclip::Geometry.from_file(file)
146
146
  end
@@ -5,14 +5,15 @@ require 'test/unit'
5
5
 
6
6
  require 'shoulda'
7
7
  require 'mocha'
8
+ require 'bourne'
8
9
 
9
10
  require 'active_record'
10
11
  require 'active_record/version'
11
12
  require 'active_support'
13
+ require 'active_support/core_ext'
12
14
  require 'mime/types'
13
15
  require 'pathname'
14
-
15
- require 'pathname'
16
+ require 'ostruct'
16
17
 
17
18
  puts "Testing against version #{ActiveRecord::VERSION::STRING}"
18
19
 
@@ -26,13 +27,6 @@ end
26
27
 
27
28
  ROOT = Pathname(File.expand_path(File.join(File.dirname(__FILE__), '..')))
28
29
 
29
- def silence_warnings
30
- old_verbose, $VERBOSE = $VERBOSE, nil
31
- yield
32
- ensure
33
- $VERBOSE = old_verbose
34
- end
35
-
36
30
  class Test::Unit::TestCase
37
31
  def setup
38
32
  silence_warnings do
@@ -66,7 +60,11 @@ def reset_class class_name
66
60
  ActiveRecord::Base.send(:include, Paperclip::Glue)
67
61
  Object.send(:remove_const, class_name) rescue nil
68
62
  klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
69
- klass.class_eval{ include Paperclip::Glue }
63
+
64
+ klass.class_eval do
65
+ include Paperclip::Glue
66
+ end
67
+
70
68
  klass
71
69
  end
72
70
 
@@ -121,7 +119,7 @@ class FakeModel
121
119
 
122
120
  end
123
121
 
124
- def attachment options
122
+ def attachment(options={})
125
123
  Paperclip::Attachment.new(:avatar, FakeModel.new, options)
126
124
  end
127
125
 
@@ -0,0 +1,8 @@
1
+ require './test/helper'
2
+
3
+ class IdentityAdapterTest < Test::Unit::TestCase
4
+ should "respond to #new by returning the argument" do
5
+ adapter = Paperclip::IdentityAdapter.new
6
+ assert_equal :target, adapter.new(:target)
7
+ end
8
+ end
@@ -40,12 +40,16 @@ class IntegrationTest < Test::Unit::TestCase
40
40
 
41
41
  should "not raise an error" do
42
42
  assert_nothing_raised do
43
- @dummy.avatar.reprocess!
43
+ silence_stream(STDERR) do
44
+ @dummy.avatar.reprocess!
45
+ end
44
46
  end
45
47
  end
46
48
 
47
49
  should "return false" do
48
- assert ! @dummy.avatar.reprocess!
50
+ silence_stream(STDERR) do
51
+ assert !@dummy.avatar.reprocess!
52
+ end
49
53
  end
50
54
 
51
55
  teardown { File.chmod(0644, @dummy.avatar.path) }
@@ -54,7 +58,6 @@ class IntegrationTest < Test::Unit::TestCase
54
58
  context "redefining its attachment styles" do
55
59
  setup do
56
60
  Dummy.class_eval do
57
- has_attached_file :avatar, :styles => { :thumb => "150x25#" }
58
61
  has_attached_file :avatar, :styles => { :thumb => "150x25#", :dynamic => lambda { |a| '50x50#' } }
59
62
  end
60
63
  @d2 = Dummy.find(@dummy.id)
@@ -71,26 +74,12 @@ class IntegrationTest < Test::Unit::TestCase
71
74
  should "change the timestamp" do
72
75
  assert_not_equal @original_timestamp, @d2.avatar_updated_at
73
76
  end
74
-
75
- should "clean up the old original if it is a tempfile" do
76
- original = @d2.avatar.to_file(:original)
77
- tf = Paperclip::Tempfile.new('original')
78
- tf.binmode
79
- original.binmode
80
- tf.write(original.read)
81
- original.close
82
- tf.rewind
83
-
84
- @d2.avatar.expects(:to_file).with(:original).returns(tf)
85
-
86
- @d2.avatar.reprocess!
87
- end
88
77
  end
89
78
  end
90
79
 
91
80
  context "Attachment" do
92
81
  setup do
93
- @thumb_path = "./test/../public/system/avatars/1/thumb/5k.png"
82
+ @thumb_path = "./test/../public/system/dummies/avatars/000/000/001/thumb/5k.png"
94
83
  File.delete(@thumb_path) if File.exists?(@thumb_path)
95
84
  rebuild_model :styles => { :thumb => "50x50#" }
96
85
  @dummy = Dummy.new
@@ -119,8 +108,8 @@ class IntegrationTest < Test::Unit::TestCase
119
108
 
120
109
  context "Attachment with no generated thumbnails" do
121
110
  setup do
122
- @thumb_small_path = "./test/../public/system/avatars/1/thumb_small/5k.png"
123
- @thumb_large_path = "./test/../public/system/avatars/1/thumb_large/5k.png"
111
+ @thumb_small_path = "./test/../public/system/dummies/avatars/000/000/001/thumb_small/5k.png"
112
+ @thumb_large_path = "./test/../public/system/dummies/avatars/000/000/001/thumb_large/5k.png"
124
113
  File.delete(@thumb_small_path) if File.exists?(@thumb_small_path)
125
114
  File.delete(@thumb_large_path) if File.exists?(@thumb_large_path)
126
115
  rebuild_model :styles => { :thumb_small => "50x50#", :thumb_large => "60x60#" }
@@ -171,7 +160,7 @@ class IntegrationTest < Test::Unit::TestCase
171
160
  end
172
161
 
173
162
  should "report the file size of the processed file and not the original" do
174
- assert_not_equal @file.size, @dummy.avatar.size
163
+ assert_not_equal File.size(@file.path), @dummy.avatar.size
175
164
  end
176
165
 
177
166
  teardown { @file.close }
@@ -223,48 +212,6 @@ class IntegrationTest < Test::Unit::TestCase
223
212
  end
224
213
  end
225
214
 
226
- context "A model with no attachment validation" do
227
- setup do
228
- rebuild_model :styles => { :large => "300x300>",
229
- :medium => "100x100",
230
- :thumb => ["32x32#", :gif] },
231
- :default_style => :medium,
232
- :url => "/:attachment/:class/:style/:id/:basename.:extension",
233
- :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
234
- @dummy = Dummy.new
235
- end
236
-
237
- should "have its definition return false when asked about whiny_thumbnails" do
238
- assert ! Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
239
- end
240
-
241
- context "when validates_attachment_thumbnails is called" do
242
- setup do
243
- Dummy.validates_attachment_thumbnails :avatar
244
- end
245
-
246
- should "have its definition return true when asked about whiny_thumbnails" do
247
- assert_equal true, Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
248
- end
249
- end
250
-
251
- context "redefined to have attachment validations" do
252
- setup do
253
- rebuild_model :styles => { :large => "300x300>",
254
- :medium => "100x100",
255
- :thumb => ["32x32#", :gif] },
256
- :whiny_thumbnails => true,
257
- :default_style => :medium,
258
- :url => "/:attachment/:class/:style/:id/:basename.:extension",
259
- :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
260
- end
261
-
262
- should "have its definition return true when asked about whiny_thumbnails" do
263
- assert_equal true, Dummy.attachment_definitions[:avatar][:whiny_thumbnails]
264
- end
265
- end
266
- end
267
-
268
215
  context "A model with no convert_options setting" do
269
216
  setup do
270
217
  rebuild_model :styles => { :large => "300x300>",
@@ -329,12 +276,32 @@ class IntegrationTest < Test::Unit::TestCase
329
276
  end
330
277
  end
331
278
 
279
+ [000,002,022].each do |umask|
280
+ context "when the umask is #{umask}" do
281
+ setup do
282
+ rebuild_model
283
+ @dummy = Dummy.new
284
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
285
+ @umask = File.umask(umask)
286
+ end
287
+
288
+ teardown do
289
+ File.umask @umask
290
+ end
291
+
292
+ should "respect the current umask" do
293
+ @dummy.avatar = @file
294
+ @dummy.save
295
+ assert_equal 0666&~umask, 0666&File.stat(@dummy.avatar.path).mode
296
+ end
297
+ end
298
+ end
299
+
332
300
  context "A model with a filesystem attachment" do
333
301
  setup do
334
302
  rebuild_model :styles => { :large => "300x300>",
335
303
  :medium => "100x100",
336
304
  :thumb => ["32x32#", :gif] },
337
- :whiny_thumbnails => true,
338
305
  :default_style => :medium,
339
306
  :url => "/:attachment/:class/:style/:id/:basename.:extension",
340
307
  :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
@@ -365,8 +332,6 @@ class IntegrationTest < Test::Unit::TestCase
365
332
  assert_equal "100x15", `identify -format "%wx%h" "#{@d2.avatar.path(:medium)}"`.chomp
366
333
  assert_equal "32x32", `identify -format "%wx%h" "#{@d2.avatar.path(:thumb)}"`.chomp
367
334
 
368
- @dummy.avatar = "not a valid file but not nil"
369
- assert_equal File.basename(@file.path), @dummy.avatar_file_name
370
335
  assert @dummy.valid?
371
336
  assert @dummy.save
372
337
 
@@ -405,13 +370,13 @@ class IntegrationTest < Test::Unit::TestCase
405
370
  end
406
371
  end
407
372
 
408
- should "know the difference between good files, bad files, and not files" do
409
- expected = @dummy.avatar.to_file
410
- @dummy.avatar = "not a file"
411
- assert @dummy.valid?
412
- assert_equal expected.path, @dummy.avatar.path
413
- expected.close
373
+ should "not abide things that don't have adapters" do
374
+ assert_raises(Paperclip::AdapterRegistry::NoHandlerError) do
375
+ @dummy.avatar = "not a file"
376
+ end
377
+ end
414
378
 
379
+ should "not be ok with bad files" do
415
380
  @dummy.avatar = @bad_file
416
381
  assert ! @dummy.valid?
417
382
  end
@@ -427,31 +392,13 @@ class IntegrationTest < Test::Unit::TestCase
427
392
 
428
393
  should "be able to reload without saving and not have the file disappear" do
429
394
  @dummy.avatar = @file
430
- assert @dummy.save
395
+ assert @dummy.save, @dummy.errors.full_messages.inspect
431
396
  @dummy.avatar.clear
432
397
  assert_nil @dummy.avatar_file_name
433
398
  @dummy.reload
434
399
  assert_equal "5k.png", @dummy.avatar_file_name
435
400
  end
436
401
 
437
- [000,002,022].each do |umask|
438
- context "when the umask is #{umask}" do
439
- setup do
440
- @umask = File.umask umask
441
- end
442
-
443
- teardown do
444
- File.umask @umask
445
- end
446
-
447
- should "respect the current umask" do
448
- @dummy.avatar = @file
449
- @dummy.save
450
- assert_equal 0666&~umask, 0666&File.stat(@dummy.avatar.path).mode
451
- end
452
- end
453
- end
454
-
455
402
  context "that is assigned its file from another Paperclip attachment" do
456
403
  setup do
457
404
  @dummy2 = Dummy.new
@@ -466,9 +413,9 @@ class IntegrationTest < Test::Unit::TestCase
466
413
 
467
414
  assert @dummy.avatar = @dummy2.avatar
468
415
  @dummy.save
416
+ assert_equal @dummy.avatar_file_name, @dummy2.avatar_file_name
469
417
  assert_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
470
418
  `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
471
- assert_equal @dummy.avatar_file_name, @dummy2.avatar_file_name
472
419
  end
473
420
  end
474
421
 
@@ -520,7 +467,6 @@ class IntegrationTest < Test::Unit::TestCase
520
467
  :medium => "100x100",
521
468
  :thumb => ["32x32#", :gif] },
522
469
  :storage => :s3,
523
- :whiny_thumbnails => true,
524
470
  :s3_credentials => File.new(File.join(File.dirname(__FILE__), "s3.yml")),
525
471
  :default_style => :medium,
526
472
  :bucket => ENV['S3_TEST_BUCKET'],
@@ -549,7 +495,6 @@ class IntegrationTest < Test::Unit::TestCase
549
495
  end
550
496
 
551
497
  should "have the same contents as the original" do
552
- @file.rewind
553
498
  assert_equal @file.read, @files_on_s3[:original].read
554
499
  end
555
500
 
@@ -77,6 +77,13 @@ class InterpolationsTest < Test::Unit::TestCase
77
77
  assert_equal "found", interpolations.content_type_extension(attachment, :style)
78
78
  end
79
79
 
80
+ should "be able to handle numeric style names" do
81
+ attachment = mock(
82
+ :styles => {:"4" => {:format => :expected_extension}}
83
+ )
84
+ assert_equal :expected_extension, Paperclip::Interpolations.extension(attachment, 4)
85
+ end
86
+
80
87
  should "return the #to_param of the attachment" do
81
88
  attachment = mock
82
89
  attachment.expects(:to_param).returns("23-awesome")
@@ -148,7 +155,7 @@ class InterpolationsTest < Test::Unit::TestCase
148
155
  Paperclip::Interpolations.url(self, :style)
149
156
  end
150
157
  end
151
- assert_raises(Paperclip::InfiniteInterpolationError){ Paperclip::Interpolations.url(attachment, :style) }
158
+ assert_raises(Paperclip::Errors::InfiniteInterpolationError){ Paperclip::Interpolations.url(attachment, :style) }
152
159
  end
153
160
 
154
161
  should "return the filename as basename.extension" do
@@ -34,7 +34,7 @@ class ValidateAttachmentSizeMatcherTest < Test::Unit::TestCase
34
34
  end
35
35
  end
36
36
 
37
- context "validates_attachment_size with infinite range" do
37
+ context "allowing anything" do
38
38
  setup{ @matcher = self.class.validate_attachment_size(:avatar) }
39
39
 
40
40
  context "given a class with an upper limit" do
@@ -42,7 +42,7 @@ class ValidateAttachmentSizeMatcherTest < Test::Unit::TestCase
42
42
  should_accept_dummy_class
43
43
  end
44
44
 
45
- context "given a class with no upper limit" do
45
+ context "given a class with a lower limit" do
46
46
  setup { @dummy_class.validates_attachment_size :avatar, :greater_than => 1 }
47
47
  should_accept_dummy_class
48
48
  end
@@ -68,5 +68,19 @@ class ValidateAttachmentSizeMatcherTest < Test::Unit::TestCase
68
68
  assert_rejects @matcher, @dummy
69
69
  end
70
70
  end
71
+
72
+ context "post processing" do
73
+ setup do
74
+ @dummy_class.validates_attachment_size :avatar, :greater_than => 1024
75
+
76
+ @dummy = @dummy_class.new
77
+ @matcher = self.class.validate_attachment_size(:avatar).greater_than(1024)
78
+ end
79
+
80
+ should "be skipped" do
81
+ @dummy.avatar.expects(:post_process).never
82
+ assert_accepts @matcher, @dummy
83
+ end
84
+ end
71
85
  end
72
86
  end
@@ -0,0 +1,25 @@
1
+ require './test/helper'
2
+
3
+ class NilAdapterTest < Test::Unit::TestCase
4
+ context 'a new instance' do
5
+ setup do
6
+ @subject = Paperclip.io_adapters.for(nil)
7
+ end
8
+
9
+ should "get the right filename" do
10
+ assert_equal "", @subject.original_filename
11
+ end
12
+
13
+ should "get the content type" do
14
+ assert_equal "", @subject.content_type
15
+ end
16
+
17
+ should "get the file's size" do
18
+ assert_equal 0, @subject.size
19
+ end
20
+
21
+ should "return true for a call to nil?" do
22
+ assert @subject.nil?
23
+ end
24
+ end
25
+ end
@@ -22,16 +22,34 @@ class PaperclipTest < Test::Unit::TestCase
22
22
  Paperclip.run("convert", "stuff")
23
23
  assert_equal [Cocaine::CommandLine.path].flatten.include?("/opt/my_app/bin"), true
24
24
  end
25
- end
26
25
 
27
- should 'not raise errors when doing a lot of running' do
28
- Paperclip.options[:command_path] = ["/usr/local/bin"] * 1024
29
- Cocaine::CommandLine.path = "/something/else"
30
- 100.times do |x|
31
- Paperclip.run("echo", x.to_s)
26
+ should "not duplicate Cocaine::CommandLine.path on multiple runs" do
27
+ Cocaine::CommandLine.expects(:new).with("convert", "more_stuff", {}).returns(stub(:run))
28
+ Cocaine::CommandLine.path = nil
29
+ Paperclip.options[:command_path] = "/opt/my_app/bin"
30
+ Paperclip.run("convert", "stuff")
31
+ Paperclip.run("convert", "more_stuff")
32
+ assert_equal 1, [Cocaine::CommandLine.path].flatten.size
32
33
  end
33
34
  end
34
35
 
36
+ context "Calling Paperclip.log without options[:logger] set" do
37
+ setup do
38
+ Paperclip.logger = nil
39
+ Paperclip.options[:logger] = nil
40
+ end
41
+
42
+ teardown do
43
+ Paperclip.options[:logger] = ActiveRecord::Base.logger
44
+ Paperclip.logger = ActiveRecord::Base.logger
45
+ end
46
+
47
+ should "not raise an error when log is called" do
48
+ silence_stream(STDOUT) do
49
+ Paperclip.log('something')
50
+ end
51
+ end
52
+ end
35
53
  context "Calling Paperclip.run with a logger" do
36
54
  should "pass the defined logger if :log_command is set" do
37
55
  Paperclip.options[:log_command] = true
@@ -48,6 +66,7 @@ class PaperclipTest < Test::Unit::TestCase
48
66
  d3 = Dummy.create(:avatar => @file)
49
67
  @expected = [d1, d3]
50
68
  end
69
+
51
70
  should "yield every instance of a model that has an attachment" do
52
71
  actual = []
53
72
  Paperclip.each_instance_with_attachment("Dummy", "avatar") do |instance|
@@ -86,12 +105,13 @@ class PaperclipTest < Test::Unit::TestCase
86
105
  end
87
106
 
88
107
  should "generate warning if attachment is redefined with the same url string" do
89
- Paperclip.expects(:log).with("Duplicate URL for blah with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Dummy class")
108
+ expected_log_msg = "Duplicate URL for blah with /system/:id/:style/:filename. This will clash with attachment defined in Dummy class"
109
+ Paperclip.expects(:log).with(expected_log_msg)
90
110
  Dummy.class_eval do
91
- has_attached_file :blah
111
+ has_attached_file :blah, :url => '/system/:id/:style/:filename'
92
112
  end
93
113
  Dummy2.class_eval do
94
- has_attached_file :blah
114
+ has_attached_file :blah, :url => '/system/:id/:style/:filename'
95
115
  end
96
116
  end
97
117
 
@@ -164,6 +184,7 @@ class PaperclipTest < Test::Unit::TestCase
164
184
  end
165
185
 
166
186
  teardown do
187
+ SubDummy.delete_all
167
188
  Object.send(:remove_const, "SubDummy") rescue nil
168
189
  end
169
190
  end
@@ -187,191 +208,11 @@ class PaperclipTest < Test::Unit::TestCase
187
208
  end
188
209
  end
189
210
 
190
- context "a validation with an if guard clause" do
191
- context "as a lambda" do
192
- setup do
193
- Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo })
194
- @dummy = Dummy.new
195
- @dummy.stubs(:avatar_file_name).returns(nil)
196
- end
197
-
198
- should "attempt validation if the guard returns true" do
199
- @dummy.expects(:foo).returns(true)
200
- assert ! @dummy.valid?
201
- end
202
-
203
- should "not attempt validation if the guard returns false" do
204
- @dummy.expects(:foo).returns(false)
205
- assert @dummy.valid?
206
- end
207
- end
208
-
209
- context "as a method name" do
210
- setup do
211
- Dummy.send(:"validates_attachment_presence", :avatar, :if => :foo)
212
- @dummy = Dummy.new
213
- @dummy.stubs(:avatar_file_name).returns(nil)
214
- end
215
-
216
- should "attempt validation if the guard returns true" do
217
- @dummy.expects(:foo).returns(true)
218
- assert ! @dummy.valid?
219
- end
220
-
221
- should "not attempt validation if the guard returns false" do
222
- @dummy.expects(:foo).returns(false)
223
- assert @dummy.valid?
224
- end
225
- end
226
- end
227
-
228
- context "a validation with an unless guard clause" do
229
- context "as a lambda" do
230
- setup do
231
- Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo })
232
- @dummy = Dummy.new
233
- @dummy.stubs(:avatar_file_name).returns(nil)
234
- end
235
-
236
- should "attempt validation if the guard returns true" do
237
- @dummy.expects(:foo).returns(false)
238
- assert ! @dummy.valid?
239
- end
240
-
241
- should "not attempt validation if the guard returns false" do
242
- @dummy.expects(:foo).returns(true)
243
- assert @dummy.valid?
244
- end
245
- end
246
-
247
- context "as a method name" do
248
- setup do
249
- Dummy.send(:"validates_attachment_presence", :avatar, :unless => :foo)
250
- @dummy = Dummy.new
251
- @dummy.stubs(:avatar_file_name).returns(nil)
252
- end
253
-
254
- should "attempt validation if the guard returns true" do
255
- @dummy.expects(:foo).returns(false)
256
- assert ! @dummy.valid?
257
- end
258
-
259
- should "not attempt validation if the guard returns false" do
260
- @dummy.expects(:foo).returns(true)
261
- assert @dummy.valid?
262
- end
263
- end
264
- end
265
-
266
211
  should "not have Attachment in the ActiveRecord::Base namespace" do
267
212
  assert_raises(NameError) do
268
213
  ActiveRecord::Base::Attachment
269
214
  end
270
215
  end
271
-
272
- def self.should_validate validation, options, valid_file, invalid_file
273
- context "with #{validation} validation and #{options.inspect} options" do
274
- setup do
275
- rebuild_class
276
- Dummy.send(:"validates_attachment_#{validation}", :avatar, options)
277
- @dummy = Dummy.new
278
- end
279
- context "and assigning nil" do
280
- setup do
281
- @dummy.avatar = nil
282
- @dummy.valid?
283
- end
284
- if validation == :presence
285
- should "have an error on the attachment" do
286
- assert @dummy.errors[:avatar]
287
- assert @dummy.errors[:avatar_file_name]
288
- end
289
- else
290
- should "not have an error on the attachment" do
291
- assert @dummy.errors.blank?, @dummy.errors.full_messages.join(", ")
292
- end
293
- end
294
- end
295
- context "and assigned a valid file" do
296
- setup do
297
- @dummy.avatar = valid_file
298
- @dummy.valid?
299
- end
300
- should "not have an error" do
301
- assert_equal 0, @dummy.errors.size, @dummy.errors.full_messages.join(", ")
302
- end
303
- end
304
- context "and assigned an invalid file" do
305
- setup do
306
- @dummy.avatar = invalid_file
307
- @dummy.valid?
308
- end
309
- should "have an error" do
310
- assert @dummy.errors.size > 0
311
- end
312
- end
313
- end
314
- end
315
-
316
- [[:presence, {}, "5k.png", nil],
317
- [:size, {:in => 1..10240}, "5k.png", "12k.png"],
318
- [:size, {:less_than => 10240}, "5k.png", "12k.png"],
319
- [:size, {:greater_than => 8096}, "12k.png", "5k.png"],
320
- [:content_type, {:content_type => "image/png"}, "5k.png", "text.txt"],
321
- [:content_type, {:content_type => "text/plain"}, "text.txt", "5k.png"],
322
- [:content_type, {:content_type => %r{image/.*}}, "5k.png", "text.txt"]].each do |args|
323
- validation, options, valid_file, invalid_file = args
324
- valid_file &&= File.open(File.join(FIXTURES_DIR, valid_file), "rb")
325
- invalid_file &&= File.open(File.join(FIXTURES_DIR, invalid_file), "rb")
326
-
327
- should_validate validation, options, valid_file, invalid_file
328
- end
329
-
330
- context "with content_type validation and lambda message" do
331
- context "and assigned an invalid file" do
332
- setup do
333
- Dummy.send(:"validates_attachment_content_type", :avatar, :content_type => %r{image/.*}, :message => lambda {'lambda content type message'})
334
- @dummy = Dummy.new
335
- @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "text.txt"), "rb")
336
- @dummy.valid?
337
- end
338
-
339
- should "have a content type error message" do
340
- assert [@dummy.errors[:avatar_content_type]].flatten.any?{|error| error =~ %r/lambda content type message/ }
341
- end
342
- end
343
- end
344
-
345
- context "with size validation and less_than 10240 option" do
346
- context "and assigned an invalid file" do
347
- setup do
348
- Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240)
349
- @dummy = Dummy.new
350
- @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
351
- @dummy.valid?
352
- end
353
-
354
- should "have a file size min/max error message" do
355
- assert [@dummy.errors[:avatar_file_size]].flatten.any?{|error| error =~ %r/between 0 and 10240 bytes/ }
356
- end
357
- end
358
- end
359
-
360
- context "with size validation and less_than 10240 option with lambda message" do
361
- context "and assigned an invalid file" do
362
- setup do
363
- Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240, :message => lambda {'lambda between 0 and 10240 bytes'})
364
- @dummy = Dummy.new
365
- @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
366
- @dummy.valid?
367
- end
368
-
369
- should "have a file size min/max error message" do
370
- assert [@dummy.errors[:avatar_file_size]].flatten.any?{|error| error =~ %r/lambda between 0 and 10240 bytes/ }
371
- end
372
- end
373
- end
374
-
375
216
  end
376
217
 
377
218
  context "configuring a custom processor" do