paperclip 4.3.7 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -0
  3. data/.hound.yml +5 -16
  4. data/.travis.yml +15 -12
  5. data/Appraisals +4 -8
  6. data/CONTRIBUTING.md +16 -5
  7. data/Gemfile +3 -8
  8. data/LICENSE +1 -1
  9. data/NEWS +105 -31
  10. data/README.md +239 -153
  11. data/Rakefile +1 -1
  12. data/UPGRADING +12 -9
  13. data/features/basic_integration.feature +3 -2
  14. data/features/migration.feature +0 -24
  15. data/features/step_definitions/attachment_steps.rb +6 -6
  16. data/features/step_definitions/rails_steps.rb +29 -28
  17. data/features/step_definitions/s3_steps.rb +2 -2
  18. data/features/support/env.rb +1 -0
  19. data/features/support/paths.rb +1 -1
  20. data/features/support/rails.rb +0 -24
  21. data/gemfiles/4.2.gemfile +3 -5
  22. data/gemfiles/{3.2.gemfile → 5.0.gemfile} +4 -6
  23. data/lib/generators/paperclip/paperclip_generator.rb +9 -1
  24. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  25. data/lib/paperclip.rb +13 -12
  26. data/lib/paperclip/attachment.rb +25 -14
  27. data/lib/paperclip/attachment_registry.rb +2 -1
  28. data/lib/paperclip/callbacks.rb +8 -6
  29. data/lib/paperclip/content_type_detector.rb +3 -2
  30. data/lib/paperclip/errors.rb +3 -1
  31. data/lib/paperclip/file_command_content_type_detector.rb +1 -1
  32. data/lib/paperclip/geometry_detector_factory.rb +2 -2
  33. data/lib/paperclip/glue.rb +1 -1
  34. data/lib/paperclip/has_attached_file.rb +7 -1
  35. data/lib/paperclip/helpers.rb +15 -11
  36. data/lib/paperclip/interpolations.rb +1 -1
  37. data/lib/paperclip/io_adapters/abstract_adapter.rb +29 -3
  38. data/lib/paperclip/io_adapters/attachment_adapter.rb +10 -5
  39. data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
  40. data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
  41. data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
  42. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +7 -7
  43. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
  44. data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
  45. data/lib/paperclip/io_adapters/registry.rb +6 -2
  46. data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
  47. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
  48. data/lib/paperclip/io_adapters/uri_adapter.rb +17 -14
  49. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
  50. data/lib/paperclip/media_type_spoof_detector.rb +3 -2
  51. data/lib/paperclip/processor.rb +5 -4
  52. data/lib/paperclip/schema.rb +2 -8
  53. data/lib/paperclip/storage/filesystem.rb +13 -2
  54. data/lib/paperclip/storage/fog.rb +20 -13
  55. data/lib/paperclip/storage/s3.rb +87 -58
  56. data/lib/paperclip/thumbnail.rb +18 -8
  57. data/lib/paperclip/url_generator.rb +17 -13
  58. data/lib/paperclip/validators.rb +1 -1
  59. data/lib/paperclip/validators/attachment_size_validator.rb +1 -7
  60. data/lib/paperclip/version.rb +3 -1
  61. data/lib/tasks/paperclip.rake +18 -4
  62. data/paperclip.gemspec +13 -10
  63. data/spec/paperclip/attachment_processing_spec.rb +2 -4
  64. data/spec/paperclip/attachment_registry_spec.rb +28 -0
  65. data/spec/paperclip/attachment_spec.rb +72 -18
  66. data/spec/paperclip/content_type_detector_spec.rb +1 -1
  67. data/spec/paperclip/file_command_content_type_detector_spec.rb +15 -1
  68. data/spec/paperclip/has_attached_file_spec.rb +24 -8
  69. data/spec/paperclip/integration_spec.rb +4 -3
  70. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +76 -22
  71. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
  72. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
  73. data/spec/paperclip/io_adapters/file_adapter_spec.rb +2 -2
  74. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +18 -1
  75. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
  76. data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
  77. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +1 -1
  78. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
  79. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +48 -3
  80. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
  81. data/spec/paperclip/media_type_spoof_detector_spec.rb +15 -0
  82. data/spec/paperclip/paperclip_spec.rb +15 -45
  83. data/spec/paperclip/processor_spec.rb +4 -4
  84. data/spec/paperclip/storage/fog_spec.rb +31 -0
  85. data/spec/paperclip/storage/s3_live_spec.rb +20 -14
  86. data/spec/paperclip/storage/s3_spec.rb +357 -190
  87. data/spec/paperclip/tempfile_spec.rb +35 -0
  88. data/spec/paperclip/thumbnail_spec.rb +38 -35
  89. data/spec/paperclip/url_generator_spec.rb +54 -43
  90. data/spec/paperclip/validators/attachment_size_validator_spec.rb +26 -20
  91. data/spec/paperclip/validators_spec.rb +5 -5
  92. data/spec/spec_helper.rb +6 -2
  93. data/spec/support/assertions.rb +12 -1
  94. data/spec/support/conditional_filter_helper.rb +5 -0
  95. data/spec/support/mock_attachment.rb +2 -0
  96. data/spec/support/mock_url_generator_builder.rb +2 -2
  97. data/spec/support/model_reconstruction.rb +9 -1
  98. data/spec/support/reporting.rb +11 -0
  99. metadata +66 -58
  100. data/cucumber/paperclip_steps.rb +0 -6
  101. data/gemfiles/4.1.gemfile +0 -19
  102. data/lib/paperclip/deprecations.rb +0 -42
  103. data/lib/paperclip/locales/de.yml +0 -18
  104. data/lib/paperclip/locales/es.yml +0 -18
  105. data/lib/paperclip/locales/ja.yml +0 -18
  106. data/lib/paperclip/locales/pt-BR.yml +0 -18
  107. data/lib/paperclip/locales/zh-CN.yml +0 -18
  108. data/lib/paperclip/locales/zh-HK.yml +0 -18
  109. data/lib/paperclip/locales/zh-TW.yml +0 -18
  110. data/spec/paperclip/deprecations_spec.rb +0 -65
  111. data/spec/support/deprecations.rb +0 -9
  112. data/spec/support/rails_helpers.rb +0 -7
