httpthumbnailer 1.2.0 → 1.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.
Files changed (57) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +4 -3
  3. data/Gemfile.lock +12 -12
  4. data/README.md +242 -68
  5. data/Rakefile +8 -2
  6. data/VERSION +1 -1
  7. data/bin/httpthumbnailer +35 -7
  8. data/lib/httpthumbnailer/error_reporter.rb +4 -2
  9. data/lib/httpthumbnailer/ownership.rb +54 -0
  10. data/lib/httpthumbnailer/plugin.rb +87 -0
  11. data/lib/httpthumbnailer/plugin/thumbnailer.rb +22 -427
  12. data/lib/httpthumbnailer/plugin/thumbnailer/service.rb +163 -0
  13. data/lib/httpthumbnailer/plugin/thumbnailer/service/built_in_plugins.rb +134 -0
  14. data/lib/httpthumbnailer/plugin/thumbnailer/service/images.rb +295 -0
  15. data/lib/httpthumbnailer/plugin/thumbnailer/service/magick.rb +208 -0
  16. data/lib/httpthumbnailer/thumbnail_specs.rb +130 -37
  17. data/lib/httpthumbnailer/thumbnailer.rb +29 -11
  18. metadata +30 -81
  19. data/.rspec +0 -1
  20. data/features/httpthumbnailer.feature +0 -24
  21. data/features/identify.feature +0 -31
  22. data/features/step_definitions/httpthumbnailer_steps.rb +0 -159
  23. data/features/support/env.rb +0 -106
  24. data/features/support/test-large.jpg +0 -0
  25. data/features/support/test-transparent.png +0 -0
  26. data/features/support/test.jpg +0 -0
  27. data/features/support/test.png +0 -0
  28. data/features/support/test.txt +0 -1
  29. data/features/thumbnail.feature +0 -269
  30. data/features/thumbnails.feature +0 -158
  31. data/httpthumbnailer.gemspec +0 -121
  32. data/load_test/extralarge.jpg +0 -0
  33. data/load_test/large.jpg +0 -0
  34. data/load_test/large.png +0 -0
  35. data/load_test/load_test-374846090-1.1.0-rc1-identify-only.csv +0 -3
  36. data/load_test/load_test-374846090-1.1.0-rc1.csv +0 -11
  37. data/load_test/load_test-cd9679c.csv +0 -10
  38. data/load_test/load_test-v0.3.1.csv +0 -10
  39. data/load_test/load_test.jmx +0 -733
  40. data/load_test/medium.jpg +0 -0
  41. data/load_test/small.jpg +0 -0
  42. data/load_test/soak_test-ac0c6bcbe5e-broken-libjpeg-tatoos.csv +0 -11
  43. data/load_test/soak_test-cd9679c.csv +0 -10
  44. data/load_test/soak_test-f98334a-tatoos.csv +0 -11
  45. data/load_test/soak_test.jmx +0 -754
  46. data/load_test/tiny.jpg +0 -0
  47. data/load_test/v0.0.13-loading.csv +0 -7
  48. data/load_test/v0.0.13.csv +0 -7
  49. data/load_test/v0.0.14-no-optimization.csv +0 -10
  50. data/load_test/v0.0.14.csv +0 -10
  51. data/spec/image_processing_spec.rb +0 -148
  52. data/spec/plugin_thumbnailer_spec.rb +0 -318
  53. data/spec/spec_helper.rb +0 -14
  54. data/spec/support/square_even.png +0 -0
  55. data/spec/support/square_odd.png +0 -0
  56. data/spec/support/test_image.rb +0 -16
  57. data/spec/thumbnail_specs_spec.rb +0 -43
