image_resizer 0.1.4

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.
Files changed (43) hide show
  1. data/.rspec +1 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +45 -0
  5. data/LICENSE +22 -0
  6. data/README.md +56 -0
  7. data/Rakefile +53 -0
  8. data/VERSION +1 -0
  9. data/image_resizer.gemspec +93 -0
  10. data/lib/image_resizer/analyzer.rb +51 -0
  11. data/lib/image_resizer/configurable.rb +206 -0
  12. data/lib/image_resizer/encoder.rb +55 -0
  13. data/lib/image_resizer/has_filename.rb +24 -0
  14. data/lib/image_resizer/loggable.rb +28 -0
  15. data/lib/image_resizer/processor.rb +220 -0
  16. data/lib/image_resizer/shell.rb +48 -0
  17. data/lib/image_resizer/temp_object.rb +216 -0
  18. data/lib/image_resizer/utils.rb +44 -0
  19. data/lib/image_resizer.rb +10 -0
  20. data/samples/DSC02119.JPG +0 -0
  21. data/samples/a.jp2 +0 -0
  22. data/samples/beach.jpg +0 -0
  23. data/samples/beach.png +0 -0
  24. data/samples/egg.png +0 -0
  25. data/samples/landscape.png +0 -0
  26. data/samples/round.gif +0 -0
  27. data/samples/sample.docx +0 -0
  28. data/samples/taj.jpg +0 -0
  29. data/samples/white pixel.png +0 -0
  30. data/spec/image_resizer/analyzer_spec.rb +78 -0
  31. data/spec/image_resizer/configurable_spec.rb +479 -0
  32. data/spec/image_resizer/encoder_spec.rb +41 -0
  33. data/spec/image_resizer/has_filename_spec.rb +88 -0
  34. data/spec/image_resizer/loggable_spec.rb +80 -0
  35. data/spec/image_resizer/processor_spec.rb +590 -0
  36. data/spec/image_resizer/shell_spec.rb +34 -0
  37. data/spec/image_resizer/temp_object_spec.rb +442 -0
  38. data/spec/spec_helper.rb +61 -0
  39. data/spec/support/argument_matchers.rb +19 -0
  40. data/spec/support/image_matchers.rb +58 -0
  41. data/spec/support/simple_matchers.rb +53 -0
  42. data/tmp/test_file +1 -0
  43. metadata +147 -0
