joshpuetz-paperclip 2.3.0.1 → 2.3.0.2

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/lib/paperclip.rb CHANGED
@@ -44,7 +44,7 @@ end
44
44
  # documentation for Paperclip::ClassMethods for more useful information.
45
45
  module Paperclip
46
46
 
47
- VERSION = "2.2.9.2"
47
+ VERSION = "2.3.0"
48
48
 
49
49
  class << self
50
50
  # Provides configurability to Paperclip. There are a number of options available, such as:
@@ -93,7 +93,7 @@ module Paperclip
93
93
  # Paperclip.options[:log_command] is set to true (defaults to false). This
94
94
  # will only log if logging in general is set to true as well.
95
95
  def run cmd, params = "", expected_outcodes = 0
96
- command = %Q<#{%Q[#{path_for_command(cmd)} #{params}].gsub(/\s+/, " ")}>
96
+ command = %Q[#{path_for_command(cmd)} #{params}].gsub(/\s+/, " ")
97
97
  command = "#{command} 2>#{bit_bucket}" if Paperclip.options[:swallow_stderr]
98
98
  Paperclip.log(command) if Paperclip.options[:log_command]
99
99
  output = `#{command}`
@@ -189,6 +189,9 @@ module Paperclip
189
189
  # to a command line error. This will override the global setting for this attachment.
190
190
  # Defaults to true. This option used to be called :whiny_thumbanils, but this is
191
191
  # deprecated.
192
+ # * +keep_old_files+: Keep the existing attachment files (original + resized) from
193
+ # being automatically deleted when an attachment is cleared or updated.
194
+ # Defaults to +false+.
192
195
  # * +convert_options+: When creating thumbnails, use this free-form options
193
196
  # field to pass in various convert command options. Typical options are "-strip" to
194
197
  # remove all Exif data from the image (save space for thumbnails and avatars) or
@@ -14,7 +14,8 @@ module Paperclip
14
14
  :default_style => :original,
15
15
  :validations => [],
16
16
  :storage => :filesystem,
17
- :whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
17
+ :whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails],
18
+ :keep_old_files=> false
18
19
  }
19
20
  end
20
21
 
@@ -40,6 +41,7 @@ module Paperclip
40
41
  @default_style = options[:default_style]
41
42
  @storage = options[:storage]
42
43
  @whiny = options[:whiny_thumbnails] || options[:whiny]
44
+ @keep_old_files = options[:keep_old_files]
43
45
  @convert_options = options[:convert_options] || {}
44
46
  @processors = options[:processors] || [:thumbnail]
45
47
  @options = options
@@ -394,9 +396,11 @@ module Paperclip
394
396
 
395
397
  def queue_existing_for_delete #:nodoc:
396
398
  return unless file?
397
- @queued_for_delete += [:original, *@styles.keys].uniq.map do |style|
398
- path(style) if exists?(style)
399
- end.compact
399
+ unless @keep_old_files
400
+ @queued_for_delete += [:original, *@styles.keys].uniq.map do |style|
401
+ path(style) if exists?(style)
402
+ end.compact
403
+ end
400
404
  instance_write(:file_name, nil)
401
405
  instance_write(:content_type, nil)
402
406
  instance_write(:file_size, nil)
@@ -33,7 +33,6 @@ module Paperclip
33
33
  def to_file style = default_style
34
34
  @queued_for_write[style] || (File.new(path(style), 'rb') if exists?(style))
35
35
  end
36
- alias_method :to_io, :to_file
37
36
 
38
37
  def flush_writes #:nodoc:
39
38
  @queued_for_write.each do |style, file|
@@ -128,17 +127,21 @@ module Paperclip
128
127
  # separate parts of your file name.
129
128
  module S3
130
129
  def self.extended base
131
- require 'right_aws'
130
+ require 'aws/s3'
132
131
  base.instance_eval do
133
132
  @s3_credentials = parse_credentials(@options[:s3_credentials])
134
133
  @bucket = @options[:bucket] || @s3_credentials[:bucket]
135
134
  @bucket = @bucket.call(self) if @bucket.is_a?(Proc)
136
135
  @s3_options = @options[:s3_options] || {}
