dragonfly 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dragonfly might be problematic. Click here for more details.

Files changed (75) hide show
  1. data/.gitignore +7 -0
  2. data/LICENSE +20 -0
  3. data/README.markdown +95 -0
  4. data/Rakefile +60 -0
  5. data/VERSION +1 -0
  6. data/config.rb +7 -0
  7. data/config.ru +10 -0
  8. data/dragonfly-rails.gemspec +41 -0
  9. data/dragonfly.gemspec +137 -0
  10. data/features/dragonfly.feature +38 -0
  11. data/features/steps/common_steps.rb +8 -0
  12. data/features/steps/dragonfly_steps.rb +39 -0
  13. data/features/support/env.rb +25 -0
  14. data/features/support/image_helpers.rb +9 -0
  15. data/generators/dragonfly_app/USAGE +16 -0
  16. data/generators/dragonfly_app/dragonfly_app_generator.rb +54 -0
  17. data/generators/dragonfly_app/templates/custom_processing.erb +13 -0
  18. data/generators/dragonfly_app/templates/initializer.erb +7 -0
  19. data/generators/dragonfly_app/templates/metal_file.erb +32 -0
  20. data/irbrc.rb +20 -0
  21. data/lib/dragonfly/active_record_extensions/attachment.rb +117 -0
  22. data/lib/dragonfly/active_record_extensions/class_methods.rb +41 -0
  23. data/lib/dragonfly/active_record_extensions/instance_methods.rb +28 -0
  24. data/lib/dragonfly/active_record_extensions/validations.rb +19 -0
  25. data/lib/dragonfly/active_record_extensions.rb +12 -0
  26. data/lib/dragonfly/analysis/analyser.rb +45 -0
  27. data/lib/dragonfly/analysis/base.rb +10 -0
  28. data/lib/dragonfly/analysis/r_magick_analyser.rb +40 -0
  29. data/lib/dragonfly/app.rb +85 -0
  30. data/lib/dragonfly/app_configuration.rb +9 -0
  31. data/lib/dragonfly/configurable.rb +113 -0
  32. data/lib/dragonfly/core_ext/object.rb +8 -0
  33. data/lib/dragonfly/data_storage/base.rb +19 -0
  34. data/lib/dragonfly/data_storage/file_data_store.rb +72 -0
  35. data/lib/dragonfly/data_storage.rb +9 -0
  36. data/lib/dragonfly/encoding/base.rb +13 -0
  37. data/lib/dragonfly/encoding/r_magick_encoder.rb +17 -0
  38. data/lib/dragonfly/extended_temp_object.rb +94 -0
  39. data/lib/dragonfly/middleware.rb +27 -0
  40. data/lib/dragonfly/parameters.rb +152 -0
  41. data/lib/dragonfly/processing/processor.rb +14 -0
  42. data/lib/dragonfly/processing/r_magick_processor.rb +71 -0
  43. data/lib/dragonfly/r_magick_configuration.rb +47 -0
  44. data/lib/dragonfly/rails/images.rb +20 -0
  45. data/lib/dragonfly/temp_object.rb +118 -0
  46. data/lib/dragonfly/url_handler.rb +148 -0
  47. data/lib/dragonfly.rb +33 -0
  48. data/samples/beach.png +0 -0
  49. data/samples/egg.png +0 -0
  50. data/samples/round.gif +0 -0
  51. data/samples/taj.jpg +0 -0
  52. data/spec/argument_matchers.rb +29 -0
  53. data/spec/dragonfly/active_record_extensions/attachment_spec.rb +8 -0
  54. data/spec/dragonfly/active_record_extensions/initializer.rb +1 -0
  55. data/spec/dragonfly/active_record_extensions/migration.rb +21 -0
  56. data/spec/dragonfly/active_record_extensions/model_spec.rb +400 -0
  57. data/spec/dragonfly/active_record_extensions/models.rb +2 -0
  58. data/spec/dragonfly/active_record_extensions/spec_helper.rb +23 -0
  59. data/spec/dragonfly/analysis/analyser_spec.rb +85 -0
  60. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +35 -0
  61. data/spec/dragonfly/app_spec.rb +69 -0
  62. data/spec/dragonfly/configurable_spec.rb +193 -0
  63. data/spec/dragonfly/data_storage/data_store_spec.rb +47 -0
  64. data/spec/dragonfly/data_storage/file_data_store_spec.rb +93 -0
  65. data/spec/dragonfly/extended_temp_object_spec.rb +67 -0
  66. data/spec/dragonfly/middleware_spec.rb +44 -0
  67. data/spec/dragonfly/parameters_spec.rb +293 -0
  68. data/spec/dragonfly/processing/rmagick_processor_spec.rb +148 -0
  69. data/spec/dragonfly/temp_object_spec.rb +233 -0
  70. data/spec/dragonfly/url_handler_spec.rb +246 -0
  71. data/spec/dragonfly_spec.rb +4 -0
  72. data/spec/image_matchers.rb +31 -0
  73. data/spec/simple_matchers.rb +14 -0
  74. data/spec/spec_helper.rb +19 -0
  75. metadata +160 -0
