fog-dragonfly 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.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
|