paperclip_jk 5.0.0.beta2

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 (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