lostboy-paperclip 2.2.6.1

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.
Files changed (44) hide show
  1. data/LICENSE +26 -0
  2. data/README.rdoc +172 -0
  3. data/Rakefile +77 -0
  4. data/generators/paperclip/USAGE +5 -0
  5. data/generators/paperclip/paperclip_generator.rb +27 -0
  6. data/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  7. data/init.rb +1 -0
  8. data/lib/paperclip/attachment.rb +398 -0
  9. data/lib/paperclip/callback_compatability.rb +33 -0
  10. data/lib/paperclip/geometry.rb +115 -0
  11. data/lib/paperclip/iostream.rb +58 -0
  12. data/lib/paperclip/matchers/have_attached_file_matcher.rb +49 -0
  13. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +66 -0
  14. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +48 -0
  15. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +83 -0
  16. data/lib/paperclip/matchers.rb +4 -0
  17. data/lib/paperclip/processor.rb +48 -0
  18. data/lib/paperclip/storage.rb +241 -0
  19. data/lib/paperclip/thumbnail.rb +70 -0
  20. data/lib/paperclip/upfile.rb +48 -0
  21. data/lib/paperclip.rb +318 -0
  22. data/shoulda_macros/paperclip.rb +68 -0
  23. data/tasks/paperclip_tasks.rake +79 -0
  24. data/test/attachment_test.rb +723 -0
  25. data/test/database.yml +4 -0
  26. data/test/fixtures/12k.png +0 -0
  27. data/test/fixtures/50x50.png +0 -0
  28. data/test/fixtures/5k.png +0 -0
  29. data/test/fixtures/bad.png +1 -0
  30. data/test/fixtures/text.txt +0 -0
  31. data/test/fixtures/twopage.pdf +0 -0
  32. data/test/geometry_test.rb +168 -0
  33. data/test/helper.rb +82 -0
  34. data/test/integration_test.rb +495 -0
  35. data/test/iostream_test.rb +71 -0
  36. data/test/matchers/have_attached_file_matcher_test.rb +21 -0
  37. data/test/matchers/validate_attachment_content_type_matcher_test.rb +30 -0
  38. data/test/matchers/validate_attachment_presence_matcher_test.rb +21 -0
  39. data/test/matchers/validate_attachment_size_matcher_test.rb +50 -0
  40. data/test/paperclip_test.rb +237 -0
  41. data/test/processor_test.rb +10 -0
  42. data/test/storage_test.rb +277 -0
  43. data/test/thumbnail_test.rb +177 -0
  44. metadata +133 -0
