paperclip 4.1.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of paperclip might be problematic. Click here for more details.

Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -6
  3. data/.travis.yml +4 -13
  4. data/Appraisals +0 -10
  5. data/CONTRIBUTING.md +10 -5
  6. data/Gemfile +8 -4
  7. data/NEWS +1 -1
  8. data/README.md +51 -10
  9. data/Rakefile +6 -8
  10. data/features/basic_integration.feature +5 -5
  11. data/features/step_definitions/attachment_steps.rb +4 -4
  12. data/features/step_definitions/rails_steps.rb +4 -4
  13. data/features/step_definitions/web_steps.rb +2 -2
  14. data/features/support/env.rb +2 -2
  15. data/features/support/fixtures/gemfile.txt +1 -1
  16. data/features/support/rails.rb +2 -1
  17. data/gemfiles/3.2.gemfile +5 -3
  18. data/gemfiles/4.0.gemfile +5 -3
  19. data/gemfiles/4.1.gemfile +5 -3
  20. data/lib/generators/paperclip/paperclip_generator.rb +0 -2
  21. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  22. data/lib/paperclip.rb +4 -1
  23. data/lib/paperclip/attachment.rb +90 -29
  24. data/lib/paperclip/content_type_detector.rb +1 -1
  25. data/lib/paperclip/geometry_detector_factory.rb +3 -1
  26. data/lib/paperclip/has_attached_file.rb +2 -1
  27. data/lib/paperclip/interpolations.rb +8 -0
  28. data/lib/paperclip/io_adapters/abstract_adapter.rb +1 -1
  29. data/lib/paperclip/io_adapters/data_uri_adapter.rb +1 -1
  30. data/lib/paperclip/io_adapters/stringio_adapter.rb +5 -11
  31. data/lib/paperclip/locales/de.yml +18 -0
  32. data/lib/paperclip/locales/es.yml +18 -0
  33. data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -1
  34. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -1
  35. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -1
  36. data/lib/paperclip/media_type_spoof_detector.rb +10 -2
  37. data/lib/paperclip/storage/filesystem.rb +1 -1
  38. data/lib/paperclip/storage/s3.rb +26 -4
  39. data/lib/paperclip/style.rb +1 -1
  40. data/lib/paperclip/thumbnail.rb +6 -6
  41. data/lib/paperclip/validators.rb +5 -3
  42. data/lib/paperclip/validators/attachment_size_validator.rb +7 -3
  43. data/lib/paperclip/version.rb +1 -1
  44. data/lib/tasks/paperclip.rake +1 -2
  45. data/paperclip.gemspec +5 -3
  46. data/shoulda_macros/paperclip.rb +0 -1
  47. data/{test → spec}/database.yml +0 -0
  48. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  49. data/{test/attachment_processing_test.rb → spec/paperclip/attachment_processing_spec.rb} +20 -21
  50. data/{test/attachment_registry_test.rb → spec/paperclip/attachment_registry_spec.rb} +10 -11
  51. data/{test/attachment_test.rb → spec/paperclip/attachment_spec.rb} +367 -360
  52. data/{test/content_type_detector_test.rb → spec/paperclip/content_type_detector_spec.rb} +8 -8
  53. data/{test/file_command_content_type_detector_test.rb → spec/paperclip/file_command_content_type_detector_spec.rb} +5 -5
  54. data/spec/paperclip/filename_cleaner_spec.rb +14 -0
  55. data/spec/paperclip/geometry_detector_spec.rb +39 -0
  56. data/{test/geometry_parser_test.rb → spec/paperclip/geometry_parser_spec.rb} +27 -27
  57. data/{test/geometry_test.rb → spec/paperclip/geometry_spec.rb} +49 -51
  58. data/{test/has_attached_file_test.rb → spec/paperclip/has_attached_file_spec.rb} +18 -27
  59. data/{test/integration_test.rb → spec/paperclip/integration_spec.rb} +134 -126
  60. data/{test/interpolations_test.rb → spec/paperclip/interpolations_spec.rb} +54 -40
  61. data/{test/io_adapters/abstract_adapter_test.rb → spec/paperclip/io_adapters/abstract_adapter_spec.rb} +21 -10
  62. data/{test/io_adapters/attachment_adapter_test.rb → spec/paperclip/io_adapters/attachment_adapter_spec.rb} +27 -29
  63. data/{test/io_adapters/data_uri_adapter_test.rb → spec/paperclip/io_adapters/data_uri_adapter_spec.rb} +22 -18
  64. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  65. data/{test/io_adapters/file_adapter_test.rb → spec/paperclip/io_adapters/file_adapter_spec.rb} +32 -28
  66. data/{test/io_adapters/http_url_proxy_adapter_test.rb → spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb} +22 -22
  67. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  68. data/{test/io_adapters/nil_adapter_test.rb → spec/paperclip/io_adapters/nil_adapter_spec.rb} +7 -7
  69. data/{test/io_adapters/registry_test.rb → spec/paperclip/io_adapters/registry_spec.rb} +10 -7
  70. data/{test/io_adapters/stringio_adapter_test.rb → spec/paperclip/io_adapters/stringio_adapter_spec.rb} +16 -17
  71. data/{test/io_adapters/uploaded_file_adapter_test.rb → spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb} +41 -41
  72. data/{test/io_adapters/uri_adapter_test.rb → spec/paperclip/io_adapters/uri_adapter_spec.rb} +22 -22
  73. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  74. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +99 -0
  75. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  76. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  77. data/{test/media_type_spoof_detector_test.rb → spec/paperclip/media_type_spoof_detector_spec.rb} +13 -8
  78. data/spec/paperclip/meta_class_spec.rb +30 -0
  79. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
  80. data/{test/paperclip_test.rb → spec/paperclip/paperclip_spec.rb} +47 -47
  81. data/{test/plural_cache_test.rb → spec/paperclip/plural_cache_spec.rb} +6 -6
  82. data/{test/processor_test.rb → spec/paperclip/processor_spec.rb} +5 -5
  83. data/{test/rake_test.rb → spec/paperclip/rake_spec.rb} +15 -15
  84. data/spec/paperclip/schema_spec.rb +206 -0
  85. data/{test/storage/filesystem_test.rb → spec/paperclip/storage/filesystem_spec.rb} +18 -18
  86. data/{test/storage/fog_test.rb → spec/paperclip/storage/fog_spec.rb} +145 -140
  87. data/spec/paperclip/storage/s3_live_spec.rb +182 -0
  88. data/spec/paperclip/storage/s3_spec.rb +1475 -0
  89. data/spec/paperclip/style_spec.rb +255 -0
  90. data/spec/paperclip/tempfile_factory_spec.rb +29 -0
  91. data/{test/thumbnail_test.rb → spec/paperclip/thumbnail_spec.rb} +107 -107
  92. data/{test/url_generator_test.rb → spec/paperclip/url_generator_spec.rb} +55 -56
  93. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
  94. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
  95. data/{test/validators/attachment_presence_validator_test.rb → spec/paperclip/validators/attachment_presence_validator_spec.rb} +19 -19
  96. data/{test/validators/attachment_size_validator_test.rb → spec/paperclip/validators/attachment_size_validator_spec.rb} +65 -58
  97. data/{test/validators/media_type_spoof_detection_validator_test.rb → spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb} +8 -8
  98. data/spec/paperclip/validators_spec.rb +164 -0
  99. data/spec/spec_helper.rb +40 -0
  100. data/spec/support/assertions.rb +71 -0
  101. data/spec/support/fake_model.rb +21 -0
  102. data/spec/support/fake_rails.rb +12 -0
  103. data/{test → spec/support}/fixtures/12k.png +0 -0
  104. data/{test → spec/support}/fixtures/50x50.png +0 -0
  105. data/{test → spec/support}/fixtures/5k.png +0 -0
  106. data/{test → spec/support}/fixtures/animated +0 -0
  107. data/{test → spec/support}/fixtures/animated.gif +0 -0
  108. data/{test → spec/support}/fixtures/animated.unknown +0 -0
  109. data/{test → spec/support}/fixtures/bad.png +0 -0
  110. data/{test → spec/support}/fixtures/empty.html +0 -0
  111. data/{test → spec/support}/fixtures/fog.yml +0 -0
  112. data/{test → spec/support}/fixtures/rotated.jpg +0 -0
  113. data/{test → spec/support}/fixtures/s3.yml +0 -0
  114. data/spec/support/fixtures/spaced file.jpg +0 -0
  115. data/test/fixtures/spaced file.png b/data/spec/support/fixtures/spaced → file.png +0 -0
  116. data/{test → spec/support}/fixtures/text.txt +0 -0
  117. data/{test → spec/support}/fixtures/twopage.pdf +0 -0
  118. data/{test → spec/support}/fixtures/uppercase.PNG +0 -0
  119. data/spec/support/matchers/accept.rb +5 -0
  120. data/spec/support/matchers/exist.rb +5 -0
  121. data/{test → spec}/support/mock_attachment.rb +0 -0
  122. data/{test → spec}/support/mock_interpolator.rb +0 -0
  123. data/{test → spec}/support/mock_model.rb +0 -0
  124. data/{test → spec}/support/mock_url_generator_builder.rb +0 -0
  125. data/spec/support/model_reconstruction.rb +60 -0
  126. data/spec/support/rails_helpers.rb +7 -0
  127. data/spec/support/test_data.rb +13 -0
  128. data/spec/support/version_helper.rb +9 -0
  129. metadata +256 -210
  130. data/gemfiles/3.0.gemfile +0 -11
  131. data/gemfiles/3.1.gemfile +0 -11
  132. data/test/attachment_definitions_test.rb +0 -13
  133. data/test/filename_cleaner_test.rb +0 -14
  134. data/test/generator_test.rb +0 -84
  135. data/test/geometry_detector_test.rb +0 -24
  136. data/test/helper.rb +0 -239
  137. data/test/io_adapters/empty_string_adapter_test.rb +0 -18
  138. data/test/io_adapters/identity_adapter_test.rb +0 -8
  139. data/test/matchers/have_attached_file_matcher_test.rb +0 -25
  140. data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -111
  141. data/test/matchers/validate_attachment_presence_matcher_test.rb +0 -70
  142. data/test/matchers/validate_attachment_size_matcher_test.rb +0 -87
  143. data/test/meta_class_test.rb +0 -32
  144. data/test/paperclip_missing_attachment_styles_test.rb +0 -90
  145. data/test/schema_test.rb +0 -206
  146. data/test/storage/s3_live_test.rb +0 -179
  147. data/test/storage/s3_test.rb +0 -1357
  148. data/test/style_test.rb +0 -251
  149. data/test/tempfile_factory_test.rb +0 -29
  150. data/test/validators/attachment_content_type_validator_test.rb +0 -324
  151. data/test/validators/attachment_file_name_validator_test.rb +0 -162
  152. data/test/validators_test.rb +0 -101
