paperclip_jk 5.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +21 -0
  3. data/.hound.yml +1066 -0
  4. data/.rubocop.yml +1 -0
  5. data/.travis.yml +26 -0
  6. data/Appraisals +27 -0
  7. data/CONTRIBUTING.md +86 -0
  8. data/Gemfile +15 -0
  9. data/LICENSE +24 -0
  10. data/NEWS +424 -0
  11. data/README.md +999 -0
  12. data/RELEASING.md +17 -0
  13. data/Rakefile +44 -0
  14. data/UPGRADING +17 -0
  15. data/features/basic_integration.feature +81 -0
  16. data/features/migration.feature +70 -0
  17. data/features/rake_tasks.feature +62 -0
  18. data/features/step_definitions/attachment_steps.rb +110 -0
  19. data/features/step_definitions/html_steps.rb +15 -0
  20. data/features/step_definitions/rails_steps.rb +230 -0
  21. data/features/step_definitions/s3_steps.rb +14 -0
  22. data/features/step_definitions/web_steps.rb +107 -0
  23. data/features/support/env.rb +11 -0
  24. data/features/support/fakeweb.rb +13 -0
  25. data/features/support/file_helpers.rb +34 -0
  26. data/features/support/fixtures/boot_config.txt +15 -0
  27. data/features/support/fixtures/gemfile.txt +5 -0
  28. data/features/support/fixtures/preinitializer.txt +20 -0
  29. data/features/support/paths.rb +28 -0
  30. data/features/support/rails.rb +63 -0
  31. data/features/support/selectors.rb +19 -0
  32. data/gemfiles/4.2.awsv2.0.gemfile +17 -0
  33. data/gemfiles/4.2.awsv2.1.gemfile +17 -0
  34. data/gemfiles/4.2.awsv2.gemfile +20 -0
  35. data/gemfiles/5.0.awsv2.0.gemfile +17 -0
  36. data/gemfiles/5.0.awsv2.1.gemfile +17 -0
  37. data/gemfiles/5.0.awsv2.gemfile +25 -0
  38. data/lib/generators/paperclip/USAGE +8 -0
  39. data/lib/generators/paperclip/paperclip_generator.rb +30 -0
  40. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +15 -0
  41. data/lib/paperclip.rb +211 -0
  42. data/lib/paperclip/attachment.rb +610 -0
  43. data/lib/paperclip/attachment_registry.rb +60 -0
  44. data/lib/paperclip/callbacks.rb +42 -0
  45. data/lib/paperclip/content_type_detector.rb +80 -0
  46. data/lib/paperclip/errors.rb +34 -0
  47. data/lib/paperclip/file_command_content_type_detector.rb +30 -0
  48. data/lib/paperclip/filename_cleaner.rb +16 -0
  49. data/lib/paperclip/geometry.rb +158 -0
  50. data/lib/paperclip/geometry_detector_factory.rb +48 -0
  51. data/lib/paperclip/geometry_parser_factory.rb +31 -0
  52. data/lib/paperclip/glue.rb +17 -0
  53. data/lib/paperclip/has_attached_file.rb +115 -0
  54. data/lib/paperclip/helpers.rb +60 -0
  55. data/lib/paperclip/interpolations.rb +197 -0
  56. data/lib/paperclip/interpolations/plural_cache.rb +18 -0
  57. data/lib/paperclip/io_adapters/abstract_adapter.rb +47 -0
  58. data/lib/paperclip/io_adapters/attachment_adapter.rb +36 -0
  59. data/lib/paperclip/io_adapters/data_uri_adapter.rb +22 -0
  60. data/lib/paperclip/io_adapters/empty_string_adapter.rb +18 -0
  61. data/lib/paperclip/io_adapters/file_adapter.rb +22 -0
  62. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +15 -0
  63. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  64. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  65. data/lib/paperclip/io_adapters/registry.rb +32 -0
  66. data/lib/paperclip/io_adapters/stringio_adapter.rb +33 -0
  67. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +42 -0
  68. data/lib/paperclip/io_adapters/uri_adapter.rb +44 -0
  69. data/lib/paperclip/locales/en.yml +18 -0
  70. data/lib/paperclip/logger.rb +21 -0
  71. data/lib/paperclip/matchers.rb +64 -0
  72. data/lib/paperclip/matchers/have_attached_file_matcher.rb +54 -0
  73. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +100 -0
  74. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +59 -0
  75. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +96 -0
  76. data/lib/paperclip/media_type_spoof_detector.rb +89 -0
  77. data/lib/paperclip/missing_attachment_styles.rb +79 -0
  78. data/lib/paperclip/processor.rb +48 -0
  79. data/lib/paperclip/processor_helpers.rb +50 -0
  80. data/lib/paperclip/rails_environment.rb +25 -0
  81. data/lib/paperclip/railtie.rb +31 -0
  82. data/lib/paperclip/schema.rb +77 -0
  83. data/lib/paperclip/storage.rb +4 -0
  84. data/lib/paperclip/storage/database.rb +140 -0
  85. data/lib/paperclip/storage/filesystem.rb +90 -0
  86. data/lib/paperclip/storage/fog.rb +244 -0
  87. data/lib/paperclip/storage/s3.rb +442 -0
  88. data/lib/paperclip/style.rb +109 -0
  89. data/lib/paperclip/tempfile.rb +43 -0
  90. data/lib/paperclip/tempfile_factory.rb +23 -0
  91. data/lib/paperclip/thumbnail.rb +121 -0
  92. data/lib/paperclip/url_generator.rb +72 -0
  93. data/lib/paperclip/validators.rb +74 -0
  94. data/lib/paperclip/validators/attachment_content_type_validator.rb +88 -0
  95. data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
  96. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
  97. data/lib/paperclip/validators/attachment_presence_validator.rb +30 -0
  98. data/lib/paperclip/validators/attachment_size_validator.rb +109 -0
  99. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
  100. data/lib/paperclip/version.rb +3 -0
  101. data/lib/tasks/paperclip.rake +127 -0
  102. data/paperclip.gemspec +54 -0
  103. data/shoulda_macros/paperclip.rb +134 -0
  104. data/spec/database.yml +4 -0
  105. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  106. data/spec/paperclip/attachment_processing_spec.rb +80 -0
  107. data/spec/paperclip/attachment_registry_spec.rb +158 -0
  108. data/spec/paperclip/attachment_spec.rb +1517 -0
  109. data/spec/paperclip/content_type_detector_spec.rb +48 -0
  110. data/spec/paperclip/file_command_content_type_detector_spec.rb +26 -0
  111. data/spec/paperclip/filename_cleaner_spec.rb +14 -0
  112. data/spec/paperclip/geometry_detector_spec.rb +39 -0
  113. data/spec/paperclip/geometry_parser_spec.rb +73 -0
  114. data/spec/paperclip/geometry_spec.rb +255 -0
  115. data/spec/paperclip/glue_spec.rb +44 -0
  116. data/spec/paperclip/has_attached_file_spec.rb +158 -0
  117. data/spec/paperclip/integration_spec.rb +668 -0
  118. data/spec/paperclip/interpolations_spec.rb +262 -0
  119. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +78 -0
  120. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +139 -0
  121. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +83 -0
  122. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  123. data/spec/paperclip/io_adapters/file_adapter_spec.rb +131 -0
  124. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +113 -0
  125. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  126. data/spec/paperclip/io_adapters/nil_adapter_spec.rb +25 -0
  127. data/spec/paperclip/io_adapters/registry_spec.rb +35 -0
  128. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +64 -0
  129. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +146 -0
  130. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +102 -0
  131. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  132. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +109 -0
  133. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  134. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  135. data/spec/paperclip/media_type_spoof_detector_spec.rb +70 -0
  136. data/spec/paperclip/meta_class_spec.rb +30 -0
  137. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
  138. data/spec/paperclip/paperclip_spec.rb +192 -0
  139. data/spec/paperclip/plural_cache_spec.rb +37 -0
  140. data/spec/paperclip/processor_helpers_spec.rb +57 -0
  141. data/spec/paperclip/processor_spec.rb +26 -0
  142. data/spec/paperclip/rails_environment_spec.rb +33 -0
  143. data/spec/paperclip/rake_spec.rb +103 -0
  144. data/spec/paperclip/schema_spec.rb +248 -0
  145. data/spec/paperclip/storage/filesystem_spec.rb +79 -0
  146. data/spec/paperclip/storage/fog_spec.rb +545 -0
  147. data/spec/paperclip/storage/s3_live_spec.rb +186 -0
  148. data/spec/paperclip/storage/s3_spec.rb +1583 -0
  149. data/spec/paperclip/style_spec.rb +255 -0
  150. data/spec/paperclip/tempfile_factory_spec.rb +33 -0
  151. data/spec/paperclip/thumbnail_spec.rb +500 -0
  152. data/spec/paperclip/url_generator_spec.rb +211 -0
  153. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
  154. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
  155. data/spec/paperclip/validators/attachment_presence_validator_spec.rb +85 -0
  156. data/spec/paperclip/validators/attachment_size_validator_spec.rb +235 -0
  157. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
  158. data/spec/paperclip/validators_spec.rb +164 -0
  159. data/spec/spec_helper.rb +45 -0
  160. data/spec/support/assertions.rb +78 -0
  161. data/spec/support/fake_model.rb +25 -0
  162. data/spec/support/fake_rails.rb +12 -0
  163. data/spec/support/fixtures/12k.png +0 -0
  164. data/spec/support/fixtures/50x50.png +0 -0
  165. data/spec/support/fixtures/5k.png +0 -0
  166. data/spec/support/fixtures/animated +0 -0
  167. data/spec/support/fixtures/animated.gif +0 -0
  168. data/spec/support/fixtures/animated.unknown +0 -0
  169. data/spec/support/fixtures/bad.png +1 -0
  170. data/spec/support/fixtures/empty.html +1 -0
  171. data/spec/support/fixtures/empty.xlsx +0 -0
  172. data/spec/support/fixtures/fog.yml +8 -0
  173. data/spec/support/fixtures/rotated.jpg +0 -0
  174. data/spec/support/fixtures/s3.yml +8 -0
  175. data/spec/support/fixtures/spaced file.jpg +0 -0
  176. data/spec/support/fixtures/spaced file.png +0 -0
  177. data/spec/support/fixtures/text.txt +1 -0
  178. data/spec/support/fixtures/twopage.pdf +0 -0
  179. data/spec/support/fixtures/uppercase.PNG +0 -0
  180. data/spec/support/matchers/accept.rb +5 -0
  181. data/spec/support/matchers/exist.rb +5 -0
  182. data/spec/support/matchers/have_column.rb +23 -0
  183. data/spec/support/mock_attachment.rb +22 -0
  184. data/spec/support/mock_interpolator.rb +24 -0
  185. data/spec/support/mock_url_generator_builder.rb +27 -0
  186. data/spec/support/model_reconstruction.rb +68 -0
  187. data/spec/support/reporting.rb +11 -0
  188. data/spec/support/test_data.rb +13 -0
  189. data/spec/support/version_helper.rb +9 -0
  190. metadata +713 -0
