paperclip 5.0.0.beta2 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -0
  3. data/.hound.yml +5 -16
  4. data/.travis.yml +14 -15
  5. data/Appraisals +3 -23
  6. data/CONTRIBUTING.md +10 -4
  7. data/Gemfile +1 -0
  8. data/NEWS +78 -2
  9. data/README.md +175 -81
  10. data/Rakefile +1 -1
  11. data/UPGRADING +1 -1
  12. data/features/basic_integration.feature +2 -2
  13. data/features/step_definitions/attachment_steps.rb +6 -6
  14. data/features/step_definitions/rails_steps.rb +29 -22
  15. data/features/step_definitions/s3_steps.rb +1 -1
  16. data/features/support/env.rb +1 -0
  17. data/features/support/paths.rb +1 -1
  18. data/features/support/rails.rb +0 -24
  19. data/gemfiles/{4.2.awsv2.0.gemfile → 4.2.gemfile} +1 -1
  20. data/gemfiles/{5.0.awsv2.1.gemfile → 5.0.gemfile} +2 -2
  21. data/lib/generators/paperclip/paperclip_generator.rb +9 -1
  22. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  23. data/lib/paperclip.rb +13 -10
  24. data/lib/paperclip/attachment.rb +16 -6
  25. data/lib/paperclip/content_type_detector.rb +3 -2
  26. data/lib/paperclip/errors.rb +3 -1
  27. data/lib/paperclip/file_command_content_type_detector.rb +1 -1
  28. data/lib/paperclip/geometry_detector_factory.rb +2 -2
  29. data/lib/paperclip/helpers.rb +15 -12
  30. data/lib/paperclip/interpolations.rb +1 -1
  31. data/lib/paperclip/io_adapters/abstract_adapter.rb +29 -3
  32. data/lib/paperclip/io_adapters/attachment_adapter.rb +10 -5
  33. data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
  34. data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
  35. data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
  36. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +7 -7
  37. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
  38. data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
  39. data/lib/paperclip/io_adapters/registry.rb +6 -2
  40. data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
  41. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
  42. data/lib/paperclip/io_adapters/uri_adapter.rb +41 -19
  43. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
  44. data/lib/paperclip/media_type_spoof_detector.rb +3 -2
  45. data/lib/paperclip/processor.rb +5 -4
  46. data/lib/paperclip/storage/filesystem.rb +13 -2
  47. data/lib/paperclip/storage/fog.rb +12 -7
  48. data/lib/paperclip/storage/s3.rb +46 -19
  49. data/lib/paperclip/thumbnail.rb +18 -8
  50. data/lib/paperclip/url_generator.rb +17 -13
  51. data/lib/paperclip/validators.rb +1 -1
  52. data/lib/paperclip/version.rb +3 -1
  53. data/lib/tasks/paperclip.rake +18 -4
  54. data/paperclip.gemspec +4 -5
  55. data/spec/paperclip/attachment_processing_spec.rb +2 -4
  56. data/spec/paperclip/attachment_spec.rb +40 -9
  57. data/spec/paperclip/content_type_detector_spec.rb +1 -1
  58. data/spec/paperclip/file_command_content_type_detector_spec.rb +15 -1
  59. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +76 -22
  60. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
  61. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
  62. data/spec/paperclip/io_adapters/file_adapter_spec.rb +2 -2
  63. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +26 -6
  64. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
  65. data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
  66. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +1 -1
  67. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
  68. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +77 -7
  69. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
  70. data/spec/paperclip/media_type_spoof_detector_spec.rb +27 -3
  71. data/spec/paperclip/paperclip_spec.rb +13 -13
  72. data/spec/paperclip/processor_spec.rb +4 -4
  73. data/spec/paperclip/storage/fog_spec.rb +28 -0
  74. data/spec/paperclip/storage/s3_live_spec.rb +12 -10
  75. data/spec/paperclip/storage/s3_spec.rb +150 -39
  76. data/spec/paperclip/tempfile_spec.rb +35 -0
  77. data/spec/paperclip/thumbnail_spec.rb +38 -35
  78. data/spec/paperclip/url_generator_spec.rb +54 -43
  79. data/spec/paperclip/validators_spec.rb +3 -2
  80. data/spec/spec_helper.rb +3 -1
  81. data/spec/support/assertions.rb +5 -1
  82. data/spec/support/conditional_filter_helper.rb +5 -0
  83. data/spec/support/mock_attachment.rb +2 -0
  84. data/spec/support/mock_url_generator_builder.rb +2 -2
  85. metadata +37 -36
  86. data/gemfiles/4.2.awsv2.1.gemfile +0 -17
  87. data/gemfiles/4.2.awsv2.gemfile +0 -20
  88. data/gemfiles/5.0.awsv2.0.gemfile +0 -17
  89. data/gemfiles/5.0.awsv2.gemfile +0 -25