@@ -36,7 +36,7 @@ module Paperclip
36
36
  options = attributes.extract_options!.dup
37
37
 
38
38
  Paperclip::Validators.constants.each do |constant|
39
- if constant.to_s =~ /\AAttachment(.+)Validator\Z/
39
+ if constant.to_s =~ /\AAttachment(.+)Validator\z/
40
40
  validator_kind = $1.underscore.to_sym
41
41
 
42
42
  if options.has_key?(validator_kind)
@@ -71,13 +71,7 @@ module Paperclip
71
71
  end
72
72
 
73
73
  def human_size(size)
74
- if defined?(ActiveSupport::NumberHelper) # Rails 4.0+
75
- ActiveSupport::NumberHelper.number_to_human_size(size)
76
- else
77
- storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
78
- unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => size.to_i, :raise => true)
79
- storage_units_format.gsub(/%n/, size.to_i.to_s).gsub(/%u/, unit).html_safe
80
- end
74
+ ActiveSupport::NumberHelper.number_to_human_size(size)
81
75
  end
82
76
 
83
77
  def min_value_in_human_size(record)
@@ -1,3 +1,5 @@
1
1
  module Paperclip
2
- VERSION = "4.3.7".freeze unless defined? Paperclip::VERSION
2
+ unless defined?(Paperclip::VERSION)
3
+ VERSION = "5.3.0".freeze
4
+ end
3
5
  end
@@ -18,7 +18,7 @@ module Paperclip
18
18
  raise "Class #{klass.name} has no attachments specified"
19
19
  end
20
20
 
21
- if !name.blank? && attachment_names.map(&:to_s).include?(name.to_s)
21
+ if name.present? && attachment_names.map(&:to_s).include?(name.to_s)
22
22
  [ name ]
23
23
  else
24
24
  attachment_names
@@ -46,7 +46,7 @@ namespace :paperclip do
46
46
  attachment = instance.send(name)
47
47
  begin
48
48
  attachment.reprocess!(*styles)
49
- rescue Exception => e
49
+ rescue StandardError => e
50
50
  Paperclip::Task.log_error("exception while processing #{klass} ID #{instance.id}:")
51
51
  Paperclip::Task.log_error(" " + e.message + "\n")
52
52
  end
@@ -64,7 +64,8 @@ namespace :paperclip do
64
64
  names = Paperclip::Task.obtain_attachments(klass)
65
65
  names.each do |name|
66
66
  Paperclip.each_instance_with_attachment(klass, name) do |instance|
