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.
- data/.gitignore +7 -0
- data/LICENSE +20 -0
- data/README.markdown +95 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/config.rb +7 -0
- data/config.ru +10 -0
- data/dragonfly-rails.gemspec +41 -0
- data/dragonfly.gemspec +137 -0
- data/features/dragonfly.feature +38 -0
- data/features/steps/common_steps.rb +8 -0
- data/features/steps/dragonfly_steps.rb +39 -0
- data/features/support/env.rb +25 -0
- data/features/support/image_helpers.rb +9 -0
- data/generators/dragonfly_app/USAGE +16 -0
- data/generators/dragonfly_app/dragonfly_app_generator.rb +54 -0
- data/generators/dragonfly_app/templates/custom_processing.erb +13 -0
- data/generators/dragonfly_app/templates/initializer.erb +7 -0
- data/generators/dragonfly_app/templates/metal_file.erb +32 -0
- data/irbrc.rb +20 -0
- data/lib/dragonfly/active_record_extensions/attachment.rb +117 -0
- data/lib/dragonfly/active_record_extensions/class_methods.rb +41 -0
- data/lib/dragonfly/active_record_extensions/instance_methods.rb +28 -0
- data/lib/dragonfly/active_record_extensions/validations.rb +19 -0
- data/lib/dragonfly/active_record_extensions.rb +12 -0
- data/lib/dragonfly/analysis/analyser.rb +45 -0
- data/lib/dragonfly/analysis/base.rb +10 -0
- data/lib/dragonfly/analysis/r_magick_analyser.rb +40 -0
- data/lib/dragonfly/app.rb +85 -0
- data/lib/dragonfly/app_configuration.rb +9 -0
- data/lib/dragonfly/configurable.rb +113 -0
- data/lib/dragonfly/core_ext/object.rb +8 -0
- data/lib/dragonfly/data_storage/base.rb +19 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +72 -0
- data/lib/dragonfly/data_storage.rb +9 -0
- data/lib/dragonfly/encoding/base.rb +13 -0
- data/lib/dragonfly/encoding/r_magick_encoder.rb +17 -0
- data/lib/dragonfly/extended_temp_object.rb +94 -0
- data/lib/dragonfly/middleware.rb +27 -0
- data/lib/dragonfly/parameters.rb +152 -0
- data/lib/dragonfly/processing/processor.rb +14 -0
- data/lib/dragonfly/processing/r_magick_processor.rb +71 -0
- data/lib/dragonfly/r_magick_configuration.rb +47 -0
- data/lib/dragonfly/rails/images.rb +20 -0
- data/lib/dragonfly/temp_object.rb +118 -0
- data/lib/dragonfly/url_handler.rb +148 -0
- data/lib/dragonfly.rb +33 -0
- data/samples/beach.png +0 -0
- data/samples/egg.png +0 -0
- data/samples/round.gif +0 -0
- data/samples/taj.jpg +0 -0
- data/spec/argument_matchers.rb +29 -0
- data/spec/dragonfly/active_record_extensions/attachment_spec.rb +8 -0
- data/spec/dragonfly/active_record_extensions/initializer.rb +1 -0
- data/spec/dragonfly/active_record_extensions/migration.rb +21 -0
- data/spec/dragonfly/active_record_extensions/model_spec.rb +400 -0
- data/spec/dragonfly/active_record_extensions/models.rb +2 -0
- data/spec/dragonfly/active_record_extensions/spec_helper.rb +23 -0
- data/spec/dragonfly/analysis/analyser_spec.rb +85 -0
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +35 -0
- data/spec/dragonfly/app_spec.rb +69 -0
- data/spec/dragonfly/configurable_spec.rb +193 -0
- data/spec/dragonfly/data_storage/data_store_spec.rb +47 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +93 -0
- data/spec/dragonfly/extended_temp_object_spec.rb +67 -0
- data/spec/dragonfly/middleware_spec.rb +44 -0
- data/spec/dragonfly/parameters_spec.rb +293 -0
- data/spec/dragonfly/processing/rmagick_processor_spec.rb +148 -0
- data/spec/dragonfly/temp_object_spec.rb +233 -0
- data/spec/dragonfly/url_handler_spec.rb +246 -0
- data/spec/dragonfly_spec.rb +4 -0
- data/spec/image_matchers.rb +31 -0
- data/spec/simple_matchers.rb +14 -0
- data/spec/spec_helper.rb +19 -0
- 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 @@
|
|
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,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
|