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.
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +22 -0
- data/README.md +56 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/image_resizer.gemspec +93 -0
- data/lib/image_resizer/analyzer.rb +51 -0
- data/lib/image_resizer/configurable.rb +206 -0
- data/lib/image_resizer/encoder.rb +55 -0
- data/lib/image_resizer/has_filename.rb +24 -0
- data/lib/image_resizer/loggable.rb +28 -0
- data/lib/image_resizer/processor.rb +220 -0
- data/lib/image_resizer/shell.rb +48 -0
- data/lib/image_resizer/temp_object.rb +216 -0
- data/lib/image_resizer/utils.rb +44 -0
- data/lib/image_resizer.rb +10 -0
- data/samples/DSC02119.JPG +0 -0
- data/samples/a.jp2 +0 -0
- data/samples/beach.jpg +0 -0
- data/samples/beach.png +0 -0
- data/samples/egg.png +0 -0
- data/samples/landscape.png +0 -0
- data/samples/round.gif +0 -0
- data/samples/sample.docx +0 -0
- data/samples/taj.jpg +0 -0
- data/samples/white pixel.png +0 -0
- data/spec/image_resizer/analyzer_spec.rb +78 -0
- data/spec/image_resizer/configurable_spec.rb +479 -0
- data/spec/image_resizer/encoder_spec.rb +41 -0
- data/spec/image_resizer/has_filename_spec.rb +88 -0
- data/spec/image_resizer/loggable_spec.rb +80 -0
- data/spec/image_resizer/processor_spec.rb +590 -0
- data/spec/image_resizer/shell_spec.rb +34 -0
- data/spec/image_resizer/temp_object_spec.rb +442 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/argument_matchers.rb +19 -0
- data/spec/support/image_matchers.rb +58 -0
- data/spec/support/simple_matchers.rb +53 -0
- data/tmp/test_file +1 -0
- metadata +147 -0
@@ -0,0 +1,442 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ImageResizer::TempObject do
|
4
|
+
|
5
|
+
####### Helper Methods #######
|
6
|
+
|
7
|
+
def sample_path(filename)
|
8
|
+
SAMPLES_DIR.join(filename)
|
9
|
+
end
|
10
|
+
|
11
|
+
def new_tempfile(data='HELLO')
|
12
|
+
tempfile = Tempfile.new('test')
|
13
|
+
tempfile.write(data)
|
14
|
+
tempfile.rewind
|
15
|
+
tempfile
|
16
|
+
end
|
17
|
+
|
18
|
+
def new_file(data='HELLO', path="tmp/test_file")
|
19
|
+
File.open(path, 'w') do |f|
|
20
|
+
f.write(data)
|
21
|
+
end
|
22
|
+
File.new(path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def new_pathname(data='HELLO', path="tmp/test_file")
|
26
|
+
File.open(path, 'w') do |f|
|
27
|
+
f.write(data)
|
28
|
+
end
|
29
|
+
Pathname.new(path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def new_temp_object(data, klass=ImageResizer::TempObject)
|
33
|
+
klass.new(initialization_object(data))
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialization_object(data)
|
37
|
+
raise NotImplementedError, "This should be implemented in the describe block!"
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_parts(temp_object)
|
41
|
+
parts = []
|
42
|
+
temp_object.each do |bytes|
|
43
|
+
parts << bytes
|
44
|
+
end
|
45
|
+
parts.length.should >= 2 # Sanity check to check that the sample file is adequate for this test
|
46
|
+
parts
|
47
|
+
end
|
48
|
+
|
49
|
+
###############################
|
50
|
+
|
51
|
+
it "should raise an error if initialized with a non-string/file/tempfile" do
|
52
|
+
lambda{
|
53
|
+
ImageResizer::TempObject.new(3)
|
54
|
+
}.should raise_error(ArgumentError)
|
55
|
+
end
|
56
|
+
|
57
|
+
shared_examples_for "common behaviour" do
|
58
|
+
|
59
|
+
describe "simple initialization" do
|
60
|
+
|
61
|
+
before(:each) do
|
62
|
+
@temp_object = new_temp_object('HELLO')
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "data" do
|
66
|
+
it "should return the data correctly" do
|
67
|
+
@temp_object.data.should == 'HELLO'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "file" do
|
72
|
+
it "should return a readable file" do
|
73
|
+
@temp_object.file.should be_a(File)
|
74
|
+
end
|
75
|
+
it "should contain the correct data" do
|
76
|
+
@temp_object.file.read.should == 'HELLO'
|
77
|
+
end
|
78
|
+
it "should yield a file then close it if a block is given" do
|
79
|
+
@temp_object.file do |f|
|
80
|
+
f.read.should == 'HELLO'
|
81
|
+
f.should_receive :close
|
82
|
+
end
|
83
|
+
end
|
84
|
+
it "should return whatever is returned from the block if a block is given" do
|
85
|
+
@temp_object.file do |f|
|
86
|
+
'doogie'
|
87
|
+
end.should == 'doogie'
|
88
|
+
end
|
89
|
+
it "should enable reading the file twice" do
|
90
|
+
@temp_object.file{|f| f.read }.should == "HELLO"
|
91
|
+
@temp_object.file{|f| f.read }.should == "HELLO"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "tempfile" do
|
96
|
+
it "should create a closed tempfile" do
|
97
|
+
@temp_object.tempfile.should be_a(Tempfile)
|
98
|
+
@temp_object.tempfile.should be_closed
|
99
|
+
end
|
100
|
+
it "should contain the correct data" do
|
101
|
+
@temp_object.tempfile.open.read.should == 'HELLO'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "path" do
|
106
|
+
it "should return an absolute file path" do
|
107
|
+
if running_on_windows?
|
108
|
+
@temp_object.path.should =~ %r{^[a-zA-Z]:/\w+}
|
109
|
+
else
|
110
|
+
@temp_object.path.should =~ %r{^/\w+}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "size" do
|
116
|
+
it "should return the size in bytes" do
|
117
|
+
@temp_object.size.should == 5
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "to_file" do
|
122
|
+
before(:each) do
|
123
|
+
@filename = 'tmp/eggnog.txt'
|
124
|
+
FileUtils.rm_f(@filename) if File.exists?(@filename)
|
125
|
+
end
|
126
|
+
after(:each) do
|
127
|
+
FileUtils.rm_f(@filename) if File.exists?(@filename)
|
128
|
+
end
|
129
|
+
it "should write to a file" do
|
130
|
+
@temp_object.to_file(@filename)
|
131
|
+
File.exists?(@filename).should be_true
|
132
|
+
end
|
133
|
+
it "should write the correct data to the file" do
|
134
|
+
@temp_object.to_file(@filename)
|
135
|
+
File.read(@filename).should == 'HELLO'
|
136
|
+
end
|
137
|
+
it "should return a readable file" do
|
138
|
+
file = @temp_object.to_file(@filename)
|
139
|
+
file.should be_a(File)
|
140
|
+
file.read.should == 'HELLO'
|
141
|
+
end
|
142
|
+
it "should have 644 permissions" do
|
143
|
+
@temp_object.to_file(@filename)
|
144
|
+
File::Stat.new(@filename).mode.to_s(8).should =~ /644$/
|
145
|
+
end
|
146
|
+
it "should allow setting different permissions" do
|
147
|
+
@temp_object.to_file(@filename, :mode => 0755)
|
148
|
+
File::Stat.new(@filename).mode.to_s(8).should =~ /755$/
|
149
|
+
end
|
150
|
+
it "should create intermediate subdirs" do
|
151
|
+
filename = 'tmp/gog/mcgee'
|
152
|
+
@temp_object.to_file(filename)
|
153
|
+
File.exists?(filename).should be_true
|
154
|
+
FileUtils.rm_rf('tmp/gog')
|
155
|
+
end
|
156
|
+
it "should allow not creating intermediate subdirs" do
|
157
|
+
filename = 'tmp/gog/mcgee'
|
158
|
+
expect{ @temp_object.to_file(filename, :mkdirs => false) }.to raise_error()
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "each" do
|
165
|
+
it "should yield 8192 bytes each time" do
|
166
|
+
temp_object = new_temp_object(File.read(sample_path('round.gif')))
|
167
|
+
parts = get_parts(temp_object)
|
168
|
+
parts[0...-1].each do |part|
|
169
|
+
part.bytesize.should == 8192
|
170
|
+
end
|
171
|
+
parts.last.bytesize.should <= 8192
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "closing" do
|
176
|
+
before(:each) do
|
177
|
+
@temp_object = new_temp_object("wassup")
|
178
|
+
end
|
179
|
+
it "should delete its tempfile" do
|
180
|
+
tempfile = @temp_object.tempfile
|
181
|
+
path = tempfile.path
|
182
|
+
path.should_not be_empty
|
183
|
+
@temp_object.close
|
184
|
+
File.exist?(path).should be_false
|
185
|
+
end
|
186
|
+
%w(tempfile file data).each do |method|
|
187
|
+
it "should raise error when calling #{method}" do
|
188
|
+
@temp_object.close
|
189
|
+
expect{
|
190
|
+
@temp_object.send(method)
|
191
|
+
}.to raise_error(ImageResizer::TempObject::Closed)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
it "should not report itself as closed to begin with" do
|
195
|
+
@temp_object.should_not be_closed
|
196
|
+
end
|
197
|
+
it "should report itself as closed after closing" do
|
198
|
+
@temp_object.close
|
199
|
+
@temp_object.should be_closed
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "initializing from a string" do
|
206
|
+
|
207
|
+
def initialization_object(data)
|
208
|
+
data
|
209
|
+
end
|
210
|
+
|
211
|
+
it_should_behave_like "common behaviour"
|
212
|
+
|
213
|
+
it "should not create a file when calling each" do
|
214
|
+
temp_object = new_temp_object('HELLO')
|
215
|
+
temp_object.should_not_receive(:tempfile)
|
216
|
+
temp_object.each{}
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should use set the file extension in path from the name" do
|
220
|
+
temp_object = ImageResizer::TempObject.new("hi", :name => 'dark.cloud')
|
221
|
+
temp_object.path.should =~ /\.cloud$/
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe "initializing from a tempfile" do
|
226
|
+
|
227
|
+
def initialization_object(data)
|
228
|
+
new_tempfile(data)
|
229
|
+
end
|
230
|
+
|
231
|
+
it_should_behave_like "common behaviour"
|
232
|
+
|
233
|
+
it "should not create a data string when calling each" do
|
234
|
+
temp_object = new_temp_object('HELLO')
|
235
|
+
temp_object.should_not_receive(:data)
|
236
|
+
temp_object.each{}
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should return the tempfile's path" do
|
240
|
+
temp_object = new_temp_object('HELLO')
|
241
|
+
temp_object.path.should == temp_object.tempfile.path
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe "initializing from a file" do
|
246
|
+
|
247
|
+
def initialization_object(data)
|
248
|
+
new_file(data)
|
249
|
+
end
|
250
|
+
|
251
|
+
it_should_behave_like "common behaviour"
|
252
|
+
|
253
|
+
it "should not create a data string when calling each" do
|
254
|
+
temp_object = new_temp_object('HELLO')
|
255
|
+
temp_object.should_not_receive(:data)
|
256
|
+
temp_object.each{}
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should return the file's path" do
|
260
|
+
file = new_file('HELLO')
|
261
|
+
temp_object = ImageResizer::TempObject.new(file)
|
262
|
+
temp_object.path.should == File.expand_path(file.path)
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should return an absolute path even if the file wasn't instantiated like that" do
|
266
|
+
file = new_file('HELLO', 'tmp/bongo')
|
267
|
+
temp_object = ImageResizer::TempObject.new(file)
|
268
|
+
if running_on_windows?
|
269
|
+
temp_object.path.should =~ %r{^[a-zA-Z]:/\w.*bongo}
|
270
|
+
else
|
271
|
+
temp_object.path.should =~ %r{^/\w.*bongo}
|
272
|
+
end
|
273
|
+
file.close
|
274
|
+
FileUtils.rm(file.path)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe "initializing from a pathname" do
|
279
|
+
|
280
|
+
def initialization_object(data)
|
281
|
+
new_pathname(data)
|
282
|
+
end
|
283
|
+
|
284
|
+
it_should_behave_like "common behaviour"
|
285
|
+
|
286
|
+
it "should not create a data string when calling each" do
|
287
|
+
temp_object = new_temp_object('HELLO')
|
288
|
+
temp_object.should_not_receive(:data)
|
289
|
+
temp_object.each{}
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should return the file's path" do
|
293
|
+
pathname = new_pathname('HELLO')
|
294
|
+
temp_object = ImageResizer::TempObject.new(pathname)
|
295
|
+
temp_object.path.should == File.expand_path(pathname.to_s)
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should return an absolute path even if the pathname is relative" do
|
299
|
+
pathname = new_pathname('HELLO', 'tmp/bingo')
|
300
|
+
temp_object = ImageResizer::TempObject.new(pathname)
|
301
|
+
if running_on_windows?
|
302
|
+
temp_object.path.should =~ %r{^[a-zA-Z]:/\w.*bingo}
|
303
|
+
else
|
304
|
+
temp_object.path.should =~ %r{^/\w.*bingo}
|
305
|
+
end
|
306
|
+
pathname.delete
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "initializing from another temp object" do
|
311
|
+
|
312
|
+
def initialization_object(data)
|
313
|
+
ImageResizer::TempObject.new(data)
|
314
|
+
end
|
315
|
+
|
316
|
+
before(:each) do
|
317
|
+
@temp_object1 = ImageResizer::TempObject.new(new_tempfile('hello'))
|
318
|
+
@temp_object2 = ImageResizer::TempObject.new(@temp_object1)
|
319
|
+
end
|
320
|
+
|
321
|
+
it_should_behave_like "common behaviour"
|
322
|
+
|
323
|
+
it "should not be the same object" do
|
324
|
+
@temp_object1.should_not == @temp_object2
|
325
|
+
end
|
326
|
+
it "should have the same data" do
|
327
|
+
@temp_object1.data.should == @temp_object2.data
|
328
|
+
end
|
329
|
+
it "should have the same file path" do
|
330
|
+
@temp_object1.path.should == @temp_object2.path
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
describe "initialize from a Rack::Test::UploadedFile" do
|
335
|
+
def initialization_object(data)
|
336
|
+
# The criteria we're using to determine if an object is a
|
337
|
+
# Rack::Test::UploadedFile is if it responds to path
|
338
|
+
#
|
339
|
+
# We can't just check if it is_a?(Rack::Test::UploadedFile) because that
|
340
|
+
# class may not always be present.
|
341
|
+
uploaded_file = mock("mock_uploadedfile")
|
342
|
+
uploaded_file.stub!(:path).and_return File.expand_path('tmp/test_file')
|
343
|
+
uploaded_file.stub!(:original_filename).and_return('foo.jpg')
|
344
|
+
|
345
|
+
# Create a real file with the contents required at the correct path
|
346
|
+
new_file(data, 'tmp/test_file')
|
347
|
+
|
348
|
+
uploaded_file
|
349
|
+
end
|
350
|
+
|
351
|
+
it_should_behave_like "common behaviour"
|
352
|
+
end
|
353
|
+
|
354
|
+
describe "original_filename" do
|
355
|
+
before(:each) do
|
356
|
+
@obj = new_tempfile
|
357
|
+
end
|
358
|
+
it "should set the original_filename if the initial object responds to 'original filename'" do
|
359
|
+
def @obj.original_filename
|
360
|
+
'jimmy.page'
|
361
|
+
end
|
362
|
+
ImageResizer::TempObject.new(@obj).original_filename.should == 'jimmy.page'
|
363
|
+
end
|
364
|
+
it "should not set the name if the initial object doesn't respond to 'original filename'" do
|
365
|
+
ImageResizer::TempObject.new(@obj).original_filename.should be_nil
|
366
|
+
end
|
367
|
+
it "should set the name if the initial object is a file object" do
|
368
|
+
file = File.new(SAMPLES_DIR.join('round.gif'))
|
369
|
+
temp_object = ImageResizer::TempObject.new(file)
|
370
|
+
temp_object.original_filename.should == 'round.gif'
|
371
|
+
end
|
372
|
+
it "should set the name if the initial object is a pathname" do
|
373
|
+
pathname = Pathname.new(SAMPLES_DIR + '/round.gif')
|
374
|
+
temp_object = ImageResizer::TempObject.new(pathname)
|
375
|
+
temp_object.original_filename.should == 'round.gif'
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
describe "meta" do
|
380
|
+
it "should default to an empty hash" do
|
381
|
+
ImageResizer::TempObject.new('sdf').meta.should == {}
|
382
|
+
end
|
383
|
+
it "should allow setting on initialize" do
|
384
|
+
ImageResizer::TempObject.new('sdf', :dub => 'wub').meta.should == {:dub => 'wub'}
|
385
|
+
end
|
386
|
+
it "should allow setting" do
|
387
|
+
temp_object = ImageResizer::TempObject.new('boo')
|
388
|
+
temp_object.meta = {:far => 'gone'}
|
389
|
+
temp_object.meta.should == {:far => 'gone'}
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
describe "name" do
|
394
|
+
it "should default to nil" do
|
395
|
+
ImageResizer::TempObject.new("HELLO").name.should be_nil
|
396
|
+
end
|
397
|
+
it "should allow setting the name via the meta" do
|
398
|
+
ImageResizer::TempObject.new("HELLO", :name => 'gosh.pig').name.should == "gosh.pig"
|
399
|
+
end
|
400
|
+
it "should fallback to the original filename if not set" do
|
401
|
+
content = "HELLO"
|
402
|
+
content.should_receive(:original_filename).and_return("some.egg")
|
403
|
+
temp_object = ImageResizer::TempObject.new(content)
|
404
|
+
temp_object.name.should == "some.egg"
|
405
|
+
end
|
406
|
+
it "should prefer the specified name to the original filename" do
|
407
|
+
content = "HELLO"
|
408
|
+
content.stub!(:original_filename).and_return("brase.nose")
|
409
|
+
temp_object = ImageResizer::TempObject.new("HELLO", :name => 'some.gug')
|
410
|
+
temp_object.name.should == "some.gug"
|
411
|
+
end
|
412
|
+
it "should allow setting with a setter" do
|
413
|
+
temp_object = ImageResizer::TempObject.new("HELLO")
|
414
|
+
temp_object.name = 'bugs'
|
415
|
+
temp_object.name.should == "bugs"
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
describe "sanity check for using HasFilename" do
|
420
|
+
it "should act like ImageResizer::HasFilename" do
|
421
|
+
temp_object = ImageResizer::TempObject.new('h', :name => 'one.big.park')
|
422
|
+
temp_object.ext = 'smeagol'
|
423
|
+
temp_object.name.should == 'one.big.smeagol'
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
describe "unique_id" do
|
428
|
+
before(:each) do
|
429
|
+
@temp_object = ImageResizer::TempObject.new('hello')
|
430
|
+
end
|
431
|
+
it "should return a unique id" do
|
432
|
+
@temp_object.unique_id.should =~ /^\d+$/
|
433
|
+
end
|
434
|
+
it "should be unique" do
|
435
|
+
@temp_object.unique_id.should_not == ImageResizer::TempObject.new('hello').unique_id
|
436
|
+
end
|
437
|
+
it "should not change" do
|
438
|
+
@temp_object.unique_id.should == @temp_object.unique_id
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler"
|
3
|
+
Bundler.setup(:default, :test)
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
require 'rspec'
|
8
|
+
require 'image_resizer'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'pry'
|
11
|
+
require 'pry-nav'
|
12
|
+
require 'pry-stack_explorer'
|
13
|
+
|
14
|
+
# Requires supporting files with custom matchers and macros, etc,
|
15
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
16
|
+
|
17
|
+
SAMPLES_DIR = Pathname.new(File.expand_path(File.dirname(__FILE__) + '/../samples')) unless defined?(SAMPLES_DIR)
|
18
|
+
|
19
|
+
def todo
|
20
|
+
raise "TODO"
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# require 'logger'
|
25
|
+
# LOG_FILE = 'tmp/test.log' unless defined?(LOG_FILE)
|
26
|
+
# FileUtils.rm_rf(LOG_FILE)
|
27
|
+
# def mock_app(extra_stubs={})
|
28
|
+
# mock('app', {
|
29
|
+
# :datastore => mock('datastore', :store => 'some_uid', :retrieve => ["SOME_DATA", {}], :destroy => nil),
|
30
|
+
# :processor => mock('processor', :process => "SOME_PROCESSED_DATA"),
|
31
|
+
# :encoder => mock('encoder', :encode => "SOME_ENCODED_DATA"),
|
32
|
+
# :analyzer => mock('analyzer', :analyse => "some_result", :analysis_methods => Module.new),
|
33
|
+
# :generator => mock('generator', :generate => "SOME_GENERATED_DATA"),
|
34
|
+
# :log => Logger.new(LOG_FILE),
|
35
|
+
# :cache_duration => 10000,
|
36
|
+
# :job_definitions => Module.new
|
37
|
+
# }.merge(extra_stubs)
|
38
|
+
# )
|
39
|
+
# end
|
40
|
+
|
41
|
+
# def test_app
|
42
|
+
# time = Time.now
|
43
|
+
# app = ImageResizer::App.send(:new, "test_#{time.sec}_#{time.usec}".to_sym)
|
44
|
+
# app.log = Logger.new(LOG_FILE)
|
45
|
+
# app.datastore.root_path = 'tmp/file_data_store_test'
|
46
|
+
# app
|
47
|
+
# end
|
48
|
+
|
49
|
+
def suppressing_stderr
|
50
|
+
original_stderr = $stderr.dup
|
51
|
+
tempfile = Tempfile.new('stderr')
|
52
|
+
$stderr.reopen(tempfile) rescue
|
53
|
+
yield
|
54
|
+
ensure
|
55
|
+
tempfile.close!
|
56
|
+
$stderr.reopen(original_stderr)
|
57
|
+
end
|
58
|
+
|
59
|
+
def running_on_windows?
|
60
|
+
ENV['OS'] && ENV['OS'].downcase == 'windows_nt'
|
61
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
def string_matching(regexp)
|
2
|
+
Spec::Mocks::ArgumentMatchers::RegexpMatcher.new(regexp)
|
3
|
+
end
|
4
|
+
|
5
|
+
class TempObjectArgumentMatcher
|
6
|
+
def initialize(data, opts)
|
7
|
+
@data = data
|
8
|
+
@opts = opts
|
9
|
+
end
|
10
|
+
def ==(actual)
|
11
|
+
actual.is_a?(ImageResizer::TempObject) &&
|
12
|
+
actual.data == @data &&
|
13
|
+
@opts.all?{|k,v| actual.send(k) == v }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def a_temp_object_with_data(data, opts={})
|
18
|
+
TempObjectArgumentMatcher.new(data, opts)
|
19
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
def image_properties(image)
|
2
|
+
if image.is_a?(Tempfile)
|
3
|
+
tempfile = image
|
4
|
+
else
|
5
|
+
tempfile = Tempfile.new('image')
|
6
|
+
tempfile.binmode
|
7
|
+
tempfile.write(image.is_a?(ImageResizer::TempObject) ? image.data : image)
|
8
|
+
tempfile.close
|
9
|
+
end
|
10
|
+
details = `identify #{tempfile.path}`
|
11
|
+
# example of details string:
|
12
|
+
# myimage.png PNG 200x100 200x100+0+0 8-bit DirectClass 31.2kb
|
13
|
+
filename, format, geometry, geometry_2, depth, image_class, size = details.split(' ')
|
14
|
+
width, height = geometry.split('x')
|
15
|
+
{
|
16
|
+
:filename => filename,
|
17
|
+
:format => format.downcase,
|
18
|
+
:width => width,
|
19
|
+
:height => height,
|
20
|
+
:depth => depth,
|
21
|
+
:image_class => image_class,
|
22
|
+
:size => size
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec::Matchers.define :have_width do |width|
|
27
|
+
match do |given|
|
28
|
+
width.should === image_properties(given)[:width].to_i
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
RSpec::Matchers.define :have_height do |height|
|
33
|
+
match do |given|
|
34
|
+
height.should === image_properties(given)[:height].to_i
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
RSpec::Matchers.define :have_format do |format|
|
39
|
+
match do |given|
|
40
|
+
image_properties(given)[:format].should == format
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
RSpec::Matchers.define :have_size do |size|
|
45
|
+
match do |given|
|
46
|
+
image_properties(given)[:size].should == size
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
RSpec::Matchers.define :equal_image do |other|
|
51
|
+
match do |given|
|
52
|
+
image_data = given.open.read
|
53
|
+
other_image_data = other.open.read
|
54
|
+
given.close
|
55
|
+
other.close
|
56
|
+
image_data == other_image_data
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
RSpec::Matchers.define :match_url do |url|
|
2
|
+
match do |given|
|
3
|
+
given_path, given_query_string = given.split('?')
|
4
|
+
path, query_string = url.split('?')
|
5
|
+
|
6
|
+
path == given_path && given_query_string.split('&').sort == query_string.split('&').sort
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec::Matchers.define :be_an_empty_directory do
|
11
|
+
match do |given|
|
12
|
+
Dir.entries(given) == ['.','..']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec::Matchers.define :include_hash do |hash|
|
17
|
+
match do |given|
|
18
|
+
given.merge(hash) == given
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def memory_usage
|
23
|
+
GC.start # Garbage collect
|
24
|
+
`ps -o rss= -p #{$$}`.strip.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
RSpec::Matchers.define :leak_memory do
|
28
|
+
match do |given|
|
29
|
+
memory_before = memory_usage
|
30
|
+
given.call
|
31
|
+
memory_after = memory_usage
|
32
|
+
result = memory_after > memory_before
|
33
|
+
puts "#{memory_after} > #{memory_before}" if result
|
34
|
+
result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
RSpec::Matchers.define :match_attachment_classes do |classes|
|
39
|
+
match do |given_classes|
|
40
|
+
given_classes.length == classes.length &&
|
41
|
+
classes.zip(given_classes).all? do |(klass, given)|
|
42
|
+
given.model_class == klass[0] && given.attribute == klass[1] && given.app == klass[2]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
RSpec::Matchers.define :be_a_text_response do
|
48
|
+
match do |given_response|
|
49
|
+
given_response.status.should == 200
|
50
|
+
given_response.body.length.should > 0
|
51
|
+
given_response.content_type.should == 'text/plain'
|
52
|
+
end
|
53
|
+
end
|
data/tmp/test_file
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
wassup
|