paperclip 3.5.4 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +17 -0
  3. data/.github/issue_template.md +3 -0
  4. data/.gitignore +0 -6
  5. data/.hound.yml +1055 -0
  6. data/.rubocop.yml +1 -0
  7. data/.travis.yml +17 -20
  8. data/Appraisals +4 -16
  9. data/CONTRIBUTING.md +29 -13
  10. data/Gemfile +11 -3
  11. data/LICENSE +1 -3
  12. data/MIGRATING-ES.md +317 -0
  13. data/MIGRATING.md +375 -0
  14. data/NEWS +262 -49
  15. data/README.md +496 -169
  16. data/RELEASING.md +17 -0
  17. data/Rakefile +6 -8
  18. data/UPGRADING +12 -9
  19. data/features/basic_integration.feature +27 -8
  20. data/features/migration.feature +0 -24
  21. data/features/step_definitions/attachment_steps.rb +44 -36
  22. data/features/step_definitions/html_steps.rb +2 -2
  23. data/features/step_definitions/rails_steps.rb +68 -37
  24. data/features/step_definitions/s3_steps.rb +2 -2
  25. data/features/step_definitions/web_steps.rb +1 -103
  26. data/features/support/env.rb +3 -2
  27. data/features/support/file_helpers.rb +2 -2
  28. data/features/support/fixtures/gemfile.txt +1 -1
  29. data/features/support/paths.rb +1 -1
  30. data/features/support/rails.rb +2 -25
  31. data/gemfiles/4.2.gemfile +17 -0
  32. data/gemfiles/5.0.gemfile +17 -0
  33. data/lib/generators/paperclip/paperclip_generator.rb +9 -3
  34. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +2 -2
  35. data/lib/paperclip/attachment.rb +170 -52
  36. data/lib/paperclip/attachment_registry.rb +3 -2
  37. data/lib/paperclip/callbacks.rb +13 -1
  38. data/lib/paperclip/content_type_detector.rb +26 -22
  39. data/lib/paperclip/errors.rb +8 -1
  40. data/lib/paperclip/file_command_content_type_detector.rb +6 -8
  41. data/lib/paperclip/filename_cleaner.rb +0 -1
  42. data/lib/paperclip/geometry_detector_factory.rb +6 -4
  43. data/lib/paperclip/geometry_parser_factory.rb +1 -1
  44. data/lib/paperclip/glue.rb +1 -1
  45. data/lib/paperclip/has_attached_file.rb +17 -1
  46. data/lib/paperclip/helpers.rb +15 -11
  47. data/lib/paperclip/interpolations/plural_cache.rb +6 -5
  48. data/lib/paperclip/interpolations.rb +31 -13
  49. data/lib/paperclip/io_adapters/abstract_adapter.rb +34 -5
  50. data/lib/paperclip/io_adapters/attachment_adapter.rb +19 -8
  51. data/lib/paperclip/io_adapters/data_uri_adapter.rb +11 -16
  52. data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
  53. data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
  54. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +8 -7
  55. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
  56. data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
  57. data/lib/paperclip/io_adapters/registry.rb +6 -2
  58. data/lib/paperclip/io_adapters/stringio_adapter.rb +15 -16
  59. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
  60. data/lib/paperclip/io_adapters/uri_adapter.rb +43 -19
  61. data/lib/paperclip/locales/en.yml +1 -0
  62. data/lib/paperclip/logger.rb +1 -1
  63. data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -1
  64. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
  65. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -1
  66. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -1
  67. data/lib/paperclip/media_type_spoof_detector.rb +93 -0
  68. data/lib/paperclip/processor.rb +15 -43
  69. data/lib/paperclip/processor_helpers.rb +50 -0
  70. data/lib/paperclip/rails_environment.rb +25 -0
  71. data/lib/paperclip/schema.rb +10 -8
  72. data/lib/paperclip/storage/filesystem.rb +14 -3
  73. data/lib/paperclip/storage/fog.rb +38 -20
  74. data/lib/paperclip/storage/s3.rb +124 -73
  75. data/lib/paperclip/style.rb +8 -3
  76. data/lib/paperclip/tempfile_factory.rb +5 -1
  77. data/lib/paperclip/thumbnail.rb +34 -19
  78. data/lib/paperclip/url_generator.rb +26 -14
  79. data/lib/paperclip/validators/attachment_content_type_validator.rb +4 -0
  80. data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
  81. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
  82. data/lib/paperclip/validators/attachment_presence_validator.rb +4 -0
  83. data/lib/paperclip/validators/attachment_size_validator.rb +5 -3
  84. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +31 -0
  85. data/lib/paperclip/validators.rb +11 -4
  86. data/lib/paperclip/version.rb +3 -1
  87. data/lib/paperclip.rb +31 -11
  88. data/lib/tasks/paperclip.rake +34 -5
  89. data/paperclip.gemspec +21 -16
  90. data/shoulda_macros/paperclip.rb +0 -1
  91. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  92. data/{test/attachment_processing_test.rb → spec/paperclip/attachment_processing_spec.rb} +17 -21
  93. data/spec/paperclip/attachment_registry_spec.rb +158 -0
  94. data/{test/attachment_test.rb → spec/paperclip/attachment_spec.rb} +519 -409
  95. data/{test/content_type_detector_test.rb → spec/paperclip/content_type_detector_spec.rb} +17 -20
  96. data/spec/paperclip/file_command_content_type_detector_spec.rb +40 -0
  97. data/spec/paperclip/filename_cleaner_spec.rb +13 -0
  98. data/spec/paperclip/geometry_detector_spec.rb +39 -0
  99. data/{test/geometry_parser_test.rb → spec/paperclip/geometry_parser_spec.rb} +27 -27
  100. data/{test/geometry_test.rb → spec/paperclip/geometry_spec.rb} +50 -52
  101. data/spec/paperclip/glue_spec.rb +44 -0
  102. data/spec/paperclip/has_attached_file_spec.rb +158 -0
  103. data/{test/integration_test.rb → spec/paperclip/integration_spec.rb} +174 -129
  104. data/{test/interpolations_test.rb → spec/paperclip/interpolations_spec.rb} +79 -46
  105. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +160 -0
  106. data/{test/io_adapters/attachment_adapter_test.rb → spec/paperclip/io_adapters/attachment_adapter_spec.rb} +33 -32
  107. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +89 -0
  108. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  109. data/{test/io_adapters/file_adapter_test.rb → spec/paperclip/io_adapters/file_adapter_spec.rb} +38 -42
  110. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +138 -0
  111. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  112. data/{test/io_adapters/nil_adapter_test.rb → spec/paperclip/io_adapters/nil_adapter_spec.rb} +7 -7
  113. data/{test/io_adapters/registry_test.rb → spec/paperclip/io_adapters/registry_spec.rb} +12 -9
  114. data/{test/io_adapters/stringio_adapter_test.rb → spec/paperclip/io_adapters/stringio_adapter_spec.rb} +21 -18
  115. data/{test/io_adapters/uploaded_file_adapter_test.rb → spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb} +46 -46
  116. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +220 -0
  117. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  118. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +109 -0
  119. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  120. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  121. data/spec/paperclip/media_type_spoof_detector_spec.rb +120 -0
  122. data/spec/paperclip/meta_class_spec.rb +30 -0
  123. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
  124. data/spec/paperclip/paperclip_spec.rb +192 -0
  125. data/spec/paperclip/plural_cache_spec.rb +37 -0
  126. data/spec/paperclip/processor_helpers_spec.rb +57 -0
  127. data/{test/processor_test.rb → spec/paperclip/processor_spec.rb} +7 -7
  128. data/spec/paperclip/rails_environment_spec.rb +33 -0
  129. data/{test/rake_test.rb → spec/paperclip/rake_spec.rb} +15 -15
  130. data/spec/paperclip/schema_spec.rb +248 -0
  131. data/{test/storage/filesystem_test.rb → spec/paperclip/storage/filesystem_spec.rb} +18 -18
  132. data/spec/paperclip/storage/fog_spec.rb +566 -0
  133. data/spec/paperclip/storage/s3_live_spec.rb +188 -0
  134. data/spec/paperclip/storage/s3_spec.rb +1693 -0
  135. data/spec/paperclip/style_spec.rb +254 -0
  136. data/spec/paperclip/tempfile_factory_spec.rb +33 -0
  137. data/spec/paperclip/tempfile_spec.rb +35 -0
  138. data/{test/thumbnail_test.rb → spec/paperclip/thumbnail_spec.rb} +158 -137
  139. data/spec/paperclip/url_generator_spec.rb +221 -0
  140. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
  141. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
  142. data/{test/validators/attachment_presence_validator_test.rb → spec/paperclip/validators/attachment_presence_validator_spec.rb} +20 -20
  143. data/{test/validators/attachment_size_validator_test.rb → spec/paperclip/validators/attachment_size_validator_spec.rb} +77 -64
  144. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
  145. data/spec/paperclip/validators_spec.rb +164 -0
  146. data/spec/spec_helper.rb +46 -0
  147. data/spec/support/assertions.rb +82 -0
  148. data/spec/support/fake_model.rb +25 -0
  149. data/spec/support/fake_rails.rb +12 -0
  150. data/spec/support/fixtures/empty.html +1 -0
  151. data/spec/support/fixtures/empty.xlsx +0 -0
  152. data/spec/support/fixtures/spaced file.jpg +0 -0
  153. data/spec/support/matchers/accept.rb +5 -0
  154. data/spec/support/matchers/exist.rb +5 -0
  155. data/spec/support/matchers/have_column.rb +23 -0
  156. data/{test → spec}/support/mock_attachment.rb +2 -0
  157. data/{test → spec}/support/mock_url_generator_builder.rb +2 -2
  158. data/spec/support/model_reconstruction.rb +68 -0
  159. data/spec/support/reporting.rb +11 -0
  160. data/spec/support/test_data.rb +13 -0
  161. data/spec/support/version_helper.rb +9 -0
  162. metadata +344 -226
  163. data/RUNNING_TESTS.md +0 -4
  164. data/cucumber/paperclip_steps.rb +0 -6
  165. data/gemfiles/3.0.gemfile +0 -11
  166. data/gemfiles/3.1.gemfile +0 -11
  167. data/gemfiles/3.2.gemfile +0 -11
  168. data/gemfiles/4.0.gemfile +0 -11
  169. data/test/attachment_definitions_test.rb +0 -12
  170. data/test/attachment_registry_test.rb +0 -88
  171. data/test/file_command_content_type_detector_test.rb +0 -27
  172. data/test/filename_cleaner_test.rb +0 -14
  173. data/test/generator_test.rb +0 -84
  174. data/test/geometry_detector_test.rb +0 -24
  175. data/test/has_attached_file_test.rb +0 -125
  176. data/test/helper.rb +0 -232
  177. data/test/io_adapters/abstract_adapter_test.rb +0 -58
  178. data/test/io_adapters/data_uri_adapter_test.rb +0 -74
  179. data/test/io_adapters/empty_string_adapter_test.rb +0 -18
  180. data/test/io_adapters/http_url_proxy_adapter_test.rb +0 -102
  181. data/test/io_adapters/identity_adapter_test.rb +0 -8
  182. data/test/io_adapters/uri_adapter_test.rb +0 -102
  183. data/test/matchers/have_attached_file_matcher_test.rb +0 -24
  184. data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -110
  185. data/test/matchers/validate_attachment_presence_matcher_test.rb +0 -69
  186. data/test/matchers/validate_attachment_size_matcher_test.rb +0 -86
  187. data/test/meta_class_test.rb +0 -32
  188. data/test/paperclip_missing_attachment_styles_test.rb +0 -90
  189. data/test/paperclip_test.rb +0 -217
  190. data/test/plural_cache_test.rb +0 -36
  191. data/test/schema_test.rb +0 -200
  192. data/test/storage/fog_test.rb +0 -473
  193. data/test/storage/s3_live_test.rb +0 -179
  194. data/test/storage/s3_test.rb +0 -1356
  195. data/test/style_test.rb +0 -213
  196. data/test/support/mock_model.rb +0 -2
  197. data/test/tempfile_factory_test.rb +0 -17
  198. data/test/url_generator_test.rb +0 -187
  199. data/test/validators/attachment_content_type_validator_test.rb +0 -324
  200. data/test/validators_test.rb +0 -61
  201. /data/{test → spec}/database.yml +0 -0
  202. /data/{test → spec/support}/fixtures/12k.png +0 -0
  203. /data/{test → spec/support}/fixtures/50x50.png +0 -0
  204. /data/{test → spec/support}/fixtures/5k.png +0 -0
  205. /data/{test → spec/support}/fixtures/animated +0 -0
  206. /data/{test → spec/support}/fixtures/animated.gif +0 -0
  207. /data/{test → spec/support}/fixtures/animated.unknown +0 -0
  208. /data/{test → spec/support}/fixtures/bad.png +0 -0
  209. /data/{test → spec/support}/fixtures/fog.yml +0 -0
  210. /data/{test → spec/support}/fixtures/rotated.jpg +0 -0
  211. /data/{test → spec/support}/fixtures/s3.yml +0 -0
  212. /data/{test → spec/support}/fixtures/spaced file.png +0 -0
  213. /data/{test → spec/support}/fixtures/text.txt +0 -0
  214. /data/{test → spec/support}/fixtures/twopage.pdf +0 -0
  215. /data/{test → spec/support}/fixtures/uppercase.PNG +0 -0
  216. /data/{test → spec}/support/mock_interpolator.rb +0 -0
