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.

Files changed (155) hide show
  1. data/.specopts +2 -0
  2. data/.yardopts +23 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.rails.2.3.5 +14 -0
  5. data/History.md +266 -0
  6. data/LICENSE +20 -0
  7. data/README.md +88 -0
  8. data/Rakefile +92 -0
  9. data/VERSION +1 -0
  10. data/config.ru +13 -0
  11. data/docs.watchr +1 -0
  12. data/dragonfly.gemspec +293 -0
  13. data/extra_docs/Analysers.md +108 -0
  14. data/extra_docs/Caching.md +23 -0
  15. data/extra_docs/Configuration.md +138 -0
  16. data/extra_docs/DataStorage.md +136 -0
  17. data/extra_docs/Encoding.md +96 -0
  18. data/extra_docs/GeneralUsage.md +121 -0
  19. data/extra_docs/Generators.md +102 -0
  20. data/extra_docs/Heroku.md +50 -0
  21. data/extra_docs/Index.md +36 -0
  22. data/extra_docs/MimeTypes.md +40 -0
  23. data/extra_docs/Models.md +266 -0
  24. data/extra_docs/Mongo.md +45 -0
  25. data/extra_docs/Processing.md +130 -0
  26. data/extra_docs/Rack.md +52 -0
  27. data/extra_docs/Rails2.md +55 -0
  28. data/extra_docs/Rails3.md +62 -0
  29. data/extra_docs/Sinatra.md +25 -0
  30. data/extra_docs/URLs.md +169 -0
  31. data/features/3.0.3.feature +8 -0
  32. data/features/images.feature +47 -0
  33. data/features/no_processing.feature +14 -0
  34. data/features/rails_2.3.5.feature +7 -0
  35. data/features/steps/common_steps.rb +8 -0
  36. data/features/steps/dragonfly_steps.rb +66 -0
  37. data/features/steps/rails_steps.rb +39 -0
  38. data/features/support/env.rb +40 -0
  39. data/fixtures/files/app/models/album.rb +3 -0
  40. data/fixtures/files/app/views/albums/new.html.erb +4 -0
  41. data/fixtures/files/app/views/albums/show.html.erb +4 -0
  42. data/fixtures/files/config/initializers/dragonfly.rb +4 -0
  43. data/fixtures/files/features/manage_album_images.feature +12 -0
  44. data/fixtures/files/features/step_definitions/image_steps.rb +15 -0
  45. data/fixtures/files/features/support/paths.rb +15 -0
  46. data/fixtures/files/features/text_images.feature +7 -0
  47. data/fixtures/rails_2.3.5/template.rb +10 -0
  48. data/fixtures/rails_3.0.3/template.rb +20 -0
  49. data/irbrc.rb +17 -0
  50. data/lib/dragonfly.rb +45 -0
  51. data/lib/dragonfly/active_model_extensions.rb +13 -0
  52. data/lib/dragonfly/active_model_extensions/attachment.rb +169 -0
  53. data/lib/dragonfly/active_model_extensions/class_methods.rb +45 -0
  54. data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
  55. data/lib/dragonfly/active_model_extensions/validations.rb +37 -0
  56. data/lib/dragonfly/analyser.rb +59 -0
  57. data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
  58. data/lib/dragonfly/analysis/image_magick_analyser.rb +47 -0
  59. data/lib/dragonfly/analysis/r_magick_analyser.rb +63 -0
  60. data/lib/dragonfly/app.rb +182 -0
  61. data/lib/dragonfly/config/heroku.rb +19 -0
  62. data/lib/dragonfly/config/image_magick.rb +41 -0
  63. data/lib/dragonfly/config/r_magick.rb +46 -0
  64. data/lib/dragonfly/config/rails.rb +17 -0
  65. data/lib/dragonfly/configurable.rb +119 -0
  66. data/lib/dragonfly/core_ext/object.rb +8 -0
  67. data/lib/dragonfly/core_ext/string.rb +9 -0
  68. data/lib/dragonfly/core_ext/symbol.rb +9 -0
  69. data/lib/dragonfly/data_storage.rb +9 -0
  70. data/lib/dragonfly/data_storage/file_data_store.rb +114 -0
  71. data/lib/dragonfly/data_storage/mongo_data_store.rb +82 -0
  72. data/lib/dragonfly/data_storage/s3data_store.rb +115 -0
  73. data/lib/dragonfly/encoder.rb +13 -0
  74. data/lib/dragonfly/encoding/image_magick_encoder.rb +57 -0
  75. data/lib/dragonfly/encoding/r_magick_encoder.rb +61 -0
  76. data/lib/dragonfly/function_manager.rb +69 -0
  77. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +23 -0
  78. data/lib/dragonfly/generation/image_magick_generator.rb +140 -0
  79. data/lib/dragonfly/generation/r_magick_generator.rb +155 -0
  80. data/lib/dragonfly/generator.rb +9 -0
  81. data/lib/dragonfly/image_magick_utils.rb +81 -0
  82. data/lib/dragonfly/job.rb +371 -0
  83. data/lib/dragonfly/job_builder.rb +39 -0
  84. data/lib/dragonfly/job_definitions.rb +26 -0
  85. data/lib/dragonfly/job_endpoint.rb +15 -0
  86. data/lib/dragonfly/loggable.rb +28 -0
  87. data/lib/dragonfly/middleware.rb +34 -0
  88. data/lib/dragonfly/processing/image_magick_processor.rb +99 -0
  89. data/lib/dragonfly/processing/r_magick_processor.rb +126 -0
  90. data/lib/dragonfly/processor.rb +9 -0
  91. data/lib/dragonfly/r_magick_utils.rb +48 -0
  92. data/lib/dragonfly/rails/images.rb +22 -0
  93. data/lib/dragonfly/response.rb +82 -0
  94. data/lib/dragonfly/routed_endpoint.rb +40 -0
  95. data/lib/dragonfly/serializer.rb +32 -0
  96. data/lib/dragonfly/simple_cache.rb +23 -0
  97. data/lib/dragonfly/simple_endpoint.rb +63 -0
  98. data/lib/dragonfly/temp_object.rb +220 -0
  99. data/samples/beach.png +0 -0
  100. data/samples/egg.png +0 -0
  101. data/samples/round.gif +0 -0
  102. data/samples/sample.docx +0 -0
  103. data/samples/taj.jpg +0 -0
  104. data/spec/argument_matchers.rb +19 -0
  105. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
  106. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
  107. data/spec/dragonfly/active_model_extensions/model_spec.rb +723 -0
  108. data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
  109. data/spec/dragonfly/analyser_spec.rb +123 -0
  110. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +57 -0
  111. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +15 -0
  112. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +27 -0
  113. data/spec/dragonfly/analysis/shared_analyser_spec.rb +51 -0
  114. data/spec/dragonfly/app_spec.rb +280 -0
  115. data/spec/dragonfly/config/r_magick_spec.rb +25 -0
  116. data/spec/dragonfly/configurable_spec.rb +220 -0
  117. data/spec/dragonfly/core_ext/string_spec.rb +17 -0
  118. data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
  119. data/spec/dragonfly/data_storage/data_store_spec.rb +76 -0
  120. data/spec/dragonfly/data_storage/file_data_store_spec.rb +169 -0
  121. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +38 -0
  122. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +94 -0
  123. data/spec/dragonfly/deprecation_spec.rb +20 -0
  124. data/spec/dragonfly/encoding/image_magick_encoder_spec.rb +41 -0
  125. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +37 -0
  126. data/spec/dragonfly/function_manager_spec.rb +154 -0
  127. data/spec/dragonfly/generation/hash_with_css_style_keys_spec.rb +24 -0
  128. data/spec/dragonfly/generation/image_magick_generator_spec.rb +12 -0
  129. data/spec/dragonfly/generation/r_magick_generator_spec.rb +24 -0
  130. data/spec/dragonfly/generation/shared_generator_spec.rb +91 -0
  131. data/spec/dragonfly/image_magick_utils_spec.rb +16 -0
  132. data/spec/dragonfly/job_builder_spec.rb +37 -0
  133. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  134. data/spec/dragonfly/job_endpoint_spec.rb +120 -0
  135. data/spec/dragonfly/job_spec.rb +773 -0
  136. data/spec/dragonfly/loggable_spec.rb +80 -0
  137. data/spec/dragonfly/middleware_spec.rb +68 -0
  138. data/spec/dragonfly/processing/image_magick_processor_spec.rb +29 -0
  139. data/spec/dragonfly/processing/r_magick_processor_spec.rb +26 -0
  140. data/spec/dragonfly/processing/shared_processing_spec.rb +215 -0
  141. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  142. data/spec/dragonfly/serializer_spec.rb +61 -0
  143. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  144. data/spec/dragonfly/simple_endpoint_spec.rb +89 -0
  145. data/spec/dragonfly/temp_object_spec.rb +352 -0
  146. data/spec/image_matchers.rb +47 -0
  147. data/spec/simple_matchers.rb +44 -0
  148. data/spec/spec_helper.rb +58 -0
  149. data/yard/handlers/configurable_attr_handler.rb +38 -0
  150. data/yard/setup.rb +15 -0
  151. data/yard/templates/default/fulldoc/html/css/common.css +107 -0
  152. data/yard/templates/default/layout/html/layout.erb +87 -0
  153. data/yard/templates/default/module/html/configuration_summary.erb +31 -0
  154. data/yard/templates/default/module/setup.rb +17 -0
  155. 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