@@ -0,0 +1,237 @@
1
+ require 'test/helper'
2
+
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
6
+ setup do
7
+ Paperclip.options[:image_magick_path] = nil
8
+ Paperclip.options[:convert_path] = nil
9
+ Paperclip.options[path] = "/usr/bin"
10
+ end
11
+
12
+ should "execute the right command" do
13
+ Paperclip.expects(:path_for_command).with("convert").returns("/usr/bin/convert")
14
+ Paperclip.expects(:bit_bucket).returns("/dev/null")
15
+ Paperclip.expects(:"`").with("/usr/bin/convert one.jpg two.jpg 2>/dev/null")
16
+ Paperclip.run("convert", "one.jpg two.jpg")
17
+ end
18
+ end
19
+ end
20
+
21
+ context "Calling Paperclip.run with no path specified" do
22
+ setup do
23
+ Paperclip.options[:image_magick_path] = nil
24
+ Paperclip.options[:convert_path] = nil
25
+ end
26
+
27
+ should "execute the right command" do
28
+ Paperclip.expects(:path_for_command).with("convert").returns("convert")
29
+ Paperclip.expects(:bit_bucket).returns("/dev/null")
30
+ Paperclip.expects(:"`").with("convert one.jpg two.jpg 2>/dev/null")
31
+ Paperclip.run("convert", "one.jpg two.jpg")
32
+ end
33
+ end
34
+
35
+ should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
36
+ assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
37
+ end
38
+
39
+ should "raise when sent #processor and the name of a class that doesn't exist" do
40
+ assert_raises(NameError){ Paperclip.processor(:boogey_man) }
41
+ end
42
+
43
+ should "return a class when sent #processor and the name of a class under Paperclip" do
44
+ assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
45
+ end
46
+
47
+ context "Paperclip.bit_bucket" do
48
+ context "on systems without /dev/null" do
49
+ setup do
50
+ File.expects(:exists?).with("/dev/null").returns(false)
51
+ end
52
+
53
+ should "return 'NUL'" do
54
+ assert_equal "NUL", Paperclip.bit_bucket
55
+ end
56
+ end
57
+
58
+ context "on systems with /dev/null" do
59
+ setup do
60
+ File.expects(:exists?).with("/dev/null").returns(true)
61
+ end
62
+
63
+ should "return '/dev/null'" do
64
+ assert_equal "/dev/null", Paperclip.bit_bucket
65
+ end
66
+ end
67
+ end
68
+
69
+ context "An ActiveRecord model with an 'avatar' attachment" do
70
+ setup do
71
+ rebuild_model :path => "tmp/:class/omg/:style.:extension"
72
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
73
+ end
74
+
75
+ teardown { @file.close }
76
+
77
+ should "not error when trying to also create a 'blah' attachment" do
78
+ assert_nothing_raised do
79
+ Dummy.class_eval do
80
+ has_attached_file :blah
81
+ end
82
+ end
83
+ end
84
+
85
+ context "that is attr_protected" do
86
+ setup do
87
+ Dummy.class_eval do
88
+ attr_protected :avatar
89
+ end
90
+ @dummy = Dummy.new
91
+ end
92
+
93
+ should "not assign the avatar on mass-set" do
94
+ @dummy.logger.expects(:debug)
95
+
96
+ @dummy.attributes = { :other => "I'm set!",
97
+ :avatar => @file }
98
+
99
+ assert_equal "I'm set!", @dummy.other
100
+ assert ! @dummy.avatar?
101
+ end
102
+
103
+ should "still allow assigment on normal set" do
104
+ @dummy.logger.expects(:debug).times(0)
105
+
106
+ @dummy.other = "I'm set!"
107
+ @dummy.avatar = @file
108
+
109
+ assert_equal "I'm set!", @dummy.other
110
+ assert @dummy.avatar?
111
+ end
112
+ end
113
+
114
+ context "with a subclass" do
115
+ setup do
116
+ class ::SubDummy < Dummy; end
117
+ end
118
+
119
+ should "be able to use the attachment from the subclass" do
120
+ assert_nothing_raised do
121
+ @subdummy = SubDummy.create(:avatar => @file)
122
+ end
123
+ end
124
+
125
+ should "be able to see the attachment definition from the subclass's class" do
126
+ assert_equal "tmp/:class/omg/:style.:extension", SubDummy.attachment_definitions[:avatar][:path]
127
+ end
128
+
129
+ teardown do
130
+ Object.send(:remove_const, "SubDummy") rescue nil
131
+ end
132
+ end
133
+
134
+ should "have an #avatar method" do
135
+ assert Dummy.new.respond_to?(:avatar)
136
+ end
137
+
138
+ should "have an #avatar= method" do
139
+ assert Dummy.new.respond_to?(:avatar=)
140
+ end
141
+
142
+ context "that is valid" do
143
+ setup do
144
+ @dummy = Dummy.new
145
+ @dummy.avatar = @file
146
+ end
147
+
148
+ should "be valid" do
149
+ assert @dummy.valid?
150
+ end
151
+
152
+ context "then has a validation added that makes it invalid" do
153
+ setup do
154
+ assert @dummy.save
155
+ Dummy.class_eval do
156
+ validates_attachment_content_type :avatar, :content_type => ["text/plain"]
157
+ end
158
+ @dummy2 = Dummy.find(@dummy.id)
159
+ end
160
+
161
+ should "be invalid when reloaded" do
162
+ assert ! @dummy2.valid?, @dummy2.errors.inspect
163
+ end
164
+
165
+ should "be able to call #valid? twice without having duplicate errors" do
166
+ @dummy2.avatar.valid?
167
+ first_errors = @dummy2.avatar.errors
168
+ @dummy2.avatar.valid?
169
+ assert_equal first_errors, @dummy2.avatar.errors
170
+ end
171
+ end
172
+ end
173
+
174
+ def self.should_validate validation, options, valid_file, invalid_file
175
+ context "with #{validation} validation and #{options.inspect} options" do
176
+ setup do
177
+ Dummy.send(:"validates_attachment_#{validation}", :avatar, options)
178
+ @dummy = Dummy.new
179
+ end
180
+ context "and assigning nil" do
181
+ setup do
182
+ @dummy.avatar = nil
183
+ @dummy.valid?
184
+ end
185
+ if validation == :presence
186
+ should "have an error on the attachment" do
187
+ assert @dummy.errors.on(:avatar)
188
+ end
189
+ else
190
+ should "not have an error on the attachment" do
191
+ assert_nil @dummy.errors.on(:avatar)
192
+ end
193
+ end
194
+ end
195
+ context "and assigned a valid file" do
196
+ setup do
197
+ @dummy.avatar = valid_file
198
+ @dummy.valid?
199
+ end
200
+ should "not have an error when assigned a valid file" do
201
+ assert ! @dummy.avatar.errors.key?(validation)
202
+ end
203
+ should "not have an error on the attachment" do
204
+ assert_nil @dummy.errors.on(:avatar)
205
+ end
206
+ end
207
+ context "and assigned an invalid file" do
208
+ setup do
209
+ @dummy.avatar = invalid_file
210
+ @dummy.valid?
211
+ end
212
+ should "have an error when assigned a valid file" do
213
+ assert_not_nil @dummy.avatar.errors[validation]
214
+ end
215
+ should "have an error on the attachment" do
216
+ assert @dummy.errors.on(:avatar)
217
+ end
218
+ end
219
+ end
220
+ end
221
+
222
+ [[:presence, {}, "5k.png", nil],
223
+ [:size, {:in => 1..10240}, nil, "12k.png"],
224
+ [:size, {:less_than => 10240}, "5k.png", "12k.png"],
225
+ [:size, {:greater_than => 8096}, "12k.png", "5k.png"],
226
+ [:content_type, {:content_type => "image/png"}, "5k.png", "text.txt"],
227
+ [:content_type, {:content_type => "text/plain"}, "text.txt", "5k.png"],
228
+ [:content_type, {:content_type => %r{image/.*}}, "5k.png", "text.txt"]].each do |args|
229
+ validation, options, valid_file, invalid_file = args
230
+ valid_file &&= File.open(File.join(FIXTURES_DIR, valid_file), "rb")
231
+ invalid_file &&= File.open(File.join(FIXTURES_DIR, invalid_file), "rb")
232
+
233
+ should_validate validation, options, valid_file, invalid_file
234
+ end
235
+
236
+ end
237
+ end
@@ -0,0 +1,10 @@
1
+ require 'test/helper'
2
+
3
+ class ProcessorTest < Test::Unit::TestCase
4
+ should "instantiate and call #make when sent #make to the class" do
5
+ processor = mock
6
+ processor.expects(:make).with()
7
+ Paperclip::Processor.expects(:new).with(:one, :two, :three).returns(processor)
8
+ Paperclip::Processor.make(:one, :two, :three)
9
+ end
10
+ end
@@ -0,0 +1,277 @@
1
+ require 'test/helper'
2
+
3
+ class StorageTest < Test::Unit::TestCase
4
+ context "Parsing S3 credentials" do
5
+ setup do
6
+ rebuild_model :storage => :s3,
7
+ :bucket => "testing",
8
+ :s3_credentials => {:not => :important}
9
+
10
+ @dummy = Dummy.new
11
+ @avatar = @dummy.avatar
12
+
13
+ @current_env = ENV['RAILS_ENV']
14
+ end
15
+
16
+ teardown do
17
+ ENV['RAILS_ENV'] = @current_env
18
+ end
19
+
20
+ should "get the correct credentials when RAILS_ENV is production" do
21
+ ENV['RAILS_ENV'] = 'production'
22
+ assert_equal({:key => "12345"},
23
+ @avatar.parse_credentials('production' => {:key => '12345'},
24
+ :development => {:key => "54321"}))
25
+ end
26
+
27
+ should "get the correct credentials when RAILS_ENV is development" do
28
+ ENV['RAILS_ENV'] = 'development'
29
+ assert_equal({:key => "54321"},
30
+ @avatar.parse_credentials('production' => {:key => '12345'},
31
+ :development => {:key => "54321"}))
32
+ end
33
+
34
+ should "return the argument if the key does not exist" do
35
+ ENV['RAILS_ENV'] = "not really an env"
36
+ assert_equal({:test => "12345"}, @avatar.parse_credentials(:test => "12345"))
37
+ end
38
+ end
39
+
40
+ context "" do
41
+ setup do
42
+ rebuild_model :storage => :s3,
43
+ :s3_credentials => {},
44
+ :bucket => "bucket",
45
+ :path => ":attachment/:basename.:extension",
46
+ :url => ":s3_path_url"
47
+ @dummy = Dummy.new
48
+ @dummy.avatar = StringIO.new(".")
49
+ end
50
+
51
+ should "return a url based on an S3 path" do
52
+ assert_match %r{^http://s3.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
53
+ end
54
+ end
55
+ context "" do
56
+ setup do
57
+ rebuild_model :storage => :s3,
58
+ :s3_credentials => {},
59
+ :bucket => "bucket",
60
+ :path => ":attachment/:basename.:extension",
61
+ :url => ":s3_domain_url"
62
+ @dummy = Dummy.new
63
+ @dummy.avatar = StringIO.new(".")
64
+ end
65
+
66
+ should "return a url based on an S3 subdomain" do
67
+ assert_match %r{^http://bucket.s3.amazonaws.com/avatars/stringio.txt}, @dummy.avatar.url
68
+ end
69
+ end
70
+ context "" do
71
+ setup do
72
+ rebuild_model :storage => :s3,
73
+ :s3_credentials => {
74
+ :production => { :bucket => "prod_bucket" },
75
+ :development => { :bucket => "dev_bucket" }
76
+ },
77
+ :s3_host_alias => "something.something.com",
78
+ :path => ":attachment/:basename.:extension",
79
+ :url => ":s3_alias_url"
80
+ @dummy = Dummy.new
81
+ @dummy.avatar = StringIO.new(".")
82
+ end
83
+
84
+ should "return a url based on the host_alias" do
85
+ assert_match %r{^http://something.something.com/avatars/stringio.txt}, @dummy.avatar.url
86
+ end
87
+ end
88
+
89
+ context "Parsing S3 credentials with a bucket in them" do
90
+ setup do
91
+ rebuild_model :storage => :s3,
92
+ :s3_credentials => {
93
+ :production => { :bucket => "prod_bucket" },
94
+ :development => { :bucket => "dev_bucket" }
95
+ }
96
+ @dummy = Dummy.new
97
+ end
98
+
99
+ should "get the right bucket in production", :before => lambda{ ENV.expects(:[]).returns('production') } do
100
+ assert_equal "prod_bucket", @dummy.avatar.bucket_name
101
+ end
102
+
103
+ should "get the right bucket in development", :before => lambda{ ENV.expects(:[]).returns('development') } do
104
+ assert_equal "dev_bucket", @dummy.avatar.bucket_name
105
+ end
106
+ end
107
+
108
+ context "An attachment with S3 storage" do
109
+ setup do
110
+ rebuild_model :storage => :s3,
111
+ :bucket => "testing",
112
+ :path => ":attachment/:style/:basename.:extension",
113
+ :s3_credentials => {
114
+ 'access_key_id' => "12345",
115
+ 'secret_access_key' => "54321"
116
+ }
117
+ end
118
+
119
+ should "be extended by the S3 module" do
120
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::S3)
121
+ end
122
+
123
+ should "not be extended by the Filesystem module" do
124
+ assert ! Dummy.new.avatar.is_a?(Paperclip::Storage::Filesystem)
125
+ end
126
+
127
+ context "when assigned" do
128
+ setup do
129
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
130
+ @dummy = Dummy.new
131
+ @dummy.avatar = @file
132
+ end
133
+
134
+ teardown { @file.close }
135
+
136
+ should "not get a bucket to get a URL" do
137
+ @dummy.avatar.expects(:s3).never
138
+ @dummy.avatar.expects(:s3_bucket).never
139
+ assert_match %r{^http://s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url
140
+ end
141
+
142
+ context "and saved" do
143
+ setup do
144
+ @s3_mock = stub
145
+ @bucket_mock = stub
146
+ RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
147
+ @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
148
+ @key_mock = stub
149
+ @bucket_mock.expects(:key).returns(@key_mock)
150
+ @key_mock.expects(:data=)
151
+ @key_mock.expects(:put).with(nil, 'public-read', 'Content-type' => 'image/png')
152
+ @dummy.save
153
+ end
154
+
155
+ should "succeed" do
156
+ assert true
157
+ end
158
+ end
159
+
160
+ context "and remove" do
161
+ setup do
162
+ @s3_mock = stub
163
+ @bucket_mock = stub
164
+ RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
165
+ @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
166
+ @key_mock = stub
167
+ @bucket_mock.expects(:key).at_least(2).returns(@key_mock)
168
+ @key_mock.expects(:delete)
169
+ @dummy.destroy_attached_files
170
+ end
171
+
172
+ should "succeed" do
173
+ assert true
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ context "An attachment with S3 storage and bucket defined as a Proc" do
180
+ setup do
181
+ rebuild_model :storage => :s3,
182
+ :bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
183
+ :s3_credentials => {:not => :important}
184
+ end
185
+
186
+ should "get the right bucket name" do
187
+ assert "bucket_a", Dummy.new(:other => 'a').avatar.bucket_name
188
+ assert "bucket_b", Dummy.new(:other => 'b').avatar.bucket_name
189
+ end
190
+ end
191
+
192
+ context "An attachment with S3 storage and specific s3 headers set" do
193
+ setup do
194
+ rebuild_model :storage => :s3,
195
+ :bucket => "testing",
196
+ :path => ":attachment/:style/:basename.:extension",
197
+ :s3_credentials => {
198
+ 'access_key_id' => "12345",
199
+ 'secret_access_key' => "54321"
200
+ },
201
+ :s3_headers => {'Cache-Control' => 'max-age=31557600'}
202
+ end
203
+
204
+ context "when assigned" do
205
+ setup do
206
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
207
+ @dummy = Dummy.new
208
+ @dummy.avatar = @file
209
+ end
210
+
211
+ teardown { @file.close }
212
+
213
+ context "and saved" do
214
+ setup do
215
+ @s3_mock = stub
216
+ @bucket_mock = stub
217
+ RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
218
+ @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
219
+ @key_mock = stub
220
+ @bucket_mock.expects(:key).returns(@key_mock)
221
+ @key_mock.expects(:data=)
222
+ @key_mock.expects(:put).with(nil,
223
+ 'public-read',
224
+ 'Content-type' => 'image/png',
225
+ 'Cache-Control' => 'max-age=31557600')
226
+ @dummy.save
227
+ end
228
+
229
+ should "succeed" do
230
+ assert true
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ unless ENV["S3_TEST_BUCKET"].blank?
237
+ context "Using S3 for real, an attachment with S3 storage" do
238
+ setup do
239
+ rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
240
+ :storage => :s3,
241
+ :bucket => ENV["S3_TEST_BUCKET"],
242
+ :path => ":class/:attachment/:id/:style.:extension",
243
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "s3.yml"))
244
+
245
+ Dummy.delete_all
246
+ @dummy = Dummy.new
247
+ end
248
+
249
+ should "be extended by the S3 module" do
250
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::S3)
251
+ end
252
+
253
+ context "when assigned" do
254
+ setup do
255
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
256
+ @dummy.avatar = @file
257
+ end
258
+
259
+ teardown { @file.close }
260
+
261
+ should "still return a Tempfile when sent #to_io" do
262
+ assert_equal Tempfile, @dummy.avatar.to_io.class
263
+ end
264
+
265
+ context "and saved" do
266
+ setup do
267
+ @dummy.save
268
+ end
269
+
270
+ should "be on S3" do
271
+ assert true
272
+ end
273
+ end
274
+ end
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,177 @@
1
+ require 'test/helper'
2
+
3
+ class ThumbnailTest < Test::Unit::TestCase
4
+
5
+ context "A Paperclip Tempfile" do
6
+ setup do
7
+ @tempfile = Paperclip::Tempfile.new("file.jpg")
8
+ end
9
+
10
+ should "have its path contain a real extension" do
11
+ assert_equal ".jpg", File.extname(@tempfile.path)
12
+ end
13
+
14
+ should "be a real Tempfile" do
15
+ assert @tempfile.is_a?(::Tempfile)
16
+ end
17
+ end
18
+
19
+ context "Another Paperclip Tempfile" do
20
+ setup do
21
+ @tempfile = Paperclip::Tempfile.new("file")
22
+ end
23
+
24
+ should "not have an extension if not given one" do
25
+ assert_equal "", File.extname(@tempfile.path)
26
+ end
27
+
28
+ should "still be a real Tempfile" do
29
+ assert @tempfile.is_a?(::Tempfile)
30
+ end
31
+ end
32
+
33
+ context "An image" do
34
+ setup do
35
+ @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
36
+ end
37
+
38
+ teardown { @file.close }
39
+
40
+ [["600x600>", "434x66"],
41
+ ["400x400>", "400x61"],
42
+ ["32x32<", "434x66"]
43
+ ].each do |args|
44
+ context "being thumbnailed with a geometry of #{args[0]}" do
45
+ setup do
46
+ @thumb = Paperclip::Thumbnail.new(@file, :geometry => args[0])
47
+ end
48
+
49
+ should "start with dimensions of 434x66" do
50
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
51
+ assert_equal "434x66", `#{cmd}`.chomp
52
+ end
53
+
54
+ should "report the correct target geometry" do
55
+ assert_equal args[0], @thumb.target_geometry.to_s
56
+ end
57
+
58
+ context "when made" do
59
+ setup do
60
+ @thumb_result = @thumb.make
61
+ end
62
+
63
+ should "be the size we expect it to be" do
64
+ cmd = %Q[identify -format "%wx%h" "#{@thumb_result.path}"]
65
+ assert_equal args[1], `#{cmd}`.chomp
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ context "being thumbnailed at 100x50 with cropping" do
72
+ setup do
73
+ @thumb = Paperclip::Thumbnail.new(@file, :geometry => "100x50#")
74
+ end
75
+
76
+ should "report its correct current and target geometries" do
77
+ assert_equal "100x50#", @thumb.target_geometry.to_s
78
+ assert_equal "434x66", @thumb.current_geometry.to_s
79
+ end
80
+
81
+ should "report its correct format" do
82
+ assert_nil @thumb.format
83
+ end
84
+
85
+ should "have whiny turned on by default" do
86
+ assert @thumb.whiny
87
+ end
88
+
89
+ should "have convert_options set to nil by default" do
90
+ assert_equal nil, @thumb.convert_options
91
+ end
92
+
93
+ should "send the right command to convert when sent #make" do
94
+ Paperclip.expects(:"`").with do |arg|
95
+ arg.match %r{convert\s+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+\"x50\"\s+-crop\s+\"100x50\+114\+0\"\s+\+repage\s+".*?"}
96
+ end
97
+ @thumb.make
98
+ end
99
+
100
+ should "create the thumbnail when sent #make" do
101
+ dst = @thumb.make
102
+ assert_match /100x50/, `identify "#{dst.path}"`
103
+ end
104
+ end
105
+
106
+ context "being thumbnailed with convert options set" do
107
+ setup do
108
+ @thumb = Paperclip::Thumbnail.new(@file,
109
+ :geometry => "100x50#",
110
+ :convert_options => "-strip -depth 8")
111
+ end
112
+
113
+ should "have convert_options value set" do
114
+ assert_equal "-strip -depth 8", @thumb.convert_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+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+"x50"\s+-crop\s+"100x50\+114\+0"\s+\+repage\s+-strip\s+-depth\s+8\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 convert_options setting" do
130
+ setup do
131
+ @thumb = Paperclip::Thumbnail.new(@file,
132
+ :geometry => "100x50#",
133
+ :convert_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
+ end
144
+
145
+ context "A multipage PDF" do
146
+ setup do
147
+ @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "twopage.pdf"), 'rb')
148
+ end
149
+
150
+ teardown { @file.close }
151
+
152
+ should "start with two pages with dimensions 612x792" do
153
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
154
+ assert_equal "612x792"*2, `#{cmd}`.chomp
155
+ end
156
+
157
+ context "being thumbnailed at 100x100 with cropping" do
158
+ setup do
159
+ @thumb = Paperclip::Thumbnail.new(@file, :geometry => "100x100#", :format => :png)
160
+ end
161
+
162
+ should "report its correct current and target geometries" do
163
+ assert_equal "100x100#", @thumb.target_geometry.to_s
164
+ assert_equal "612x792", @thumb.current_geometry.to_s
165
+ end
166
+
167
+ should "report its correct format" do
168
+ assert_equal :png, @thumb.format
169
+ end
170
+
171
+ should "create the thumbnail when sent #make" do
172
+ dst = @thumb.make
173
+ assert_match /100x100/, `identify "#{dst.path}"`
174
+ end
175
+ end
176
+ end
177
+ end