@@ -1,21 +1,38 @@
1
- # encoding: utf-8
2
-
3
- require './test/helper'
1
+ require 'spec_helper'
4
2
  require 'open-uri'
5
3
 
6
- class IntegrationTest < Test::Unit::TestCase
4
+ describe 'Paperclip' do
5
+ around do |example|
6
+ files_before = ObjectSpace.each_object(Tempfile).select do |file|
7
+ file.path && File.file?(file.path)
8
+ end
9
+
10
+ example.run
11
+
12
+ files_after = ObjectSpace.each_object(Tempfile).select do |file|
13
+ file.path && File.file?(file.path)
14
+ end
15
+
16
+ diff = files_after - files_before
17
+ expect(diff).to eq([]), "Leaked tempfiles: #{diff.inspect}"
18
+ end
19
+
7
20
  context "Many models at once" do
8
- setup do
21
+ before do
9
22
  rebuild_model
10
- @file = File.new(fixture_file("5k.png"), 'rb')
11
- 300.times do |i|
12
- Dummy.create! :avatar => @file
13
- end
23
+ @file = File.new(fixture_file("5k.png"), 'rb')
24
+ # Deals with `Too many open files` error
25
+ dummies = Array.new(300) { Dummy.new avatar: @file }
26
+ Dummy.import dummies
27
+ # save attachment instances to run after hooks including tempfile cleanup
28
+ # since activerecord-import does not use our usually hooked-in hooks
29
+ # (such as after_save)
30
+ dummies.each { |dummy| dummy.avatar.save }
14
31
  end