Binary file
@@ -1,7 +0,0 @@
1
- sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
2
- tiny,16,55,46,50,43,187,0.0,0.9256045354622238,67.94967748466966
3
- small,16,141,140,145,132,150,0.0,0.921605898277749,77.99539917055469
4
- medium,16,118,114,129,110,137,0.0,0.9236808682600162,82.94996969172152
5
- large,16,146,146,154,128,163,0.0625,0.9237875288683602,93.9015025079388
6
- extra large,15,678,675,691,655,747,0.0,0.8956293288750896,89.44310747925125
7
- RAZEM,79,222,140,675,43,747,0.012658227848101266,4.471613743136922,401.30654964057277
@@ -1,7 +0,0 @@
1
- sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
2
- tiny,11,54,56,59,47,66,0.0,0.17140898183064793,13.240004713746998
3
- small,11,79,80,85,72,87,0.0,0.17137159593693524,14.533449349956378
4
- medium,11,127,129,133,110,140,0.0,0.1712595360423478,15.379741870037364
5
- large,11,452,477,510,114,516,0.09090909090909091,0.17129153819801302,16.917609378406365
6
- extra large,10,5654,5604,5868,5408,6147,0.0,0.157855688329729,15.774623760832847
7
- RAZEM,54,1192,126,5604,47,6147,0.018518518518518517,0.8372482441043769,75.29186798416981
@@ -1,10 +0,0 @@
1
- sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
2
- tiny,5,54,54,54,49,60,0.0,0.08831113780069944,6.821345464339962
3
- small,5,77,78,80,73,81,0.0,0.088281512085739,7.486858469286862
4
- medium,5,122,120,133,111,133,0.0,0.08818808755313333,7.919617522752526
5
- large,5,511,507,521,491,537,0.0,0.0875871492134674,9.501409468827735
6
- extra large,4,6220,5973,6931,5748,6931,0.0,0.08261219769098907,4.524873370990727
7
- extra large w prescale,4,6066,6046,6257,5825,6257,0.0,0.08256615613260124,4.769001826776204
8
- large PNG,4,532,536,568,486,568,0.0,0.0931619154089808,9.325471341065771
9
- large PNG w prescale,4,547,541,571,533,571,0.0,0.0930925339787749,10.098630812465089
10
- RAZEM,36,1591,500,6046,49,6931,0.0,0.6278996755851676,53.82679507360379
@@ -1,10 +0,0 @@
1
- sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth
2
- tiny,48,51,50,57,42,72,0.0,0.3999566713606026,29.36127232049861
3
- small,48,147,146,154,138,171,0.0,0.39959707295144065,33.81785345609843
4
- medium,48,118,119,125,105,132,0.0,0.3996968965201389,35.89426455771041
5
- large,48,143,142,153,130,183,0.0,0.3995804405374357,43.283068403176664
6
- extra large,48,656,647,676,636,894,0.0,0.3977757704833804,21.74248576708571
7
- extra large w prescale,48,593,590,604,579,654,0.0,0.39787468605200554,23.01534097031689
8
- large PNG,48,509,505,540,483,587,0.0,0.39790766884134265,39.83040221833525
9
- large PNG w prescale,48,326,307,361,299,608,0.0,0.39849898714840765,43.22196289808389
10
- RAZEM,384,318,183,642,42,894,0.0,3.1306559702587684,265.0230977596243
@@ -1,148 +0,0 @@
1
- require_relative 'spec_helper'
2
- require 'unicorn-cuba-base'
3
- require 'httpthumbnailer/plugin/thumbnailer'
4
-
5
- class StubImage
6
- include Plugin::Thumbnailer::ImageProcessing
7
-
8
- @@created = 0
9
- @@destroyed = 0
10
-
11
- def self.alive
12
- @@created - @@destroyed
13
- end
14
-
15
- def initialize
16
- @@created += 1
17
- @destroyed = false
18
- @final = false
19
- end
20
-
21
- def destroy!
22
- fail "already destroyed: #{self}" if @destroyed
23
- @destroyed = true
24
- @@destroyed += 1
25
- self
26
- end
27
-
28
- def copy
29
- StubImage.new
30
- end
31
-
32
- def destroyed?
33
- @destroyed
34
- end
35
-
36
- def final!
37
- @final = true
38
- self
39
- end
40
-
41
- def final?
42
- @final
43
- end
44
- end
45
-
46
- describe 'image processing module' do
47
- it '#replace will return new or original image makng sure that all other images are destroyed' do
48
- image = StubImage.new.replace do |image|
49
- image.copy.replace do |image|
50
- image.final!
51
- end
52
- end
53
- image.should be_final
54
- image.should_not be_destroyed
55
-
56
- StubImage.alive.should == 1
57
- image.destroy!
58
-
59
- image = StubImage.new.replace do |image|
60
- image.copy.replace do |image|
61
- image.copy.replace do |image|
62
- image.copy
63
- end.replace do |image|
64
- image.final!
65
- end
66
- end
67
- end
68
- image.should be_final
69
- image.should_not be_destroyed
70
-
71
- StubImage.alive.should == 1
72
- image.destroy!
73
-
74
- image = StubImage.new.replace do |image|
75
- image.copy.replace do |image|
76
- image = image.copy.replace do |image|
77
- image.copy
78
- end
79
- image.replace do |image|
80
- image.copy.replace do |image|
81
- image.final!
82
- end
83
- end
84
- end
85
- end
86
- image.should be_final
87
- image.should_not be_destroyed
88
-
89
- StubImage.alive.should == 1
90
- image.destroy!
91
- end
92
-
93
- it '#replace will destroy created images on exception' do
94
- lambda {
95
- image = StubImage.new.replace do |image|
96
- image.copy.replace do |image|
97
- image.copy.replace do |image|
98
- image.copy.replace do |image|
99
- fail 'test'
100
- end
101
- end
102
- end
103
- end
104
- }.should raise_error(RuntimeError, 'test')
105
-
106
- StubImage.alive.should == 0
107
-
108
- lambda {
109
- image = StubImage.new.replace do |image|
110
- image.copy.replace do |image|
111
- image.copy.replace do |image|
112
- image.copy
113
- end.replace do |image|
114
- fail 'test'
115
- image.final!
116
- end
117
- end
118
- end
119
- }.should raise_error(RuntimeError, 'test')
120
-
121
- StubImage.alive.should == 0
122
- end
123
-
124
- it '#use should return image to be used for multiple processing and destroy it at the end' do
125
- image = StubImage.new.use do |image|
126
- i1 = image.replace do |image|
127
- image.copy.final!
128
- end
129
- i1.should be_final
130
- i1.destroy!
131
-
132
- i2 = image.replace do |image|
133
- image.copy.final!
134
- end
135
- i2.should be_final
136
- i2.destroy!
137
-
138
- i3 = image.replace do |image|
139
- nil
140
- end
141
- i3.should_not be_destroyed
142
- end
143
- image.should be_destroyed
144
-
145
- StubImage.alive.should == 0
146
- end
147
- end
148
-
@@ -1,318 +0,0 @@
1
- require_relative 'spec_helper'
2
- require 'unicorn-cuba-base'
3
- require 'httpthumbnailer/plugin/thumbnailer'
4
- require 'httpthumbnailer/thumbnail_specs'
5
-
6
- describe Plugin::Thumbnailer::Service do
7
- subject do
8
- service = Plugin::Thumbnailer::Service.new
9
- service.setup_default_methods
10
- service
11
- end
12
-
13
- def square_odd
14
- subject.load(TestImage.io('square_odd.png'))
15
- end
16
-
17
- def square_even
18
- subject.load(TestImage.io('square_even.png'))
19
- end
20
-
21
- before :each do
22
- @before_stats = Plugin::Thumbnailer::Service.stats.to_hash
23
- end
24
-
25
- def diff_stat(name)
26
- Plugin::Thumbnailer::Service.stats.to_hash[name] - @before_stats[name]
27
- end
28
-
29
- it "should load images from provided blob" do
30
- image = subject.load(TestImage.io('square_odd.png'))
31
- image.format.should == 'PNG'
32
- image.width.should == 99
33
- image.height.should == 99
34
- end
35
-
36
- describe 'encoding' do
37
- describe 'interlace' do
38
- it 'should fail if unknown interlace is specified' do
39
- expect {
40
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,99,99,jpeg,interlace:Blah')) do |thumbnail|
41
- end
42
- }.to raise_error RuntimeError, 'unsupported interlace: Blah'
43
- end
44
-
45
- it 'should allow to construct progressive JPEG with interlace JPEGInterlace or LineInterlace or PlaneInerlace' do
46
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,99,99,jpeg')) do |thumbnail|
47
- image = Magick::Image.from_blob(thumbnail.data).first
48
- image.columns.should == 99
49
- image.rows.should == 99
50
- image.interlace.to_s.should == 'NoInterlace'
51
- image.destroy!
52
- end
53
-
54
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,99,99,jpeg,interlace:JPEGInterlace')) do |thumbnail|
55
- image = Magick::Image.from_blob(thumbnail.data).first
56
- image.columns.should == 99
57
- image.rows.should == 99
58
- image.interlace.to_s.should == 'JPEGInterlace'
59
- image.destroy!
60
- end
61
-
62
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,99,99,jpeg,interlace:LineInterlace')) do |thumbnail|
63
- image = Magick::Image.from_blob(thumbnail.data).first
64
- image.columns.should == 99
65
- image.rows.should == 99
66
- image.interlace.to_s.should == 'JPEGInterlace'
67
- image.destroy!
68
- end
69
-
70
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,99,99,jpeg,interlace:PlaneInterlace')) do |thumbnail|
71
- image = Magick::Image.from_blob(thumbnail.data).first
72
- image.columns.should == 99
73
- image.rows.should == 99
74
- image.interlace.to_s.should == 'JPEGInterlace'
75
- image.destroy!
76
- end
77
- end
78
- end
79
- end
80
-
81
- describe 'thumbnailing' do
82
- describe 'cropping' do
83
- it 'should be a noop if same width and height are used as original image' do
84
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,99,99,png')) do |thumbnail|
85
- thumbnail.width.should == 99
86
- thumbnail.height.should == 99
87
- end
88
- diff_stat(:total_images_created_resize).should == 0
89
- diff_stat(:total_images_created_crop).should == 0
90
- end
91
-
92
- it 'should be a resize operation if same proportions are used as original image' do
93
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,50,50,png')) do |thumbnail|
94
- thumbnail.width.should == 50
95
- thumbnail.height.should == 50
96
- end
97
- diff_stat(:total_images_created_resize).should == 1
98
- diff_stat(:total_images_created_crop).should == 0
99
- end
100
-
101
- it 'should be a resize and crop operation if different proportions are used as original image' do
102
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,50,60,png')) do |thumbnail|
103
- thumbnail.width.should == 50
104
- thumbnail.height.should == 60
105
- end
106
- diff_stat(:total_images_created_resize).should == 1
107
- diff_stat(:total_images_created_crop).should == 1
108
- end
109
-
110
- it 'should crop to even and odd proportions' do
111
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,33,33,png')) do |thumbnail|
112
- thumbnail.width.should == 33
113
- thumbnail.height.should == 33
114
- end
115
-
116
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,91,91,png')) do |thumbnail|
117
- thumbnail.width.should == 91
118
- thumbnail.height.should == 91
119
- end
120
-
121
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,33,50,png')) do |thumbnail|
122
- thumbnail.width.should == 33
123
- thumbnail.height.should == 50
124
- end
125
- end
126
-
127
- it 'should crop with upwards scaling' do
128
- square_odd.thumbnail(ThumbnailSpec.from_uri('crop,198,99,png')) do |thumbnail|
129
- thumbnail.width.should == 198
130
- thumbnail.height.should == 99
131
- #show_blob thumbnail.data
132
- end
133
- end
134
-
135
- describe 'floating' do
136
- it 'should crop with floating horizontally' do
137
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,100,200,png')) do |thumbnail|
138
- thumbnail.width.should == 100
139
- thumbnail.height.should == 200
140
- #show_blob thumbnail.data
141
- end
142
-
143
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,100,200,png,float-x:1.0')) do |thumbnail|
144
- thumbnail.width.should == 100
145
- thumbnail.height.should == 200
146
- #show_blob thumbnail.data
147
- end
148
-
149
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,100,200,png,float-x:0.0')) do |thumbnail|
150
- thumbnail.width.should == 100
151
- thumbnail.height.should == 200
152
- #show_blob thumbnail.data
153
- end
154
-
155
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,100,200,png,float-x:0.8')) do |thumbnail|
156
- thumbnail.width.should == 100
157
- thumbnail.height.should == 200
158
- #show_blob thumbnail.data
159
- end
160
-
161
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,100,200,png,float-x:-9.8')) do |thumbnail|
162
- thumbnail.width.should == 100
163
- thumbnail.height.should == 200
164
- #show_blob thumbnail.data
165
- end
166
-
167
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,100,200,png,float-x:3')) do |thumbnail|
168
- thumbnail.width.should == 100
169
- thumbnail.height.should == 200
170
- #show_blob thumbnail.data
171
- end
172
- end
173
-
174
- it 'should crop with floating vertically' do
175
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,200,100,png')) do |thumbnail|
176
- thumbnail.width.should == 200
177
- thumbnail.height.should == 100
178
- #show_blob thumbnail.data
179
- end
180
-
181
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,200,100,png,float-y:1.0')) do |thumbnail|
182
- thumbnail.width.should == 200
183
- thumbnail.height.should == 100
184
- #show_blob thumbnail.data
185
- end
186
-
187
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,200,100,png,float-y:0.0')) do |thumbnail|
188
- thumbnail.width.should == 200
189
- thumbnail.height.should == 100
190
- #show_blob thumbnail.data
191
- end
192
-
193
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,200,100,png,float-y:0.8')) do |thumbnail|
194
- thumbnail.width.should == 200
195
- thumbnail.height.should == 100
196
- #show_blob thumbnail.data
197
- end
198
-
199
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,200,100,png,float-y:-9.8')) do |thumbnail|
200
- thumbnail.width.should == 200
201
- thumbnail.height.should == 100
202
- #show_blob thumbnail.data
203
- end
204
-
205
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,200,100,png,float-y:3')) do |thumbnail|
206
- thumbnail.width.should == 200
207
- thumbnail.height.should == 100
208
- #show_blob thumbnail.data
209
- end
210
- end
211
-
212
- it 'should crop with floating horizontally and vertically' do
213
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,100,200,png,float-x:0.25,float-y:0.25')) do |thumbnail|
214
- thumbnail.width.should == 100
215
- thumbnail.height.should == 200
216
- #show_blob thumbnail.data
217
- end
218
-
219
- square_even.thumbnail(ThumbnailSpec.from_uri('crop,200,100,png,float-x:0.25,float-y:0.25')) do |thumbnail|
220
- thumbnail.width.should == 200
221
- thumbnail.height.should == 100
222
- #show_blob thumbnail.data
223
- end
224
- end
225
-
226
- it 'should pad with floating horizontaly' do
227
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,200,100,png')) do |thumbnail|
228
- thumbnail.width.should == 200
229
- thumbnail.height.should == 100
230
- #show_blob thumbnail.data
231
- end
232
-
233
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,200,100,png,float-x:1.0')) do |thumbnail|
234
- thumbnail.width.should == 200
235
- thumbnail.height.should == 100
236
- #show_blob thumbnail.data
237
- end
238
-
239
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,200,100,png,float-x:0.0')) do |thumbnail|
240
- thumbnail.width.should == 200
241
- thumbnail.height.should == 100
242
- #show_blob thumbnail.data
243
- end
244
-
245
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,200,100,png,float-x:0.8')) do |thumbnail|
246
- thumbnail.width.should == 200
247
- thumbnail.height.should == 100
248
- #show_blob thumbnail.data
249
- end
250
-
251
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,200,100,png,float-x:-9.8')) do |thumbnail|
252
- thumbnail.width.should == 200
253
- thumbnail.height.should == 100
254
- #show_blob thumbnail.data
255
- end
256
-
257
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,200,100,png,float-x:3')) do |thumbnail|
258
- thumbnail.width.should == 200
259
- thumbnail.height.should == 100
260
- #show_blob thumbnail.data
261
- end
262
- end
263
-
264
- it 'should pad with floating verticaly' do
265
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,100,200,png')) do |thumbnail|
266
- thumbnail.width.should == 100
267
- thumbnail.height.should == 200
268
- #show_blob thumbnail.data
269
- end
270
-
271
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,100,200,png,float-y:1.0')) do |thumbnail|
272
- thumbnail.width.should == 100
273
- thumbnail.height.should == 200
274
- #show_blob thumbnail.data
275
- end
276
-
277
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,100,200,png,float-y:0.0')) do |thumbnail|
278
- thumbnail.width.should == 100
279
- thumbnail.height.should == 200
280
- #show_blob thumbnail.data
281
- end
282
-
283
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,100,200,png,float-y:0.8')) do |thumbnail|
284
- thumbnail.width.should == 100
285
- thumbnail.height.should == 200
286
- #show_blob thumbnail.data
287
- end
288
-
289
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,100,200,png,float-y:-9.8')) do |thumbnail|
290
- thumbnail.width.should == 100
291
- thumbnail.height.should == 200
292
- #show_blob thumbnail.data
293
- end
294
-
295
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,100,200,png,float-y:3')) do |thumbnail|
296
- thumbnail.width.should == 100
297
- thumbnail.height.should == 200
298
- #show_blob thumbnail.data
299
- end
300
- end
301
-
302
- it 'should pad with floating horizontally and vertically' do
303
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,100,200,png,float-x:0.25,float-y:0.25')) do |thumbnail|
304
- thumbnail.width.should == 100
305
- thumbnail.height.should == 200
306
- #show_blob thumbnail.data
307
- end
308
-
309
- square_even.thumbnail(ThumbnailSpec.from_uri('pad,200,100,png,float-x:0.25,float-y:0.25')) do |thumbnail|
310
- thumbnail.width.should == 200
311
- thumbnail.height.should == 100
312
- #show_blob thumbnail.data
313
- end
314
- end
315
- end
316
- end
317
- end
318
- end