@@ -1,22 +1,22 @@
1
- require './test/helper'
1
+ require 'spec_helper'
2
2
 
3
- class MediaTypeSpoofDetectionValidatorTest < Test::Unit::TestCase
4
- def setup
3
+ describe Paperclip::Validators::MediaTypeSpoofDetectionValidator do
4
+ before do
5
5
  rebuild_model
6
6
  @dummy = Dummy.new
7
7
  end
8
8
 
9
9
  def build_validator(options = {})
10
10
  @validator = Paperclip::Validators::MediaTypeSpoofDetectionValidator.new(options.merge(
11
- :attributes => :avatar
11
+ attributes: :avatar
12
12
  ))
13
13
  end
14
14
 
15
- should "be on the attachment without being explicitly added" do
15
+ it "is on the attachment without being explicitly added" do
16
16
  assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :media_type_spoof_detection }
17
17
  end
18
18
 
19
- should "return default error message for spoofed media type" do
19
+ it "returns default error message for spoofed media type" do
20
20
  build_validator
21
21
  file = File.new(fixture_file("5k.png"), "rb")
22
22
  @dummy.avatar.assign(file)
@@ -28,7 +28,7 @@ class MediaTypeSpoofDetectionValidatorTest < Test::Unit::TestCase
28
28
  assert_equal "has an extension that does not match its contents", @dummy.errors[:avatar].first