15
32
 
16
- teardown { @file.close }
33
+ after { @file.close }
17
34
 
18
- should "not exceed the open file limit" do
35
+ it "does not exceed the open file limit" do
19
36
  assert_nothing_raised do
20
37
  Dummy.all.each { |dummy| dummy.avatar }
21
38
  end
@@ -23,24 +40,24 @@ class IntegrationTest < Test::Unit::TestCase
23
40
  end
24
41
 
25
42
  context "An attachment" do
26
- setup do
27
- rebuild_model :styles => { :thumb => "50x50#" }
43
+ before do
44
+ rebuild_model styles: { thumb: "50x50#" }
28
45
  @dummy = Dummy.new
29
46
  @file = File.new(fixture_file("5k.png"), 'rb')
30
47
  @dummy.avatar = @file
31
48
  assert @dummy.save
32
49
  end
33
50
 
34
- teardown { @file.close }
51
+ after { @file.close }
35
52
 
36
- should "create its thumbnails properly" do
53
+ it "creates its thumbnails properly" do
37
54
  assert_match(/\b50x50\b/, `identify "#{@dummy.avatar.path(:thumb)}"`)
38
55
  end
39
56
 
40
57
  context 'reprocessing with unreadable original' do
41
- setup { File.chmod(0000, @dummy.avatar.path) }
58
+ before { File.chmod(0000, @dummy.avatar.path) }
42
59
 
