fog-dragonfly 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fog-dragonfly might be problematic. Click here for more details.
- data/.specopts +2 -0
- data/.yardopts +23 -0
- data/Gemfile +23 -0
- data/Gemfile.rails.2.3.5 +14 -0
- data/History.md +266 -0
- data/LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +92 -0
- data/VERSION +1 -0
- data/config.ru +13 -0
- data/docs.watchr +1 -0
- data/dragonfly.gemspec +293 -0
- data/extra_docs/Analysers.md +108 -0
- data/extra_docs/Caching.md +23 -0
- data/extra_docs/Configuration.md +138 -0
- data/extra_docs/DataStorage.md +136 -0
- data/extra_docs/Encoding.md +96 -0
- data/extra_docs/GeneralUsage.md +121 -0
- data/extra_docs/Generators.md +102 -0
- data/extra_docs/Heroku.md +50 -0
- data/extra_docs/Index.md +36 -0
- data/extra_docs/MimeTypes.md +40 -0
- data/extra_docs/Models.md +266 -0
- data/extra_docs/Mongo.md +45 -0
- data/extra_docs/Processing.md +130 -0
- data/extra_docs/Rack.md +52 -0
- data/extra_docs/Rails2.md +55 -0
- data/extra_docs/Rails3.md +62 -0
- data/extra_docs/Sinatra.md +25 -0
- data/extra_docs/URLs.md +169 -0
- data/features/3.0.3.feature +8 -0
- data/features/images.feature +47 -0
- data/features/no_processing.feature +14 -0
- data/features/rails_2.3.5.feature +7 -0
- data/features/steps/common_steps.rb +8 -0
- data/features/steps/dragonfly_steps.rb +66 -0
- data/features/steps/rails_steps.rb +39 -0
- data/features/support/env.rb +40 -0
- data/fixtures/files/app/models/album.rb +3 -0
- data/fixtures/files/app/views/albums/new.html.erb +4 -0
- data/fixtures/files/app/views/albums/show.html.erb +4 -0
- data/fixtures/files/config/initializers/dragonfly.rb +4 -0
- data/fixtures/files/features/manage_album_images.feature +12 -0
- data/fixtures/files/features/step_definitions/image_steps.rb +15 -0
- data/fixtures/files/features/support/paths.rb +15 -0
- data/fixtures/files/features/text_images.feature +7 -0
- data/fixtures/rails_2.3.5/template.rb +10 -0
- data/fixtures/rails_3.0.3/template.rb +20 -0
- data/irbrc.rb +17 -0
- data/lib/dragonfly.rb +45 -0
- data/lib/dragonfly/active_model_extensions.rb +13 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +169 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +45 -0
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
- data/lib/dragonfly/active_model_extensions/validations.rb +37 -0
- data/lib/dragonfly/analyser.rb +59 -0
- data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
- data/lib/dragonfly/analysis/image_magick_analyser.rb +47 -0
- data/lib/dragonfly/analysis/r_magick_analyser.rb +63 -0
- data/lib/dragonfly/app.rb +182 -0
- data/lib/dragonfly/config/heroku.rb +19 -0
- data/lib/dragonfly/config/image_magick.rb +41 -0
- data/lib/dragonfly/config/r_magick.rb +46 -0
- data/lib/dragonfly/config/rails.rb +17 -0
- data/lib/dragonfly/configurable.rb +119 -0
- data/lib/dragonfly/core_ext/object.rb +8 -0
- data/lib/dragonfly/core_ext/string.rb +9 -0
- data/lib/dragonfly/core_ext/symbol.rb +9 -0
- data/lib/dragonfly/data_storage.rb +9 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +114 -0
- data/lib/dragonfly/data_storage/mongo_data_store.rb +82 -0
- data/lib/dragonfly/data_storage/s3data_store.rb +115 -0
- data/lib/dragonfly/encoder.rb +13 -0
- data/lib/dragonfly/encoding/image_magick_encoder.rb +57 -0
- data/lib/dragonfly/encoding/r_magick_encoder.rb +61 -0
- data/lib/dragonfly/function_manager.rb +69 -0
- data/lib/dragonfly/generation/hash_with_css_style_keys.rb +23 -0
- data/lib/dragonfly/generation/image_magick_generator.rb +140 -0
- data/lib/dragonfly/generation/r_magick_generator.rb +155 -0
- data/lib/dragonfly/generator.rb +9 -0
- data/lib/dragonfly/image_magick_utils.rb +81 -0
- data/lib/dragonfly/job.rb +371 -0
- data/lib/dragonfly/job_builder.rb +39 -0
- data/lib/dragonfly/job_definitions.rb +26 -0
- data/lib/dragonfly/job_endpoint.rb +15 -0
- data/lib/dragonfly/loggable.rb +28 -0
- data/lib/dragonfly/middleware.rb +34 -0
- data/lib/dragonfly/processing/image_magick_processor.rb +99 -0
- data/lib/dragonfly/processing/r_magick_processor.rb +126 -0
- data/lib/dragonfly/processor.rb +9 -0
- data/lib/dragonfly/r_magick_utils.rb +48 -0
- data/lib/dragonfly/rails/images.rb +22 -0
- data/lib/dragonfly/response.rb +82 -0
- data/lib/dragonfly/routed_endpoint.rb +40 -0
- data/lib/dragonfly/serializer.rb +32 -0
- data/lib/dragonfly/simple_cache.rb +23 -0
- data/lib/dragonfly/simple_endpoint.rb +63 -0
- data/lib/dragonfly/temp_object.rb +220 -0
- data/samples/beach.png +0 -0
- data/samples/egg.png +0 -0
- data/samples/round.gif +0 -0
- data/samples/sample.docx +0 -0
- data/samples/taj.jpg +0 -0
- data/spec/argument_matchers.rb +19 -0
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +723 -0
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
- data/spec/dragonfly/analyser_spec.rb +123 -0
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +57 -0
- data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +15 -0
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +27 -0
- data/spec/dragonfly/analysis/shared_analyser_spec.rb +51 -0
- data/spec/dragonfly/app_spec.rb +280 -0
- data/spec/dragonfly/config/r_magick_spec.rb +25 -0
- data/spec/dragonfly/configurable_spec.rb +220 -0
- data/spec/dragonfly/core_ext/string_spec.rb +17 -0
- data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
- data/spec/dragonfly/data_storage/data_store_spec.rb +76 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +169 -0
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +38 -0
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +94 -0
- data/spec/dragonfly/deprecation_spec.rb +20 -0
- data/spec/dragonfly/encoding/image_magick_encoder_spec.rb +41 -0
- data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +37 -0
- data/spec/dragonfly/function_manager_spec.rb +154 -0
- data/spec/dragonfly/generation/hash_with_css_style_keys_spec.rb +24 -0
- data/spec/dragonfly/generation/image_magick_generator_spec.rb +12 -0
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +24 -0
- data/spec/dragonfly/generation/shared_generator_spec.rb +91 -0
- data/spec/dragonfly/image_magick_utils_spec.rb +16 -0
- data/spec/dragonfly/job_builder_spec.rb +37 -0
- data/spec/dragonfly/job_definitions_spec.rb +35 -0
- data/spec/dragonfly/job_endpoint_spec.rb +120 -0
- data/spec/dragonfly/job_spec.rb +773 -0
- data/spec/dragonfly/loggable_spec.rb +80 -0
- data/spec/dragonfly/middleware_spec.rb +68 -0
- data/spec/dragonfly/processing/image_magick_processor_spec.rb +29 -0
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +26 -0
- data/spec/dragonfly/processing/shared_processing_spec.rb +215 -0
- data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
- data/spec/dragonfly/serializer_spec.rb +61 -0
- data/spec/dragonfly/simple_cache_spec.rb +27 -0
- data/spec/dragonfly/simple_endpoint_spec.rb +89 -0
- data/spec/dragonfly/temp_object_spec.rb +352 -0
- data/spec/image_matchers.rb +47 -0
- data/spec/simple_matchers.rb +44 -0
- data/spec/spec_helper.rb +58 -0
- data/yard/handlers/configurable_attr_handler.rb +38 -0
- data/yard/setup.rb +15 -0
- data/yard/templates/default/fulldoc/html/css/common.css +107 -0
- data/yard/templates/default/layout/html/layout.erb +87 -0
- data/yard/templates/default/module/html/configuration_summary.erb +31 -0
- data/yard/templates/default/module/setup.rb +17 -0
- metadata +550 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Dragonfly::Config::RMagick do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@app = test_app
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should configure all to use the filesystem by default" do
|
10
|
+
@app.configure_with(Dragonfly::Config::RMagick)
|
11
|
+
@app.analyser.get_registered(Dragonfly::Analysis::RMagickAnalyser).use_filesystem.should be_true
|
12
|
+
@app.processor.get_registered(Dragonfly::Processing::RMagickProcessor).use_filesystem.should be_true
|
13
|
+
@app.encoder.get_registered(Dragonfly::Encoding::RMagickEncoder).use_filesystem.should be_true
|
14
|
+
@app.generator.get_registered(Dragonfly::Generation::RMagickGenerator).use_filesystem.should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should configure all not to use the filesystem if requested" do
|
18
|
+
@app.configure_with(Dragonfly::Config::RMagick, :use_filesystem => false)
|
19
|
+
@app.analyser.get_registered(Dragonfly::Analysis::RMagickAnalyser).use_filesystem.should be_false
|
20
|
+
@app.processor.get_registered(Dragonfly::Processing::RMagickProcessor).use_filesystem.should be_false
|
21
|
+
@app.encoder.get_registered(Dragonfly::Encoding::RMagickEncoder).use_filesystem.should be_false
|
22
|
+
@app.generator.get_registered(Dragonfly::Generation::RMagickGenerator).use_filesystem.should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Dragonfly::Configurable do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
class Car
|
7
|
+
include Dragonfly::Configurable
|
8
|
+
configurable_attr :colour
|
9
|
+
configurable_attr :top_speed, 216
|
10
|
+
def self.other_thing=(thing); end
|
11
|
+
end
|
12
|
+
@car = Car.new
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "setup" do
|
16
|
+
it "should provide attr_readers for configurable attributes" do
|
17
|
+
@car.should respond_to(:colour)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should provide attr_writers for configurable attributes" do
|
21
|
+
@car.colour = 'verde'
|
22
|
+
@car.colour.should == 'verde'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set default values for configurable attributes" do
|
26
|
+
@car.top_speed.should == 216
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should set the default as nil if not specified" do
|
30
|
+
@car.colour.should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should allow specifying configurable attrs as strings" do
|
34
|
+
class Bike
|
35
|
+
include Dragonfly::Configurable
|
36
|
+
configurable_attr 'colour', 'rude'
|
37
|
+
end
|
38
|
+
Bike.new.colour.should == 'rude'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "configuring" do
|
43
|
+
it "should allow you to change values" do
|
44
|
+
@car.configure do |c|
|
45
|
+
c.colour = 'red'
|
46
|
+
end
|
47
|
+
@car.colour.should == 'red'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not allow you to call other methods on the object via the configuration" do
|
51
|
+
lambda{
|
52
|
+
@car.configure do |c|
|
53
|
+
c.other_thing = 5
|
54
|
+
end
|
55
|
+
}.should raise_error(Dragonfly::Configurable::BadConfigAttribute)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return itself" do
|
59
|
+
@car.configure{|c|}.should == @car
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "getting configuration" do
|
64
|
+
it "should return the configuration as a hash" do
|
65
|
+
@car.configuration.should == {:colour => nil, :top_speed => 216}
|
66
|
+
end
|
67
|
+
it "should not allow you to change the configuration via the hash" do
|
68
|
+
@car.configuration[:top_speed] = 555
|
69
|
+
@car.top_speed.should == 216
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "multiple objects" do
|
74
|
+
it "should return the default configuration" do
|
75
|
+
Car.default_configuration.should == {:colour => nil, :top_speed => 216}
|
76
|
+
end
|
77
|
+
it "should allow instances to be configured differently" do
|
78
|
+
car1 = Car.new
|
79
|
+
car1.configure{|c| c.colour = 'green'}
|
80
|
+
car2 = Car.new
|
81
|
+
car2.configure{|c| c.colour = 'yellow'}
|
82
|
+
car1.configuration.should == {:colour => 'green', :top_speed => 216}
|
83
|
+
car2.configuration.should == {:colour => 'yellow', :top_speed => 216}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "lazy attributes" do
|
88
|
+
before(:each) do
|
89
|
+
cow = @cow = mock('cow')
|
90
|
+
class Lazy; end
|
91
|
+
Lazy.class_eval do
|
92
|
+
include Dragonfly::Configurable
|
93
|
+
configurable_attr(:sound){ cow.moo }
|
94
|
+
end
|
95
|
+
@lazy = Lazy.new
|
96
|
+
end
|
97
|
+
it "should not call the block if the configurable attribute is set to something else" do
|
98
|
+
@cow.should_not_receive(:moo)
|
99
|
+
@lazy.configure{|c| c.sound = 'baa' }
|
100
|
+
@lazy.sound.should == 'baa'
|
101
|
+
end
|
102
|
+
it "should call the block if it's not been changed, once it's accessed" do
|
103
|
+
@cow.should_receive(:moo).and_return('mooo!')
|
104
|
+
@lazy.sound.should == 'mooo!'
|
105
|
+
end
|
106
|
+
it "should not call the block when accessed again" do
|
107
|
+
@cow.should_receive(:moo).exactly(:once).and_return('mooo!')
|
108
|
+
@lazy.sound.should == 'mooo!'
|
109
|
+
@lazy.sound.should == 'mooo!'
|
110
|
+
end
|
111
|
+
it "should not call an explicitly passed in proc" do
|
112
|
+
@lazy.configure{|c| c.sound = lambda{ @cow.fart }}
|
113
|
+
@lazy.sound.should be_a(Proc)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "using in the singleton class" do
|
118
|
+
it "should work" do
|
119
|
+
class OneOff
|
120
|
+
class << self
|
121
|
+
include Dragonfly::Configurable
|
122
|
+
configurable_attr :food, 'bread'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
OneOff.food.should == 'bread'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "configuration method" do
|
130
|
+
|
131
|
+
before(:each) do
|
132
|
+
class ClassWithMethod
|
133
|
+
include Dragonfly::Configurable
|
134
|
+
def add_thing(thing)
|
135
|
+
'poo'
|
136
|
+
end
|
137
|
+
def remove_thing(thing)
|
138
|
+
'bum'
|
139
|
+
end
|
140
|
+
configuration_method :add_thing, :remove_thing
|
141
|
+
end
|
142
|
+
@thing = ClassWithMethod.new
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should allow calling the method through 'configure'" do
|
146
|
+
@thing.configure do |c|
|
147
|
+
c.add_thing('duck')
|
148
|
+
c.remove_thing('dog')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "nested configurable objects" do
|
155
|
+
|
156
|
+
it "should allow configuring nested configurable objects" do
|
157
|
+
|
158
|
+
class NestedThing
|
159
|
+
include Dragonfly::Configurable
|
160
|
+
configurable_attr :age, 29
|
161
|
+
end
|
162
|
+
|
163
|
+
class Car
|
164
|
+
def nested_thing
|
165
|
+
@nested_thing ||= NestedThing.new
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
@car.configure do |c|
|
170
|
+
c.nested_thing.configure do |nt|
|
171
|
+
nt.age = 50
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
@car.nested_thing.age.should == 50
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "configuring with a configurer" do
|
182
|
+
before(:each) do
|
183
|
+
@cool_configuration = Object.new
|
184
|
+
def @cool_configuration.apply_configuration(car, colour=nil)
|
185
|
+
car.configure do |c|
|
186
|
+
c.colour = (colour || 'vermelho')
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should allow configuration by a configurer" do
|
192
|
+
@car.configure_with(@cool_configuration)
|
193
|
+
@car.colour.should == 'vermelho'
|
194
|
+
@car.top_speed.should == 216
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should pass any args through to the configurer" do
|
198
|
+
@car.configure_with(@cool_configuration, 'preto')
|
199
|
+
@car.colour.should == 'preto'
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should yield a block for any extra configuration" do
|
203
|
+
@car.configure_with(@cool_configuration) do |c|
|
204
|
+
c.colour = 'branco'
|
205
|
+
end
|
206
|
+
@car.colour.should == 'branco'
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should return itself" do
|
210
|
+
@car.configure_with(@cool_configuration).should == @car
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should ask the object which object to configure with if a symbol is given" do
|
214
|
+
@car.should_receive(:configurer_for).with(:cool).and_return(@cool_configuration)
|
215
|
+
@car.configure_with(:cool)
|
216
|
+
@car.colour.should == 'vermelho'
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
|
5
|
+
describe "to_method_name" do
|
6
|
+
if RUBY_VERSION =~ /^1.8/
|
7
|
+
it "should return a string" do
|
8
|
+
'hello'.to_method_name.should == 'hello'
|
9
|
+
end
|
10
|
+
else
|
11
|
+
it "should return a symbol" do
|
12
|
+
'hello'.to_method_name.should == :hello
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Symbol do
|
4
|
+
|
5
|
+
describe "to_method_name" do
|
6
|
+
if RUBY_VERSION =~ /^1.8/
|
7
|
+
it "should return a string" do
|
8
|
+
:hello.to_method_name.should == 'hello'
|
9
|
+
end
|
10
|
+
else
|
11
|
+
it "should return a symbol" do
|
12
|
+
:hello.to_method_name.should == :hello
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe "data_store", :shared => true do
|
4
|
+
|
5
|
+
# Using these shared spec requires you to set the inst var @data_store
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@temp_object = Dragonfly::TempObject.new('gollum')
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "store" do
|
12
|
+
it "should return a unique identifier for each storage" do
|
13
|
+
temp_object2 = Dragonfly::TempObject.new('gollum')
|
14
|
+
@data_store.store(@temp_object).should_not == @data_store.store(temp_object2)
|
15
|
+
end
|
16
|
+
it "should return a unique identifier for each storage even when the first is deleted" do
|
17
|
+
uid1 = @data_store.store(@temp_object)
|
18
|
+
@data_store.destroy(uid1)
|
19
|
+
uid2 = @data_store.store(@temp_object)
|
20
|
+
uid1.should_not == uid2
|
21
|
+
end
|
22
|
+
it "should allow for passing in options as a second argument" do
|
23
|
+
@data_store.store(@temp_object, :some => :option)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "retrieve" do
|
28
|
+
|
29
|
+
describe "without extra info" do
|
30
|
+
before(:each) do
|
31
|
+
uid = @data_store.store(@temp_object)
|
32
|
+
@obj, @extra_info = @data_store.retrieve(uid)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should retrieve the stored data" do
|
36
|
+
Dragonfly::TempObject.new(@obj).data.should == @temp_object.data
|
37
|
+
end
|
38
|
+
|
39
|
+
it { @extra_info[:name].should be_nil }
|
40
|
+
it { @extra_info[:meta].should be_a(Hash) }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "when extra info is given" do
|
44
|
+
before(:each) do
|
45
|
+
temp_object = Dragonfly::TempObject.new('gollum',
|
46
|
+
:name => 'danny.boy',
|
47
|
+
:meta => {:bitrate => '35'}
|
48
|
+
)
|
49
|
+
@uid = @data_store.store(temp_object)
|
50
|
+
@obj, @extra_info = @data_store.retrieve(@uid)
|
51
|
+
end
|
52
|
+
|
53
|
+
it { @extra_info[:name].should == 'danny.boy' }
|
54
|
+
it { @extra_info[:meta].should include_hash(:bitrate => '35') }
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should raise an exception if the data doesn't exist" do
|
58
|
+
lambda{
|
59
|
+
@data_store.retrieve('gooble/gubbub')
|
60
|
+
}.should raise_error(Dragonfly::DataStorage::DataNotFound)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "destroy" do
|
65
|
+
|
66
|
+
it "should destroy the stored data" do
|
67
|
+
uid = @data_store.store(@temp_object)
|
68
|
+
@data_store.destroy(uid)
|
69
|
+
lambda{
|
70
|
+
@data_store.retrieve(uid)
|
71
|
+
}.should raise_error(Dragonfly::DataStorage::DataNotFound)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/data_store_spec'
|
3
|
+
|
4
|
+
describe Dragonfly::DataStorage::FileDataStore do
|
5
|
+
|
6
|
+
def touch_file(filename)
|
7
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
8
|
+
FileUtils.touch(filename)
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@data_store = Dragonfly::DataStorage::FileDataStore.new
|
13
|
+
@data_store.root_path = '/var/tmp/dragonfly_test'
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:each) do
|
17
|
+
# Clean up created files
|
18
|
+
FileUtils.rm_rf("#{@data_store.root_path}")
|
19
|
+
end
|
20
|
+
|
21
|
+
it_should_behave_like 'data_store'
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
@temp_object = Dragonfly::TempObject.new('goobydoo')
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "store" do
|
28
|
+
|
29
|
+
def it_should_write_to_file(storage_path, temp_object)
|
30
|
+
temp_object.should_receive(:to_file).with(storage_path).and_return(mock('file', :close => nil))
|
31
|
+
end
|
32
|
+
|
33
|
+
before(:each) do
|
34
|
+
# Set 'now' to a date in the past
|
35
|
+
Time.stub!(:now).and_return Time.mktime(1984,"may",4,14,28,1)
|
36
|
+
@file_pattern_prefix_without_root = '1984/05/04/14_28_01_0_'
|
37
|
+
@file_pattern_prefix = "#{@data_store.root_path}/#{@file_pattern_prefix_without_root}"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should store the file in a folder based on date, with default filename" do
|
41
|
+
it_should_write_to_file("#{@file_pattern_prefix}file", @temp_object)
|
42
|
+
@data_store.store(@temp_object)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should use the temp_object name if it exists" do
|
46
|
+
@temp_object.should_receive(:name).at_least(:once).and_return('hello.there')
|
47
|
+
it_should_write_to_file("#{@file_pattern_prefix}hello.there", @temp_object)
|
48
|
+
@data_store.store(@temp_object)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should get rid of funny characters in the temp_object name" do
|
52
|
+
@temp_object.should_receive(:name).at_least(:once).and_return('A Picture with many spaces in its name (at 20:00 pm).png')
|
53
|
+
it_should_write_to_file("#{@file_pattern_prefix}A_Picture_with_many_spaces_in_its_name_at_20_00_pm_.png", @temp_object)
|
54
|
+
@data_store.store(@temp_object)
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "when the filename already exists" do
|
58
|
+
|
59
|
+
it "should use a different filename" do
|
60
|
+
touch_file("#{@file_pattern_prefix}file")
|
61
|
+
@data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}file").and_return("#{@file_pattern_prefix}file_2")
|
62
|
+
it_should_write_to_file("#{@file_pattern_prefix}file_2", @temp_object)
|
63
|
+
@data_store.store(@temp_object)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should use a different filename taking into account the name and ext" do
|
67
|
+
@temp_object.should_receive(:name).at_least(:once).and_return('hello.png')
|
68
|
+
touch_file("#{@file_pattern_prefix}hello.png")
|
69
|
+
@data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}hello.png").and_return("#{@file_pattern_prefix}blah.png")
|
70
|
+
@data_store.store(@temp_object)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should keep trying until it finds a free filename" do
|
74
|
+
touch_file("#{@file_pattern_prefix}file")
|
75
|
+
touch_file("#{@file_pattern_prefix}file_2")
|
76
|
+
@data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}file").and_return("#{@file_pattern_prefix}file_2")
|
77
|
+
@data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}file_2").and_return("#{@file_pattern_prefix}file_3")
|
78
|
+
it_should_write_to_file("#{@file_pattern_prefix}file_3", @temp_object)
|
79
|
+
@data_store.store(@temp_object)
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "specifying the uid" do
|
83
|
+
it "should allow for specifying the path to use" do
|
84
|
+
it_should_write_to_file("#{@data_store.root_path}/hello/there/mate.png", @temp_object)
|
85
|
+
@data_store.store(@temp_object, :path => 'hello/there/mate.png')
|
86
|
+
end
|
87
|
+
it "should correctly disambiguate if the file exists" do
|
88
|
+
touch_file("#{@data_store.root_path}/hello/there/mate.png")
|
89
|
+
@data_store.should_receive(:disambiguate).with("#{@data_store.root_path}/hello/there/mate.png").and_return("#{@data_store.root_path}/hello/there/mate_2.png")
|
90
|
+
it_should_write_to_file("#{@data_store.root_path}/hello/there/mate_2.png", @temp_object)
|
91
|
+
@data_store.store(@temp_object, :path => 'hello/there/mate.png')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "return value" do
|
98
|
+
|
99
|
+
it "should return the filepath without the root of the stored file when a file name is not provided" do
|
100
|
+
@data_store.store(@temp_object).should == "#{@file_pattern_prefix_without_root}file"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return the filepath without the root of the stored file when a file name is provided" do
|
104
|
+
@temp_object.should_receive(:name).at_least(:once).and_return('hello.you.png')
|
105
|
+
@data_store.store(@temp_object).should == "#{@file_pattern_prefix_without_root}hello.you.png"
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "disambiguate" do
|
113
|
+
it "should add a suffix" do
|
114
|
+
@data_store.disambiguate('/some/file').should =~ %r{^/some/file_\w+$}
|
115
|
+
end
|
116
|
+
it "should add a suffix to the basename" do
|
117
|
+
@data_store.disambiguate('/some/file.png').should =~ %r{^/some/file_\w+\.png$}
|
118
|
+
end
|
119
|
+
it "should be random(-ish)" do
|
120
|
+
@data_store.disambiguate('/some/file').should_not == @data_store.disambiguate('/some/file')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "errors" do
|
125
|
+
|
126
|
+
it "should raise an error if it can't create a directory" do
|
127
|
+
FileUtils.should_receive(:mkdir_p).and_raise(Errno::EACCES)
|
128
|
+
lambda{ @data_store.store(@temp_object) }.should raise_error(Dragonfly::DataStorage::UnableToStore)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should raise an error if it can't create a file" do
|
132
|
+
@temp_object.should_receive(:to_file).and_raise(Errno::EACCES)
|
133
|
+
lambda{ @data_store.store(@temp_object) }.should raise_error(Dragonfly::DataStorage::UnableToStore)
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "retrieve" do
|
139
|
+
it "should return a closed file" do
|
140
|
+
uid = @data_store.store(@temp_object)
|
141
|
+
file, extra = @data_store.retrieve(uid)
|
142
|
+
file.should be_closed
|
143
|
+
end
|
144
|
+
it "should be able to retrieve any file, stored or not (and without extra data)" do
|
145
|
+
FileUtils.mkdir_p("#{@data_store.root_path}/jelly_beans/are")
|
146
|
+
File.open("#{@data_store.root_path}/jelly_beans/are/good", 'w'){|f| f.write('hey dog') }
|
147
|
+
file, meta = @data_store.retrieve("jelly_beans/are/good")
|
148
|
+
File.read(file.path).should == 'hey dog'
|
149
|
+
meta.should == {}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "destroying" do
|
154
|
+
|
155
|
+
it "should raise an error if the data doesn't exist" do
|
156
|
+
lambda{
|
157
|
+
@data_store.destroy('gooble/gubbub')
|
158
|
+
}.should raise_error(Dragonfly::DataStorage::DataNotFound)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should prune empty directories when destroying" do
|
162
|
+
uid = @data_store.store(@temp_object)
|
163
|
+
@data_store.destroy(uid)
|
164
|
+
@data_store.root_path.should be_an_empty_directory
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|