29
29
  end
30
30
 
31
- should "run when attachment is dirty" do
31
+ it "runs when attachment is dirty" do
32
32
  build_validator
33
33
  file = File.new(fixture_file("5k.png"), "rb")
34
34
  @dummy.avatar.assign(file)
@@ -39,7 +39,7 @@ class MediaTypeSpoofDetectionValidatorTest < Test::Unit::TestCase
39
39
  assert_received(Paperclip::MediaTypeSpoofDetector, :using){|e| e.once }
40
40
  end
41
41
 
42
- should "not run when attachment is not dirty" do
42
+ it "does not run when attachment is not dirty" do
43
43
  Paperclip::MediaTypeSpoofDetector.stubs(:using).never
44
44
  @dummy.valid?
45
45
  assert_received(Paperclip::MediaTypeSpoofDetector, :using){|e| e.never }
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paperclip::Validators do
4
+ context "using the helper" do
5
+ before do
6
+ Dummy.validates_attachment :avatar, presence: true, content_type: { content_type: "image/jpeg" }, size: { in: 0..10240 }
7
+ end
8
+
9
+ it "adds the attachment_presence validator to the class" do
10
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_presence }
11
+ end
12
+
13
+ it "adds the attachment_content_type validator to the class" do
14
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_content_type }
15
+ end
16
+
17
+ it "adds the attachment_size validator to the class" do
18
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_size }
19
+ end
20
+
21
+ it 'prevents you from attaching a file that violates that validation' do
22
+ Dummy.class_eval{ validate(:name) { raise "DO NOT RUN THIS" } }
23
+ dummy = Dummy.new(avatar: File.new(fixture_file("12k.png")))
24
+ expect(dummy.errors.keys).to match_array [:avatar_content_type, :avatar, :avatar_file_size]
25
+ assert_raises(RuntimeError){ dummy.valid? }
26
+ end
27
+ end
28
+
29
+ context 'using the helper with array of validations' do
30
+ before do
31
+ rebuild_class
32
+ Dummy.validates_attachment :avatar, file_type_ignorance: true, file_name: [
33
+ { matches: /\A.*\.jpe?g\Z/i, message: :invalid_extension },
34
+ { matches: /\A.{,8}\..+\Z/i, message: [:too_long, count: 8] },
35
+ ]
36
+ end
37
+
38
+ it 'adds the attachment_file_name validator to the class' do
39
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_file_name }
40
+ end
41
+
42
+ it 'adds the attachment_file_name validator with two validations' do
43
+ assert_equal 2, Dummy.validators_on(:avatar).select{ |validator| validator.kind == :attachment_file_name }.size
44
+ end
45
+
46
+ it 'prevents you from attaching a file that violates all of these validations' do
47
+ Dummy.class_eval{ validate(:name) { raise 'DO NOT RUN THIS' } }
48
+ dummy = Dummy.new(avatar: File.new(fixture_file('spaced file.png')))
49
+ expect(dummy.errors.keys).to match_array [:avatar, :avatar_file_name]
50
+ assert_raises(RuntimeError){ dummy.valid? }
51
+ end
52
+
53
+ it 'prevents you from attaching a file that violates only first of these validations' do
54
+ Dummy.class_eval{ validate(:name) { raise 'DO NOT RUN THIS' } }
55
+ dummy = Dummy.new(avatar: File.new(fixture_file('5k.png')))
56
+ expect(dummy.errors.keys).to match_array [:avatar, :avatar_file_name]
57
+ assert_raises(RuntimeError){ dummy.valid? }
58
+ end
59
+
60
+ it 'prevents you from attaching a file that violates only second of these validations' do
61
+ Dummy.class_eval{ validate(:name) { raise 'DO NOT RUN THIS' } }
62
+ dummy = Dummy.new(avatar: File.new(fixture_file('spaced file.jpg')))
63
+ expect(dummy.errors.keys).to match_array [:avatar, :avatar_file_name]
64
+ assert_raises(RuntimeError){ dummy.valid? }
65
+ end
66
+
67
+ it 'allows you to attach a file that does not violates these validations' do
68
+ dummy = Dummy.new(avatar: File.new(fixture_file('rotated.jpg')))
69
+ expect(dummy.errors.keys).to match_array []
70
+ assert dummy.valid?
71
+ end
72
+
73
+ end
74
+
75
+ context "using the helper with a conditional" do
76
+ before do
77
+ rebuild_class
78
+ Dummy.validates_attachment :avatar, presence: true,
79
+ content_type: { content_type: "image/jpeg" },
80
+ size: { in: 0..10240 },
81
+ if: :title_present?
82
+ end
83
+
84
+ it "validates the attachment if title is present" do
85
+ Dummy.class_eval do
86
+ def title_present?
87
+ true
88
+ end
89
+ end
90
+ dummy = Dummy.new(avatar: File.new(fixture_file("12k.png")))
91
+ expect(dummy.errors.keys).to match_array [:avatar_content_type, :avatar, :avatar_file_size]
92
+ end
93
+
94
+ it "does not validate attachment if title is not present" do
95
+ Dummy.class_eval do
96
+ def title_present?
97
+ false
98
+ end
99
+ end
100
+ dummy = Dummy.new(avatar: File.new(fixture_file("12k.png")))
101
+ assert_equal [], dummy.errors.keys
102
+ end
103
+ end
104
+
105
+ context 'with no other validations on the Dummy#avatar attachment' do
106
+ before do
107
+ reset_class("Dummy")
108
+ Dummy.has_attached_file :avatar
109
+ Paperclip.reset_duplicate_clash_check!
110
+ end
111
+
112
+ it 'raises an error when no content_type validation exists' do
113
+ assert_raises(Paperclip::Errors::MissingRequiredValidatorError) do
114
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
115
+ end
116
+ end
117
+
118
+ it 'does not raise an error when a content_type validation exists' do
119
+ Dummy.validates_attachment :avatar, content_type: { content_type: "image/jpeg" }
120
+
121
+ assert_nothing_raised do
122
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
123
+ end
124
+ end
125
+
126
+ it 'does not raise an error when a content_type validation exists using validates_with' do
127
+ Dummy.validates_with Paperclip::Validators::AttachmentContentTypeValidator, attributes: :attachment, content_type: 'images/jpeg'
128
+
129
+ assert_nothing_raised do
130
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
131
+ end
132
+ end
133
+
134
+ it 'does not raise an error when an inherited validator is used' do
135
+ class MyValidator < Paperclip::Validators::AttachmentContentTypeValidator
136
+ def initialize(options)
137
+ options[:content_type] = "images/jpeg" unless options.has_key?(:content_type)
138
+ super
139
+ end
140
+ end
141
+ Dummy.validates_with MyValidator, attributes: :attachment
142
+
143
+ assert_nothing_raised do
144
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
145
+ end
146
+ end
147
+
148
+ it 'does not raise an error when a file_name validation exists' do
149
+ Dummy.validates_attachment :avatar, file_name: { matches: /png$/ }
150
+
151
+ assert_nothing_raised do
152
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
153
+ end
154
+ end
155
+
156
+ it 'does not raise an error when a the validation has been explicitly rejected' do
157
+ Dummy.validates_attachment :avatar, file_type_ignorance: true
158
+
159
+ assert_nothing_raised do
160
+ Dummy.new(avatar: File.new(fixture_file("12k.png")))
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'active_record'
4
+ require 'active_record/version'
5
+ require 'active_support'
6
+ require 'active_support/core_ext'
7
+ require 'mocha/api'
8
+ require 'bourne'
9
+ require 'ostruct'
10
+
11
+ ROOT = Pathname(File.expand_path(File.join(File.dirname(__FILE__), '..')))
12
+
13
+ puts "Testing against version #{ActiveRecord::VERSION::STRING}"
14
+
15
+ $LOAD_PATH << File.join(ROOT, 'lib')
16
+ $LOAD_PATH << File.join(ROOT, 'lib', 'paperclip')
17
+ require File.join(ROOT, 'lib', 'paperclip.rb')
18
+
19
+ FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
20
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
21
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
22
+ ActiveRecord::Base.establish_connection(config['test'])
23
+ Paperclip.options[:logger] = ActiveRecord::Base.logger
24
+
25
+ Dir[File.join(ROOT, 'spec', 'support', '**', '*.rb')].each{|f| require f }
26
+
27
+ Rails = FakeRails.new('test', Pathname.new(ROOT).join('tmp'))
28
+ ActiveSupport::Deprecation.silenced = true
29
+
30
+ RSpec.configure do |config|
31
+ config.include Assertions
32
+ config.include ModelReconstruction
33
+ config.include TestData
34
+ config.extend VersionHelper
35
+ config.extend RailsHelpers::ClassMethods
36
+ config.mock_framework = :mocha
37
+ config.before(:all) do
38
+ rebuild_model
39
+ end
40
+ end
@@ -0,0 +1,71 @@
1
+ module Assertions
2
+ def assert(truthy, message = nil)
3
+ expect(!!truthy).to(eq(true), message)
4
+ end
5
+
6
+ def assert_equal(expected, actual, message = nil)
7
+ expect(actual).to(eq(expected), message)
8
+ end
9
+
10
+ def assert_not_equal(expected, actual, message = nil)
11
+ expect(actual).to_not(eq(expected), message)
12
+ end
13
+
14
+ def assert_raises(exception_class, message = nil, &block)
15
+ expect(&block).to raise_error(exception_class, message)
16
+ end
17
+
18
+ def assert_nothing_raised(&block)
19
+ expect(&block).to_not raise_error
20
+ end
21
+
22
+ def assert_nil(thing)
23
+ expect(thing).to be_nil
24
+ end
25
+
26
+ def assert_contains(haystack, needle)
27
+ expect(haystack).to include(needle)
28
+ end
29
+
30
+ def assert_match(pattern, value)
31
+ expect(value).to match(pattern)
32
+ end
33
+
34
+ def assert_no_match(pattern, value)
35
+ expect(value).to_not match(pattern)
36
+ end
37
+
38
+ def assert_file_exists(path_to_file)
39
+ expect(path_to_file).to exist
40
+ end
41
+
42
+ def assert_file_not_exists(path_to_file)
43
+ expect(path_to_file).to_not exist
44
+ end
45
+
46
+ def assert_empty(object)
47
+ expect(object).to be_empty
48
+ end
49
+
50
+ def assert_success_response(url)
51
+ Net::HTTP.get_response(URI.parse(url)) do |response|
52
+ assert_equal "200", response.code,
53
+ "Expected HTTP response code 200, got #{response.code}"
54
+ end
55
+ end
56
+
57
+ def assert_not_found_response(url)
58
+ Net::HTTP.get_response(URI.parse(url)) do |response|
59
+ assert_equal "404", response.code,
60
+ "Expected HTTP response code 404, got #{response.code}"
61
+ end
62
+ end
63
+
64
+ def assert_frame_dimensions(range, frames)
65
+ frames.each_with_index do |frame, frame_index|
66
+ frame.split('x').each_with_index do |dimension, dimension_index |
67
+ assert range.include?(dimension.to_i), "Frame #{frame_index}[#{dimension_index}] should have been within #{range.inspect}, but was #{dimension}"
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,21 @@
1
+ class FakeModel
2
+ attr_accessor(
3
+ :avatar_file_name,
4
+ :avatar_file_size,
5
+ :avatar_updated_at,
6
+ :avatar_content_type,
7
+ :avatar_fingerprint,
8
+ :id
9
+ )
10
+
11
+ def errors
12
+ @errors ||= []
13
+ end
14
+
15
+ def run_paperclip_callbacks name, *args
16
+ end
17
+
18
+ def valid?
19
+ errors.empty?
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ class FakeRails
2
+ def initialize(env, root)
3
+ @env = env
4
+ @root = root
5
+ end
6
+
7
+ attr_accessor :env, :root
8
+
9
+ def const_defined?(const)
10
+ false
11
+ end
12
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :accept do |expected|
2
+ match do |actual|
3
+ actual.matches?(expected)
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :exist do |expected|
2
+ match do |actual|
3
+ File.exist?(actual)
4
+ end
5
+ end
File without changes
@@ -0,0 +1,60 @@
1
+ module ModelReconstruction
2
+ def reset_class class_name
3
+ ActiveRecord::Base.send(:include, Paperclip::Glue)
4
+ Object.send(:remove_const, class_name) rescue nil
5
+ klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
6
+
7
+ klass.class_eval do
8
+ include Paperclip::Glue
9
+ end
10
+
11
+ klass.reset_column_information
12
+ klass.connection_pool.clear_table_cache!(klass.table_name) if klass.connection_pool.respond_to?(:clear_table_cache!)
13
+ klass.connection.schema_cache.clear_table_cache!(klass.table_name) if klass.connection.respond_to?(:schema_cache)
14
+ klass
15
+ end
16
+
17
+ def reset_table table_name, &block
18
+ block ||= lambda { |table| true }
19
+ ActiveRecord::Base.connection.create_table :dummies, {force: true}, &block
20
+ end
21
+
22
+ def modify_table table_name, &block
23
+ ActiveRecord::Base.connection.change_table :dummies, &block
24
+ end
25
+
26
+ def rebuild_model options = {}
27
+ ActiveRecord::Base.connection.create_table :dummies, force: true do |table|
28
+ table.column :title, :string
29
+ table.column :other, :string
30
+ table.column :avatar_file_name, :string
31
+ table.column :avatar_content_type, :string
32
+ table.column :avatar_file_size, :integer
33
+ table.column :avatar_updated_at, :datetime
34
+ table.column :avatar_fingerprint, :string
35
+ end
36
+ rebuild_class options
37
+ end
38
+
39
+ def rebuild_class options = {}
40
+ reset_class("Dummy").tap do |klass|
41
+ klass.has_attached_file :avatar, options
42
+ klass.do_not_validate_attachment_file_type :avatar
43
+ Paperclip.reset_duplicate_clash_check!
44
+ end
45
+ end
46
+
47
+ def rebuild_meta_class_of obj, options = {}
48
+ meta_class_of(obj).tap do |metaklass|
49
+ metaklass.has_attached_file :avatar, options
50
+ metaklass.do_not_validate_attachment_file_type :avatar
51
+ Paperclip.reset_duplicate_clash_check!
52
+ end
53
+ end
54
+
55
+ def meta_class_of(obj)
56
+ class << obj
57
+ self
58
+ end
59
+ end
60
+ end