43
- should "not raise an error" do
60
+ it "does not raise an error" do
44
61
  assert_nothing_raised do
45
62
  silence_stream(STDERR) do
46
63
  @dummy.avatar.reprocess!
@@ -48,19 +65,19 @@ class IntegrationTest < Test::Unit::TestCase
48
65
  end
49
66
  end
50
67
 
51
- should "return false" do
68
+ it "returns false" do
52
69
  silence_stream(STDERR) do
53
70
  assert !@dummy.avatar.reprocess!
54
71
  end
55
72
  end
56
73
 
57
- teardown { File.chmod(0644, @dummy.avatar.path) }
74
+ after { File.chmod(0644, @dummy.avatar.path) }
58
75
  end
59
76
 
60
77
  context "redefining its attachment styles" do
61
- setup do
78
+ before do
62
79
  Dummy.class_eval do
63
- has_attached_file :avatar, :styles => { :thumb => "150x25#", :dynamic => lambda { |a| '50x50#' } }
80
+ has_attached_file :avatar, styles: { thumb: "150x25#", dynamic: lambda { |a| '50x50#' } }
64
81
  end
65
82
  @d2 = Dummy.find(@dummy.id)
66
83
  @original_timestamp = @d2.avatar_updated_at
@@ -68,37 +85,37 @@ class IntegrationTest < Test::Unit::TestCase
68
85
  @d2.save
69
86
  end
70
87
 
71
- should "create its thumbnails properly" do
88
+ it "creates its thumbnails properly" do
72
89
  assert_match(/\b150x25\b/, `identify "#{@dummy.avatar.path(:thumb)}"`)
73
90
  assert_match(/\b50x50\b/, `identify "#{@dummy.avatar.path(:dynamic)}"`)
74
91
  end
75
92
 
76
- should "change the timestamp" do
93
+ it "changes the timestamp" do
77
94
  assert_not_equal @original_timestamp, @d2.avatar_updated_at
78
95
  end
79
96
  end
80
97
  end
81
98
 
82
99
  context "Attachment" do
83
- setup do
100
+ before do
84
101
  @thumb_path = "tmp/public/system/dummies/avatars/000/000/001/thumb/5k.png"
85
- File.delete(@thumb_path) if File.exists?(@thumb_path)
86
- rebuild_model :styles => { :thumb => "50x50#" }
102
+ File.delete(@thumb_path) if File.exist?(@thumb_path)
103
+ rebuild_model styles: { thumb: "50x50#" }
87
104
  @dummy = Dummy.new
88
105
  @file = File.new(fixture_file("5k.png"), 'rb')
89
106
 
90
107
  end
91
108
 
92
- teardown { @file.close }
109
+ after { @file.close }
93
110
 
94
- should "not create the thumbnails upon saving when post-processing is disabled" do
111
+ it "does not create the thumbnails upon saving when post-processing is disabled" do
95
112
  @dummy.avatar.post_processing = false
96
113
  @dummy.avatar = @file
97
114
  assert @dummy.save
98
115
  assert_file_not_exists @thumb_path
99
116
  end
100
117
 
101
- should "create the thumbnails upon saving when post_processing is enabled" do
118
+ it "creates the thumbnails upon saving when post_processing is enabled" do
102
119
  @dummy.avatar.post_processing = true
103
120
  @dummy.avatar = @file
104
121
  assert @dummy.save
@@ -107,12 +124,12 @@ class IntegrationTest < Test::Unit::TestCase
107
124
  end
108
125
 
109
126
  context "Attachment with no generated thumbnails" do
110
- setup do
127
+ before do
111
128
  @thumb_small_path = "tmp/public/system/dummies/avatars/000/000/001/thumb_small/5k.png"
112
129
  @thumb_large_path = "tmp/public/system/dummies/avatars/000/000/001/thumb_large/5k.png"
113
- File.delete(@thumb_small_path) if File.exists?(@thumb_small_path)
114
- File.delete(@thumb_large_path) if File.exists?(@thumb_large_path)
115
- rebuild_model :styles => { :thumb_small => "50x50#", :thumb_large => "60x60#" }
130
+ File.delete(@thumb_small_path) if File.exist?(@thumb_small_path)
131
+ File.delete(@thumb_large_path) if File.exist?(@thumb_large_path)
132
+ rebuild_model styles: { thumb_small: "50x50#", thumb_large: "60x60#" }
116
133
  @dummy = Dummy.new
117
134
  @file = File.new(fixture_file("5k.png"), 'rb')