67
- if file = Paperclip.io_adapters.for(instance.send(name))
67
+ attachment = instance.send(name)
68
+ if file = Paperclip.io_adapters.for(attachment, attachment.options[:adapter_options])
68
69
  instance.send("#{name}_file_name=", instance.send("#{name}_file_name").strip)
69
70
  instance.send("#{name}_content_type=", file.content_type.to_s.strip)
70
71
  instance.send("#{name}_file_size=", file.size) if instance.respond_to?("#{name}_file_size")
@@ -90,6 +91,19 @@ namespace :paperclip do
90
91
  end
91
92
  Paperclip.save_current_attachments_styles!
92
93
  end
94
+
95
+ desc "Regenerates fingerprints for a given CLASS (and optional ATTACHMENT). Useful when changing digest."
96
+ task :fingerprints => :environment do
97
+ klass = Paperclip::Task.obtain_class
98
+ names = Paperclip::Task.obtain_attachments(klass)
99
+ names.each do |name|
100
+ Paperclip.each_instance_with_attachment(klass, name) do |instance|
101
+ attachment = instance.send(name)
102
+ attachment.assign(attachment)
103
+ instance.save(:validate => false)
104
+ end
105
+ end
106
+ end
93
107
  end
94
108
 
95
109
  desc "Cleans out invalid attachments. Useful after you've added new validations."
@@ -109,7 +123,7 @@ namespace :paperclip do
109
123
  end
110
124
  end
111
125
 
112
- desc "find missing attachments. Useful to know which attachments are broken"
126
+ desc "find missing attachments. Useful to know which attachments are broken"
113
127
  task :find_broken_attachments => :environment do
114
128
  klass = Paperclip::Task.obtain_class
115
129
  names = Paperclip::Task.obtain_attachments(klass)
data/paperclip.gemspec CHANGED
@@ -17,26 +17,30 @@ Gem::Specification.new do |s|
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
19
 
20
+ if File.exist?('UPGRADING')
21
+ s.post_install_message = File.read("UPGRADING")
22
+ end
23
+
20
24
  s.requirements << "ImageMagick"
21
- s.required_ruby_version = ">= 1.9.2"
25
+ s.required_ruby_version = ">= 2.1.0"
22
26
 
23
- s.add_dependency('activemodel', '>= 3.2.0')
24
- s.add_dependency('activesupport', '>= 3.2.0')
25
- s.add_dependency('cocaine', '~> 0.5.5')
27
+ s.add_dependency('activemodel', '>= 4.2.0')
28
+ s.add_dependency('activesupport', '>= 4.2.0')
29
+ s.add_dependency('terrapin', '~> 0.6.0')
26
30
  s.add_dependency('mime-types')
27
- s.add_dependency('mimemagic', '0.3.0')
31
+ s.add_dependency('mimemagic', '~> 0.3.0')
28
32
 
29
- s.add_development_dependency('activerecord', '>= 3.2.0')
33
+ s.add_development_dependency('activerecord', '>= 4.2.0')
30
34
  s.add_development_dependency('shoulda')
31
35
  s.add_development_dependency('rspec', '~> 3.0')
32
36
  s.add_development_dependency('appraisal')
33
37
  s.add_development_dependency('mocha')
34
- s.add_development_dependency('aws-sdk', '>= 1.5.7', "<= 2.0")
38
+ s.add_development_dependency('aws-sdk', '>= 2.3.0', '< 3.0')
35
39
  s.add_development_dependency('bourne')
36
- s.add_development_dependency('cucumber', '~> 1.3.18')
40
+ s.add_development_dependency('cucumber-rails')
41
+ s.add_development_dependency('cucumber-expressions', '4.0.3') # TODO: investigate failures on 4.0.4
37
42
  s.add_development_dependency('aruba', '~> 0.9.0')
38
43
  s.add_development_dependency('nokogiri')
39
- # Ruby version < 1.9.3 can't install capybara > 2.0.3.
40
44
  s.add_development_dependency('capybara')
41
45
  s.add_development_dependency('bundler')
42
46
  s.add_development_dependency('fog-aws')
@@ -45,7 +49,6 @@ Gem::Specification.new do |s|
45
49
  s.add_development_dependency('rake')
46
50
  s.add_development_dependency('fakeweb')
47
51
  s.add_development_dependency('railties')
48
- s.add_development_dependency('actionmailer', '>= 3.2.0')
49
52
  s.add_development_dependency('generator_spec')
50
53
  s.add_development_dependency('timecop')
51
54
  end