@@ -0,0 +1,590 @@
1
+ require 'spec_helper'
2
+
3
+ describe ImageResizer::Processor do
4
+
5
+ before(:each) do
6
+ @image = ImageResizer::TempObject.new(SAMPLES_DIR.join('beach.png')) # 280x355
7
+ @processor = ImageResizer::Processor.new
8
+ end
9
+
10
+ describe "_resize" do
11
+
12
+ it "should work correctly with xNN" do
13
+ image = @processor._resize(@image, 'x30')
14
+ image.should have_width(24)
15
+ image.should have_height(30)
16
+ end
17
+
18
+ it "should work correctly with NNx" do
19
+ image = @processor._resize(@image, '30x')
20
+ image.should have_width(30)
21
+ image.should have_height(38)
22
+ end
23
+
24
+ it "should work correctly with NNxNN" do
25
+ image = @processor._resize(@image, '30x30')
26
+ image.should have_width(24)
27
+ image.should have_height(30)
28
+ end
29
+
30
+ it "should work correctly with NNxNN!" do
31
+ image = @processor._resize(@image, '30x30!')
32
+ image.should have_width(30)
33
+ image.should have_height(30)
34
+ end
35
+
36
+ it "should work correctly with NNxNN%" do
37
+ image = @processor._resize(@image, '25x50%')
38
+ image.should have_width(70)
39
+ image.should have_height(178)
40
+ end
41
+
42
+ describe "NNxNN>" do
43
+
44
+ it "should not resize if the image is smaller than specified" do
45
+ image = @processor._resize(@image, '1000x1000>')
46
+ image.should have_width(280)
47
+ image.should have_height(355)
48
+ end
49
+
50
+ it "should resize if the image is larger than specified" do
51
+ image = @processor._resize(@image, '30x30>')
52
+ image.should have_width(24)
53
+ image.should have_height(30)
54
+ end
55
+
56
+ end
57
+
58
+ describe "NNxNN<" do
59
+
60
+ it "should not resize if the image is larger than specified" do
61
+ image = @processor._resize(@image, '10x10<')
62
+ image.should have_width(280)
63
+ image.should have_height(355)
64
+ end
65
+
66
+ it "should resize if the image is smaller than specified" do
67
+ image = @processor._resize(@image, '400x400<')
68
+ image.should have_width(315)
69
+ image.should have_height(400)
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ describe "crop" do # Difficult to test here other than dimensions
77
+
78
+ it "should not crop if no args given" do
79
+ image = @processor.crop(@image)
80
+ image.should have_width(280)
81
+ image.should have_height(355)
82
+ end
83
+
84
+ it "should crop using the offset given" do
85
+ image = @processor.crop(@image, :x => '7', :y => '12')
86
+ image.should have_width(273)
87
+ image.should have_height(343)
88
+ end
89
+
90
+ it "should crop using the dimensions given" do
91
+ image = @processor.crop(@image, :width => '10', :height => '20')
92
+ image.should have_width(10)
93
+ image.should have_height(20)
94
+ end
95
+
96
+ it "should crop in one dimension if given" do
97
+ image = @processor.crop(@image, :width => '10')
98
+ image.should have_width(10)
99
+ image.should have_height(355)
100
+ end
101
+
102
+ it "should take into account the gravity given" do
103
+ image1 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'nw')
104
+ image2 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'se')
105
+ image1.should_not equal_image(image2)
106
+ end
107
+
108
+ it "should clip bits of the image outside of the requested crop area when not nw gravity" do
109
+ # Rmagick was previously throwing an error when the cropping area was outside the image size, when
110
+ # using a gravity other than nw
111
+ image = @processor.crop(@image, :width => '500', :height => '1000', :x => '100', :y => '200', :gravity => 'se')
112
+ image.should have_width(180)
113
+ image.should have_height(155)
114
+ end
115
+
116
+ it "should crop twice in a row correctly" do
117
+ image1 = @processor.crop(@image, :x => '10', :y => '10', :width => '100', :height => '100')
118
+ image2 = @processor.crop(ImageResizer::TempObject.new(image1), :x => '0' , :y => '0' , :width => '50' , :height => '50' )
119
+ image2.should have_width(50)
120
+ image2.should have_height(50)
121
+ end
122
+
123
+ it "should crop twice in a row while consciously keeping page geometry" do
124
+ # see http://www.imagemagick.org/Usage/crop/#crop_page
125
+ # it explains how cropping multiple times without resetting geometry behaves
126
+ image1 = @processor.crop(@image, :x => '10', :y => '10', :width => '100', :height => '100', :repage => false)
127
+ image2 = @processor.crop(ImageResizer::TempObject.new(image1), :x => '0' , :y => '0' , :width => '50' , :height => '50')
128
+ image2.should have_width(40)
129
+ image2.should have_height(40)
130
+ end
131
+
132
+ end
133
+
134
+
135
+ describe "#resize(temp_object, width, height)" do
136
+ context "when both the width and the height are non-zero" do
137
+ it "should crop and scale to the specified dimensions" do
138
+ @processor.should_receive(:resize_and_crop).with(@image, :width => 77, :height => 33, :gravity => 'c')
139
+ @processor.resize(@image, :width => 77, :height => 33)
140
+ end
141
+
142
+ context "with the crop_from_top_if_portrait option" do
143
+ context "with a portrait oriented image" do
144
+ it "should resize and crop with a gravity of 'n'" do
145
+ @processor.should_receive(:resize_and_crop).with(@image, :width => 77, :height => 33, :gravity => 'n')
146
+ @processor.resize(@image, :width => 77, :height => 33, :crop_from_top_if_portrait => true)
147
+ end
148
+ end
149
+
150
+ context "with a landscape oriented image" do
151
+ it "should resize and crop with a gravity of 'c'" do
152
+ @image = ImageResizer::TempObject.new(SAMPLES_DIR.join('landscape.png')) # 355x280
153
+ @processor.should_receive(:resize_and_crop).with(@image, :width => 77, :height => 33, :gravity => 'c')
154
+ @processor.resize(@image, :width => 77, :height => 33, :crop_from_top_if_portrait => true)
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ context "when the height is 0, nil, or not present" do
161
+ it "should restrict only in the horizontal dimension" do
162
+ @processor.should_receive(:_resize).with(@image, '77x').exactly(3).times
163
+ @processor.resize(@image, :width => 77, :height => 0)
164
+ @processor.resize(@image, :width => 77, :height => nil)
165
+ @processor.resize(@image, :width => 77)
166
+ end
167
+ end
168
+
169
+ context "when the width is 0, nil, or not present" do
170
+ it "should restrict only in the vertical dimension" do
171
+ @processor.should_receive(:_resize).with(@image, 'x33').exactly(3).times
172
+ @processor.resize(@image, :width => 0, :height => 33)
173
+ @processor.resize(@image, :width => nil, :height => 33)
174
+ @processor.resize(@image, :height => 33)
175
+ end
176
+ end
177
+
178
+ context "when both height and width are 0, nil, or not present" do
179
+ it "should return the original image file" do
180
+ @image.should_receive(:file).exactly(3).times
181
+ @processor.should_not_receive(:_resize)
182
+ @processor.resize(@image, :width => 0, :height => 0)
183
+ @processor.resize(@image, :width => nil, :height => nil)
184
+ @processor.resize(@image)
185
+ end
186
+ end
187
+ end
188
+
189
+
190
+
191
+
192
+ describe "#resize_and_crop_around_point(:point => [x%, y%], :width => w, :height => h" do
193
+ context "when the source image is portrait, but the requested ratio is landscape" do
194
+ it "should call crop_to_frame_and_resize with a frame that is vertically centered on the focus point" do
195
+ # original is 280px x 355px
196
+ @processor.should_receive(:crop_to_frame_and_resize ).with(@image,
197
+ :width => 100,
198
+ :height => 60,
199
+ :upper_left => [0.0, 0.5 - 280 * 0.6 / 355 / 2.0],
200
+ :lower_right => [1.0, 0.5 + 280 * 0.6 / 355 / 2.0])
201
+ @processor.resize_and_crop_around_point(@image,
202
+ :point => [0.5, 0.5],
203
+ :width => 100,
204
+ :height => 60
205
+ )
206
+ end
207
+
208
+ context "when the focus point is too close to the top to be the vertical center" do
209
+ it "should call crop_to_frame_and_resize with a frame that is pinned at the top of the image" do
210
+ # original is 280px x 355px
211
+ @processor.should_receive(:crop_to_frame_and_resize ).with(@image,
212
+ :width => 100,
213
+ :height => 60,
214
+ :upper_left => [0.0, 0.0],
215
+ :lower_right => [1.0, 280 * 0.6 / 355])
216
+ @processor.resize_and_crop_around_point(@image,
217
+ :point => [0.5, 0.1],
218
+ :width => 100,
219
+ :height => 60
220
+ )
221
+ end
222
+ end
223
+
224
+ context "when the focus point is too close to the bottom to be the vertical center" do
225
+ it "should call crop_to_frame_and_resize with a frame that is pinned at the bottom of the image" do
226
+ # original is 280px x 355px
227
+ @processor.should_receive(:crop_to_frame_and_resize ).with(@image,
228
+ :width => 100,
229
+ :height => 60,
230
+ :upper_left => [0.0, 1 - 280 * 0.6 / 355],
231
+ :lower_right => [1.0, 1.0])
232
+ @processor.resize_and_crop_around_point(@image,
233
+ :point => [0.5, 0.9],
234
+ :width => 100,
235
+ :height => 60
236
+ )
237
+ end
238
+ end
239
+ end
240
+
241
+ context "when the source image is landscape, but the requested ratio is portrait" do
242
+ before(:each) do
243
+ @image = ImageResizer::TempObject.new(SAMPLES_DIR.join('landscape.png')) # 355x280
244
+ end
245
+
246
+ it "should call crop_to_frame_and_resize with a frame that is vertically centered on the focus point" do
247
+ # original is 355px x 280px
248
+ @processor.should_receive(:crop_to_frame_and_resize ).with(@image,
249
+ :width => 60,
250
+ :height => 100,
251
+ :upper_left => [0.5 - 280 * 0.6 / 355 / 2.0, 0.0],
252
+ :lower_right => [0.5 + 280 * 0.6 / 355 / 2.0, 1.0])
253
+ @processor.resize_and_crop_around_point(@image,
254
+ :point => [0.5, 0.5],
255
+ :width => 60,
256
+ :height => 100
257
+ )
258
+ end
259
+
260
+ context "when the focus point is too close to the left to be the vertical center" do
261
+ it "should call crop_to_frame_and_resize with a frame that is pinned at the left of the image" do
262
+ # original is 355px x 280px
263
+ @processor.should_receive(:crop_to_frame_and_resize ).with(@image,
264
+ :width => 60,
265
+ :height => 100,
266
+ :upper_left => [0.0, 0.0],
267
+ :lower_right => [280 * 0.6 / 355, 1.0])
268
+ @processor.resize_and_crop_around_point(@image,
269
+ :point => [0.1, 0.5],
270
+ :width => 60,
271
+ :height => 100
272
+ )
273
+ end
274
+ end
275
+
276
+ context "when the focus point is too close to the right to be the vertical center" do
277
+ it "should call crop_to_frame_and_resize with a frame that is pinned at the right of the image" do
278
+ # original is 355px x 280px
279
+ @processor.should_receive(:crop_to_frame_and_resize ).with(@image,
280
+ :width => 60,
281
+ :height => 100,
282
+ :upper_left => [1.0 - 280 * 0.6 / 355, 0.0],
283
+ :lower_right => [1.0, 1.0])
284
+ @processor.resize_and_crop_around_point(@image,
285
+ :point => [0.9, 0.5],
286
+ :width => 60,
287
+ :height => 100
288
+ )
289
+ end
290
+ end
291
+ end
292
+
293
+ context "when the specified width is 0" do
294
+ it "should not raise an exception" do
295
+ lambda {
296
+ @processor.resize_and_crop_around_point(@image,
297
+ :point => [0.20, 0.30],
298
+ :width => 0,
299
+ :height => 80
300
+ )
301
+ }.should_not raise_error
302
+ end
303
+ end
304
+
305
+ context "when the specified height is 0" do
306
+ it "should not raise an exception" do
307
+ lambda {
308
+ @processor.resize_and_crop_around_point(@image,
309
+ :point => [0.20, 0.30],
310
+ :width => 80,
311
+ :height => 0
312
+ )
313
+ }.should_not raise_error
314
+ end
315
+ end
316
+ end
317
+
318
+ describe "#crop_to_frame_and_resize(:upper_left => [x%, y%], :lower_right => [x%, y%], :width => w, :height => h" do
319
+ it "should call #crop with the :x & :y and :width & :height expressed in pixels and :width and :height determined by the frame bounds (not the width and height we pass in), and :resize expressed as widthxheight" do
320
+ # original is 280px x 355px
321
+ @processor.should_receive(:convert).with(@image, "-crop 140x178+56+107 -resize 70x89 +repage")
322
+ @processor.crop_to_frame_and_resize(@image,
323
+ :upper_left => [0.20, 0.30],
324
+ :lower_right => [0.70, 0.80],
325
+ :width => 70,
326
+ :height => 89
327
+ )
328
+ end
329
+
330
+ context "when width is 0, nil, or not present as an option" do
331
+ it "should use the ratio defined by the upper_left and lower_right points to determine the width from the height" do
332
+ # original is 280px x 355px
333
+ @processor.should_receive(:convert).with(@image, "-crop 140x178+56+107 -resize 70x89 +repage").exactly(3).times
334
+ @processor.crop_to_frame_and_resize(@image,
335
+ :upper_left => [0.20, 0.30],
336
+ :lower_right => [0.70, 0.80],
337
+ :width => 0,
338
+ :height => 89
339
+ )
340
+
341
+ @processor.crop_to_frame_and_resize(@image,
342
+ :upper_left => [0.20, 0.30],
343
+ :lower_right => [0.70, 0.80],
344
+ :width => nil,
345
+ :height => 89
346
+ )
347
+
348
+ @processor.crop_to_frame_and_resize(@image,
349
+ :upper_left => [0.20, 0.30],
350
+ :lower_right => [0.70, 0.80],
351
+ :height => 89
352
+ )
353
+ end
354
+
355
+ end
356
+
357
+ context "when height is 0, nil, or not present as an option" do
358
+ it "should use the ratio defined by the upper_left and lower_right points to determine the height from the width" do
359
+ # original is 280px x 355px
360
+ @processor.should_receive(:convert).with(@image, "-crop 140x178+56+107 -resize 70x89 +repage").exactly(3).times
361
+ @processor.crop_to_frame_and_resize(@image,
362
+ :upper_left => [0.20, 0.30],
363
+ :lower_right => [0.70, 0.80],
364
+ :width => 70,
365
+ :height => 0
366
+ )
367
+
368
+ @processor.crop_to_frame_and_resize(@image,
369
+ :upper_left => [0.20, 0.30],
370
+ :lower_right => [0.70, 0.80],
371
+ :width => 70,
372
+ :height => nil
373
+ )
374
+
375
+ @processor.crop_to_frame_and_resize(@image,
376
+ :upper_left => [0.20, 0.30],
377
+ :lower_right => [0.70, 0.80],
378
+ :width => 70
379
+ )
380
+ end
381
+ end
382
+
383
+ context "when both width and heigth are 0 or nil" do
384
+ it "should not raise an exception" do
385
+ lambda {
386
+ @processor.crop_to_frame_and_resize(@image,
387
+ :upper_left => [0.20, 0.30],
388
+ :lower_right => [0.70, 0.80],
389
+ :width => 0,
390
+ :height => 0
391
+ )
392
+ }.should_not raise_error
393
+
394
+ lambda {
395
+ @processor.crop_to_frame_and_resize(@image,
396
+ :upper_left => [0.20, 0.30],
397
+ :lower_right => [0.70, 0.80]
398
+ )
399
+ }.should_not raise_error
400
+ end
401
+
402
+ context "when the frame specifies a width of 0" do
403
+ it "should not raise an exception" do
404
+ lambda {
405
+ @processor.crop_to_frame_and_resize(@image,
406
+ :upper_left => [0.20, 0.30],
407
+ :lower_right => [0.20, 0.80],
408
+ :width => 0,
409
+ :height => 0
410
+ )
411
+ }.should_not raise_error
412
+ end
413
+ end
414
+
415
+ context "when the frame specifies a height of 0" do
416
+ it "should not raise an exception" do
417
+ lambda {
418
+ @processor.crop_to_frame_and_resize(@image,
419
+ :upper_left => [0.20, 0.30],
420
+ :lower_right => [0.70, 0.30],
421
+ :width => 0,
422
+ :height => 0
423
+ )
424
+ }.should_not raise_error
425
+ end
426
+ end
427
+ end
428
+
429
+ end
430
+
431
+ describe "greyscale" do
432
+ it "should not raise an error" do
433
+ # Bit tricky to test
434
+ @processor.greyscale(@image)
435
+ end
436
+ end
437
+
438
+ describe "resize_and_crop" do
439
+
440
+ it "should do nothing if no args given" do
441
+ image = @processor.resize_and_crop(@image)
442
+ image.should have_width(280)
443
+ image.should have_height(355)
444
+ end
445
+
446
+ it "should do nothing if called without width and height" do
447
+ image = @processor.resize_and_crop(@image)
448
+ image.should have_width(280)
449
+ image.should have_height(355)
450
+ image.should eq @image
451
+ end
452
+
453
+ it "should crop to the correct dimensions" do
454
+ image = @processor.resize_and_crop(@image, :width => '100', :height => '100')
455
+ image.should have_width(100)
456
+ image.should have_height(100)
457
+ end
458
+
459
+ it "should actually resize before cropping" do
460
+ image1 = @processor.resize_and_crop(@image, :width => '100', :height => '100')
461
+ image2 = @processor.crop(@image, :width => '100', :height => '100', :gravity => 'c')
462
+ image1.should_not equal_image(image2)
463
+ end
464
+
465
+ it "should allow cropping in one dimension" do
466
+ image = @processor.resize_and_crop(@image, :width => '100')
467
+ image.should have_width(100)
468
+ image.should have_height(355)
469
+ end
470
+
471
+ it "should take into account the gravity given" do
472
+ image1 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'nw')
473
+ image2 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'se')
474
+ image1.should_not equal_image(image2)
475
+ end
476
+
477
+ end
478
+
479
+ describe "rotate" do
480
+
481
+ it "should rotate by 90 degrees" do
482
+ image = @processor.rotate(@image, 90)
483
+ image.should have_width(355)
484
+ image.should have_height(280)
485
+ end
486
+
487
+ it "should not rotate given a larger height and the '>' qualifier" do
488
+ image = @processor.rotate(@image, 90, :qualifier => '>')
489
+ image.should have_width(280)
490
+ image.should have_height(355)
491
+ end
492
+
493
+ it "should rotate given a larger height and the '<' qualifier" do
494
+ image = @processor.rotate(@image, 90, :qualifier => '<')
495
+ image.should have_width(355)
496
+ image.should have_height(280)
497
+ end
498
+
499
+ end
500
+
501
+ describe "strip" do
502
+ it "should strip exif data" do
503
+ jpg = ImageResizer::TempObject.new(SAMPLES_DIR.join('taj.jpg'))
504
+ image = @processor.strip(jpg)
505
+ image.should have_width(300)
506
+ image.should have_height(300)
507
+ image.size.should < jpg.size
508
+ end
509
+ end
510
+
511
+ describe "thumb" do
512
+ it "should call resize if the correct string given" do
513
+ @processor.should_receive(:resize).with(@image, '30x40').and_return(image = mock)
514
+ @processor.thumb(@image, '30x40').should == image
515
+ end
516
+ it "should call resize_and_crop if the correct string given" do
517
+ @processor.should_receive(:resize_and_crop).with(@image, :width => '30', :height => '40', :gravity => 'se').and_return(image = mock)
518
+ @processor.thumb(@image, '30x40#se').should == image
519
+ end
520
+ it "should call crop if x and y given" do
521
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '+10', :y => '+20', :gravity => nil).and_return(image = mock)
522
+ @processor.thumb(@image, '30x40+10+20').should == image
523
+ end
524
+ it "should call crop if just gravity given" do
525
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => nil, :y => nil, :gravity => 'sw').and_return(image = mock)
526
+ @processor.thumb(@image, '30x40sw').should == image
527
+ end
528
+ it "should call crop if x, y and gravity given" do
529
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '-10', :y => '-20', :gravity => 'se').and_return(image = mock)
530
+ @processor.thumb(@image, '30x40-10-20se').should == image
531
+ end
532
+ it "should raise an argument error if an unrecognized string is given" do
533
+ lambda{ @processor.thumb(@image, '30x40#ne!') }.should raise_error(ArgumentError)
534
+ end
535
+ end
536
+
537
+ describe "auto-orient" do
538
+ it "should rotate an image according to exif information" do
539
+ @image = ImageResizer::TempObject.new(SAMPLES_DIR.join('beach.jpg'))
540
+ @image.should have_width(355)
541
+ @image.should have_height(280)
542
+ image = @processor.auto_orient(@image)
543
+ image.should have_width(280)
544
+ image.should have_height(355)
545
+ end
546
+ end
547
+
548
+ describe "flip" do
549
+ it "should flip the image, leaving the same dimensions" do
550
+ image = @processor.flip(@image)
551
+ image.should have_width(280)
552
+ image.should have_height(355)
553
+ end
554
+ end
555
+
556
+ describe "flop" do
557
+ it "should flop the image, leaving the same dimensions" do
558
+ image = @processor.flop(@image)
559
+ image.should have_width(280)
560
+ image.should have_height(355)
561
+ end
562
+ end
563
+
564
+ describe "convert" do
565
+ it "should allow for general convert commands" do
566
+ image = @processor.convert(@image, '-scale 56x71')
567
+ image.should have_width(56)
568
+ image.should have_height(71)
569
+ end
570
+
571
+ it "should allow for general convert commands with added format" do
572
+ image, extra = @processor.convert(@image, '-scale 56x71', :gif)
573
+ image.should have_width(56)
574
+ image.should have_height(71)
575
+ image.should have_format('gif')
576
+ extra[:format].should == :gif
577
+ end
578
+
579
+ it "should work for commands with parenthesis" do
580
+ image = @processor.convert(@image, "\\( +clone -sparse-color Barycentric '0,0 black 0,%[fx:h-1] white' -function polynomial 2,-2,0.5 \\) -compose Blur -set option:compose:args 15 -composite")
581
+ image.should have_width(280)
582
+ end
583
+
584
+ it "should work for files with spaces in the name" do
585
+ image = ImageResizer::TempObject.new(SAMPLES_DIR.join('white pixel.png'))
586
+ @processor.convert(image, "-resize 2x2!").should have_width(2)
587
+ end
588
+ end
589
+
590
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe ImageResizer::Shell do
4
+
5
+ include ImageResizer::Shell
6
+
7
+ it "should raise an error if the identify command isn't found" do
8
+ suppressing_stderr do
9
+ lambda{
10
+ run "non-existent-command"
11
+ }.should raise_error(ImageResizer::Shell::CommandFailed)
12
+ end
13
+ end
14
+
15
+ describe "escaping args" do
16
+ {
17
+ %q(hello) => %q('hello'),
18
+ %q("hello") => %q('hello'),
19
+ %q('hello') => %q('hello'),
20
+ %q(he\'llo) => %q('he'\''llo'),
21
+ %q('he'\''llo') => %q('he'\''llo'),
22
+ %q("he'llo") => %q('he'\''llo'),
23
+ %q(hel$(lo)) => %q('hel$(lo)'),
24
+ %q(hel\$(lo)) => %q('hel$(lo)'),
25
+ %q('hel\$(lo)') => %q('hel\$(lo)')
26
+ }.each do |args, escaped_args|
27
+ it "should escape #{args.inspect} -> #{escaped_args.inspect}" do
28
+ pending "not applicable to windows" if running_on_windows?
29
+ escape_args(args).should == escaped_args
30
+ end
31
+ end
32
+ end
33
+
34
+ end