118
135
 
@@ -122,9 +139,9 @@ class IntegrationTest < Test::Unit::TestCase
122
139
  @dummy.avatar.post_processing = true
123
140
  end
124
141
 
125
- teardown { @file.close }
142
+ after { @file.close }
126
143
 
127
- should "allow us to create all thumbnails in one go" do
144
+ it "allows us to create all thumbnails in one go" do
128
145
  assert_file_not_exists(@thumb_small_path)
129
146
  assert_file_not_exists(@thumb_large_path)
130
147
 
@@ -134,7 +151,15 @@ class IntegrationTest < Test::Unit::TestCase
134
151
  assert_file_exists(@thumb_large_path)
135
152
  end
136
153
 
137
- should "allow us to selectively create each thumbnail" do
154
+ it "allows us to selectively create each thumbnail" do
155
+ skip <<-EXPLANATION
156
+ #reprocess! calls #assign which calls Paperclip.io_adapters.for
157
+ which creates the tempfile. #assign then calls #post_process_file which
158
+ calls MediaTypeSpoofDetectionValidator#validate_each which calls
159
+ Paperclip.io_adapters.for, which creates another tempfile. That first
160
+ tempfile is the one that leaks.
161
+ EXPLANATION
162
+
138
163
  assert_file_not_exists(@thumb_small_path)
139
164
  assert_file_not_exists(@thumb_large_path)
140
165
 
@@ -148,59 +173,69 @@ class IntegrationTest < Test::Unit::TestCase
148
173
  end
149
174
 
150
175
  context "A model that modifies its original" do
151
- setup do
152
- rebuild_model :styles => { :original => "2x2#" }
176
+ before do
177
+ rebuild_model styles: { original: "2x2#" }
153
178
  @dummy = Dummy.new
154
179
  @file = File.new(fixture_file("5k.png"), 'rb')
155
180
  @dummy.avatar = @file
156
181
  end
157
182
 
158
- should "report the file size of the processed file and not the original" do
183
+ it "reports the file size of the processed file and not the original" do
159
184
  assert_not_equal File.size(@file.path), @dummy.avatar.size
160
185
  end
161
186
 
162
- teardown { @file.close }
187
+ after do
188
+ @file.close
189
+ # save attachment instance to run after hooks (including tempfile cleanup)
190
+ @dummy.avatar.save
191
+ end
163
192
  end
164
193
 
165
194
  context "A model with attachments scoped under an id" do
166
- setup do
167
- rebuild_model :styles => { :large => "100x100",
168
- :medium => "50x50" },
169
- :path => ":rails_root/tmp/:id/:attachments/:style.:extension"
195
+ before do
196
+ rebuild_model styles: { large: "100x100",
197
+ medium: "50x50" },
198
+ path: ":rails_root/tmp/:id/:attachments/:style.:extension"
170
199
  @dummy = Dummy.new
171
200
  @file = File.new(fixture_file("5k.png"), 'rb')
172
201
  @dummy.avatar = @file
173
202
  end
174
203
 
175
- teardown { @file.close }
204
+ after { @file.close }
176
205
 
177
206
  context "when saved" do
178
- setup do
207
+ before do
179
208
  @dummy.save
180
209
  @saved_path = @dummy.avatar.path(:large)
181
210
  end
182
211
 
183
- should "have a large file in the right place" do
212
+ it "has a large file in the right place" do
184
213
  assert_file_exists(@dummy.avatar.path(:large))
185
214
  end
186
215
 
187
216
  context "and deleted" do
188
- setup do
217
+ before do
189
218
  @dummy.avatar.clear
190
219
  @dummy.save
191
220
  end
192
221
 
193
- should "not have a large file in the right place anymore" do
222
+ it "does not have a large file in the right place anymore" do
194
223
  assert_file_not_exists(@saved_path)
195
224
  end
196
225
 
197
- should "not have its next two parent directories" do
226
+ it "does not have its next two parent directories" do
198
227
  assert_file_not_exists(File.dirname(@saved_path))
199
228
  assert_file_not_exists(File.dirname(File.dirname(@saved_path)))
200
229
  end
230
+ end
201
231
 
202
- before_should "not die if an unexpected SystemCallError happens" do
232
+ context 'and deleted where the delete fails' do
233
+ it "does not die if an unexpected SystemCallError happens" do
203
234
  FileUtils.stubs(:rmdir).raises(Errno::EPIPE)
235
+ assert_nothing_raised do
236
+ @dummy.avatar.clear
237
+ @dummy.save
238
+ end
204
239
  end
205
240
  end
206
241
  end
@@ -208,19 +243,19 @@ class IntegrationTest < Test::Unit::TestCase
208
243
 
209
244
  [000,002,022].each do |umask|
210
245
  context "when the umask is #{umask}" do
211
- setup do
246
+ before do
212
247
  rebuild_model
213
248
  @dummy = Dummy.new
214
249
  @file = File.new(fixture_file("5k.png"), 'rb')
215
250
  @umask = File.umask(umask)
216
251
  end
217
252
 
218
- teardown do
253
+ after do
219
254
  File.umask @umask
220
255
  @file.close
221
256
  end
222
257
 
223
- should "respect the current umask" do
258
+ it "respects the current umask" do
224
259
  @dummy.avatar = @file