@@ -2,11 +2,9 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe 'Attachment Processing' do
5
- context 'using validates_attachment_content_type' do
6
- before do
7
- rebuild_class
8
- end
5
+ before { rebuild_class }
9
6
 
7
+ context 'using validates_attachment_content_type' do
10
8
  it 'processes attachments given a valid assignment' do
11
9
  file = File.new(fixture_file("5k.png"))
12
10
  Dummy.validates_attachment_content_type :avatar, content_type: "image/png"
@@ -111,6 +111,34 @@ describe 'Attachment Registry' do
111
111
 
112
112
  assert_equal expected_definitions, definitions
113
113
  end
114
+
115
+ it 'allows subclasses to override attachment defitions' do
116
+ foo_definitions = { avatar: { yo: "greeting" } }
117
+ bar_definitions = { avatar: { yo: "hello" } }
118
+
119
+ expected_definitions = {
120
+ avatar: {
121
+ yo: "hello"
122
+ }
123
+ }
124
+
125
+ foo = Class.new
126
+ bar = Class.new(foo)
127
+ Paperclip::AttachmentRegistry.register(
128
+ foo,
129
+ :avatar,
130
+ foo_definitions[:avatar]
131
+ )
132
+ Paperclip::AttachmentRegistry.register(
133
+ bar,
134
+ :avatar,
135
+ bar_definitions[:avatar]
136
+ )
137
+
138
+ definitions = Paperclip::AttachmentRegistry.definitions_for(bar)
139
+
140
+ assert_equal expected_definitions, definitions
141
+ end
114
142
  end
115
143
 
116
144
  context '.clear' do
@@ -222,9 +222,6 @@ describe Paperclip::Attachment do
222
222
  dummy.avatar_file_name = "fake.jpg"
223
223
  dummy.stubs(:new_record?).returns(false)
224
224
  expected_string = '{"avatar":"/system/dummies/avatars/000/001/234/original/fake.jpg"}'
225
- if ActiveRecord::Base.include_root_in_json # This is true by default in Rails 3, and false in 4
226
- expected_string = %({"dummy":#{expected_string}})
227
- end
228
225
  # active_model pre-3.2 checks only by calling any? on it, thus it doesn't work if it is empty
229
226
  assert_equal expected_string, dummy.to_json(only: [:dummy_key_for_old_active_model], methods: [:avatar])
230
227
  end
@@ -503,6 +500,7 @@ describe Paperclip::Attachment do
503
500
  @attachment.expects(:post_process).with(:thumb)
504
501
  @attachment.expects(:post_process).with(:large).never
505
502
  @attachment.assign(@file)
503
+ @attachment.save
506
504
  end
507
505
  end
508
506
 
@@ -700,9 +698,6 @@ describe Paperclip::Attachment do
700
698
 
701
699
  context "when assigned" do
702
700
  it "calls #make on all specified processors" do
703
- Paperclip::Thumbnail.stubs(:make).with(any_parameters).returns(@file)
704
- Paperclip::Test.stubs(:make).with(any_parameters).returns(@file)
705
-
706
701
  @dummy.avatar = @file
707
702
 
708
703
  expect(Paperclip::Thumbnail).to have_received(:make)
@@ -717,7 +712,6 @@ describe Paperclip::Attachment do
717
712
  convert_options: "",
718
713
  source_file_options: ""
719
714
  })
720
- Paperclip::Thumbnail.stubs(:make).returns(@file)
721
715
 
722
716
  @dummy.avatar = @file
723
717
 
@@ -725,12 +719,36 @@ describe Paperclip::Attachment do
725
719
  end
726
720
 
727
721
  it "calls #make with attachment passed as third argument" do
728
- Paperclip::Test.expects(:make).returns(@file)
729
-
730
722
  @dummy.avatar = @file
731
723
 
732
724
  expect(Paperclip::Test).to have_received(:make).with(anything, anything, @dummy.avatar)
733
725
  end
726
+
727
+ it "calls #make and unlinks intermediary files afterward" do
728
+ @dummy.avatar.expects(:unlink_files).with([@file, @file])
729
+
730
+ @dummy.avatar = @file
731
+ end
732
+ end
733
+ end
734
+
735
+ context "An attachment with a processor that returns original file" do
736
+ before do
737
+ class Paperclip::Test < Paperclip::Processor
738
+ def make; @file; end
739
+ end
740
+ rebuild_model processors: [:test], styles: { once: "100x100" }
741
+ @file = StringIO.new("...")
742
+ @file.stubs(:close)
743
+ @dummy = Dummy.new
744
+ end
745
+
746
+ context "when assigned" do
747
+ it "#calls #make and doesn't unlink the original file" do
748
+ @dummy.avatar.expects(:unlink_files).with([])
749
+
750
+ @dummy.avatar = @file
751
+ end
734
752
  end