137
- @s3_permissions = @options[:s3_permissions] || 'public-read'
138
- @s3_protocol = @options[:s3_protocol] || (@s3_permissions == 'public-read' ? 'http' : 'https')
136
+ @s3_permissions = @options[:s3_permissions] || :public_read
137
+ @s3_protocol = @options[:s3_protocol] || (@s3_permissions == :public_read ? 'http' : 'https')
139
138
  @s3_headers = @options[:s3_headers] || {}
140
139
  @s3_host_alias = @options[:s3_host_alias]
141
140
  @url = ":s3_path_url" unless @url.to_s.match(/^:s3.*url$/)
141
+ AWS::S3::Base.establish_connection!( @s3_options.merge(
142
+ :access_key_id => @s3_credentials[:access_key_id],
143
+ :secret_access_key => @s3_credentials[:secret_access_key]
144
+ ))
142
145
  end
143
146
  Paperclip.interpolates(:s3_alias_url) do |attachment, style|
144
147
  "#{attachment.s3_protocol}://#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{^/}, "")}"
@@ -151,16 +154,6 @@ module Paperclip
151
154
  end
152
155
  end
153
156
 
154
- def s3
155
- @s3 ||= RightAws::S3.new(@s3_credentials[:access_key_id],
156
- @s3_credentials[:secret_access_key],
157
- @s3_options)
158
- end
159
-
160
- def s3_bucket
161
- @s3_bucket ||= s3.bucket(@bucket, true, @s3_permissions)
162
- end
163
-
164
157
  def bucket_name
165
158
  @bucket
166
159
  end
@@ -175,7 +168,11 @@ module Paperclip
175
168
  end
176
169
 
177
170
  def exists?(style = default_style)
178
- s3_bucket.key(path(style)) ? true : false
171
+ if original_filename
172
+ AWS::S3::S3Object.exists?(path(style), bucket_name)
173
+ else
174
+ false
175
+ end
179
176
  end
180
177
 
181
178
  def s3_protocol
@@ -185,18 +182,24 @@ module Paperclip
185
182
  # Returns representation of the data of the file assigned to the given
186
183
  # style, in the format most representative of the current storage.
187
184
  def to_file style = default_style
188
- @queued_for_write[style] || s3_bucket.key(path(style))
185
+ return @queued_for_write[style] if @queued_for_write[style]
186
+ file = Tempfile.new(path(style))
187
+ file.write(AWS::S3::S3Object.value(path(style), bucket_name))
188
+ file.rewind
189
+ return file
189
190
  end
190
- alias_method :to_io, :to_file
191
191
 
192
192
  def flush_writes #:nodoc:
193
193
  @queued_for_write.each do |style, file|
194
194
  begin
195
195
  log("saving #{path(style)}")
196
- key = s3_bucket.key(path(style))
197
- key.data = file
198
- key.put(nil, @s3_permissions, {'Content-type' => instance_read(:content_type)}.merge(@s3_headers))
199
- rescue RightAws::AwsError => e
196
+ AWS::S3::S3Object.store(path(style),
197
+ file,
198
+ bucket_name,
199
+ {:content_type => instance_read(:content_type),
200
+ :access => @s3_permissions,
201
+ }.merge(@s3_headers))
202
+ rescue AWS::S3::ResponseError => e
200
203
  raise
201
204
  end
202
205
  end
@@ -207,10 +210,8 @@ module Paperclip
207
210
  @queued_for_delete.each do |path|
208
211
  begin
209
212
  log("deleting #{path}")
210
- if file = s3_bucket.key(path)
211
- file.delete
212
- end
213
- rescue RightAws::AwsError
213
+ AWS::S3::S3Object.delete(path, bucket_name)
214
+ rescue AWS::S3::ResponseError
214
215
  # Ignore this.
215
216
  end
216
217
  end
@@ -2,7 +2,7 @@ module Paperclip
2
2
  # Handles thumbnailing images that are uploaded.
3
3
  class Thumbnail < Processor
4
4
 
5
- attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options
5
+ attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options, :source_file_options
6
6
 
7
7
  # Creates a Thumbnail object set to work on the +file+ given. It