225
260
  @dummy.save
226
261
  assert_equal 0666&~umask, 0666&File.stat(@dummy.avatar.path).mode
@@ -230,17 +265,17 @@ class IntegrationTest < Test::Unit::TestCase
230
265
 
231
266
  [0666,0664,0640].each do |perms|
232
267
  context "when the perms are #{perms}" do
233
- setup do
234
- rebuild_model :override_file_permissions => perms
268
+ before do
269
+ rebuild_model override_file_permissions: perms
235
270
  @dummy = Dummy.new
236
271
  @file = File.new(fixture_file("5k.png"), 'rb')
237
272
  end
238
273
 
239
- teardown do
274
+ after do
240
275
  @file.close
241
276
  end
242
277
 
243
- should "respect the current perms" do
278
+ it "respects the current perms" do
244
279
  @dummy.avatar = @file
245
280
  @dummy.save
246
281
  assert_equal perms, File.stat(@dummy.avatar.path).mode & 0777
@@ -248,23 +283,23 @@ class IntegrationTest < Test::Unit::TestCase
248
283
  end
249
284
  end
250
285
 
251
- should "skip chmod operation, when override_file_permissions is set to false (e.g. useful when using CIFS mounts)" do
286
+ it "skips chmod operation, when override_file_permissions is set to false (e.g. useful when using CIFS mounts)" do
252
287
  FileUtils.expects(:chmod).never
253
288
 
254
- rebuild_model :override_file_permissions => false
289
+ rebuild_model override_file_permissions: false
255
290
  dummy = Dummy.create!
256
291
  dummy.avatar = @file
257
292
  dummy.save
258
293
  end
259
294
 
260
295
  context "A model with a filesystem attachment" do
261
- setup do
262
- rebuild_model :styles => { :large => "300x300>",
263
- :medium => "100x100",
264
- :thumb => ["32x32#", :gif] },
265
- :default_style => :medium,
266
- :url => "/:attachment/:class/:style/:id/:basename.:extension",
267
- :path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
296
+ before do
297
+ rebuild_model styles: { large: "300x300>",
298
+ medium: "100x100",
299
+ thumb: ["32x32#", :gif] },
300
+ default_style: :medium,
301
+ url: "/:attachment/:class/:style/:id/:basename.:extension",
302
+ path: ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
268
303
  @dummy = Dummy.new
269
304
  @file = File.new(fixture_file("5k.png"), 'rb')
270
305
  @bad_file = File.new(fixture_file("bad.png"), 'rb')
@@ -274,9 +309,9 @@ class IntegrationTest < Test::Unit::TestCase
274
309
  assert @dummy.save
275
310
  end
276
311
 
277
- teardown { [@file, @bad_file].each(&:close) }
312
+ after { [@file, @bad_file].each(&:close) }
278
313
 