735
753
  end
736
754
 
@@ -1104,7 +1122,7 @@ describe Paperclip::Attachment do
1104
1122
  context "with a file assigned but not saved yet" do
1105
1123
  it "clears out any attached files" do
1106
1124
  @attachment.assign(@file)
1107
- assert !@attachment.queued_for_write.blank?
1125
+ assert @attachment.queued_for_write.present?
1108
1126
  @attachment.clear
1109
1127
  assert @attachment.queued_for_write.blank?
1110
1128
  end
@@ -1354,6 +1372,12 @@ describe Paperclip::Attachment do
1354
1372
  end
1355
1373
 
1356
1374
  it "does not calculate fingerprint" do
1375
+ Digest::MD5.stubs(:file)
1376
+ @dummy.avatar = @file
1377
+ expect(Digest::MD5).to have_received(:file).never
1378
+ end
1379
+
1380
+ it "does not assign fingerprint" do
1357
1381
  @dummy.avatar = @file
1358
1382
  assert_nil @dummy.avatar.fingerprint
1359
1383
  end
@@ -1410,16 +1434,46 @@ describe Paperclip::Attachment do
1410
1434
  assert_nothing_raised { @dummy.avatar = @file }
1411
1435
  end
1412
1436
 
1413
- it "returns the right value when sent #avatar_fingerprint" do
1414
- @dummy.avatar = @file
1415
- assert_equal 'aec488126c3b33c08a10c3fa303acf27', @dummy.avatar_fingerprint
1437
+ context "with explicitly set digest" do
1438
+ before do
1439
+ rebuild_class adapter_options: { hash_digest: Digest::SHA256 }
1440
+ @dummy = Dummy.new
1441
+ end
1442
+
1443
+ it "returns the right value when sent #avatar_fingerprint" do
1444
+ @dummy.avatar = @file
1445
+ assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
1446
+ @dummy.avatar_fingerprint
1447
+ end
1448
+
1449
+ it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
1450
+ @dummy.avatar = @file
1451
+ @dummy.save
1452
+ @dummy = Dummy.find(@dummy.id)
1453
+ assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
1454
+ @dummy.avatar_fingerprint
1455
+ end
1416
1456
  end
1417
1457
 
1418
- it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
1419
- @dummy.avatar = @file
1420
- @dummy.save
1421
- @dummy = Dummy.find(@dummy.id)
1422
- assert_equal 'aec488126c3b33c08a10c3fa303acf27', @dummy.avatar_fingerprint
1458
+ context "with the default digest" do
1459
+ before do
1460
+ rebuild_class # MD5 is the default
1461
+ @dummy = Dummy.new
1462
+ end
1463
+
1464
+ it "returns the right value when sent #avatar_fingerprint" do
1465
+ @dummy.avatar = @file
1466
+ assert_equal "aec488126c3b33c08a10c3fa303acf27",
1467
+ @dummy.avatar_fingerprint
1468
+ end
1469
+
1470
+ it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
1471
+ @dummy.avatar = @file
1472
+ @dummy.save
1473
+ @dummy = Dummy.find(@dummy.id)
1474
+ assert_equal "aec488126c3b33c08a10c3fa303acf27",
1475
+ @dummy.avatar_fingerprint
1476
+ end
1423
1477
  end
1424
1478
  end
1425
1479
  end
@@ -41,7 +41,7 @@ describe Paperclip::ContentTypeDetector do
41
41
  end
42
42
 
43
43
  it 'returns a sensible default when the file command is missing' do
44
- Paperclip.stubs(:run).raises(Cocaine::CommandLineError.new)
44
+ Paperclip.stubs(:run).raises(Terrapin::CommandLineError.new)
45
45
  @filename = "/path/to/something"
46
46
  assert_equal "application/octet-stream", Paperclip::ContentTypeDetector.new(@filename).detect
47
47
  end
@@ -12,7 +12,7 @@ describe Paperclip::FileCommandContentTypeDetector do
12
12
  end
13
13
 
14
14
  it 'returns a sensible default when the file command is missing' do
15
- Paperclip.stubs(:run).raises(Cocaine::CommandLineError.new)
15
+ Paperclip.stubs(:run).raises(Terrapin::CommandLineError.new)
16
16
  @filename = "/path/to/something"