data/lib/dragonfly.rb ADDED
@@ -0,0 +1,33 @@
1
+ # AUTOLOAD EVERYTHING IN THE IMAGETASTIC DIRECTORY TREE
2
+
3
+ # The convention is that dirs are modules
4
+ # so declare them here and autoload any modules/classes inside them
5
+ # All paths here are absolute
6
+ def camelize(path)
7
+ # e.g. 'test/this_one' => Test::ThisOne
8
+ "#{path}".
9
+ chomp('/').
10
+ gsub('/','::').
11
+ gsub(/([^a-z])(\w)/){ "#{$1}#{$2.upcase}" }.
12
+ gsub('_','').
13
+ sub(/^(\w)/){ $1.upcase }
14
+ end
15
+ def autoload_files_in_dir(path, namespace)
16
+ # Define the module
17
+ eval("module #{namespace}; end")
18
+ # Autoload modules/classes in that module
19
+ Dir.glob("#{path}/*.rb").each do |file|
20
+ sub_const_name = camelize( File.basename(file, '.rb') )
21
+ eval("#{namespace}.autoload('#{sub_const_name}', '#{file}')")
22
+ end
23
+ # Recurse on subdirectories
24
+ Dir.glob("#{path}/*/").each do |dir|
25
+ sub_namespace = camelize( File.basename(dir) )
26
+ autoload_files_in_dir(dir, "#{namespace}::#{sub_namespace}")
27
+ end
28
+ end
29
+
30
+ autoload_files_in_dir("#{File.dirname(__FILE__)}/dragonfly", 'Dragonfly')
31
+
32
+ require 'rubygems'
33
+ require File.dirname(__FILE__) + '/dragonfly/core_ext/object'
data/samples/beach.png ADDED
Binary file
data/samples/egg.png ADDED
Binary file
data/samples/round.gif ADDED
Binary file
data/samples/taj.jpg ADDED
Binary file
@@ -0,0 +1,29 @@
1
+ def string_matching(regexp)
2
+ Spec::Mocks::ArgumentMatchers::RegexpMatcher.new(regexp)
3
+ end
4
+
5
+ class TempObjectArgumentMatcher
6
+ def initialize(data)
7
+ @data = data
8
+ end
9
+ def ==(actual)
10
+ actual.is_a?(Dragonfly::TempObject) && actual.data == @data
11
+ end
12
+ end
13
+
14
+ def a_temp_object_with_data(data)
15
+ TempObjectArgumentMatcher.new(data)
16
+ end
17
+
18
+ class ParametersArgumentMatcher
19
+ def initialize(hash)
20
+ @hash = hash
21
+ end
22
+ def ==(actual)
23
+ actual.to_hash.reject{|k,v| v.nil? || v.respond_to?(:empty?) && v.empty?} == @hash
24
+ end
25
+ end
26
+
27
+ def parameters_matching(hash)
28
+ ParametersArgumentMatcher.new(hash)
29
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Dragonfly::ActiveRecordExtensions::Attachment do
4
+
5
+ # See model_spec - tests are less brittle if doing mini integration tests
6
+ # at the model level
7
+
8
+ end
@@ -0,0 +1 @@
1
+ ActiveRecord::Base.extend Dragonfly::ActiveRecordExtensions
@@ -0,0 +1,21 @@
1
+ class MigrationForTest < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ create_table :items, :force => true do |t|
5
+ t.string :title
6
+ t.string :preview_image_uid
7
+ t.string :preview_image_some_analyser_method
8
+ t.integer :preview_image_size
9
+ t.string :preview_image_blah_blah
10
+ t.string :other_image_uid
11
+ t.string :yet_another_image_uid
12
+ t.string :trailer_video_uid
13
+ t.timestamps
14
+ end
15
+ end
16
+
17
+ def self.down
18
+ drop_table :items
19
+ end
20
+
21
+ end
@@ -0,0 +1,400 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Item do
4
+
5
+ # See extra setup in models / initializer files
6
+
7
+ describe "registering dragonfly apps" do
8
+
9
+ before(:each) do
10
+ @app1, @app2 = Dragonfly::App[:images], Dragonfly::App[:videos]
11
+ ActiveRecord::Base.register_dragonfly_app(:image, @app1)
12
+ ActiveRecord::Base.register_dragonfly_app(:video, @app2)
13
+ end
14
+
15
+ it "should return the mapping of apps to attributes" do
16
+ Item.class_eval do
17
+ image_accessor :preview_image
18
+ video_accessor :trailer_video
19
+ end
20
+ Item.dragonfly_apps_for_attributes.should == {:preview_image => @app1, :trailer_video => @app2}
21
+ end
22
+
23
+ end
24
+
25
+ describe "defining accessors" do
26
+
27
+ it "should raise an error if the wrong method prefix is used" do
28
+ lambda{
29
+ Item.class_eval do
30
+ dog_accessor :preview_image
31
+ end
32
+ }.should raise_error(NameError)
33
+ end
34
+
35
+ describe "correctly defined" do
36
+
37
+ before(:each) do
38
+ @app = Dragonfly::App[:images]
39
+ ActiveRecord::Base.register_dragonfly_app(:image, @app)
40
+ Item.class_eval do
41
+ image_accessor :preview_image
42
+ end
43
+ @item = Item.new
44
+ end
45
+
46
+ it "should provide a reader" do
47
+ @item.should respond_to(:preview_image)
48
+ end
49
+
50
+ it "should provide a writer" do
51
+ @item.should respond_to(:preview_image=)
52
+ end
53
+
54
+ describe "when there has been nothing assigned" do
55
+ it "the reader should return nil" do
56
+ @item.preview_image.should be_nil
57
+ end
58
+ it "the uid should be nil" do
59
+ @item.preview_image_uid.should be_nil
60
+ end
61
+ it "should not try to store anything on save" do
62
+ @app.datastore.should_not_receive(:store)
63
+ @item.save!
64
+ end
65
+ it "should not try to destroy anything on save" do
66
+ @app.datastore.should_not_receive(:destroy)
67
+ @item.save!
68
+ end
69
+ it "should not try to destroy anything on destroy" do
70
+ @app.datastore.should_not_receive(:destroy)
71
+ @item.destroy
72
+ end
73
+ end
74
+
75
+ describe "when there has been some thing assigned but not saved" do
76
+ before(:each) do
77
+ @item.preview_image = "DATASTRING"
78
+ end
79
+ it "the reader should return an attachment" do
80
+ @item.preview_image.should be_a(Dragonfly::ActiveRecordExtensions::Attachment)
81
+ end
82
+ it "the uid should be a 'pending' object" do
83
+ @item.preview_image_uid.should be_a(Dragonfly::ActiveRecordExtensions::PendingUID)
84
+ end
85
+ it "should store the image when saved" do
86
+ @app.datastore.should_receive(:store).with(a_temp_object_with_data("DATASTRING"))
87
+ @item.save!
88
+ end
89
+ it "should not try to destroy anything on destroy" do
90
+ @app.datastore.should_not_receive(:destroy)
91
+ @item.destroy
92
+ end
93
+ it "should return nil for the url" do
94
+ @item.preview_image.url.should be_nil
95
+ end
96
+ it "should return the size" do
97
+ @item.preview_image.size.should == 10
98
+ end
99
+ it "should return the temp_object" do
100
+ temp_object = @item.preview_image.temp_object
101
+ temp_object.should be_a(Dragonfly::ExtendedTempObject)
102
+ temp_object.data.should == 'DATASTRING'
103
+ end
104
+ end
105
+
106
+ describe "when something has been assigned and saved" do
107
+
108
+ before(:each) do
109
+ @item.preview_image = "DATASTRING"
110
+ @app.datastore.should_receive(:store).with(a_temp_object_with_data("DATASTRING")).once.and_return('some_uid')
111
+ @app.datastore.stub!(:store)
112
+ @app.datastore.stub!(:destroy)
113
+ @item.save!
114
+ end
115
+ it "should have the correct uid" do
116
+ @item.preview_image_uid.should == 'some_uid'
117
+ end
118
+ it "should not try to store anything if saved again" do
119
+ @app.datastore.should_not_receive(:store)
120
+ @item.save!
121
+ end
122
+
123
+ it "should not try to destroy anything if saved again" do
124
+ @app.datastore.should_not_receive(:destroy)
125
+ @item.save!
126
+ end
127
+
128
+ it "should destroy the data on destroy" do
129
+ @app.datastore.should_receive(:destroy).with('some_uid')
130
+ @item.destroy
131
+ end
132
+
133
+ it "should return the url for the data" do
134
+ @app.should_receive(:url_for).with(@item.preview_image_uid, :arg).and_return('some.url')
135
+ @item.preview_image.url(:arg).should == 'some.url'
136
+ end
137
+
138
+ describe "when reloaded" do
139
+ before(:each) do
140
+ @item.reload
141
+ end
142
+ it "should destroy the data on destroy" do
143
+ @app.datastore.should_receive(:destroy).with(@item.preview_image_uid)
144
+ @item.destroy
145
+ end
146
+ it "should return the size" do
147
+ @item.preview_image.size.should == 10
148
+ end
149
+ it "should return the temp_object" do
150
+ temp_object = @item.preview_image.temp_object
151
+ temp_object.should be_a(Dragonfly::ExtendedTempObject)
152
+ temp_object.data.should == 'DATASTRING'
153
+ end
154
+ end
155
+
156
+ describe "when something new is assigned" do
157
+ before(:each) do
158
+ @item.preview_image = "NEWDATASTRING"
159
+ end
160
+ it "should set the uid to pending" do
161
+ @item.preview_image_uid.should be_a(Dragonfly::ActiveRecordExtensions::PendingUID)
162
+ end
163
+ it "should destroy the old data when saved" do
164
+ @app.datastore.should_receive(:store).with(a_temp_object_with_data("NEWDATASTRING")).once.and_return('some_uid')
165
+
166
+ @app.datastore.should_receive(:destroy).with('some_uid')
167
+ @item.save!
168
+ end
169
+ it "should store the new data when saved" do
170
+ @app.datastore.should_receive(:store).with(a_temp_object_with_data("NEWDATASTRING"))
171
+ @item.save!
172
+ end
173
+ it "should destroy the old data on destroy" do
174
+ @app.datastore.should_receive(:destroy).with('some_uid')
175
+ @item.destroy
176
+ end
177
+ it "should return the new size" do
178
+ @item.preview_image.size.should == 13
179
+ end
180
+ it "should return the new temp_object" do
181
+ temp_object = @item.preview_image.temp_object
182
+ temp_object.should be_a(Dragonfly::ExtendedTempObject)
183
+ temp_object.data.should == 'NEWDATASTRING'
184
+ end
185
+ end
186
+
187
+ describe "when it is set to nil" do
188
+ before(:each) do
189
+ @item.preview_image = nil
190
+ end
191
+ it "should set the uid to nil" do
192
+ @item.preview_image_uid.should be_nil
193
+ end
194
+ it "should return the attribute as nil" do
195
+ @item.preview_image.should be_nil
196
+ end
197
+ it "should destroy the data on save" do
198
+ @app.datastore.should_receive(:destroy).with('some_uid')
199
+ @item.save!
200
+ end
201
+ it "should destroy the old data on destroy" do
202
+ @app.datastore.should_receive(:destroy).with('some_uid')
203
+ @item.destroy
204
+ end
205
+ end
206
+
207
+ describe "when the data can't be found" do
208
+ before(:each) do
209
+ @app.datastore.stub!(:destroy).with('some_uid').and_raise(Dragonfly::DataStorage::DataNotFound)
210
+ @app.datastore.stub!(:retrieve).with('some_uid').and_raise(Dragonfly::DataStorage::DataNotFound)
211
+ end
212
+ it "should log a warning if the data wasn't found on destroy" do
213
+ @app.log.should_receive(:warn)
214
+ @item.destroy
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ end
221
+ end
222
+
223
+ describe "validations" do
224
+
225
+ before(:all) do
226
+ @app = Dragonfly::App[:images]
227
+ ActiveRecord::Base.register_dragonfly_app(:image, @app)
228
+ end
229
+
230
+ describe "validates_presence_of" do
231
+
232
+ before(:all) do
233
+ Item.class_eval do
234
+ image_accessor :preview_image
235
+ validates_presence_of :preview_image
236
+ end
237
+ end
238
+
239
+ it "should be valid if set" do
240
+ Item.new(:preview_image => "1234567890").should be_valid
241
+ end
242
+
243
+ it "should be invalid if not set" do
244
+ Item.new.should_not be_valid
245
+ end
246
+
247
+ end
248
+
249
+ describe "validates_size_of" do
250
+
251
+ before(:all) do
252
+ Item.class_eval do
253
+ image_accessor :preview_image
254
+ validates_size_of :preview_image, :within => (6..10)
255
+ end
256
+ end
257
+
258
+ it "should be valid if ok" do
259
+ Item.new(:preview_image => "1234567890").should be_valid
260
+ end
261
+
262
+ it "should be invalid if too small" do
263
+ Item.new(:preview_image => "12345").should_not be_valid
264
+ end
265
+
266
+ end
267
+
268
+ describe "validates_mime_type_of" do
269
+
270
+ before(:each) do
271
+ @item = Item.new(:preview_image => "1234567890")
272
+ end
273
+
274
+ before(:all) do
275
+ custom_analyser = Object.new
276
+ def custom_analyser.mime_type(temp_object)
277
+ case temp_object.data
278
+ when "WRONG TYPE" then 'wrong/type'
279
+ when "OTHER TYPE" then nil
280
+ else 'how/special'
281
+ end
282
+ end
283
+ @app.analyser.register(custom_analyser)
284
+
285
+ Item.class_eval do
286
+ validates_mime_type_of :preview_image, :in => ['how/special', 'how/crazy'], :if => :its_friday
287
+ validates_mime_type_of :other_image, :yet_another_image, :as => 'how/special'
288
+
289
+ image_accessor :preview_image
290
+ image_accessor :other_image
291
+ image_accessor :yet_another_image
292
+
293
+ def its_friday
294
+ true
295
+ end
296
+
297
+ end
298
+ end
299
+
300
+ it "should be valid if nil, if not validated on presence (even with validates_mime_type_of)" do
301
+ @item.other_image = nil
302
+ @item.should be_valid
303
+ end
304
+
305
+ it "should be invalid if the mime_type is unknown" do
306
+ @item.preview_image = "OTHER TYPE"
307
+ @item.should_not be_valid
308
+ @item.errors.on(:preview_image).should == "doesn't have the correct MIME-type. It needs to be one of 'how/special', 'how/crazy', but was 'unknown'"
309
+ end
310
+
311
+ it "should be invalid if the mime_type is wrong" do
312
+ @item.preview_image = "WRONG TYPE"
313
+ @item.should_not be_valid
314
+ @item.errors.on(:preview_image).should == "doesn't have the correct MIME-type. It needs to be one of 'how/special', 'how/crazy', but was 'wrong/type'"
315
+ end
316
+
317
+ it "should validate individually" do
318
+ @item.other_image = "1234567"
319
+ @item.yet_another_image = "WRONG TYPE"
320
+ @item.should_not be_valid
321
+ @item.errors.on(:other_image).should be_nil
322
+ @item.errors.on(:yet_another_image).should == "doesn't have the correct MIME-type. It needs to be 'how/special', but was 'wrong/type'"
323
+ end
324
+
325
+ it "should include standard extra options like 'if' on mime type validation" do
326
+ @item.should_receive(:its_friday).and_return(false)
327
+ @item.preview_image = "WRONG TYPE"
328
+ @item.should be_valid
329
+ end
330
+
331
+ it "should require either :as or :in as an argument" do
332
+ lambda{
333
+ Item.class_eval do
334
+ validates_mime_type_of :preview_image
335
+ end
336
+ }.should raise_error(ArgumentError)
337
+ end
338
+
339
+ end
340
+
341
+ end
342
+
343
+ describe "magic attributes" do
344
+
345
+ before(:each) do
346
+ @app = Dragonfly::App[:images]
347
+ custom_analyser = Object.new
348
+ def custom_analyser.some_analyser_method(temp_object)
349
+ "abc" + temp_object.data[0..0]
350
+ end
351
+ @app.analyser.register(custom_analyser)
352
+ ActiveRecord::Base.register_dragonfly_app(:image, @app)
353
+ Item.class_eval do
354
+ image_accessor :preview_image
355
+ end
356
+ @item = Item.new
357
+ end
358
+
359
+ it "should default the magic attribute as nil" do
360
+ @item.preview_image_some_analyser_method.should be_nil
361
+ end
362
+
363
+ it "should set the magic attribute when assigned" do
364
+ @item.preview_image = '123'
365
+ @item.preview_image_some_analyser_method.should == 'abc1'
366
+ end
367
+
368
+ it "should not set non-magic attributes with the same prefix when assigned" do
369
+ @item.preview_image_blah_blah = 'wassup'
370
+ @item.preview_image = '123'
371
+ @item.preview_image_blah_blah.should == 'wassup'
372
+ end
373
+
374
+ it "should update the magic attribute when something else is assigned" do
375
+ @item.preview_image = '123'
376
+ @item.preview_image = '456'
377
+ @item.preview_image_some_analyser_method.should == 'abc4'
378
+ end
379
+
380
+ it "should reset the magic attribute when set to nil" do
381
+ @item.preview_image = '123'
382
+ @item.preview_image = nil
383
+ @item.preview_image_some_analyser_method.should be_nil
384
+ end
385
+
386
+ it "should not reset non-magic attributes with the same prefix when set to nil" do
387
+ @item.preview_image_blah_blah = 'wassup'
388
+ @item.preview_image = '123'
389
+ @item.preview_image = nil
390
+ @item.preview_image_blah_blah.should == 'wassup'
391
+ end
392
+
393
+ it "should work for size too" do
394
+ @item.preview_image = '123'
395
+ @item.preview_image_size.should == 3
396
+ end
397
+
398
+ end
399
+
400
+ end
@@ -0,0 +1,2 @@
1
+ class Item < ActiveRecord::Base
2
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ require 'active_record'
4
+
5
+ DB_FILE = File.expand_path(File.dirname(__FILE__)+'/db.sqlite3')
6
+
7
+ %w{migration initializer models}.each do |file|
8
+ require "#{File.dirname(__FILE__)}/#{file}"
9
+ end
10
+
11
+ Spec::Runner.configure do |config|
12
+
13
+ config.before(:all) do
14
+ FileUtils.rm_f(DB_FILE)
15
+ ActiveRecord::Base.establish_connection(
16
+ :adapter => "sqlite3",
17
+ :database => DB_FILE
18
+ )
19
+ MigrationForTest.verbose = false
20
+ MigrationForTest.up
21
+ end
22
+
23
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ class ImageAnalyser < Dragonfly::Analysis::Base
4
+
5
+ def width(temp_object)
6
+ temp_object.data.length
7
+ end
8
+
9
+ def mime_type(temp_object)
10
+ return 'image/fart' if temp_object.data == 'THIS IS AN IMAGE'
11
+ return 'image/pdf' if temp_object.data == 'THIS IS A PDF'
12
+ end
13
+
14
+ end
15
+
16
+ class PdfAnalyser < Dragonfly::Analysis::Base
17
+
18
+ def pdf_type(temp_object)
19
+ 'egg'
20
+ end
21
+
22
+ def mime_type(temp_object)
23
+ 'application/pdf' if temp_object.data == 'THIS IS A PDF'
24
+ end
25
+
26
+ end
27
+
28
+ describe Dragonfly::Analysis::Analyser do
29
+
30
+ describe "mime_type" do
31
+
32
+ before(:each) do
33
+ @analyser = Dragonfly::Analysis::Analyser.new
34
+ @image = Dragonfly::TempObject.new("THIS IS AN IMAGE")
35
+ @pdf = Dragonfly::TempObject.new("THIS IS A PDF")
36
+ end
37
+
38
+ describe "when no analysers have been registered" do
39
+
40
+ it "should return nil when no modules have been registered" do
41
+ @analyser.mime_type(@image).should be_nil
42
+ end
43
+
44
+ it "should should return analysis methods as an empty array" do
45
+ @analyser.analysis_methods.should == []
46
+ end
47
+
48
+ end
49
+
50
+ describe "after registering a number of modules" do
51
+
52
+ before(:each) do
53
+ @analyser.register(ImageAnalyser.new)
54
+ @analyser.register(PdfAnalyser.new)
55
+ end
56
+
57
+ it "should return the correct value when one of the modules returns non-nil" do
58
+ @analyser.mime_type(@image).should == 'image/fart'
59
+ end
60
+
61
+ it "should override the first registered modules's value with the second, when they both return non-nil" do
62
+ @analyser.mime_type(@pdf).should == 'application/pdf'
63
+ end
64
+
65
+ it "should return all the analysis methods" do
66
+ @analyser.analysis_methods.sort.should == ['mime_type', 'pdf_type', 'width']
67
+ end
68
+
69
+ it "should say if if has an analysis method (as a symbol)" do
70
+ @analyser.has_analysis_method?('pdf_type').should be_true
71
+ end
72
+
73
+ it "should say if if has an analysis method (as a string)" do
74
+ @analyser.has_analysis_method?(:pdf_type).should be_true
75
+ end
76
+
77
+ it "should delegate the call of a method to the registered analysers" do
78
+ @analyser.width(@image).should == 16
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Dragonfly::Analysis::RMagickAnalyser do
4
+
5
+ before(:each) do
6
+ image_path = File.dirname(__FILE__) + '/../../../samples/beach.png'
7
+ @beach = Dragonfly::TempObject.new(File.new(image_path))
8
+ @analyser = Dragonfly::Analysis::RMagickAnalyser.new
9
+ end
10
+
11
+ it "should return the width" do
12
+ @analyser.width(@beach).should == 280
13
+ end
14
+
15
+ it "should return the height" do
16
+ @analyser.height(@beach).should == 355
17
+ end
18
+
19
+ it "should return the mime type" do
20
+ @analyser.mime_type(@beach).should == 'image/png'
21
+ end
22
+
23
+ it "should return nil if it doesn't know the mime type" do
24
+ @analyser.mime_type(Dragonfly::TempObject.new('asdf')).should be_nil
25
+ end
26
+
27
+ it "should return the number of colours" do
28
+ @analyser.number_of_colours(@beach).should == 34703
29
+ end
30
+
31
+ it "should return the depth" do
32
+ @analyser.depth(@beach).should == 8
33
+ end
34
+
35
+ end