279
- should "write and delete its files" do
314
+ it "writes and delete its files" do
280
315
  [["434x66", :original],
281
316
  ["300x46", :large],
282
317
  ["100x15", :medium],
@@ -314,7 +349,7 @@ class IntegrationTest < Test::Unit::TestCase
314
349
  assert_nil @d2.avatar_file_name
315
350
  end
316
351
 
317
- should "work exactly the same when new as when reloaded" do
352
+ it "works exactly the same when new as when reloaded" do
318
353
  @d2 = Dummy.find(@dummy.id)
319
354
 
320
355
  assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
@@ -332,27 +367,34 @@ class IntegrationTest < Test::Unit::TestCase
332
367
  end
333
368
  end
334
369
 
335
- should "not abide things that don't have adapters" do
370
+ it "does not abide things that don't have adapters" do
336
371
  assert_raises(Paperclip::AdapterRegistry::NoHandlerError) do
337
372
  @dummy.avatar = "not a file"
338
373
  end
339
374
  end
340
375
 
341
- should "not be ok with bad files" do
376
+ it "is not ok with bad files" do
342
377
  @dummy.avatar = @bad_file
343
378
  assert ! @dummy.valid?
379
+ # save attachment instance to run after hooks (including tempfile cleanup)
380
+ @dummy.avatar.save
344
381
  end
345
382
 
346
- should "know the difference between good files, bad files, and not files when validating" do
383
+ it "knows the difference between good files, bad files, and not files when validating" do
347
384
  Dummy.validates_attachment_presence :avatar
348
385
  @d2 = Dummy.find(@dummy.id)
349
386
  @d2.avatar = @file
350
387
  assert @d2.valid?, @d2.errors.full_messages.inspect
388
+ # save attachment instance to run after hooks (including tempfile cleanup)
389
+ @d2.avatar.save
390
+
351
391
  @d2.avatar = @bad_file
352
392
  assert ! @d2.valid?
393
+ # save attachment instance to run after hooks (including tempfile cleanup)
394
+ @d2.avatar.save
353
395
  end
354
396
 
355
- should "be able to reload without saving and not have the file disappear" do
397
+ it "is able to reload without saving and not have the file disappear" do
356
398
  @dummy.avatar = @file
357
399
  assert @dummy.save, @dummy.errors.full_messages.inspect
358
400
  @dummy.avatar.clear
@@ -362,33 +404,33 @@ class IntegrationTest < Test::Unit::TestCase
362
404
  end
363
405
 
364
406
  context "that is assigned its file from another Paperclip attachment" do
365
- setup do
407
+ before do
366
408
  @dummy2 = Dummy.new
367
- @file2 = File.new(fixture_file("12k.png"), 'rb')
368
- assert @dummy2.avatar = @file2
409
+ @file2 = File.new(fixture_file("12k.png"), 'rb')
410
+ assert @dummy2.avatar = @file2
369
411
  @dummy2.save
370
412
  end
371
413
 
372
- teardown { @file2.close }
414
+ after { @file2.close }
373
415
 
374
- should "work when assigned a file" do
416
+ it "works when assigned a file" do
375
417
  assert_not_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
376
- `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
418
+ `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
377
419
 
378
420
  assert @dummy.avatar = @dummy2.avatar
379
421
  @dummy.save
380
422
  assert_equal @dummy.avatar_file_name, @dummy2.avatar_file_name
381
423
  assert_equal `identify -format "%wx%h" "#{@dummy.avatar.path(:original)}"`,
382
- `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
424
+ `identify -format "%wx%h" "#{@dummy2.avatar.path(:original)}"`
383
425
  end
384
426
  end
385
427
 
386
428
  end
387
429
 
388
430
  context "A model with an attachments association and a Paperclip attachment" do
389
- setup do
431
+ before do
390
432
  Dummy.class_eval do
391
- has_many :attachments, :class_name => 'Dummy'
433
+ has_many :attachments, class_name: 'Dummy'
392
434
  end
393
435
 
394
436
  @file = File.new(fixture_file("5k.png"), 'rb')
@@ -396,45 +438,45 @@ class IntegrationTest < Test::Unit::TestCase
396
438
  @dummy.avatar = @file
397
439
  end
398
440
 
399
- teardown { @file.close }
441
+ after { @file.close }
400
442
 
401
- should "should not error when saving" do
443
+ it "does not error when saving" do
402
444
  @dummy.save!
403
445
  end
404
446
  end
405
447
 
406
448
  context "A model with an attachment with hash in file name" do
407
- setup do
408
- @settings = { :styles => { :thumb => "50x50#" },
409
- :path => ":rails_root/public/system/:attachment/:id_partition/:style/:hash.:extension",
410
- :url => "/system/:attachment/:id_partition/:style/:hash.:extension",
411
- :hash_secret => "somesecret" }
449
+ before do
450
+ @settings = { styles: { thumb: "50x50#" },
451
+ path: ":rails_root/public/system/:attachment/:id_partition/:style/:hash.:extension",
452
+ url: "/system/:attachment/:id_partition/:style/:hash.:extension",
453
+ hash_secret: "somesecret" }
412
454
 
413
455
  rebuild_model @settings
414
456
 
415
457
  @file = File.new(fixture_file("5k.png"), 'rb')
416
- @dummy = Dummy.create! :avatar => @file
458
+ @dummy = Dummy.create! avatar: @file
417
459
  end
418
460
 
419
- teardown do
461
+ after do
420
462
  @file.close
421
463
  end
422
464
 
423
- should "be accessible" do
465
+ it "is accessible" do
424
466
  assert_file_exists(@dummy.avatar.path(:original))
425
467
  assert_file_exists(@dummy.avatar.path(:thumb))
426
468
  end
427
469
 
428
470
  context "when new style is added" do
429
- setup do
471
+ before do
430
472
  @dummy.avatar.options[:styles][:mini] = "25x25#"
431
473
  @dummy.avatar.instance_variable_set :@normalized_styles, nil
432
- Time.stubs(:now => Time.now + 10)
474
+ Time.stubs(now: Time.now + 10)
433
475
  @dummy.avatar.reprocess!
434
476
  @dummy.reload
435
477
  end
436
478
 
437
- should "make all the styles accessible" do
479
+ it "makes all the styles accessible" do
438
480
  assert_file_exists(@dummy.avatar.path(:original))
439
481
  assert_file_exists(@dummy.avatar.path(:thumb))
440
482
  assert_file_exists(@dummy.avatar.path(:mini))
@@ -464,22 +506,25 @@ class IntegrationTest < Test::Unit::TestCase
464
506
  end
465
507
 
466
508
  context "A model with an S3 attachment" do
467
- setup do
468
- rebuild_model :styles => { :large => "300x300>",
469
- :medium => "100x100",
470
- :thumb => ["32x32#", :gif],
471
- :custom => {
472
- :geometry => "32x32#",
473
- :s3_headers => { 'Cache-Control' => 'max-age=31557600' },
474
- :s3_metadata => { 'foo' => 'bar'}
475
- }
476
- },
477
- :storage => :s3,
478
- :s3_credentials => File.new(fixture_file('s3.yml')),
479
- :s3_options => { :logger => Paperclip.logger },
480
- :default_style => :medium,
481
- :bucket => ENV['S3_BUCKET'],
482
- :path => ":class/:attachment/:id/:style/:basename.:extension"
509
+ before do
510
+ rebuild_model(
511
+ styles: {
512
+ large: "300x300>",
513
+ medium: "100x100",
514
+ thumb: ["32x32#", :gif],
515
+ custom: {
516
+ geometry: "32x32#",
517
+ s3_headers: { 'Cache-Control' => 'max-age=31557600' },
518
+ s3_metadata: { 'foo' => 'bar'}
519
+ }
520
+ },
521
+ storage: :s3,
522
+ s3_credentials: File.new(fixture_file('s3.yml')),
523
+ s3_options: { logger: Paperclip.logger },
524
+ default_style: :medium,
525
+ bucket: ENV['S3_BUCKET'],
526
+ path: ":class/:attachment/:id/:style/:basename.:extension"
527
+ )
483
528
 
484
529
  @dummy = Dummy.new
485
530
  @file = File.new(fixture_file('5k.png'), 'rb')
@@ -492,29 +537,29 @@ class IntegrationTest < Test::Unit::TestCase
492
537
  @files_on_s3 = s3_files_for(@dummy.avatar)
493
538
  end
494
539
 
495
- teardown do
540
+ after do
496
541
  @file.close
497
542
  @bad_file.close
498
543
  @files_on_s3.values.each(&:close) if @files_on_s3
499
544
  end
500
545
 
501
546
  context 'assigning itself to a new model' do
502
- setup do
547
+ before do
503
548
  @d2 = Dummy.new
504
549
  @d2.avatar = @dummy.avatar
505
550
  @d2.save
506
551
  end
507
552
 
508
- should "have the same name as the old file" do
553
+ it "has the same name as the old file" do
509
554
  assert_equal @d2.avatar.original_filename, @dummy.avatar.original_filename
510
555
  end
511
556
  end
512
557
 
513
- should "have the same contents as the original" do
558
+ it "has the same contents as the original" do
514
559
  assert_equal @file.read, @files_on_s3[:original].read
515
560
  end
516
561
 
517
- should "write and delete its files" do
562
+ it "writes and delete its files" do
518
563
  [["434x66", :original],
519
564
  ["300x46", :large],
520
565
  ["100x15", :medium],
@@ -546,7 +591,7 @@ class IntegrationTest < Test::Unit::TestCase
546
591
  assert_nil @d2.avatar_file_name
547
592
  end
548
593
 
549
- should "work exactly the same when new as when reloaded" do
594
+ it "works exactly the same when new as when reloaded" do
550
595
  @d2 = Dummy.find(@dummy.id)
551
596
 
552
597
  assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
@@ -570,7 +615,7 @@ class IntegrationTest < Test::Unit::TestCase
570
615
  end
571
616
  end
572
617
 
573
- should "know the difference between good files, bad files, and nil" do
618
+ it "knows the difference between good files, bad files, and nil" do
574
619
  @dummy.avatar = @bad_file
575
620
  assert ! @dummy.valid?
576
621
  @dummy.avatar = nil
@@ -586,7 +631,7 @@ class IntegrationTest < Test::Unit::TestCase
586
631
  assert ! @d2.valid?
587
632
  end
588
633
 
589
- should "be able to reload without saving and not have the file disappear" do
634
+ it "is able to reload without saving and not have the file disappear" do
590
635
  @dummy.avatar = @file
591
636
  assert @dummy.save
592
637
  @dummy.avatar = nil
@@ -595,28 +640,28 @@ class IntegrationTest < Test::Unit::TestCase
595
640
  assert_equal "5k.png", @dummy.avatar_file_name
596
641
  end
597
642
 
598
- should "have the right content type" do
643
+ it "has the right content type" do
599
644
  headers = s3_headers_for(@dummy.avatar, :original)
600
645
  assert_equal 'image/png', headers['content-type']
601
646
  end
602
647
 
603
- should "have the right style-specific headers" do
648
+ it "has the right style-specific headers" do
604
649
  headers = s3_headers_for(@dummy.avatar, :custom)
605
650
  assert_equal 'max-age=31557600', headers['cache-control']
606
651
  end
607
652
 
608
- should "have the right style-specific metadata" do
653
+ it "has the right style-specific metadata" do
609
654
  headers = s3_headers_for(@dummy.avatar, :custom)
610
655
  assert_equal 'bar', headers['x-amz-meta-foo']
611
656
  end
612
657
 
613
658
  context "with non-english character in the file name" do
614
- setup do
659
+ before do
615
660
  @file.stubs(:original_filename).returns("クリップ.png")
616
661
  @dummy.avatar = @file
617
662
  end
618
663
 
619
- should "not raise any error" do
664
+ it "does not raise any error" do
620
665
  @dummy.save!
621
666
  end
622
667
  end
@@ -624,14 +669,14 @@ class IntegrationTest < Test::Unit::TestCase
624
669
  end
625
670
 
626
671
  context "Copying attachments between models" do
627
- setup do
672
+ before do
628
673
  rebuild_model
629
674
  @file = File.new(fixture_file("5k.png"), 'rb')
630
675
  end
631
676
 
632
- teardown { @file.close }
677
+ after { @file.close }
633
678
 
634
- should "succeed when original attachment is a file" do
679
+ it "succeeds when original attachment is a file" do
635
680
  original = Dummy.new
636
681
  original.avatar = @file
637
682
  assert original.save
@@ -643,7 +688,7 @@ class IntegrationTest < Test::Unit::TestCase
643
688
  assert copy.avatar.present?
644
689
  end
645
690
 
646
- should "succeed when original attachment is empty" do
691
+ it "succeeds when original attachment is empty" do
647
692
  original = Dummy.create!
648
693
 
649
694
  copy = Dummy.new