8
8
  # will attempt to transform the image into one defined by +target_geometry+
@@ -12,17 +12,18 @@ module Paperclip
12
12
  # set, the options will be appended to the convert command upon image conversion
13
13
  def initialize file, options = {}, attachment = nil
14
14
  super
15
- geometry = options[:geometry]
16
- @file = file
17
- @crop = geometry[-1,1] == '#'
18
- @target_geometry = Geometry.parse geometry
19
- @current_geometry = Geometry.from_file @file
20
- @convert_options = options[:convert_options]
21
- @whiny = options[:whiny].nil? ? true : options[:whiny]
22
- @format = options[:format]
15
+ geometry = options[:geometry]
16
+ @file = file
17
+ @crop = geometry[-1,1] == '#'
18
+ @target_geometry = Geometry.parse geometry
19
+ @current_geometry = Geometry.from_file @file
20
+ @source_file_options = options[:source_file_options]
21
+ @convert_options = options[:convert_options]
22
+ @whiny = options[:whiny].nil? ? true : options[:whiny]
23
+ @format = options[:format]
23
24
 
24
- @current_format = File.extname(@file.path)
25
- @basename = File.basename(@file.path, @current_format)
25
+ @current_format = File.extname(@file.path)
26
+ @basename = File.basename(@file.path, @current_format)
26
27
  end
27
28
 
28
29
  # Returns true if the +target_geometry+ is meant to crop.
@@ -43,6 +44,7 @@ module Paperclip
43
44
  dst.binmode
44
45
 
45
46
  command = <<-end_command
47
+ #{ source_file_options }
46
48
  "#{ File.expand_path(src.path) }[0]"
47
49
  #{ transformation_command }
48
50
  "#{ File.expand_path(dst.path) }"
@@ -61,7 +63,8 @@ module Paperclip
61
63
  # into the thumbnail.
62
64
  def transformation_command
63
65
  scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
64
- trans = "-resize \"#{scale}\""
66
+ trans = ""
67
+ trans << " -resize \"#{scale}\"" unless scale.blank?
65
68
  trans << " -crop \"#{crop}\" +repage" if crop
66
69
  trans << " #{convert_options}" if convert_options?
67
70
  trans
@@ -14,14 +14,27 @@ class AttachmentTest < Test::Unit::TestCase
14
14
  assert_equal "#{RAILS_ROOT}/public/fake_models/1234/fake", @attachment.path
15
15
  end
16
16
 
17
+ should "call a proc sent to check_guard" do
18
+ @dummy = Dummy.new
19
+ @dummy.expects(:one).returns(:one)
20
+ assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
21
+ end
22
+
23
+ should "call a method name sent to check_guard" do
24
+ @dummy = Dummy.new
25
+ @dummy.expects(:one).returns(:one)
26
+ assert_equal :one, @dummy.avatar.send(:check_guard, :one)
27
+ end
28
+
17
29
  context "Attachment default_options" do
18
30
  setup do
19
31
  rebuild_model
20
32
  @old_default_options = Paperclip::Attachment.default_options.dup
21
33
  @new_default_options = @old_default_options.merge({
22
- :path => "argle/bargle",
23
- :url => "fooferon",
24
- :default_url => "not here.png"
34
+ :path => "argle/bargle",
35
+ :url => "fooferon",
36
+ :default_url => "not here.png",
37
+ :keep_old_files => false
25
38
  })
26
39
  end
27
40
 
@@ -592,7 +605,7 @@ class AttachmentTest < Test::Unit::TestCase
592
605
 
593
606
  should "commit the files to disk" do
594
607
  [:large, :medium, :small].each do |style|
595
- io = @attachment.to_io(style)
608
+ io = @attachment.to_file(style)
596
609
  assert File.exists?(io)
597
610
  assert ! io.is_a?(::Tempfile)
598
611
  io.close
@@ -764,4 +777,94 @@ class AttachmentTest < Test::Unit::TestCase
764
777
  end
765
778
  end
766
779
  end