@@ -0,0 +1,255 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Paperclip::Style do
5
+ context "A style rule" do
6
+ before do
7
+ @attachment = attachment path: ":basename.:extension",
8
+ styles: { foo: {geometry: "100x100#", format: :png} },
9
+ whiny: true
10
+ @style = @attachment.styles[:foo]
11
+ end
12
+
13
+ it "is held as a Style object" do
14
+ expect(@style).to be_a Paperclip::Style
15
+ end
16
+
17
+ it "gets processors from the attachment definition" do
18
+ assert_equal [:thumbnail], @style.processors
19
+ end
20
+
21
+ it "has the right geometry" do
22
+ assert_equal "100x100#", @style.geometry
23
+ end
24
+
25
+ it "is whiny if the attachment is" do
26
+ assert @style.whiny?
27
+ end
28
+
29
+ it "responds to hash notation" do
30
+ assert_equal [:thumbnail], @style[:processors]
31
+ assert_equal "100x100#", @style[:geometry]
32
+ end
33
+
34
+ it "returns the name of the style in processor options" do
35
+ assert_equal :foo, @style.processor_options[:style]
36
+ end
37
+ end
38
+
39
+ context "A style rule with properties supplied as procs" do
40
+ before do
41
+ @attachment = attachment path: ":basename.:extension",
42
+ whiny_thumbnails: true,
43
+ processors: lambda {|a| [:test]},
44
+ styles: {
45
+ foo: lambda{|a| "300x300#"},
46
+ bar: {
47
+ geometry: lambda{|a| "300x300#"},
48
+ convert_options: lambda{|a| "-do_stuff"},
49
+ source_file_options: lambda{|a| "-do_extra_stuff"}
50
+ }
51
+ }
52
+ end
53
+
54
+ it "calls procs when they are needed" do
55
+ assert_equal "300x300#", @attachment.styles[:foo].geometry
56
+ assert_equal "300x300#", @attachment.styles[:bar].geometry
57
+ assert_equal [:test], @attachment.styles[:foo].processors
58
+ assert_equal [:test], @attachment.styles[:bar].processors
59
+ assert_equal "-do_stuff", @attachment.styles[:bar].convert_options
60
+ assert_equal "-do_extra_stuff", @attachment.styles[:bar].source_file_options
61
+ end
62
+ end
63
+
64
+ context "An attachment with style rules in various forms" do
65
+ before do
66
+ styles = {}
67
+ styles[:aslist] = ["100x100", :png]
68
+ styles[:ashash] = {geometry: "100x100", format: :png}
69
+ styles[:asstring] = "100x100"
70
+ @attachment = attachment path: ":basename.:extension",
71
+ styles: styles
72
+ end
73
+
74
+ it "has the right number of styles" do
75
+ expect(@attachment.styles).to be_a Hash
76
+ assert_equal 3, @attachment.styles.size
77
+ end
78
+
79
+ it "has styles as Style objects" do
80
+ [:aslist, :ashash, :aslist].each do |s|
81
+ expect(@attachment.styles[s]).to be_a Paperclip::Style
82
+ end
83
+ end
84
+
85
+ it "has the right geometries" do
86
+ [:aslist, :ashash, :aslist].each do |s|
87
+ assert_equal @attachment.styles[s].geometry, "100x100"
88
+ end
89
+ end
90
+
91
+ it "has the right formats" do
92
+ assert_equal @attachment.styles[:aslist].format, :png
93
+ assert_equal @attachment.styles[:ashash].format, :png
94
+ assert_nil @attachment.styles[:asstring].format
95
+ end
96
+
97
+ it "retains order" do
98
+ assert_equal [:aslist, :ashash, :asstring], @attachment.styles.keys
99
+ end
100
+ end
101
+
102
+ context "An attachment with :convert_options" do
103
+ it "does not have called extra_options_for(:thumb/:large) on initialization" do
104
+ @attachment = attachment path: ":basename.:extension",
105
+ styles: {thumb: "100x100", large: "400x400"},
106
+ convert_options: {all: "-do_stuff", thumb: "-thumbnailize"}
107
+ @attachment.expects(:extra_options_for).never
108
+ @style = @attachment.styles[:thumb]
109
+ end
110
+
111
+ it "calls extra_options_for(:thumb/:large) when convert options are requested" do
112
+ @attachment = attachment path: ":basename.:extension",
113
+ styles: {thumb: "100x100", large: "400x400"},
114
+ convert_options: {all: "-do_stuff", thumb: "-thumbnailize"}
115
+ @style = @attachment.styles[:thumb]
116
+ @file = StringIO.new("...")
117
+ @file.stubs(:original_filename).returns("file.jpg")
118
+
119
+ @attachment.expects(:extra_options_for).with(:thumb)
120
+ @attachment.styles[:thumb].convert_options
121
+ end
122
+ end
123
+
124
+ context "An attachment with :source_file_options" do
125
+ it "does not have called extra_source_file_options_for(:thumb/:large) on initialization" do
126
+ @attachment = attachment path: ":basename.:extension",
127
+ styles: {thumb: "100x100", large: "400x400"},
128
+ source_file_options: {all: "-density 400", thumb: "-depth 8"}
129
+ @attachment.expects(:extra_source_file_options_for).never
130
+ @style = @attachment.styles[:thumb]
131
+ end
132
+
133
+ it "calls extra_options_for(:thumb/:large) when convert options are requested" do
134
+ @attachment = attachment path: ":basename.:extension",
135
+ styles: {thumb: "100x100", large: "400x400"},
136
+ source_file_options: {all: "-density 400", thumb: "-depth 8"}
137
+ @style = @attachment.styles[:thumb]
138
+ @file = StringIO.new("...")
139
+ @file.stubs(:original_filename).returns("file.jpg")
140
+
141
+ @attachment.expects(:extra_source_file_options_for).with(:thumb)
142
+ @attachment.styles[:thumb].source_file_options
143
+ end
144
+ end
145
+
146
+ context "A style rule with its own :processors" do
147
+ before do
148
+ @attachment = attachment path: ":basename.:extension",
149
+ styles: {
150
+ foo: {
151
+ geometry: "100x100#",
152
+ format: :png,
153
+ processors: [:test]
154
+ }
155
+ },
156
+ processors: [:thumbnail]
157
+ @style = @attachment.styles[:foo]
158
+ end
159
+
160
+ it "does not get processors from the attachment" do
161
+ @attachment.expects(:processors).never
162
+ assert_not_equal [:thumbnail], @style.processors
163
+ end
164
+
165
+ it "reports its own processors" do
166
+ assert_equal [:test], @style.processors
167
+ end
168
+
169
+ end
170
+
171
+ context "A style rule with :processors supplied as procs" do
172
+ before do
173
+ @attachment = attachment path: ":basename.:extension",
174
+ styles: {
175
+ foo: {
176
+ geometry: "100x100#",
177
+ format: :png,
178
+ processors: lambda{|a| [:test]}
179
+ }
180
+ },
181
+ processors: [:thumbnail]
182
+ end
183
+
184
+ it "defers processing of procs until they are needed" do
185
+ expect(@attachment.styles[:foo].instance_variable_get("@processors")).to be_a Proc
186
+ end
187
+
188
+ it "calls procs when they are needed" do
189
+ assert_equal [:test], @attachment.styles[:foo].processors
190
+ end
191
+ end
192
+
193
+ context "An attachment with :convert_options and :source_file_options in :styles" do
194
+ before do
195
+ @attachment = attachment path: ":basename.:extension",
196
+ styles: {
197
+ thumb: "100x100",
198
+ large: {geometry: "400x400",
199
+ convert_options: "-do_stuff",
200
+ source_file_options: "-do_extra_stuff"
201
+ }
202
+ }
203
+ @file = StringIO.new("...")
204
+ @file.stubs(:original_filename).returns("file.jpg")
205
+ end
206
+
207
+ it "has empty options for :thumb style" do
208
+ assert_equal "", @attachment.styles[:thumb].processor_options[:convert_options]
209
+ assert_equal "", @attachment.styles[:thumb].processor_options[:source_file_options]
210
+ end
211
+
212
+ it "has the right options for :large style" do
213
+ assert_equal "-do_stuff", @attachment.styles[:large].processor_options[:convert_options]
214
+ assert_equal "-do_extra_stuff", @attachment.styles[:large].processor_options[:source_file_options]
215
+ end
216
+ end
217
+
218
+ context "A style rule supplied with default format" do
219
+ before do
220
+ @attachment = attachment default_format: :png,
221
+ styles: {
222
+ asstring: "300x300#",
223
+ aslist: ["300x300#", :jpg],
224
+ ashash: {
225
+ geometry: "300x300#",
226
+ convert_options: "-do_stuff"
227
+ }
228
+ }
229
+ end
230
+
231
+ it "has the right number of styles" do
232
+ expect(@attachment.styles).to be_a Hash
233
+ assert_equal 3, @attachment.styles.size
234
+ end
235
+
236
+ it "has styles as Style objects" do
237
+ [:aslist, :ashash, :aslist].each do |s|
238
+ expect(@attachment.styles[s]).to be_a Paperclip::Style
239
+ end
240
+ end
241
+
242
+ it "has the right geometries" do
243
+ [:aslist, :ashash, :aslist].each do |s|
244
+ assert_equal @attachment.styles[s].geometry, "300x300#"
245
+ end
246
+ end
247
+
248
+ it "has the right formats" do
249
+ assert_equal @attachment.styles[:aslist].format, :jpg
250
+ assert_equal @attachment.styles[:ashash].format, :png
251
+ assert_equal @attachment.styles[:asstring].format, :png
252
+ end
253
+
254
+ end
255
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::TempfileFactory do
4
+ it "is able to generate a tempfile with the right name" do
5
+ file = subject.generate("omg.png")
6
+ assert File.extname(file.path), "png"
7
+ end
8
+
9
+ it "is able to generate a tempfile with the right name with a tilde at the beginning" do
10
+ file = subject.generate("~omg.png")
11
+ assert File.extname(file.path), "png"
12
+ end
13
+
14
+ it "is able to generate a tempfile with the right name with a tilde at the end" do
15
+ file = subject.generate("omg.png~")
16
+ assert File.extname(file.path), "png"
17
+ end
18
+
19
+ it "is able to generate a tempfile from a file with a really long name" do
20
+ filename = "#{"longfilename" * 100}.png"
21
+ file = subject.generate(filename)
22
+ assert File.extname(file.path), "png"
23
+ end
24
+
25
+ it 'is able to take nothing as a parameter and not error' do
26
+ file = subject.generate
27
+ assert File.exist?(file.path)
28
+ end
29
+
30
+ it "does not throw Errno::ENAMETOOLONG when it has a really long name" do
31
+ expect { subject.generate("o" * 255) }.to_not raise_error
32
+ end
33
+ end
@@ -0,0 +1,500 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::Thumbnail do
4
+ context "A Paperclip Tempfile" do
5
+ before do
6
+ @tempfile = Paperclip::Tempfile.new(["file", ".jpg"])
7
+ end
8
+
9
+ after { @tempfile.close }
10
+
11
+ it "has its path contain a real extension" do
12
+ assert_equal ".jpg", File.extname(@tempfile.path)
13
+ end
14
+
15
+ it "is a real Tempfile" do
16
+ assert @tempfile.is_a?(::Tempfile)
17
+ end
18
+ end
19
+
20
+ context "Another Paperclip Tempfile" do
21
+ before do
22
+ @tempfile = Paperclip::Tempfile.new("file")
23
+ end
24
+
25
+ after { @tempfile.close }
26
+
27
+ it "does not have an extension if not given one" do
28
+ assert_equal "", File.extname(@tempfile.path)
29
+ end
30
+
31
+ it "is a real Tempfile" do
32
+ assert @tempfile.is_a?(::Tempfile)
33
+ end
34
+ end
35
+
36
+ context "An image" do
37
+ before do
38
+ @file = File.new(fixture_file("5k.png"), 'rb')
39
+ end
40
+
41
+ after { @file.close }
42
+
43
+ [["600x600>", "434x66"],
44
+ ["400x400>", "400x61"],
45
+ ["32x32<", "434x66"],
46
+ [nil, "434x66"]
47
+ ].each do |args|
48
+ context "being thumbnailed with a geometry of #{args[0]}" do
49
+ before do
50
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: args[0])
51
+ end
52
+
53
+ it "starts with dimensions of 434x66" do
54
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
55
+ assert_equal "434x66", `#{cmd}`.chomp
56
+ end
57
+
58
+ it "reports the correct target geometry" do
59
+ assert_equal args[0].to_s, @thumb.target_geometry.to_s
60
+ end
61
+
62
+ context "when made" do
63
+ before do
64
+ @thumb_result = @thumb.make
65
+ end
66
+
67
+ it "is the size we expect it to be" do
68
+ cmd = %Q[identify -format "%wx%h" "#{@thumb_result.path}"]
69
+ assert_equal args[1], `#{cmd}`.chomp
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ context "being thumbnailed at 100x50 with cropping" do
76
+ before do
77
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "100x50#")
78
+ end
79
+
80
+ it "lets us know when a command isn't found versus a processing error" do
81
+ old_path = ENV['PATH']
82
+ begin
83
+ Cocaine::CommandLine.path = ''
84
+ Paperclip.options[:command_path] = ''
85
+ ENV['PATH'] = ''
86
+ assert_raises(Paperclip::Errors::CommandNotFoundError) do
87
+ silence_stream(STDERR) do
88
+ @thumb.make
89
+ end
90
+ end
91
+ ensure
92
+ ENV['PATH'] = old_path
93
+ end
94
+ end
95
+
96
+ it "reports its correct current and target geometries" do
97
+ assert_equal "100x50#", @thumb.target_geometry.to_s
98
+ assert_equal "434x66", @thumb.current_geometry.to_s
99
+ end
100
+
101
+ it "reports its correct format" do
102
+ assert_nil @thumb.format
103
+ end
104
+
105
+ it "has whiny turned on by default" do
106
+ assert @thumb.whiny
107
+ end
108
+
109
+ it "has convert_options set to nil by default" do
110
+ assert_equal nil, @thumb.convert_options
111
+ end
112
+
113
+ it "has source_file_options set to nil by default" do
114
+ assert_equal nil, @thumb.source_file_options
115
+ end
116
+
117
+ it "sends the right command to convert when sent #make" do
118
+ @thumb.expects(:convert).with do |*arg|
119
+ arg[0] == ':source -auto-orient -resize "x50" -crop "100x50+114+0" +repage :dest' &&
120
+ arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
121
+ end
122
+ @thumb.make
123
+ end
124
+
125
+ it "creates the thumbnail when sent #make" do
126
+ dst = @thumb.make
127
+ assert_match /100x50/, `identify "#{dst.path}"`
128
+ end
129
+ end
130
+
131
+ it 'crops a EXIF-rotated image properly' do
132
+ file = File.new(fixture_file('rotated.jpg'))
133
+ thumb = Paperclip::Thumbnail.new(file, geometry: "50x50#")
134
+
135
+ output_file = thumb.make
136
+
137
+ command = Cocaine::CommandLine.new("identify", "-format %wx%h :file")
138
+ assert_equal "50x50", command.run(file: output_file.path).strip
139
+ end
140
+
141
+ context "being thumbnailed with source file options set" do
142
+ before do
143
+ @thumb = Paperclip::Thumbnail.new(@file,
144
+ geometry: "100x50#",
145
+ source_file_options: "-strip")
146
+ end
147
+
148
+ it "has source_file_options value set" do
149
+ assert_equal ["-strip"], @thumb.source_file_options
150
+ end
151
+
152
+ it "sends the right command to convert when sent #make" do
153
+ @thumb.expects(:convert).with do |*arg|
154
+ arg[0] == '-strip :source -auto-orient -resize "x50" -crop "100x50+114+0" +repage :dest' &&
155
+ arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
156
+ end
157
+ @thumb.make
158
+ end
159
+
160
+ it "creates the thumbnail when sent #make" do
161
+ dst = @thumb.make
162
+ assert_match /100x50/, `identify "#{dst.path}"`
163
+ end
164
+
165
+ context "redefined to have bad source_file_options setting" do
166
+ before do
167
+ @thumb = Paperclip::Thumbnail.new(@file,
168
+ geometry: "100x50#",
169
+ source_file_options: "-this-aint-no-option")
170
+ end
171
+
172
+ it "errors when trying to create the thumbnail" do
173
+ assert_raises(Paperclip::Error) do
174
+ silence_stream(STDERR) do
175
+ @thumb.make
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ context "being thumbnailed with convert options set" do
183
+ before do
184
+ @thumb = Paperclip::Thumbnail.new(@file,
185
+ geometry: "100x50#",
186
+ convert_options: "-strip -depth 8")
187
+ end
188
+
189
+ it "has convert_options value set" do
190
+ assert_equal %w"-strip -depth 8", @thumb.convert_options
191
+ end
192
+
193
+ it "sends the right command to convert when sent #make" do
194
+ @thumb.expects(:convert).with do |*arg|
195
+ arg[0] == ':source -auto-orient -resize "x50" -crop "100x50+114+0" +repage -strip -depth 8 :dest' &&
196
+ arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
197
+ end
198
+ @thumb.make
199
+ end
200
+
201
+ it "creates the thumbnail when sent #make" do
202
+ dst = @thumb.make
203
+ assert_match /100x50/, `identify "#{dst.path}"`
204
+ end
205
+
206
+ context "redefined to have bad convert_options setting" do
207
+ before do
208
+ @thumb = Paperclip::Thumbnail.new(@file,
209
+ geometry: "100x50#",
210
+ convert_options: "-this-aint-no-option")
211
+ end
212
+
213
+ it "errors when trying to create the thumbnail" do
214
+ assert_raises(Paperclip::Error) do
215
+ silence_stream(STDERR) do
216
+ @thumb.make
217
+ end
218
+ end
219
+ end
220
+
221
+ it "lets us know when a command isn't found versus a processing error" do
222
+ old_path = ENV['PATH']
223
+ begin
224
+ Cocaine::CommandLine.path = ''
225
+ Paperclip.options[:command_path] = ''
226
+ ENV['PATH'] = ''
227
+ assert_raises(Paperclip::Errors::CommandNotFoundError) do
228
+ silence_stream(STDERR) do
229
+ @thumb.make
230
+ end
231
+ end
232
+ ensure
233
+ ENV['PATH'] = old_path
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ context "being thumbnailed with a blank geometry string" do
240
+ before do
241
+ @thumb = Paperclip::Thumbnail.new(@file,
242
+ geometry: "",
243
+ convert_options: "-gravity center -crop \"300x300+0-0\"")
244
+ end
245
+
246
+ it "does not get resized by default" do
247
+ assert !@thumb.transformation_command.include?("-resize")
248
+ end
249
+ end
250
+
251
+ context "being thumbnailed with default animated option (true)" do
252
+ it "calls identify to check for animated images when sent #make" do
253
+ thumb = Paperclip::Thumbnail.new(@file, geometry: "100x50#")
254
+ thumb.expects(:identify).at_least_once.with do |*arg|
255
+ arg[0] == '-format %m :file' &&
256
+ arg[1][:file] == "#{File.expand_path(thumb.file.path)}[0]"
257
+ end
258
+ thumb.make
259
+ end
260
+ end
261
+
262
+ context "passing a custom file geometry parser" do
263
+ after do
264
+ Object.send(:remove_const, :GeoParser) if Object.const_defined?(:GeoParser)
265
+ end
266
+
267
+ it "produces the appropriate transformation_command" do
268
+ GeoParser = Class.new do
269
+ def self.from_file(file)
270
+ new
271
+ end
272
+
273
+ def transformation_to(target, should_crop)
274
+ ["SCALE", "CROP"]
275
+ end
276
+ end
277
+
278
+ thumb = Paperclip::Thumbnail.new(@file, geometry: '50x50', file_geometry_parser: ::GeoParser)
279
+
280
+ transformation_command = thumb.transformation_command
281
+
282
+ assert transformation_command.include?('-crop'),
283
+ %{expected #{transformation_command.inspect} to include '-crop'}
284
+ assert transformation_command.include?('"CROP"'),
285
+ %{expected #{transformation_command.inspect} to include '"CROP"'}
286
+ assert transformation_command.include?('-resize'),
287
+ %{expected #{transformation_command.inspect} to include '-resize'}
288
+ assert transformation_command.include?('"SCALE"'),
289
+ %{expected #{transformation_command.inspect} to include '"SCALE"'}
290
+ end
291
+ end
292
+
293
+ context "passing a custom geometry string parser" do
294
+ after do
295
+ Object.send(:remove_const, :GeoParser) if Object.const_defined?(:GeoParser)
296
+ end
297
+
298
+ it "produces the appropriate transformation_command" do
299
+ GeoParser = Class.new do
300
+ def self.parse(s)
301
+ new
302
+ end
303
+
304
+ def to_s
305
+ "151x167"
306
+ end
307
+ end
308
+
309
+ thumb = Paperclip::Thumbnail.new(@file, geometry: '50x50', string_geometry_parser: ::GeoParser)
310
+
311
+ transformation_command = thumb.transformation_command
312
+
313
+ assert transformation_command.include?('"151x167"'),
314
+ %{expected #{transformation_command.inspect} to include '151x167'}
315
+ end
316
+ end
317
+ end
318
+
319
+ context "A multipage PDF" do
320
+ before do
321
+ @file = File.new(fixture_file("twopage.pdf"), 'rb')
322
+ end
323
+
324
+ after { @file.close }
325
+
326
+ it "starts with two pages with dimensions 612x792" do
327
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
328
+ assert_equal "612x792"*2, `#{cmd}`.chomp
329
+ end
330
+
331
+ context "being thumbnailed at 100x100 with cropping" do
332
+ before do
333
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "100x100#", format: :png)
334
+ end
335
+
336
+ it "reports its correct current and target geometries" do
337
+ assert_equal "100x100#", @thumb.target_geometry.to_s
338
+ assert_equal "612x792", @thumb.current_geometry.to_s
339
+ end
340
+
341
+ it "reports its correct format" do
342
+ assert_equal :png, @thumb.format
343
+ end
344
+
345
+ it "creates the thumbnail when sent #make" do
346
+ dst = @thumb.make
347
+ assert_match /100x100/, `identify "#{dst.path}"`
348
+ end
349
+ end
350
+ end
351
+
352
+ context "An animated gif" do
353
+ before do
354
+ @file = File.new(fixture_file("animated.gif"), 'rb')
355
+ end
356
+
357
+ after { @file.close }
358
+
359
+ it "starts with 12 frames with size 100x100" do
360
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
361
+ assert_equal "100x100"*12, `#{cmd}`.chomp
362
+ end
363
+
364
+ context "with static output" do
365
+ before do
366
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "50x50", format: :jpg)
367
+ end
368
+
369
+ it "creates the single frame thumbnail when sent #make" do
370
+ dst = @thumb.make
371
+ cmd = %Q[identify -format "%wx%h" "#{dst.path}"]
372
+ assert_equal "50x50", `#{cmd}`.chomp
373
+ end
374
+ end
375
+
376
+ context "with animated output format" do
377
+ before do
378
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "50x50", format: :gif)
379
+ end
380
+
381
+ it "creates the 12 frames thumbnail when sent #make" do
382
+ dst = @thumb.make
383
+ cmd = %Q[identify -format "%wx%h," "#{dst.path}"]
384
+ frames = `#{cmd}`.chomp.split(',')
385
+ assert_equal 12, frames.size
386
+ assert_frame_dimensions (45..50), frames
387
+ end
388
+
389
+ it "uses the -coalesce option" do
390
+ assert_equal @thumb.transformation_command.first, "-coalesce"
391
+ end
392
+
393
+ it "uses the -layers 'optimize' option" do
394
+ assert_equal @thumb.transformation_command.last, '-layers "optimize"'
395
+ end
396
+ end
397
+
398
+ context "with omitted output format" do
399
+ before do
400
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "50x50")
401
+ end
402
+
403
+ it "creates the 12 frames thumbnail when sent #make" do
404
+ dst = @thumb.make
405
+ cmd = %Q[identify -format "%wx%h," "#{dst.path}"]
406
+ frames = `#{cmd}`.chomp.split(',')
407
+ assert_equal 12, frames.size
408
+ assert_frame_dimensions (45..50), frames
409
+ end
410
+
411
+ it "uses the -coalesce option" do
412
+ assert_equal @thumb.transformation_command.first, "-coalesce"
413
+ end
414
+
415
+ it "uses the -layers 'optimize' option" do
416
+ assert_equal @thumb.transformation_command.last, '-layers "optimize"'
417
+ end
418
+ end
419
+
420
+ context "with unidentified source format" do
421
+ before do
422
+ @unidentified_file = File.new(fixture_file("animated.unknown"), 'rb')
423
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "60x60")
424
+ end
425
+
426
+ it "creates the 12 frames thumbnail when sent #make" do
427
+ dst = @thumb.make
428
+ cmd = %Q[identify -format "%wx%h," "#{dst.path}"]
429
+ frames = `#{cmd}`.chomp.split(',')
430
+ assert_equal 12, frames.size
431
+ assert_frame_dimensions (55..60), frames
432
+ end
433
+
434
+ it "uses the -coalesce option" do
435
+ assert_equal @thumb.transformation_command.first, "-coalesce"
436
+ end
437
+
438
+ it "uses the -layers 'optimize' option" do
439
+ assert_equal @thumb.transformation_command.last, '-layers "optimize"'
440
+ end
441
+ end
442
+
443
+ context "with no source format" do
444
+ before do
445
+ @unidentified_file = File.new(fixture_file("animated"), 'rb')
446
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "70x70")
447
+ end
448
+
449
+ it "creates the 12 frames thumbnail when sent #make" do
450
+ dst = @thumb.make
451
+ cmd = %Q[identify -format "%wx%h," "#{dst.path}"]
452
+ frames = `#{cmd}`.chomp.split(',')
453
+ assert_equal 12, frames.size
454
+ assert_frame_dimensions (60..70), frames
455
+ end
456
+
457
+ it "uses the -coalesce option" do
458
+ assert_equal @thumb.transformation_command.first, "-coalesce"
459
+ end
460
+
461
+ it "uses the -layers 'optimize' option" do
462
+ assert_equal @thumb.transformation_command.last, '-layers "optimize"'
463
+ end
464
+ end
465
+
466
+ context "with animated option set to false" do
467
+ before do
468
+ @thumb = Paperclip::Thumbnail.new(@file, geometry: "50x50", animated: false)
469
+ end
470
+
471
+ it "outputs the gif format" do
472
+ dst = @thumb.make
473
+ cmd = %Q[identify "#{dst.path}"]
474
+ assert_match /GIF/, `#{cmd}`.chomp
475
+ end
476
+
477
+ it "creates the single frame thumbnail when sent #make" do
478
+ dst = @thumb.make
479
+ cmd = %Q[identify -format "%wx%h" "#{dst.path}"]
480
+ assert_equal "50x50", `#{cmd}`.chomp
481
+ end
482
+ end
483
+ end
484
+
485
+ context "with a really long file name" do
486
+ before do
487
+ tempfile = Tempfile.new("f")
488
+ tempfile_additional_chars = tempfile.path.split("/")[-1].length + 15
489
+ image_file = File.new(fixture_file("5k.png"), "rb")
490
+ @file = Tempfile.new("f" * (255 - tempfile_additional_chars))
491
+ @file.write(image_file.read)
492
+ @file.rewind
493
+ end
494
+
495
+ it "does not throw Errno::ENAMETOOLONG" do
496
+ thumb = Paperclip::Thumbnail.new(@file, geometry: "50x50", format: :gif)
497
+ expect { thumb.make }.to_not raise_error
498
+ end
499
+ end
500
+ end