17
17
  assert_equal "application/octet-stream",
18
18
  Paperclip::FileCommandContentTypeDetector.new(@filename).detect
@@ -23,4 +23,18 @@ describe Paperclip::FileCommandContentTypeDetector do
23
23
  assert_equal "application/octet-stream",
24
24
  Paperclip::FileCommandContentTypeDetector.new("windows").detect
25
25
  end
26
+
27
+ context "#type_from_file_command" do
28
+ let(:detector) { Paperclip::FileCommandContentTypeDetector.new("html") }
29
+
30
+ it "does work with the output of old versions of file" do
31
+ Paperclip.stubs(:run).returns("text/html charset=us-ascii")
32
+ expect(detector.detect).to eq("text/html")
33
+ end
34
+
35
+ it "does work with the output of new versions of file" do
36
+ Paperclip.stubs(:run).returns("text/html; charset=us-ascii")
37
+ expect(detector.detect).to eq("text/html")
38
+ end
39
+ end
26
40
  end
@@ -38,6 +38,15 @@ describe Paperclip::HasAttachedFile do
38
38
  assert_adding_attachment('avatar').defines_callback('after_commit')
39
39
  end
40
40
 
41
+ context 'when the class does not allow after_commit callbacks' do
42
+ it 'defines an after_destroy callback' do
43
+ assert_adding_attachment(
44
+ 'avatar',
45
+ unstub_methods: [:after_commit]
46
+ ).defines_callback('after_destroy')
47
+ end
48
+ end
49
+
41
50
  it 'defines the Paperclip-specific callbacks' do
42
51
  assert_adding_attachment('avatar').defines_callback('define_paperclip_callbacks')
43
52
  end
@@ -53,20 +62,26 @@ describe Paperclip::HasAttachedFile do
53
62
 
54
63
  private
55
64
 
56
- def assert_adding_attachment(attachment_name)
57
- AttachmentAdder.new(attachment_name)
65
+ def assert_adding_attachment(attachment_name, options={})
66
+ AttachmentAdder.new(attachment_name, options)
58
67
  end
59
68
 
60
69
  class AttachmentAdder
61
70
  include Mocha::API
62
71
  include RSpec::Matchers
63
72
 
64
- def initialize(attachment_name)
73
+ def initialize(attachment_name, options = {})
65
74
  @attachment_name = attachment_name
75
+ @stubbed_class = stub_class
76
+ if options.present?
77
+ options[:unstub_methods].each do |method|
78
+ @stubbed_class.unstub(method)
79
+ end
80
+ end
66
81
  end
67
82
 
68
83
  def defines_method(method_name)
69
- a_class = stub_class
84
+ a_class = @stubbed_class
70
85
 
71
86
  Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
72
87
 
@@ -74,7 +89,7 @@ describe Paperclip::HasAttachedFile do
74
89
  end
75
90
 
76
91
  def defines_class_method(method_name)
77
- a_class = stub_class
92
+ a_class = @stubbed_class
78
93
  a_class.class.stubs(:define_method)
79
94
 
80
95
  Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
@@ -83,7 +98,7 @@ describe Paperclip::HasAttachedFile do
83
98
  end
84
99
 
85
100
  def defines_validation
86
- a_class = stub_class
101
+ a_class = @stubbed_class
87
102
 
88
103
  Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
89
104
 
@@ -91,7 +106,7 @@ describe Paperclip::HasAttachedFile do
91
106
  end
92
107
 
93
108
  def registers_attachment
94
- a_class = stub_class
109
+ a_class = @stubbed_class
95
110
  Paperclip::AttachmentRegistry.stubs(:register)
96
111
 
97
112
  Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {size: 1})
@@ -100,7 +115,7 @@ describe Paperclip::HasAttachedFile do
100
115
  end
101
116
 
102
117
  def defines_callback(callback_name)
103
- a_class = stub_class
118
+ a_class = @stubbed_class
104
119
 
105
120
  Paperclip::HasAttachedFile.define_on(a_class, @attachment_name, {})
106
121
 
@@ -132,6 +147,7 @@ describe Paperclip::HasAttachedFile do
132
147
  after_save: nil,
133
148
  before_destroy: nil,
134
149
  after_commit: nil,
150
+ after_destroy: nil,
135
151
  define_paperclip_callbacks: nil,
136
152
  extend: nil,
137
153
  name: 'Billy',