780
+
781
+
782
+ ######################
783
+ # test :keep_old_files
784
+ ######################
785
+
786
+ context "An attachment with :keep_old_files => true" do
787
+
788
+ setup do
789
+ @old_defaults = Paperclip::Attachment.default_options.dup
790
+ Paperclip::Attachment.default_options.merge!( {
791
+ :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
792
+ })
793
+ FileUtils.rm_rf("tmp")
794
+
795
+ @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png" ), 'rb')
796
+ @file_2 = File.new(File.join(File.dirname(__FILE__), "fixtures", "50x50.png"), 'rb')
797
+
798
+ rebuild_model
799
+ @instance = Dummy.new
800
+
801
+ @attachment = Paperclip::Attachment.new(:avatar, @instance, {
802
+ :keep_old_files => true,
803
+ :styles => {:small => "32x32#"}
804
+ })
805
+ @attachment.assign(@file)
806
+ @attachment.save
807
+ end
808
+
809
+ teardown do
810
+ @file.close
811
+ @file_2.close
812
+ Paperclip::Attachment.default_options.merge!(@old_defaults)
813
+ end
814
+
815
+ should "return the real urls" do
816
+ assert_match %r{^/system/avatars/#{@instance.id}/original/5k\.png}, @attachment.url
817
+ assert_match %r{^/system/avatars/#{@instance.id}/small/5k\.png} , @attachment.url(:small)
818
+ end
819
+
820
+ should "commit the files to disk" do
821
+ assert File.exists?(@attachment.path(:original))
822
+ assert File.exists?(@attachment.path(:small ))
823
+ end
824
+
825
+
826
+ context "after assigning a new file" do
827
+ setup do
828
+ @previous_files_path = @attachment.styles.keys.collect do |style|
829
+ @attachment.path(style)
830
+ end
831
+ @attachment.assign @file_2
832
+ @attachment.save
833
+ end
834
+
835
+ should "NOT delete the previous files after assigning nil and saving" do
836
+ @previous_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
837
+ end
838
+ end
839
+
840
+
841
+ context "" do
842
+ setup do
843
+ @old_files_path = @attachment.styles.keys.collect do |style|
844
+ @attachment.path(style)
845
+ end
846
+ end
847
+
848
+ should "NOT delete the files after assigning nil and saving" do
849
+ @attachment.expects_instance_write_with_nil___in_the_4_paperclip_columns
850
+ @attachment.assign nil
851
+ @attachment.save
852
+ @old_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
853
+ end
854
+
855
+ should "NOT delete the files when you call #clear and #save" do
856
+ @attachment.expects_instance_write_with_nil___in_the_4_paperclip_columns
857
+ @attachment.clear
858
+ @attachment.save
859
+ @old_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
860
+ end
861
+
862
+ should "NOT delete the files when you call #delete" do
863
+ @attachment.expects_instance_write_with_nil___in_the_4_paperclip_columns
864
+ @attachment.destroy
865
+ @old_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
866
+ end
867
+ end
868
+
869
+ end
767
870
  end
data/test/helper.rb CHANGED
@@ -97,3 +97,14 @@ end
97
97
  def attachment options
98
98
  Paperclip::Attachment.new(:avatar, FakeModel.new, options)
99
99
  end
100
+
101
+ module Paperclip
102
+ class Attachment
103
+ def expects_instance_write_with_nil___in_the_4_paperclip_columns
104
+ expects(:instance_write).with(:file_name , nil)
105
+ expects(:instance_write).with(:content_type , nil)
106
+ expects(:instance_write).with(:file_size , nil)
107
+ expects(:instance_write).with(:updated_at , nil)
108
+ end
109
+ end
110
+ end
@@ -379,6 +379,11 @@ class IntegrationTest < Test::Unit::TestCase
379
379
  @files_on_s3 = s3_files_for @dummy.avatar
380
380
  end
381
381
 
382
+ should "have the same contents as the original" do
383
+ @file.rewind
384
+ assert_equal @file.read, @files_on_s3[:original].read
385
+ end
386
+
382
387
  should "write and delete its files" do
383
388
  [["434x66", :original],
384
389
  ["300x46", :large],
@@ -403,10 +408,8 @@ class IntegrationTest < Test::Unit::TestCase
403
408
  assert @dummy.valid?
404
409
  assert @dummy.save
405
410
 
406
- saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
407
-
408
- saved_keys.each do |key|
409
- assert key.exists?
411
+ [:thumb, :medium, :large, :original].each do |style|
412
+ assert @dummy.avatar.exists?(style)
410
413
  end
411
414
 
412
415
  @dummy.avatar.clear
@@ -414,8 +417,8 @@ class IntegrationTest < Test::Unit::TestCase
414
417
  assert @dummy.valid?
415
418
  assert @dummy.save
416
419
 
417
- saved_keys.each do |key|
418
- assert ! key.exists?
420
+ [:thumb, :medium, :large, :original].each do |style|
421
+ assert ! @dummy.avatar.exists?(style)
419
422
  end
420
423
 
421
424
  @d2 = Dummy.find(@dummy.id)
@@ -427,7 +430,7 @@ class IntegrationTest < Test::Unit::TestCase
427
430
 
428
431
  assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
429
432
  [:thumb, :medium, :large, :original].each do |style|
430
- assert_equal @dummy.avatar.to_file(style).to_s, @d2.avatar.to_file(style).to_s
433
+ assert_equal @dummy.avatar.to_file(style).read, @d2.avatar.to_file(style).read
431
434
  end
432
435
 
433
436
  saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
@@ -435,8 +438,8 @@ class IntegrationTest < Test::Unit::TestCase
435
438
  @d2.avatar.clear
436
439
  assert @d2.save
437
440
 
438
- saved_keys.each do |key|
439
- assert ! key.exists?
441
+ [:thumb, :medium, :large, :original].each do |style|
442
+ assert ! @dummy.avatar.exists?(style)
440
443
  end
441
444
  end
442
445
 
@@ -444,7 +447,7 @@ class IntegrationTest < Test::Unit::TestCase
444
447
  expected = @dummy.avatar.to_file
445
448
  @dummy.avatar = "not a file"
446
449
  assert @dummy.valid?
447
- assert_equal expected.full_name, @dummy.avatar.to_file.full_name
450
+ assert_equal expected.read, @dummy.avatar.to_file.read
448
451
 
449
452
  @dummy.avatar = @bad_file
450
453
  assert ! @dummy.valid?
@@ -472,7 +475,6 @@ class IntegrationTest < Test::Unit::TestCase
472
475
 
473
476
  should "have the right content type" do
474
477
  headers = s3_headers_for(@dummy.avatar, :original)
475
- p headers
476
478
  assert_equal 'image/png', headers['content-type']
477
479
  end
478
480
  end
@@ -1,14 +1,18 @@
1
1
  require 'test/helper'
2
2
 
3
3
  class PaperclipTest < Test::Unit::TestCase
4
- [:image_magick_path, :convert_path].each do |path|
5
- context "Calling Paperclip.run with an #{path} specified" do
4
+ [:image_magick_path, :command_path].each do |path|
5
+ context "Calling Paperclip.run with #{path} specified" do
6
6
  setup do
7
7
  Paperclip.options[:image_magick_path] = nil
8
- Paperclip.options[:convert_path] = nil
8
+ Paperclip.options[:command_path] = nil
9
9
  Paperclip.options[path] = "/usr/bin"
10
10
  end
11
11
 
12
+ should "return the expected path for path_for_command" do
13
+ assert_equal "/usr/bin/convert", Paperclip.path_for_command("convert")
14
+ end
15
+
12
16
  should "execute the right command" do
13
17
  Paperclip.expects(:path_for_command).with("convert").returns("/usr/bin/convert")
14
18
  Paperclip.expects(:bit_bucket).returns("/dev/null")
@@ -21,7 +25,11 @@ class PaperclipTest < Test::Unit::TestCase
21
25
  context "Calling Paperclip.run with no path specified" do
22
26
  setup do
23
27
  Paperclip.options[:image_magick_path] = nil
24
- Paperclip.options[:convert_path] = nil
28
+ Paperclip.options[:command_path] = nil
29
+ end
30
+
31
+ should "return the expected path fro path_for_command" do
32
+ assert_equal "convert", Paperclip.path_for_command("convert")
25
33
  end
26
34
 
27
35
  should "execute the right command" do
@@ -30,38 +38,38 @@ class PaperclipTest < Test::Unit::TestCase
30
38
  Paperclip.expects(:"`").with("convert one.jpg two.jpg 2>/dev/null")
31
39
  Paperclip.run("convert", "one.jpg two.jpg")
32
40
  end
41
+ end
33
42
 
34
- should "log the command when :log_command is set" do
43
+ context "Calling Paperclip.run and logging" do
44
+ setup do
45
+ Paperclip.options[:image_magick_path] = nil
46
+ Paperclip.options[:command_path] = nil
47
+ Paperclip.stubs(:bit_bucket).returns("/dev/null")
48
+ Paperclip.stubs(:log)
49
+ Paperclip.stubs(:"`").with("this is the command 2>/dev/null")
50
+ end
51
+
52
+ should "log the command when :log_command is true" do
35
53
  Paperclip.options[:log_command] = true
36
- Paperclip.expects(:bit_bucket).returns("/dev/null")
37
- Paperclip.expects(:log).with("this is the command 2>/dev/null")
38
- Paperclip.expects(:"`").with("this is the command 2>/dev/null")
39
54
  Paperclip.run("this","is the command")
55
+ assert_received(Paperclip, :log) do |p|
56
+ p.with("this is the command 2>/dev/null")
57
+ end
58
+ assert_received(Paperclip, :`) do |p|
59
+ p.with("this is the command 2>/dev/null")
60
+ end
40
61
  end
41
- end
42
-
43
- should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
44
- assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
45
- end
46
62
 
47
- should "raise when sent #processor and the name of a class that doesn't exist" do
48
- assert_raises(NameError){ Paperclip.processor(:boogey_man) }
49
- end
50
-
51
- should "return a class when sent #processor and the name of a class under Paperclip" do
52
- assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
53
- end
54
-
55
- should "call a proc sent to check_guard" do
56
- @dummy = Dummy.new
57
- @dummy.expects(:one).returns(:one)
58
- assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
59
- end
60
-
61
- should "call a method name sent to check_guard" do
62
- @dummy = Dummy.new
63
- @dummy.expects(:one).returns(:one)
64
- assert_equal :one, @dummy.avatar.send(:check_guard, :one)
63
+ should "not log the command when :log_command is false" do
64
+ Paperclip.options[:log_command] = false
65
+ Paperclip.run("this","is the command")
66
+ assert_received(Paperclip, :log) do |p|
67
+ p.with("this is the command 2>/dev/null").never
68
+ end
69
+ assert_received(Paperclip, :`) do |p|
70
+ p.with("this is the command 2>/dev/null")
71
+ end
72
+ end
65
73
  end
66
74
 
67
75
  context "Paperclip.bit_bucket" do
@@ -86,6 +94,18 @@ class PaperclipTest < Test::Unit::TestCase
86
94
  end
87
95
  end
88
96
 
97
+ should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
98
+ assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
99
+ end
100
+
101
+ should "raise when sent #processor and the name of a class that doesn't exist" do
102
+ assert_raises(NameError){ Paperclip.processor(:boogey_man) }
103
+ end
104
+
105
+ should "return a class when sent #processor and the name of a class under Paperclip" do
106
+ assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
107
+ end
108
+
89
109
  context "An ActiveRecord model with an 'avatar' attachment" do
90
110
  setup do
91
111
  rebuild_model :path => "tmp/:class/omg/:style.:extension"
@@ -139,7 +159,8 @@ class PaperclipTest < Test::Unit::TestCase
139
159
  end
140
160
 
141
161
  should "be able to see the attachment definition from the subclass's class" do
142
- assert_equal "tmp/:class/omg/:style.:extension", SubDummy.attachment_definitions[:avatar][:path]
162
+ assert_equal "tmp/:class/omg/:style.:extension",
163
+ SubDummy.attachment_definitions[:avatar][:path]
143
164
  end
144
165
 
145
166
  teardown do
data/test/storage_test.rb CHANGED
@@ -3,6 +3,7 @@ require 'test/helper'
3
3
  class StorageTest < Test::Unit::TestCase
4
4
  context "Parsing S3 credentials" do
5
5
  setup do
6
+ AWS::S3::Base.stubs(:establish_connection!)
6
7
  rebuild_model :storage => :s3,
7
8
  :bucket => "testing",
8
9
  :s3_credentials => {:not => :important}
@@ -39,6 +40,7 @@ class StorageTest < Test::Unit::TestCase
39
40
 
40
41
  context "" do
41
42
  setup do
43
+ AWS::S3::Base.stubs(:establish_connection!)
42
44
  rebuild_model :storage => :s3,
43
45
  :s3_credentials => {},
44
46
  :bucket => "bucket",
@@ -54,6 +56,7 @@ class StorageTest < Test::Unit::TestCase
54
56
  end
55
57
  context "" do
56
58
  setup do
59
+ AWS::S3::Base.stubs(:establish_connection!)
57
60
  rebuild_model :storage => :s3,
58
61
  :s3_credentials => {},
59
62
  :bucket => "bucket",
@@ -69,6 +72,7 @@ class StorageTest < Test::Unit::TestCase
69
72
  end
70
73
  context "" do
71
74
  setup do
75
+ AWS::S3::Base.stubs(:establish_connection!)
72
76
  rebuild_model :storage => :s3,
73
77
  :s3_credentials => {
74
78
  :production => { :bucket => "prod_bucket" },
@@ -88,6 +92,7 @@ class StorageTest < Test::Unit::TestCase
88
92
 
89
93
  context "Parsing S3 credentials with a bucket in them" do
90
94
  setup do
95
+ AWS::S3::Base.stubs(:establish_connection!)
91
96
  rebuild_model :storage => :s3,
92
97
  :s3_credentials => {
93
98
  :production => { :bucket => "prod_bucket" },
@@ -146,14 +151,7 @@ class StorageTest < Test::Unit::TestCase
146
151
 
147
152
  context "and saved" do
148
153
  setup do
149
- @s3_mock = stub
150
- @bucket_mock = stub
151
- RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
152
- @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
153
- @key_mock = stub
154
- @bucket_mock.expects(:key).returns(@key_mock)
155
- @key_mock.expects(:data=)
156
- @key_mock.expects(:put).with(nil, 'public-read', 'Content-type' => 'image/png')
154
+ AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path, anything, 'testing', :content_type => 'image/png', :access => :public_read)
157
155
  @dummy.save
158
156
  end
159
157
 
@@ -164,13 +162,8 @@ class StorageTest < Test::Unit::TestCase
164
162
 
165
163
  context "and remove" do
166
164
  setup do
167
- @s3_mock = stub
168
- @bucket_mock = stub
169
- RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
170
- @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
171
- @key_mock = stub
172
- @bucket_mock.expects(:key).at_least(2).returns(@key_mock)
173
- @key_mock.expects(:delete)
165
+ AWS::S3::S3Object.stubs(:exists?).returns(true)
166
+ AWS::S3::S3Object.stubs(:delete)
174
167
  @dummy.destroy_attached_files
175
168
  end
176
169
 
@@ -183,6 +176,7 @@ class StorageTest < Test::Unit::TestCase
183
176
 
184
177
  context "An attachment with S3 storage and bucket defined as a Proc" do
185
178
  setup do
179
+ AWS::S3::Base.stubs(:establish_connection!)
186
180
  rebuild_model :storage => :s3,
187
181
  :bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
188
182
  :s3_credentials => {:not => :important}
@@ -196,6 +190,7 @@ class StorageTest < Test::Unit::TestCase
196
190
 
197
191
  context "An attachment with S3 storage and specific s3 headers set" do
198
192
  setup do
193
+ AWS::S3::Base.stubs(:establish_connection!)
199
194
  rebuild_model :storage => :s3,
200
195
  :bucket => "testing",
201
196
  :path => ":attachment/:style/:basename.:extension",
@@ -217,17 +212,13 @@ class StorageTest < Test::Unit::TestCase
217
212
 
218
213
  context "and saved" do
219
214
  setup do
220
- @s3_mock = stub
221
- @bucket_mock = stub
222
- RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
223
- @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
224
- @key_mock = stub
225
- @bucket_mock.expects(:key).returns(@key_mock)
226
- @key_mock.expects(:data=)
227
- @key_mock.expects(:put).with(nil,
228
- 'public-read',
229
- 'Content-type' => 'image/png',
230
- 'Cache-Control' => 'max-age=31557600')
215
+ AWS::S3::Base.stubs(:establish_connection!)
216
+ AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path,
217
+ anything,
218
+ 'testing',
219
+ :content_type => 'image/png',
220
+ :access => :public_read,
221
+ 'Cache-Control' => 'max-age=31557600')
231
222
  @dummy.save
232
223
  end
233
224
 
@@ -263,8 +254,8 @@ class StorageTest < Test::Unit::TestCase
263
254
 
264
255
  teardown { @file.close }
265
256
 
266
- should "still return a Tempfile when sent #to_io" do
267
- assert_equal Tempfile, @dummy.avatar.to_io.class
257
+ should "still return a Tempfile when sent #to_file" do
258
+ assert_equal Tempfile, @dummy.avatar.to_file.class
268
259
  end
269
260
 
270
261
  context "and saved" do
@@ -103,6 +103,44 @@ class ThumbnailTest < Test::Unit::TestCase
103
103
  end
104
104
  end
105
105
 
106
+ context "being thumbnailed with source file options set" do
107
+ setup do
108
+ @thumb = Paperclip::Thumbnail.new(@file,
109
+ :geometry => "100x50#",
110
+ :source_file_options => "-strip")
111
+ end
112
+
113
+ should "have source_file_options value set" do
114
+ assert_equal "-strip", @thumb.source_file_options
115
+ end
116
+
117
+ should "send the right command to convert when sent #make" do
118
+ Paperclip.expects(:"`").with do |arg|
119
+ arg.match %r{convert\s+-strip\s+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+"x50"\s+-crop\s+"100x50\+114\+0"\s+\+repage\s+".*?"}
120
+ end
121
+ @thumb.make
122
+ end
123
+
124
+ should "create the thumbnail when sent #make" do
125
+ dst = @thumb.make
126
+ assert_match /100x50/, `identify "#{dst.path}"`
127
+ end
128
+
129
+ context "redefined to have bad source_file_options setting" do
130
+ setup do
131
+ @thumb = Paperclip::Thumbnail.new(@file,
132
+ :geometry => "100x50#",
133
+ :source_file_options => "-this-aint-no-option")
134
+ end
135
+
136
+ should "error when trying to create the thumbnail" do
137
+ assert_raises(Paperclip::PaperclipError) do
138
+ @thumb.make
139
+ end
140
+ end
141
+ end
142
+ end
143
+
106
144
  context "being thumbnailed with convert options set" do
107
145
  setup do
108
146
  @thumb = Paperclip::Thumbnail.new(@file,
@@ -140,6 +178,18 @@ class ThumbnailTest < Test::Unit::TestCase
140
178
  end
141
179
  end
142
180
  end
181
+
182
+ context "being thumbnailed with a blank geometry string" do
183
+ setup do
184
+ @thumb = Paperclip::Thumbnail.new(@file,
185
+ :geometry => "",
186
+ :convert_options => "-gravity center -crop \"300x300+0-0\"")
187
+ end
188
+
189
+ should "not get resized by default" do
190
+ assert_no_match(/-resize/, @thumb.transformation_command)
191
+ end
192
+ end
143
193
  end
144
194
 
145
195
  context "A multipage PDF" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joshpuetz-paperclip
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0.1
4
+ version: 2.3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Yurek
@@ -95,7 +95,6 @@ files:
95
95
  - shoulda_macros/paperclip.rb
96
96
  has_rdoc: true
97
97
  homepage: http://www.thoughtbot.com/projects/paperclip
98
- licenses:
99
98
  post_install_message:
100
99
  rdoc_options:
101
100
  - --line-numbers
@@ -117,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
116
  requirements:
118
117
  - ImageMagick
119
118
  rubyforge_project: paperclip
120
- rubygems_version: 1.3.5
119
+ rubygems_version: 1.2.0
121
120
  signing_key:
122
121
  specification_version: 2
123
122
  summary: File attachments as attributes for ActiveRecord