@@ -10,8 +10,8 @@ unless ENV["S3_BUCKET"].blank?
10
10
  path: ":class/:attachment/:id/:style.:extension",
11
11
  s3_region: ENV["S3_REGION"],
12
12
  s3_credentials: {
13
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
14
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
13
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
14
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
15
15
  }
16
16
 
17
17
  @file = File.new(fixture_file("5k.png"))
@@ -48,8 +48,8 @@ unless ENV["S3_BUCKET"].blank?
48
48
  path: ":class/:attachment/:id/:style.:extension",
49
49
  s3_region: ENV["S3_REGION"],
50
50
  s3_credentials: {
51
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
52
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
51
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
52
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
53
53
  }
54
54
 
55
55
  @dummy = Dummy.new
@@ -68,8 +68,8 @@ unless ENV["S3_BUCKET"].blank?
68
68
  path: ":class/:attachment/:id/:style.:extension",
69
69
  s3_region: ENV["S3_REGION"],
70
70
  s3_credentials: {
71
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
72
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
71
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
72
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
73
73
  }
74
74
 
75
75
  Dummy.delete_all
@@ -109,9 +109,11 @@ unless ENV["S3_BUCKET"].blank?
109
109
  storage: :s3,
110
110
  bucket: ENV["S3_BUCKET"],
111
111
  s3_region: ENV["S3_REGION"],
112
+ url: ":s3_domain_url",
113
+ path: "/:class/:attachment/:id_partition/:style/:filename",
112
114
  s3_credentials: {
113
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
114
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
115
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
116
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
115
117
  }
116
118
 
117
119
  Dummy.delete_all
@@ -152,8 +154,8 @@ unless ENV["S3_BUCKET"].blank?
152
154
  path: ":class/:attachment/:id/:style.:extension",
153
155
  s3_region: ENV["S3_REGION"],
154
156
  s3_credentials: {
155
- aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
156
- aws_secre_access_key: ENV['AWS_SECRET_ACCESS_KEY']
157
+ access_key_id: ENV['AWS_ACCESS_KEY_ID'],
158
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
157
159
  },
158
160
  s3_server_side_encryption: "AES256"
159
161
  Dummy.delete_all
@@ -114,7 +114,7 @@ describe Paperclip::Storage::S3 do
114
114
  end
115
115
 
116
116
  it "returns a url based on an S3 path" do
