jr-paperclip 7.3.0
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.
- checksums.yaml +7 -0
- data/.github/FUNDING.yml +3 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/custom.md +10 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/reviewdog.yml +23 -0
- data/.github/workflows/test.yml +46 -0
- data/.gitignore +19 -0
- data/.qlty/.gitignore +7 -0
- data/.qlty/qlty.toml +89 -0
- data/.rubocop.yml +1060 -0
- data/Appraisals +29 -0
- data/CONTRIBUTING.md +85 -0
- data/Gemfile +17 -0
- data/LICENSE +25 -0
- data/NEWS +567 -0
- data/README.md +1083 -0
- data/RELEASING.md +17 -0
- data/Rakefile +52 -0
- data/bin/console +11 -0
- data/features/basic_integration.feature +85 -0
- data/features/migration.feature +29 -0
- data/features/rake_tasks.feature +62 -0
- data/features/step_definitions/attachment_steps.rb +121 -0
- data/features/step_definitions/html_steps.rb +15 -0
- data/features/step_definitions/rails_steps.rb +271 -0
- data/features/step_definitions/s3_steps.rb +16 -0
- data/features/step_definitions/web_steps.rb +106 -0
- data/features/support/env.rb +12 -0
- data/features/support/file_helpers.rb +34 -0
- data/features/support/fixtures/boot_config.txt +15 -0
- data/features/support/fixtures/gemfile.txt +5 -0
- data/features/support/fixtures/preinitializer.txt +20 -0
- data/features/support/paths.rb +28 -0
- data/features/support/rails.rb +39 -0
- data/features/support/selectors.rb +19 -0
- data/features/support/webmock_setup.rb +8 -0
- data/gemfiles/7.0.gemfile +20 -0
- data/gemfiles/7.1.gemfile +20 -0
- data/gemfiles/7.2.gemfile +20 -0
- data/gemfiles/8.0.gemfile +20 -0
- data/gemfiles/8.1.gemfile +20 -0
- data/lib/generators/paperclip/USAGE +8 -0
- data/lib/generators/paperclip/paperclip_generator.rb +36 -0
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +15 -0
- data/lib/jr-paperclip.rb +1 -0
- data/lib/paperclip/attachment.rb +634 -0
- data/lib/paperclip/attachment_registry.rb +60 -0
- data/lib/paperclip/callbacks.rb +42 -0
- data/lib/paperclip/content_type_detector.rb +85 -0
- data/lib/paperclip/errors.rb +34 -0
- data/lib/paperclip/file_command_content_type_detector.rb +28 -0
- data/lib/paperclip/filename_cleaner.rb +15 -0
- data/lib/paperclip/geometry.rb +157 -0
- data/lib/paperclip/geometry_detector_factory.rb +45 -0
- data/lib/paperclip/geometry_parser_factory.rb +31 -0
- data/lib/paperclip/glue.rb +18 -0
- data/lib/paperclip/has_attached_file.rb +116 -0
- data/lib/paperclip/helpers.rb +60 -0
- data/lib/paperclip/interpolations/plural_cache.rb +18 -0
- data/lib/paperclip/interpolations.rb +205 -0
- data/lib/paperclip/io_adapters/abstract_adapter.rb +75 -0
- data/lib/paperclip/io_adapters/attachment_adapter.rb +56 -0
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +22 -0
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +19 -0
- data/lib/paperclip/io_adapters/file_adapter.rb +26 -0
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +16 -0
- data/lib/paperclip/io_adapters/identity_adapter.rb +17 -0
- data/lib/paperclip/io_adapters/nil_adapter.rb +37 -0
- data/lib/paperclip/io_adapters/registry.rb +36 -0
- data/lib/paperclip/io_adapters/stringio_adapter.rb +36 -0
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +44 -0
- data/lib/paperclip/io_adapters/uri_adapter.rb +78 -0
- data/lib/paperclip/locales/en.yml +18 -0
- data/lib/paperclip/locales/fr.yml +18 -0
- data/lib/paperclip/locales/gd.yml +20 -0
- data/lib/paperclip/logger.rb +21 -0
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +54 -0
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +101 -0
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +59 -0
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +97 -0
- data/lib/paperclip/matchers.rb +64 -0
- data/lib/paperclip/media_type_spoof_detector.rb +93 -0
- data/lib/paperclip/missing_attachment_styles.rb +84 -0
- data/lib/paperclip/processor.rb +56 -0
- data/lib/paperclip/processor_helpers.rb +52 -0
- data/lib/paperclip/rails_environment.rb +21 -0
- data/lib/paperclip/railtie.rb +31 -0
- data/lib/paperclip/schema.rb +104 -0
- data/lib/paperclip/storage/filesystem.rb +99 -0
- data/lib/paperclip/storage/fog.rb +262 -0
- data/lib/paperclip/storage/s3.rb +497 -0
- data/lib/paperclip/storage.rb +3 -0
- data/lib/paperclip/style.rb +106 -0
- data/lib/paperclip/tempfile.rb +42 -0
- data/lib/paperclip/tempfile_factory.rb +22 -0
- data/lib/paperclip/thumbnail.rb +131 -0
- data/lib/paperclip/url_generator.rb +83 -0
- data/lib/paperclip/validators/attachment_content_type_validator.rb +95 -0
- data/lib/paperclip/validators/attachment_file_name_validator.rb +82 -0
- data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +28 -0
- data/lib/paperclip/validators/attachment_presence_validator.rb +28 -0
- data/lib/paperclip/validators/attachment_size_validator.rb +126 -0
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +29 -0
- data/lib/paperclip/validators.rb +73 -0
- data/lib/paperclip/version.rb +3 -0
- data/lib/paperclip.rb +215 -0
- data/lib/tasks/paperclip.rake +140 -0
- data/paperclip.gemspec +51 -0
- data/shoulda_macros/paperclip.rb +134 -0
- data/spec/database.yml +4 -0
- data/spec/paperclip/attachment_definitions_spec.rb +13 -0
- data/spec/paperclip/attachment_processing_spec.rb +79 -0
- data/spec/paperclip/attachment_registry_spec.rb +158 -0
- data/spec/paperclip/attachment_spec.rb +1617 -0
- data/spec/paperclip/content_type_detector_spec.rb +58 -0
- data/spec/paperclip/file_command_content_type_detector_spec.rb +40 -0
- data/spec/paperclip/filename_cleaner_spec.rb +13 -0
- data/spec/paperclip/geometry_detector_spec.rb +47 -0
- data/spec/paperclip/geometry_parser_spec.rb +73 -0
- data/spec/paperclip/geometry_spec.rb +267 -0
- data/spec/paperclip/glue_spec.rb +63 -0
- data/spec/paperclip/has_attached_file_spec.rb +78 -0
- data/spec/paperclip/integration_spec.rb +702 -0
- data/spec/paperclip/interpolations_spec.rb +270 -0
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +160 -0
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +167 -0
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +88 -0
- data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +134 -0
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +142 -0
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
- data/spec/paperclip/io_adapters/nil_adapter_spec.rb +25 -0
- data/spec/paperclip/io_adapters/registry_spec.rb +35 -0
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +64 -0
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +146 -0
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +231 -0
- data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +108 -0
- data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
- data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
- data/spec/paperclip/media_type_spoof_detector_spec.rb +126 -0
- data/spec/paperclip/meta_class_spec.rb +30 -0
- data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +88 -0
- data/spec/paperclip/paperclip_spec.rb +196 -0
- data/spec/paperclip/plural_cache_spec.rb +37 -0
- data/spec/paperclip/processor_helpers_spec.rb +57 -0
- data/spec/paperclip/processor_spec.rb +26 -0
- data/spec/paperclip/rails_environment_spec.rb +30 -0
- data/spec/paperclip/rake_spec.rb +103 -0
- data/spec/paperclip/schema_spec.rb +298 -0
- data/spec/paperclip/storage/filesystem_spec.rb +102 -0
- data/spec/paperclip/storage/fog_spec.rb +606 -0
- data/spec/paperclip/storage/s3_live_spec.rb +188 -0
- data/spec/paperclip/storage/s3_spec.rb +1974 -0
- data/spec/paperclip/style_spec.rb +251 -0
- data/spec/paperclip/tempfile_factory_spec.rb +33 -0
- data/spec/paperclip/tempfile_spec.rb +35 -0
- data/spec/paperclip/thumbnail_spec.rb +504 -0
- data/spec/paperclip/url_generator_spec.rb +231 -0
- data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +410 -0
- data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +249 -0
- data/spec/paperclip/validators/attachment_presence_validator_spec.rb +85 -0
- data/spec/paperclip/validators/attachment_size_validator_spec.rb +325 -0
- data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +48 -0
- data/spec/paperclip/validators_spec.rb +179 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/support/assertions.rb +84 -0
- data/spec/support/fake_model.rb +24 -0
- data/spec/support/fake_rails.rb +12 -0
- data/spec/support/fixtures/12k.png +0 -0
- data/spec/support/fixtures/50x50.png +0 -0
- data/spec/support/fixtures/5k.png +0 -0
- data/spec/support/fixtures/animated +0 -0
- data/spec/support/fixtures/animated.gif +0 -0
- data/spec/support/fixtures/animated.unknown +0 -0
- data/spec/support/fixtures/aws_s3.yml +13 -0
- data/spec/support/fixtures/bad.png +1 -0
- data/spec/support/fixtures/empty.html +1 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/fixtures/fog.yml +8 -0
- data/spec/support/fixtures/rotated.jpg +0 -0
- data/spec/support/fixtures/s3.yml +8 -0
- data/spec/support/fixtures/sample.xlsm +0 -0
- data/spec/support/fixtures/spaced file.jpg +0 -0
- data/spec/support/fixtures/spaced file.png +0 -0
- data/spec/support/fixtures/text.txt +1 -0
- data/spec/support/fixtures/twopage.pdf +0 -0
- data/spec/support/fixtures/uppercase.PNG +0 -0
- data/spec/support/matchers/accept.rb +5 -0
- data/spec/support/matchers/exist.rb +5 -0
- data/spec/support/matchers/have_column.rb +23 -0
- data/spec/support/mock_attachment.rb +24 -0
- data/spec/support/mock_interpolator.rb +24 -0
- data/spec/support/mock_url_generator_builder.rb +26 -0
- data/spec/support/model_reconstruction.rb +72 -0
- data/spec/support/reporting.rb +11 -0
- data/spec/support/test_data.rb +13 -0
- data/spec/support/version_helper.rb +9 -0
- metadata +702 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::ContentTypeDetector do
|
|
4
|
+
it "returns a meaningful content type for open xml spreadsheets" do
|
|
5
|
+
file = File.new(fixture_file("empty.xlsx"))
|
|
6
|
+
assert_equal "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
7
|
+
Paperclip::ContentTypeDetector.new(file.path).detect
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'returns a more specific content type based on the filename if it matches
|
|
11
|
+
multiple content types' do
|
|
12
|
+
file = File.new(fixture_file('sample.xlsm'))
|
|
13
|
+
assert_equal 'application/vnd.ms-excel.sheet.macroenabled.12',
|
|
14
|
+
Paperclip::ContentTypeDetector.new(file.path).detect
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "gives a sensible default when the name is empty" do
|
|
18
|
+
assert_equal "application/octet-stream", Paperclip::ContentTypeDetector.new("").detect
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "returns the empty content type when the file is empty" do
|
|
22
|
+
tempfile = Tempfile.new("empty")
|
|
23
|
+
assert_equal "inode/x-empty", Paperclip::ContentTypeDetector.new(tempfile.path).detect
|
|
24
|
+
tempfile.close
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "returns content type of file if it is an acceptable type" do
|
|
28
|
+
allow(MIME::Types).to receive(:type_for).and_return([
|
|
29
|
+
MIME::Type.new("content-type" => "application/mp4"),
|
|
30
|
+
MIME::Type.new("content-type" => "video/mp4"),
|
|
31
|
+
MIME::Type.new("content-type" => "audio/mp4"),
|
|
32
|
+
])
|
|
33
|
+
allow_any_instance_of(Paperclip::ContentTypeDetector).to receive(:type_from_file_contents).and_return("video/mp4")
|
|
34
|
+
@filename = "my_file.mp4"
|
|
35
|
+
assert_equal "video/mp4", Paperclip::ContentTypeDetector.new(@filename).detect
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "finds the right type in the list via the file command" do
|
|
39
|
+
@filename = "#{Dir.tmpdir}/something.hahalolnotreal"
|
|
40
|
+
File.open(@filename, "w+") do |file|
|
|
41
|
+
file.puts "This is a text file."
|
|
42
|
+
file.rewind
|
|
43
|
+
assert_equal "text/plain", Paperclip::ContentTypeDetector.new(file.path).detect
|
|
44
|
+
end
|
|
45
|
+
FileUtils.rm @filename
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "returns a sensible default if something is wrong, like the file is gone" do
|
|
49
|
+
@filename = "/path/to/nothing"
|
|
50
|
+
assert_equal "application/octet-stream", Paperclip::ContentTypeDetector.new(@filename).detect
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "returns a sensible default when the file command is missing" do
|
|
54
|
+
allow(Paperclip).to receive(:run).and_raise(Terrapin::CommandLineError.new)
|
|
55
|
+
@filename = "/path/to/something"
|
|
56
|
+
assert_equal "application/octet-stream", Paperclip::ContentTypeDetector.new(@filename).detect
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::FileCommandContentTypeDetector do
|
|
4
|
+
it "returns a content type based on the content of the file" do
|
|
5
|
+
tempfile = Tempfile.new("something")
|
|
6
|
+
tempfile.write("This is a file.")
|
|
7
|
+
tempfile.rewind
|
|
8
|
+
|
|
9
|
+
assert_equal "text/plain", Paperclip::FileCommandContentTypeDetector.new(tempfile.path).detect
|
|
10
|
+
|
|
11
|
+
tempfile.close
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "returns a sensible default when the file command is missing" do
|
|
15
|
+
allow(Paperclip).to receive(:run).and_raise(Terrapin::CommandLineError.new)
|
|
16
|
+
@filename = "/path/to/something"
|
|
17
|
+
assert_equal "application/octet-stream",
|
|
18
|
+
Paperclip::FileCommandContentTypeDetector.new(@filename).detect
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "returns a sensible default on the odd chance that run returns nil" do
|
|
22
|
+
allow(Paperclip).to receive(:run).and_return(nil)
|
|
23
|
+
assert_equal "application/octet-stream",
|
|
24
|
+
Paperclip::FileCommandContentTypeDetector.new("windows").detect
|
|
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
|
+
allow(Paperclip).to receive(:run).and_return("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
|
+
allow(Paperclip).to receive(:run).and_return("text/html; charset=us-ascii")
|
|
37
|
+
expect(detector.detect).to eq("text/html")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::FilenameCleaner do
|
|
4
|
+
it "converts invalid characters to underscores" do
|
|
5
|
+
cleaner = Paperclip::FilenameCleaner.new(/[aeiou]/)
|
|
6
|
+
expect(cleaner.call("baseball")).to eq "b_s_b_ll"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "does not convert anything if the character regex is nil" do
|
|
10
|
+
cleaner = Paperclip::FilenameCleaner.new(nil)
|
|
11
|
+
expect(cleaner.call("baseball")).to eq "baseball"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::GeometryDetector do
|
|
4
|
+
it "identifies an image and extract its dimensions" do
|
|
5
|
+
allow_any_instance_of(Paperclip::GeometryParser).to receive(:make).and_return(:correct)
|
|
6
|
+
file = fixture_file("5k.png")
|
|
7
|
+
factory = Paperclip::GeometryDetector.new(file)
|
|
8
|
+
|
|
9
|
+
output = factory.make
|
|
10
|
+
|
|
11
|
+
expect(output).to eq :correct
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "identifies an image and extract its dimensions and orientation" do
|
|
15
|
+
allow_any_instance_of(Paperclip::GeometryParser).to receive(:make).and_return(:correct)
|
|
16
|
+
file = fixture_file("rotated.jpg")
|
|
17
|
+
factory = Paperclip::GeometryDetector.new(file)
|
|
18
|
+
|
|
19
|
+
output = factory.make
|
|
20
|
+
|
|
21
|
+
expect(output).to eq :correct
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "avoids reading EXIF orientation if so configured" do
|
|
25
|
+
begin
|
|
26
|
+
Paperclip.options[:use_exif_orientation] = false
|
|
27
|
+
allow_any_instance_of(Paperclip::GeometryParser).to receive(:make).and_return(:correct)
|
|
28
|
+
file = fixture_file("rotated.jpg")
|
|
29
|
+
factory = Paperclip::GeometryDetector.new(file)
|
|
30
|
+
|
|
31
|
+
output = factory.make
|
|
32
|
+
|
|
33
|
+
expect(output).to eq :correct
|
|
34
|
+
ensure
|
|
35
|
+
Paperclip.options[:use_exif_orientation] = true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "raises an exception with a message when the file is not an image" do
|
|
40
|
+
file = fixture_file("text.txt")
|
|
41
|
+
factory = Paperclip::GeometryDetector.new(file)
|
|
42
|
+
|
|
43
|
+
expect do
|
|
44
|
+
factory.make
|
|
45
|
+
end.to raise_error(Paperclip::Errors::NotIdentifiedByImageMagickError, "Could not identify image size")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::GeometryParser do
|
|
4
|
+
it "identifies an image and extract its dimensions with no orientation" do
|
|
5
|
+
allow(Paperclip::Geometry).to receive(:new).with(
|
|
6
|
+
height: "73",
|
|
7
|
+
width: "434",
|
|
8
|
+
modifier: nil,
|
|
9
|
+
orientation: nil
|
|
10
|
+
).and_return(:correct)
|
|
11
|
+
factory = Paperclip::GeometryParser.new("434x73")
|
|
12
|
+
|
|
13
|
+
output = factory.make
|
|
14
|
+
|
|
15
|
+
assert_equal :correct, output
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "identifies an image and extract its dimensions with an empty orientation" do
|
|
19
|
+
allow(Paperclip::Geometry).to receive(:new).with(
|
|
20
|
+
height: "73",
|
|
21
|
+
width: "434",
|
|
22
|
+
modifier: nil,
|
|
23
|
+
orientation: ""
|
|
24
|
+
).and_return(:correct)
|
|
25
|
+
factory = Paperclip::GeometryParser.new("434x73,")
|
|
26
|
+
|
|
27
|
+
output = factory.make
|
|
28
|
+
|
|
29
|
+
assert_equal :correct, output
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "identifies an image and extract its dimensions and orientation" do
|
|
33
|
+
allow(Paperclip::Geometry).to receive(:new).with(
|
|
34
|
+
height: "200",
|
|
35
|
+
width: "300",
|
|
36
|
+
modifier: nil,
|
|
37
|
+
orientation: "6"
|
|
38
|
+
).and_return(:correct)
|
|
39
|
+
factory = Paperclip::GeometryParser.new("300x200,6")
|
|
40
|
+
|
|
41
|
+
output = factory.make
|
|
42
|
+
|
|
43
|
+
assert_equal :correct, output
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "identifies an image and extract its dimensions and modifier" do
|
|
47
|
+
allow(Paperclip::Geometry).to receive(:new).with(
|
|
48
|
+
height: "64",
|
|
49
|
+
width: "64",
|
|
50
|
+
modifier: "#",
|
|
51
|
+
orientation: nil
|
|
52
|
+
).and_return(:correct)
|
|
53
|
+
factory = Paperclip::GeometryParser.new("64x64#")
|
|
54
|
+
|
|
55
|
+
output = factory.make
|
|
56
|
+
|
|
57
|
+
assert_equal :correct, output
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "identifies an image and extract its dimensions, orientation, and modifier" do
|
|
61
|
+
allow(Paperclip::Geometry).to receive(:new).with(
|
|
62
|
+
height: "50",
|
|
63
|
+
width: "100",
|
|
64
|
+
modifier: ">",
|
|
65
|
+
orientation: "7"
|
|
66
|
+
).and_return(:correct)
|
|
67
|
+
factory = Paperclip::GeometryParser.new("100x50,7>")
|
|
68
|
+
|
|
69
|
+
output = factory.make
|
|
70
|
+
|
|
71
|
+
assert_equal :correct, output
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::Geometry do
|
|
4
|
+
context "Paperclip::Geometry" do
|
|
5
|
+
it "correctly reports its given dimensions" do
|
|
6
|
+
assert @geo = Paperclip::Geometry.new(1024, 768)
|
|
7
|
+
assert_equal 1024, @geo.width
|
|
8
|
+
assert_equal 768, @geo.height
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "sets height to 0 if height dimension is missing" do
|
|
12
|
+
assert @geo = Paperclip::Geometry.new(1024)
|
|
13
|
+
assert_equal 1024, @geo.width
|
|
14
|
+
assert_equal 0, @geo.height
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "sets width to 0 if width dimension is missing" do
|
|
18
|
+
assert @geo = Paperclip::Geometry.new(nil, 768)
|
|
19
|
+
assert_equal 0, @geo.width
|
|
20
|
+
assert_equal 768, @geo.height
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "is generated from a WxH-formatted string" do
|
|
24
|
+
assert @geo = Paperclip::Geometry.parse("800x600")
|
|
25
|
+
assert_equal 800, @geo.width
|
|
26
|
+
assert_equal 600, @geo.height
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "is generated from a xH-formatted string" do
|
|
30
|
+
assert @geo = Paperclip::Geometry.parse("x600")
|
|
31
|
+
assert_equal 0, @geo.width
|
|
32
|
+
assert_equal 600, @geo.height
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "is generated from a Wx-formatted string" do
|
|
36
|
+
assert @geo = Paperclip::Geometry.parse("800x")
|
|
37
|
+
assert_equal 800, @geo.width
|
|
38
|
+
assert_equal 0, @geo.height
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "is generated from a W-formatted string" do
|
|
42
|
+
assert @geo = Paperclip::Geometry.parse("800")
|
|
43
|
+
assert_equal 800, @geo.width
|
|
44
|
+
assert_equal 0, @geo.height
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "ensures the modifier is nil if not present" do
|
|
48
|
+
assert @geo = Paperclip::Geometry.parse("123x456")
|
|
49
|
+
assert_nil @geo.modifier
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "recognizes an EXIF orientation and not rotate with auto_orient if not necessary" do
|
|
53
|
+
geo = Paperclip::Geometry.new(width: 1024, height: 768, orientation: 1)
|
|
54
|
+
assert geo
|
|
55
|
+
assert_equal 1024, geo.width
|
|
56
|
+
assert_equal 768, geo.height
|
|
57
|
+
|
|
58
|
+
geo.auto_orient
|
|
59
|
+
|
|
60
|
+
assert_equal 1024, geo.width
|
|
61
|
+
assert_equal 768, geo.height
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "recognizes an EXIF orientation and rotate with auto_orient if necessary" do
|
|
65
|
+
geo = Paperclip::Geometry.new(width: 1024, height: 768, orientation: 6)
|
|
66
|
+
assert geo
|
|
67
|
+
assert_equal 1024, geo.width
|
|
68
|
+
assert_equal 768, geo.height
|
|
69
|
+
|
|
70
|
+
geo.auto_orient
|
|
71
|
+
|
|
72
|
+
assert_equal 768, geo.width
|
|
73
|
+
assert_equal 1024, geo.height
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "treats x and X the same in geometries" do
|
|
77
|
+
@lower = Paperclip::Geometry.parse("123x456")
|
|
78
|
+
@upper = Paperclip::Geometry.parse("123X456")
|
|
79
|
+
assert_equal 123, @lower.width
|
|
80
|
+
assert_equal 123, @upper.width
|
|
81
|
+
assert_equal 456, @lower.height
|
|
82
|
+
assert_equal 456, @upper.height
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
[">", "<", "#", "@", "@>", ">@", "%", "^", "!", nil].each do |mod|
|
|
86
|
+
it "ensures the modifier #{description} is preserved" do
|
|
87
|
+
assert @geo = Paperclip::Geometry.parse("123x456#{mod}")
|
|
88
|
+
assert_equal mod, @geo.modifier
|
|
89
|
+
assert_equal "123x456#{mod}", @geo.to_s
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "ensures the modifier #{description} is preserved with no height" do
|
|
93
|
+
assert @geo = Paperclip::Geometry.parse("123x#{mod}")
|
|
94
|
+
assert_equal mod, @geo.modifier
|
|
95
|
+
assert_equal "123#{mod}", @geo.to_s
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "makes sure the modifier gets passed during transformation_to" do
|
|
100
|
+
assert @src = Paperclip::Geometry.parse("123x456")
|
|
101
|
+
assert @dst = Paperclip::Geometry.parse("123x456>")
|
|
102
|
+
assert_equal ["123x456>", nil], @src.transformation_to(@dst)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "generates correct ImageMagick formatting string for W-formatted string" do
|
|
106
|
+
assert @geo = Paperclip::Geometry.parse("800")
|
|
107
|
+
assert_equal "800", @geo.to_s
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "generates correct ImageMagick formatting string for Wx-formatted string" do
|
|
111
|
+
assert @geo = Paperclip::Geometry.parse("800x")
|
|
112
|
+
assert_equal "800", @geo.to_s
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "generates correct ImageMagick formatting string for xH-formatted string" do
|
|
116
|
+
assert @geo = Paperclip::Geometry.parse("x600")
|
|
117
|
+
assert_equal "x600", @geo.to_s
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "generates correct ImageMagick formatting string for WxH-formatted string" do
|
|
121
|
+
assert @geo = Paperclip::Geometry.parse("800x600")
|
|
122
|
+
assert_equal "800x600", @geo.to_s
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "is generated from a file" do
|
|
126
|
+
file = fixture_file("5k.png")
|
|
127
|
+
file = File.new(file, "rb")
|
|
128
|
+
assert_nothing_raised { @geo = Paperclip::Geometry.from_file(file) }
|
|
129
|
+
assert_equal 66, @geo.height
|
|
130
|
+
assert_equal 434, @geo.width
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "is generated from a file path" do
|
|
134
|
+
file = fixture_file("5k.png")
|
|
135
|
+
assert_nothing_raised { @geo = Paperclip::Geometry.from_file(file) }
|
|
136
|
+
assert_equal 66, @geo.height
|
|
137
|
+
assert_equal 434, @geo.width
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "calculates an EXIF-rotated image dimensions from a path" do
|
|
141
|
+
file = fixture_file("rotated.jpg")
|
|
142
|
+
assert_nothing_raised { @geo = Paperclip::Geometry.from_file(file) }
|
|
143
|
+
@geo.auto_orient
|
|
144
|
+
assert_equal 300, @geo.height
|
|
145
|
+
assert_equal 200, @geo.width
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "does not generate from a bad file" do
|
|
149
|
+
file = "/home/This File Does Not Exist.omg"
|
|
150
|
+
expect do
|
|
151
|
+
@geo = Paperclip::Geometry.from_file(file)
|
|
152
|
+
end.to raise_error(Paperclip::Errors::NotIdentifiedByImageMagickError,
|
|
153
|
+
"Could not identify image size")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "does not generate from a blank filename" do
|
|
157
|
+
file = ""
|
|
158
|
+
expect do
|
|
159
|
+
@geo = Paperclip::Geometry.from_file(file)
|
|
160
|
+
end.to raise_error(Paperclip::Errors::NotIdentifiedByImageMagickError,
|
|
161
|
+
"Cannot find the geometry of a file with a blank name")
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "does not generate from a nil file" do
|
|
165
|
+
file = nil
|
|
166
|
+
expect do
|
|
167
|
+
@geo = Paperclip::Geometry.from_file(file)
|
|
168
|
+
end.to raise_error(Paperclip::Errors::NotIdentifiedByImageMagickError,
|
|
169
|
+
"Cannot find the geometry of a file with a blank name")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "does not generate from a file with no path" do
|
|
173
|
+
file = double("file", path: "")
|
|
174
|
+
allow(file).to receive(:respond_to?).with(:path).and_return(true)
|
|
175
|
+
expect do
|
|
176
|
+
@geo = Paperclip::Geometry.from_file(file)
|
|
177
|
+
end.to raise_error(Paperclip::Errors::NotIdentifiedByImageMagickError,
|
|
178
|
+
"Cannot find the geometry of a file with a blank name")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "lets us know when a command isn't found versus a processing error" do
|
|
182
|
+
old_path = ENV["PATH"]
|
|
183
|
+
begin
|
|
184
|
+
ENV["PATH"] = ""
|
|
185
|
+
assert_raises(Paperclip::Errors::CommandNotFoundError) do
|
|
186
|
+
file = fixture_file("5k.png")
|
|
187
|
+
@geo = Paperclip::Geometry.from_file(file)
|
|
188
|
+
end
|
|
189
|
+
ensure
|
|
190
|
+
ENV["PATH"] = old_path
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
[["vertical", 900, 1440, true, false, false, 1440, 900, 0.625],
|
|
195
|
+
["horizontal", 1024, 768, false, true, false, 1024, 768, 1.3333],
|
|
196
|
+
["square", 100, 100, false, false, true, 100, 100, 1]].each do |args|
|
|
197
|
+
context "performing calculations on a #{args[0]} viewport" do
|
|
198
|
+
before do
|
|
199
|
+
@geo = Paperclip::Geometry.new(args[1], args[2])
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "is #{args[3] ? '' : 'not'} vertical" do
|
|
203
|
+
assert_equal args[3], @geo.vertical?
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "is #{args[4] ? '' : 'not'} horizontal" do
|
|
207
|
+
assert_equal args[4], @geo.horizontal?
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it "is #{args[5] ? '' : 'not'} square" do
|
|
211
|
+
assert_equal args[5], @geo.square?
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it "reports that #{args[6]} is the larger dimension" do
|
|
215
|
+
assert_equal args[6], @geo.larger
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "reports that #{args[7]} is the smaller dimension" do
|
|
219
|
+
assert_equal args[7], @geo.smaller
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it "has an aspect ratio of #{args[8]}" do
|
|
223
|
+
expect(@geo.aspect).to be_within(0.0001).of(args[8])
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
[[[1000, 100], [64, 64], "x64", "64x64+288+0"],
|
|
229
|
+
[[100, 1000], [50, 950], "x950", "50x950+22+0"],
|
|
230
|
+
[[100, 1000], [50, 25], "50x", "50x25+0+237"]]. each do |args|
|
|
231
|
+
context "of #{args[0].inspect} and given a Geometry #{args[1].inspect} and sent transform_to" do
|
|
232
|
+
before do
|
|
233
|
+
@geo = Paperclip::Geometry.new(*args[0])
|
|
234
|
+
@dst = Paperclip::Geometry.new(*args[1])
|
|
235
|
+
@scale, @crop = @geo.transformation_to @dst, true
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "is able to return the correct scaling transformation geometry #{args[2]}" do
|
|
239
|
+
assert_equal args[2], @scale
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "is able to return the correct crop transformation geometry #{args[3]}" do
|
|
243
|
+
assert_equal args[3], @crop
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
[["256x256", { "150x150!" => [150, 150], "150x150#" => [150, 150], "150x150>" => [150, 150], "150x150<" => [256, 256], "150x150" => [150, 150] }],
|
|
249
|
+
["256x256", { "512x512!" => [512, 512], "512x512#" => [512, 512], "512x512>" => [256, 256], "512x512<" => [512, 512], "512x512" => [512, 512] }],
|
|
250
|
+
["600x400", { "512x512!" => [512, 512], "512x512#" => [512, 512], "512x512>" => [512, 341], "512x512<" => [600, 400], "512x512" => [512, 341] }]].each do |original_size, options|
|
|
251
|
+
options.each_pair do |size, dimensions|
|
|
252
|
+
context "#{original_size} resize_to #{size}" do
|
|
253
|
+
before do
|
|
254
|
+
@source = Paperclip::Geometry.parse original_size
|
|
255
|
+
@new_geometry = @source.resize_to size
|
|
256
|
+
end
|
|
257
|
+
it "has #{dimensions.first} width" do
|
|
258
|
+
assert_equal dimensions.first, @new_geometry.width
|
|
259
|
+
end
|
|
260
|
+
it "has #{dimensions.last} height" do
|
|
261
|
+
assert_equal dimensions.last, @new_geometry.height
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::Glue do
|
|
4
|
+
describe "when ActiveRecord does not exist" do
|
|
5
|
+
before do
|
|
6
|
+
ActiveRecordSaved = ActiveRecord
|
|
7
|
+
Object.send :remove_const, "ActiveRecord"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
after do
|
|
11
|
+
ActiveRecord = ActiveRecordSaved
|
|
12
|
+
Object.send :remove_const, "ActiveRecordSaved"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "does not fail" do
|
|
16
|
+
NonActiveRecordModel = Class.new
|
|
17
|
+
NonActiveRecordModel.include Paperclip::Glue
|
|
18
|
+
Object.send :remove_const, "NonActiveRecordModel"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "when ActiveRecord does exist" do
|
|
23
|
+
before do
|
|
24
|
+
if Object.const_defined?("ActiveRecord")
|
|
25
|
+
@defined_active_record = false
|
|
26
|
+
else
|
|
27
|
+
ActiveRecord = :defined
|
|
28
|
+
@defined_active_record = true
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
after do
|
|
33
|
+
Object.send :remove_const, "ActiveRecord" if @defined_active_record
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "does not fail" do
|
|
37
|
+
NonActiveRecordModel = Class.new
|
|
38
|
+
NonActiveRecordModel.include Paperclip::Glue
|
|
39
|
+
Object.send :remove_const, "NonActiveRecordModel"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "when included" do
|
|
44
|
+
it "does not mutate I18n.load_path more than once" do
|
|
45
|
+
before_load_path = I18n.load_path
|
|
46
|
+
I18n.load_path = []
|
|
47
|
+
|
|
48
|
+
# expect twice because the load_path is reset after creating the classes
|
|
49
|
+
expect(I18n.config).to receive(:load_path=).and_call_original.twice
|
|
50
|
+
|
|
51
|
+
FirstModel = Class.new
|
|
52
|
+
FirstModel.include Paperclip::Glue
|
|
53
|
+
|
|
54
|
+
SecondModel = Class.new
|
|
55
|
+
SecondModel.include Paperclip::Glue
|
|
56
|
+
|
|
57
|
+
ThirdModel = Class.new
|
|
58
|
+
ThirdModel.include Paperclip::Glue
|
|
59
|
+
|
|
60
|
+
I18n.load_path = before_load_path
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Paperclip::HasAttachedFile do
|
|
4
|
+
let(:a_class) { spy("Class") }
|
|
5
|
+
|
|
6
|
+
context "#define_on" do
|
|
7
|
+
it "defines a setter on the class object" do
|
|
8
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
9
|
+
expect(a_class).to have_received(:define_method).with("avatar=")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "defines a getter on the class object" do
|
|
13
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
14
|
+
expect(a_class).to have_received(:define_method).with("avatar")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "defines a query on the class object" do
|
|
18
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
19
|
+
expect(a_class).to have_received(:define_method).with("avatar?")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "defines a method on the class to get all of its attachments" do
|
|
23
|
+
allow(a_class).to receive(:extend)
|
|
24
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
25
|
+
expect(a_class).to have_received(:extend).with(Paperclip::HasAttachedFile::ClassMethods)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "flushes errors as part of validations" do
|
|
29
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
30
|
+
expect(a_class).to have_received(:validates_each).with("avatar")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "registers the attachment with Paperclip::AttachmentRegistry" do
|
|
34
|
+
allow(Paperclip::AttachmentRegistry).to receive(:register)
|
|
35
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", size: 1)
|
|
36
|
+
expect(Paperclip::AttachmentRegistry).to have_received(:register).with(a_class, "avatar", size: 1)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "defines an after_save callback" do
|
|
40
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
41
|
+
expect(a_class).to have_received("after_save")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "defines a before_destroy callback" do
|
|
45
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
46
|
+
expect(a_class).to have_received("before_destroy")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "defines an after_commit callback" do
|
|
50
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
51
|
+
expect(a_class).to have_received("after_commit")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "when the class does not allow after_commit callbacks" do
|
|
55
|
+
it "defines an after_destroy callback" do
|
|
56
|
+
a_class = double("class", after_destroy: nil, validates_each: nil, define_method: nil, after_save: nil, before_destroy: nil, define_paperclip_callbacks: nil, validates_media_type_spoof_detection: nil)
|
|
57
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", {})
|
|
58
|
+
expect(a_class).to have_received("after_destroy")
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "defines the Paperclip-specific callbacks" do
|
|
63
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", validate_media_type: false)
|
|
64
|
+
expect(a_class).to_not have_received(:validates_media_type_spoof_detection)
|
|
65
|
+
expect(a_class).to have_received("define_paperclip_callbacks")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "does not define a media_type check if told not to" do
|
|
69
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", validate_media_type: false)
|
|
70
|
+
expect(a_class).to_not have_received(:validates_media_type_spoof_detection)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "does define a media_type check if told to" do
|
|
74
|
+
Paperclip::HasAttachedFile.define_on(a_class, "avatar", validate_media_type: true)
|
|
75
|
+
expect(a_class).to have_received(:validates_media_type_spoof_detection)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|