117
- assert_match %r{^http://s3.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
117
+ assert_match %r{^//s3.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
118
118
  end
119
119
 
120
120
  it "uses the correct bucket" do
@@ -252,11 +252,11 @@ describe Paperclip::Storage::S3 do
252
252
  end
253
253
 
254
254
  it "returns a url based on an :s3_host_name path" do
255
- assert_match %r{^http://s3-ap-northeast-1.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
255
+ assert_match %r{^//s3-ap-northeast-1.amazonaws.com/bucket/avatars/data[^\.]}, @dummy.avatar.url
256
256
  end
257
257
 
258
258
  it "uses the S3 bucket with the correct host name" do
259
- assert_equal "s3-ap-northeast-1.amazonaws.com",
259
+ assert_equal "s3.ap-northeast-1.amazonaws.com",
260
260
  @dummy.avatar.s3_bucket.client.config.endpoint.host
261
261
  end
262
262
  end
@@ -278,7 +278,60 @@ describe Paperclip::Storage::S3 do
278
278
 
279
279
  it "uses s3_host_name as a proc if available" do
280
280
  @dummy.value = "s3.something.com"
281
- assert_equal "http://s3.something.com/bucket/avatars/data", @dummy.avatar.url(:original, timestamp: false)
281
+ assert_equal "//s3.something.com/bucket/avatars/data", @dummy.avatar.url(:original, timestamp: false)
282
+ end
283
+ end
284
+
285
+ context "use_accelerate_endpoint", if: aws_accelerate_available? do
286
+ context "defaults to false" do
287
+ before do
288
+ rebuild_model(
289
+ storage: :s3,
290
+ s3_credentials: {},
291
+ bucket: "bucket",
292
+ path: ":attachment/:basename:dotextension",
293
+ s3_host_name: "s3-ap-northeast-1.amazonaws.com",
294
+ s3_region: "ap-northeast-1",
295
+ )
296
+ @dummy = Dummy.new
297
+ @dummy.avatar = stringy_file
298
+ @dummy.stubs(:new_record?).returns(false)
299
+ end
300
+
301
+ it "returns a url based on an :s3_host_name path" do
302
+ assert_match %r{^//s3-ap-northeast-1.amazonaws.com/bucket/avatars/data[^\.]},
303
+ @dummy.avatar.url
304
+ end
305
+
306
+ it "uses the S3 client with the use_accelerate_endpoint config is false" do
307
+ expect(@dummy.avatar.s3_bucket.client.config.use_accelerate_endpoint).to be(false)
308
+ end
309
+ end
310
+
311
+ context "set to true", if: aws_accelerate_available? do
312
+ before do
313
+ rebuild_model(
314
+ storage: :s3,
315
+ s3_credentials: {},
316
+ bucket: "bucket",
317
+ path: ":attachment/:basename:dotextension",
318
+ s3_host_name: "s3-accelerate.amazonaws.com",
319
+ s3_region: "ap-northeast-1",
320
+ use_accelerate_endpoint: true,
321
+ )
322
+ @dummy = Dummy.new
323
+ @dummy.avatar = stringy_file
324
+ @dummy.stubs(:new_record?).returns(false)
325
+ end
326
+
327
+ it "returns a url based on an :s3_host_name path" do
328
+ assert_match %r{^//s3-accelerate.amazonaws.com/bucket/avatars/data[^\.]},
329
+ @dummy.avatar.url
330
+ end
331
+
332
+ it "uses the S3 client with the use_accelerate_endpoint config is true" do
333
+ expect(@dummy.avatar.s3_bucket.client.config.use_accelerate_endpoint).to be(true)
334
+ end
282
335
  end
283
336
  end
284
337
 
@@ -364,6 +417,58 @@ describe Paperclip::Storage::S3 do
364
417
  end
365
418
  end
366
419
 
420
+ context "An attachment that uses S3 for storage and has styles" do
421
+ before do
422
+ rebuild_model(
423
+ (aws2_add_region).merge(
424
+ storage: :s3,
425
+ styles: { thumb: ["90x90#", :jpg] },
426
+ bucket: "bucket",
427
+ s3_credentials: {
428
+ "access_key_id" => "12345",
429
+ "secret_access_key" => "54321" }
430
+ )
431
+ )
432
+
433
+ @file = File.new(fixture_file("5k.png"), "rb")
434
+ @dummy = Dummy.new
435
+ @dummy.avatar = @file
436
+ @dummy.save
437
+ end
438
+
439
+ context "reprocess" do
440
+ before do
441
+ @object = stub
442
+ @dummy.avatar.stubs(:s3_object).with(:original).returns(@object)
443
+ @dummy.avatar.stubs(:s3_object).with(:thumb).returns(@object)
444
+ @object.stubs(:get).yields(@file.read)
445
+ @object.stubs(:exists?).returns(true)
446
+ end
447
+
448
+ it "uploads original" do
449
+ @object.expects(:upload_file).with(
450
+ anything,
451
+ content_type: "image/png",
452
+ acl: :"public-read").returns(true)
453
+ @object.expects(:upload_file).with(
454
+ anything,
455
+ content_type: "image/jpeg",
456
+ acl: :"public-read").returns(true)
457
+ @dummy.avatar.reprocess!
458
+ end
459
+
460
+ it "doesn't upload original" do
461
+ @object.expects(:upload_file).with(
462
+ anything,
463
+ content_type: "image/jpeg",
464
+ acl: :"public-read").returns(true)
465
+ @dummy.avatar.reprocess!(:thumb)
466
+ end
467
+ end
468
+
469
+ after { @file.close }
470
+ end
471
+
367
472
  context "An attachment that uses S3 for storage and has spaces in file name" do
368
473
  before do
369
474
  rebuild_model(
@@ -406,7 +511,7 @@ describe Paperclip::Storage::S3 do
406
511
  "question?mark.png"
407
512
  end
408
513
  end
409
- file = Paperclip.io_adapters.for(stringio)
514
+ file = Paperclip.io_adapters.for(stringio, hash_digest: Digest::MD5)
410
515
  @dummy = Dummy.new
411
516
  @dummy.avatar = file
412
517
  @dummy.save
@@ -435,7 +540,7 @@ describe Paperclip::Storage::S3 do
435
540
  end
436
541
 
437
542
  it "returns a url based on an S3 subdomain" do
438
- assert_match %r{^http://bucket.s3.amazonaws.com/avatars/data[^\.]}, @dummy.avatar.url
543
+ assert_match %r{^//bucket.s3.amazonaws.com/avatars/data[^\.]}, @dummy.avatar.url
439
544
  end
440
545
  end
441
546
 
@@ -458,7 +563,34 @@ describe Paperclip::Storage::S3 do
458
563
  end
459
564
 
460
565
  it "returns a url based on the host_alias" do
461
- assert_match %r{^http://something.something.com/avatars/data[^\.]}, @dummy.avatar.url
566
+ assert_match %r{^//something.something.com/avatars/data[^\.]}, @dummy.avatar.url
567
+ end
568
+ end
569
+
570
+ context "generating a url with a prefixed host alias" do
571
+ before do
572
+ rebuild_model(
573
+ aws2_add_region.merge(
574
+ storage: :s3,
575
+ s3_credentials: {
576
+ production: { bucket: "prod_bucket" },
577
+ development: { bucket: "dev_bucket" },
578
+ },
579
+ bucket: "bucket",
580
+ s3_host_alias: "something.something.com",
581
+ s3_prefixes_in_alias: 2,
582
+ path: "prefix1/prefix2/:attachment/:basename:dotextension",
583
+ url: ":s3_alias_url",
584
+ )
585
+ )
586
+ @dummy = Dummy.new
587
+ @dummy.avatar = stringy_file
588
+ @dummy.stubs(:new_record?).returns(false)
589
+ end
590
+
591
+ it "returns a url with the prefixes removed" do
592
+ assert_match %r{^//something.something.com/avatars/data[^\.]},
593
+ @dummy.avatar.url
462
594
  end
463
595
  end
464
596
 
@@ -482,8 +614,8 @@ describe Paperclip::Storage::S3 do
482
614
  end
483
615
 
484
616
  it "returns a url based on the host_alias" do
485
- assert_match %r{^http://cdn1.example.com/avatars/data[^\.]}, @dummy.avatar.url
486
- assert_match %r{^http://cdn2.example.com/avatars/data[^\.]}, @dummy.avatar.url
617
+ assert_match %r{^//cdn1.example.com/avatars/data[^\.]}, @dummy.avatar.url
618
+ assert_match %r{^//cdn2.example.com/avatars/data[^\.]}, @dummy.avatar.url
487
619
  end
488
620
 
489
621
  it "still returns the bucket name" do
@@ -672,7 +804,9 @@ describe Paperclip::Storage::S3 do
672
804
  s3_host_name: "s3-world-end.amazonaws.com" },
673
805
  development: {
674
806
  s3_region: "ap-northeast-1",
675
- s3_host_name: "s3-ap-northeast-1.amazonaws.com" }
807
+ s3_host_name: "s3-ap-northeast-1.amazonaws.com" },
808
+ test: {
809
+ s3_region: "" }
676
810
  }
677
811
  @dummy = Dummy.new
678
812
  end
@@ -687,8 +821,9 @@ describe Paperclip::Storage::S3 do
687
821
 
688
822
  it "gets the right s3_host_name in development" do
689
823
  rails_env("development") do
690
- assert_match %r{^s3-ap-northeast-1.amazonaws.com}, @dummy.avatar.s3_host_name
691
- assert_match %r{^s3-ap-northeast-1.amazonaws.com},
824
+ assert_match %r{^s3.ap-northeast-1.amazonaws.com},
825
+ @dummy.avatar.s3_host_name
826
+ assert_match %r{^s3.ap-northeast-1.amazonaws.com},
692
827
  @dummy.avatar.s3_bucket.client.config.endpoint.host
693
828
  end
694
829
  end
@@ -735,7 +870,7 @@ describe Paperclip::Storage::S3 do
735
870
  it "does not get a bucket to get a URL" do
736
871
  @dummy.avatar.expects(:s3).never
737
872
  @dummy.avatar.expects(:s3_bucket).never
738
- assert_match %r{^http://s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url
873
+ assert_match %r{^//s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url
739
874
  end
740
875
 
741
876
  it "is rewound after flush_writes" do
@@ -1205,7 +1340,7 @@ describe Paperclip::Storage::S3 do
1205
1340
  'access_key_id' => "12345",
1206
1341
  'secret_access_key' => "54321"
1207
1342
  },
1208
- s3_server_side_encryption: :aes256
1343
+ s3_server_side_encryption: "AES256"
1209
1344
  end
1210
1345
 
1211
1346
  context "when assigned" do
@@ -1225,7 +1360,7 @@ describe Paperclip::Storage::S3 do
1225
1360
  object.expects(:upload_file)
1226
1361
  .with(anything, content_type: "image/png",
1227
1362
  acl: :"public-read",
1228
- server_side_encryption: :aes256)
1363
+ server_side_encryption: "AES256")
1229
1364
  @dummy.save
1230
1365
  end
1231
1366
 
@@ -1472,29 +1607,6 @@ describe Paperclip::Storage::S3 do
1472
1607
  }
1473
1608
  )
1474
1609
  end
1475
-
1476
- context "when assigned" do
1477
- before do
1478
- @file = File.new(fixture_file('5k.png'), 'rb')
1479
- @dummy = Dummy.new
1480
- @dummy.stubs(:private_attachment? => true)
1481
- @dummy.avatar = @file
1482
- end
1483
-
1484
- after { @file.close }
1485
-
1486
- context "and saved" do
1487
- before do
1488
- @dummy.save
1489
- end
1490
-
1491
- it "succeeds" do
1492
- assert @dummy.avatar.url().include? "https://"
1493
- assert @dummy.avatar.url(:thumb).include? "http://"
1494
- end
1495
- end
1496
- end
1497
-
1498
1610
  end
1499
1611
  end
1500
1612
 
@@ -1578,5 +1690,4 @@ describe Paperclip::Storage::S3 do
1578
1690
  Rails.env = stored_env
1579
1691
  end
1580
1692
  end
1581
-
1582
1693
  end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe Paperclip::Tempfile do
4
+ context "A Paperclip Tempfile" do
5
+ before do
6
+ @tempfile = described_class.new(["file", ".jpg"])
7
+ end
8
+
9
+ after { @tempfile.close }
10
+
11
+ it "has its path contain a real extension" do
12
+ assert_equal ".jpg", File.extname(@tempfile.path)
13
+ end
14
+
15
+ it "is a real Tempfile" do
16
+ assert @tempfile.is_a?(::Tempfile)
17
+ end
18
+ end
19
+
20
+ context "Another Paperclip Tempfile" do
21
+ before do
22
+ @tempfile = described_class.new("file")
23
+ end
24
+
25
+ after { @tempfile.close }
26
+
27
+ it "does not have an extension if not given one" do
28
+ assert_equal "", File.extname(@tempfile.path)
29
+ end
30
+
31
+ it "is a real Tempfile" do
32
+ assert @tempfile.is_a?(::Tempfile)
33
+ end
34
+ end
35
+ end
@@ -1,38 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Paperclip::Thumbnail do
4
- context "A Paperclip Tempfile" do
5
- before do
6
- @tempfile = Paperclip::Tempfile.new(["file", ".jpg"])
7
- end
8
-
9
- after { @tempfile.close }
10
-
11
- it "has its path contain a real extension" do
12
- assert_equal ".jpg", File.extname(@tempfile.path)
13
- end
14
-
15
- it "is a real Tempfile" do
16
- assert @tempfile.is_a?(::Tempfile)
17
- end
18
- end
19
-
20
- context "Another Paperclip Tempfile" do
21
- before do
22
- @tempfile = Paperclip::Tempfile.new("file")
23
- end
24
-
25
- after { @tempfile.close }
26
-
27
- it "does not have an extension if not given one" do
28
- assert_equal "", File.extname(@tempfile.path)
29
- end
30
-
31
- it "is a real Tempfile" do
32
- assert @tempfile.is_a?(::Tempfile)
33
- end
34
- end
35
-
36
4
  context "An image" do
37
5
  before do
38
6
  @file = File.new(fixture_file("5k.png"), 'rb')
@@ -80,7 +48,7 @@ describe Paperclip::Thumbnail do
80
48
  it "lets us know when a command isn't found versus a processing error" do
81
49
  old_path = ENV['PATH']
82
50
  begin
83
- Cocaine::CommandLine.path = ''
51
+ Terrapin::CommandLine.path = ''
84
52
  Paperclip.options[:command_path] = ''
85
53
  ENV['PATH'] = ''
86
54
  assert_raises(Paperclip::Errors::CommandNotFoundError) do
@@ -134,7 +102,7 @@ describe Paperclip::Thumbnail do
134
102
 
135
103
  output_file = thumb.make
136
104
 
137
- command = Cocaine::CommandLine.new("identify", "-format %wx%h :file")
105
+ command = Terrapin::CommandLine.new("identify", "-format %wx%h :file")
138
106
  assert_equal "50x50", command.run(file: output_file.path).strip
139
107
  end
140
108
 
@@ -221,7 +189,7 @@ describe Paperclip::Thumbnail do
221
189
  it "lets us know when a command isn't found versus a processing error" do
222
190
  old_path = ENV['PATH']
223
191
  begin
224
- Cocaine::CommandLine.path = ''
192
+ Terrapin::CommandLine.path = ''
225
193
  Paperclip.options[:command_path] = ''
226
194
  ENV['PATH'] = ''
227
195
  assert_raises(Paperclip::Errors::CommandNotFoundError) do
@@ -480,6 +448,41 @@ describe Paperclip::Thumbnail do
480
448
  assert_equal "50x50", `#{cmd}`.chomp
481
449
  end
482
450
  end
451
+
452
+ context "with a specified frame_index" do
453
+ before do
454
+ @thumb = Paperclip::Thumbnail.new(
455
+ @file,
456
+ geometry: "50x50",
457
+ frame_index: 5,
458
+ format: :jpg,
459
+ )
460
+ end
461
+
462
+ it "creates the thumbnail from the frame index when sent #make" do
463
+ @thumb.make
464
+ assert_equal 5, @thumb.frame_index
465
+ end
466
+ end
467
+
468
+ context "with a specified frame_index out of bounds" do
469
+ before do
470
+ @thumb = Paperclip::Thumbnail.new(
471
+ @file,
472
+ geometry: "50x50",
473
+ frame_index: 20,
474
+ format: :jpg,
475
+ )
476
+ end
477
+
478
+ it "errors when trying to create the thumbnail" do
479
+ assert_raises(Paperclip::Error) do
480
+ silence_stream(STDERR) do
481
+ @thumb.make
482
+ end
483
+ end
484
+ end
485
+ end
483
486
  end
484
487
 
485
488
  context "with a really long file name" do