oahu-dragonfly 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/.yardopts +24 -0
- data/Gemfile +30 -0
- data/History.md +323 -0
- data/LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/config.ru +14 -0
- data/docs.watchr +1 -0
- data/dragonfly.gemspec +297 -0
- data/extra_docs/Analysers.md +66 -0
- data/extra_docs/Caching.md +23 -0
- data/extra_docs/Configuration.md +124 -0
- data/extra_docs/Couch.md +49 -0
- data/extra_docs/DataStorage.md +153 -0
- data/extra_docs/Encoding.md +67 -0
- data/extra_docs/GeneralUsage.md +121 -0
- data/extra_docs/Generators.md +60 -0
- data/extra_docs/Heroku.md +50 -0
- data/extra_docs/ImageMagick.md +125 -0
- data/extra_docs/Index.md +33 -0
- data/extra_docs/MimeTypes.md +40 -0
- data/extra_docs/Models.md +272 -0
- data/extra_docs/Mongo.md +45 -0
- data/extra_docs/Processing.md +77 -0
- data/extra_docs/Rack.md +52 -0
- data/extra_docs/Rails2.md +57 -0
- data/extra_docs/Rails3.md +62 -0
- data/extra_docs/Sinatra.md +25 -0
- data/extra_docs/URLs.md +169 -0
- data/features/images.feature +47 -0
- data/features/no_processing.feature +14 -0
- data/features/rails_3.0.5.feature +8 -0
- data/features/steps/common_steps.rb +8 -0
- data/features/steps/dragonfly_steps.rb +66 -0
- data/features/steps/rails_steps.rb +28 -0
- data/features/support/env.rb +13 -0
- data/features/support/setup.rb +32 -0
- data/fixtures/rails_3.0.5/files/app/models/album.rb +7 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/show.html.erb +6 -0
- data/fixtures/rails_3.0.5/files/config/initializers/dragonfly.rb +4 -0
- data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/image_steps.rb +25 -0
- data/fixtures/rails_3.0.5/files/features/support/paths.rb +17 -0
- data/fixtures/rails_3.0.5/files/features/text_images.feature +7 -0
- data/fixtures/rails_3.0.5/template.rb +20 -0
- data/irbrc.rb +18 -0
- data/lib/dragonfly.rb +55 -0
- data/lib/dragonfly/active_model_extensions.rb +13 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +250 -0
- data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +148 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +95 -0
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
- data/lib/dragonfly/active_model_extensions/validations.rb +41 -0
- data/lib/dragonfly/analyser.rb +58 -0
- data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
- data/lib/dragonfly/analysis/image_magick_analyser.rb +6 -0
- data/lib/dragonfly/app.rb +172 -0
- data/lib/dragonfly/config/heroku.rb +19 -0
- data/lib/dragonfly/config/image_magick.rb +6 -0
- data/lib/dragonfly/config/rails.rb +20 -0
- data/lib/dragonfly/configurable.rb +207 -0
- data/lib/dragonfly/core_ext/array.rb +7 -0
- data/lib/dragonfly/core_ext/hash.rb +7 -0
- data/lib/dragonfly/core_ext/object.rb +12 -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/couch_data_store.rb +64 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +141 -0
- data/lib/dragonfly/data_storage/mongo_data_store.rb +86 -0
- data/lib/dragonfly/data_storage/s3data_store.rb +145 -0
- data/lib/dragonfly/encoder.rb +13 -0
- data/lib/dragonfly/encoding/image_magick_encoder.rb +6 -0
- data/lib/dragonfly/function_manager.rb +71 -0
- data/lib/dragonfly/generation/image_magick_generator.rb +6 -0
- data/lib/dragonfly/generator.rb +9 -0
- data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
- data/lib/dragonfly/image_magick/analyser.rb +51 -0
- data/lib/dragonfly/image_magick/config.rb +41 -0
- data/lib/dragonfly/image_magick/encoder.rb +57 -0
- data/lib/dragonfly/image_magick/generator.rb +145 -0
- data/lib/dragonfly/image_magick/processor.rb +99 -0
- data/lib/dragonfly/image_magick/utils.rb +72 -0
- data/lib/dragonfly/image_magick_utils.rb +4 -0
- data/lib/dragonfly/job.rb +451 -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 +20 -0
- data/lib/dragonfly/processing/image_magick_processor.rb +6 -0
- data/lib/dragonfly/processor.rb +9 -0
- data/lib/dragonfly/rails/images.rb +27 -0
- data/lib/dragonfly/response.rb +97 -0
- data/lib/dragonfly/routed_endpoint.rb +40 -0
- data/lib/dragonfly/serializer.rb +32 -0
- data/lib/dragonfly/server.rb +113 -0
- data/lib/dragonfly/simple_cache.rb +23 -0
- data/lib/dragonfly/temp_object.rb +175 -0
- data/lib/dragonfly/url_mapper.rb +78 -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/dragonfly/active_model_extensions/model_spec.rb +1426 -0
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +91 -0
- data/spec/dragonfly/analyser_spec.rb +123 -0
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +48 -0
- data/spec/dragonfly/app_spec.rb +135 -0
- data/spec/dragonfly/configurable_spec.rb +461 -0
- data/spec/dragonfly/core_ext/array_spec.rb +19 -0
- data/spec/dragonfly/core_ext/hash_spec.rb +19 -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/couch_data_store_spec.rb +76 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +296 -0
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +57 -0
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +258 -0
- data/spec/dragonfly/data_storage/shared_data_store_examples.rb +77 -0
- data/spec/dragonfly/function_manager_spec.rb +154 -0
- data/spec/dragonfly/hash_with_css_style_keys_spec.rb +24 -0
- data/spec/dragonfly/image_magick/analyser_spec.rb +64 -0
- data/spec/dragonfly/image_magick/encoder_spec.rb +41 -0
- data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
- data/spec/dragonfly/image_magick/processor_spec.rb +233 -0
- data/spec/dragonfly/image_magick/utils_spec.rb +18 -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 +173 -0
- data/spec/dragonfly/job_spec.rb +1046 -0
- data/spec/dragonfly/loggable_spec.rb +80 -0
- data/spec/dragonfly/middleware_spec.rb +47 -0
- data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
- data/spec/dragonfly/serializer_spec.rb +61 -0
- data/spec/dragonfly/server_spec.rb +278 -0
- data/spec/dragonfly/simple_cache_spec.rb +27 -0
- data/spec/dragonfly/temp_object_spec.rb +306 -0
- data/spec/dragonfly/url_mapper_spec.rb +126 -0
- data/spec/functional/deprecations_spec.rb +51 -0
- data/spec/functional/image_magick_app_spec.rb +27 -0
- data/spec/functional/model_urls_spec.rb +85 -0
- data/spec/functional/remote_on_the_fly_spec.rb +51 -0
- data/spec/functional/to_response_spec.rb +31 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/argument_matchers.rb +19 -0
- data/spec/support/image_matchers.rb +47 -0
- data/spec/support/simple_matchers.rb +53 -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 +89 -0
- data/yard/templates/default/module/html/configuration_summary.erb +31 -0
- data/yard/templates/default/module/setup.rb +17 -0
- metadata +544 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require File.dirname(__FILE__) + '/shared_data_store_examples'
|
4
|
+
require 'mongo'
|
5
|
+
|
6
|
+
describe Dragonfly::DataStorage::MongoDataStore do
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
begin
|
10
|
+
Mongo::Connection.new
|
11
|
+
rescue Mongo::ConnectionFailure => e
|
12
|
+
pending "You need to start mongo on localhost:27017 to test the MongoDataStore"
|
13
|
+
end
|
14
|
+
@data_store = Dragonfly::DataStorage::MongoDataStore.new :database => 'dragonfly_test'
|
15
|
+
end
|
16
|
+
|
17
|
+
it_should_behave_like 'data_store'
|
18
|
+
|
19
|
+
describe "authenticating" do
|
20
|
+
before(:each) do
|
21
|
+
@temp_object = Dragonfly::TempObject.new('Feijão verde')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not attempt to authenticate if a username is not given" do
|
25
|
+
@data_store.db.should_not_receive(:authenticate)
|
26
|
+
@data_store.store(@temp_object)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should attempt to authenticate once if a username is given" do
|
30
|
+
@data_store.username = 'terry'
|
31
|
+
@data_store.password = 'butcher'
|
32
|
+
@data_store.db.should_receive(:authenticate).exactly(:once).with('terry','butcher').and_return(true)
|
33
|
+
uid = @data_store.store(@temp_object)
|
34
|
+
@data_store.retrieve(uid)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "sharing already configured stuff" do
|
39
|
+
before(:each) do
|
40
|
+
@connection = Mongo::Connection.new
|
41
|
+
@temp_object = Dragonfly::TempObject.new('asdf')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should allow sharing the connection" do
|
45
|
+
@data_store.connection = @connection
|
46
|
+
@connection.should_receive(:db).with('dragonfly_test').and_return(db=mock)
|
47
|
+
@data_store.db.should == db
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should allow sharing the db" do
|
51
|
+
db = @connection.db('dragonfly_test_yo')
|
52
|
+
@data_store.db = db
|
53
|
+
@data_store.grid.instance_eval{@db}.should == db # so wrong
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/shared_data_store_examples'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
describe Dragonfly::DataStorage::S3DataStore do
|
6
|
+
|
7
|
+
# To run these tests, put a file ".s3_spec.yml" in the dragonfly root dir, like this:
|
8
|
+
# key: XXXXXXXXXX
|
9
|
+
# secret: XXXXXXXXXX
|
10
|
+
# enabled: true
|
11
|
+
if File.exist?(file = File.expand_path('../../../../.s3_spec.yml', __FILE__))
|
12
|
+
config = YAML.load_file(file)
|
13
|
+
KEY = config['key']
|
14
|
+
SECRET = config['secret']
|
15
|
+
enabled = config['enabled']
|
16
|
+
else
|
17
|
+
enabled = false
|
18
|
+
end
|
19
|
+
|
20
|
+
if enabled
|
21
|
+
|
22
|
+
# Make sure it's a new bucket name
|
23
|
+
BUCKET_NAME = "dragonfly-test-#{Time.now.to_i.to_s(36)}"
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
WebMock.allow_net_connect!
|
27
|
+
@data_store = Dragonfly::DataStorage::S3DataStore.new
|
28
|
+
@data_store.configure do |d|
|
29
|
+
d.bucket_name = BUCKET_NAME
|
30
|
+
d.access_key_id = KEY
|
31
|
+
d.secret_access_key = SECRET
|
32
|
+
d.region = 'eu-west-1'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
else
|
37
|
+
|
38
|
+
BUCKET_NAME = 'test-bucket'
|
39
|
+
|
40
|
+
before(:each) do
|
41
|
+
Fog.mock!
|
42
|
+
@data_store = Dragonfly::DataStorage::S3DataStore.new
|
43
|
+
@data_store.configure do |d|
|
44
|
+
d.bucket_name = BUCKET_NAME
|
45
|
+
d.access_key_id = 'XXXXXXXXX'
|
46
|
+
d.secret_access_key = 'XXXXXXXXX'
|
47
|
+
d.region = 'eu-west-1'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
it_should_behave_like 'data_store'
|
54
|
+
|
55
|
+
describe "store" do
|
56
|
+
it "should return a unique identifier for each storage" do
|
57
|
+
temp_object = Dragonfly::TempObject.new('gollum')
|
58
|
+
temp_object2 = Dragonfly::TempObject.new('gollum')
|
59
|
+
@data_store.store(temp_object).should_not == @data_store.store(temp_object2)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should use the name in the meta if set" do
|
63
|
+
temp_object = Dragonfly::TempObject.new('eggheads')
|
64
|
+
uid = @data_store.store(temp_object, :meta => {:name => 'doobie'})
|
65
|
+
uid.should =~ /doobie$/
|
66
|
+
data, meta = @data_store.retrieve(uid)
|
67
|
+
data.should == 'eggheads'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should work ok with files with funny names" do
|
71
|
+
temp_object = Dragonfly::TempObject.new('eggheads')
|
72
|
+
uid = @data_store.store(temp_object, :meta => {:name => 'A Picture with many spaces in its name (at 20:00 pm).png'})
|
73
|
+
uid.should =~ /A_Picture_with_many_spaces_in_its_name_at_20_00_pm_\.png$/
|
74
|
+
data, meta = @data_store.retrieve(uid)
|
75
|
+
data.should == 'eggheads'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should allow for setting the path manually" do
|
79
|
+
temp_object = Dragonfly::TempObject.new('eggheads')
|
80
|
+
uid = @data_store.store(temp_object, :path => 'hello/there')
|
81
|
+
uid.should == 'hello/there'
|
82
|
+
data, meta = @data_store.retrieve(uid)
|
83
|
+
data.should == 'eggheads'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should work fine when not using the filesystem" do
|
87
|
+
@data_store.use_filesystem = false
|
88
|
+
temp_object = Dragonfly::TempObject.new('gollum')
|
89
|
+
uid = @data_store.store(temp_object)
|
90
|
+
@data_store.retrieve(uid).first.should == "gollum"
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "generate_uid" do
|
94
|
+
context "without a specific_uid" do
|
95
|
+
it 'should the default value' do
|
96
|
+
@data_store.send(:generate_uid, "hello").should =~ /\d+\/\d+\/\d+\/\d+\/\d+\/\d+\/\w+\/hello/
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "with a specific_uid" do
|
101
|
+
before do
|
102
|
+
@data_store.specific_uid = lambda{|name| name}
|
103
|
+
end
|
104
|
+
|
105
|
+
after do
|
106
|
+
@data_store.specific_uid = nil
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should call the specific_uid lambda' do
|
110
|
+
@data_store.send(:generate_uid, "hello").should == 'hello'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
if enabled # Fog.mock! doesn't work consistently with real one here
|
117
|
+
|
118
|
+
describe "destroy" do
|
119
|
+
before(:each) do
|
120
|
+
@temp_object = Dragonfly::TempObject.new('gollum')
|
121
|
+
end
|
122
|
+
it "should raise an error if the data doesn't exist on destroy" do
|
123
|
+
uid = @data_store.store(@temp_object)
|
124
|
+
@data_store.destroy(uid)
|
125
|
+
lambda{
|
126
|
+
@data_store.destroy(uid)
|
127
|
+
}.should raise_error(Dragonfly::DataStorage::DataNotFound)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "domain" do
|
134
|
+
it "should default to the US" do
|
135
|
+
@data_store.region = nil
|
136
|
+
@data_store.domain.should == 's3.amazonaws.com'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should return the correct domain" do
|
140
|
+
@data_store.region = 'eu-west-1'
|
141
|
+
@data_store.domain.should == 's3-eu-west-1.amazonaws.com'
|
142
|
+
end
|
143
|
+
|
144
|
+
it "does raise an error if an unknown region is given" do
|
145
|
+
@data_store.region = 'latvia-central'
|
146
|
+
lambda{
|
147
|
+
@data_store.domain
|
148
|
+
}.should raise_error
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "not configuring stuff properly" do
|
153
|
+
before(:each) do
|
154
|
+
@temp_object = Dragonfly::TempObject.new("Hi guys")
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should require a bucket name on store" do
|
158
|
+
@data_store.bucket_name = nil
|
159
|
+
proc{ @data_store.store(@temp_object) }.should raise_error(Dragonfly::Configurable::NotConfigured)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should require an access_key_id on store" do
|
163
|
+
@data_store.access_key_id = nil
|
164
|
+
proc{ @data_store.store(@temp_object) }.should raise_error(Dragonfly::Configurable::NotConfigured)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should require a secret access key on store" do
|
168
|
+
@data_store.secret_access_key = nil
|
169
|
+
proc{ @data_store.store(@temp_object) }.should raise_error(Dragonfly::Configurable::NotConfigured)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should require a bucket name on retrieve" do
|
173
|
+
@data_store.bucket_name = nil
|
174
|
+
proc{ @data_store.retrieve('asdf') }.should raise_error(Dragonfly::Configurable::NotConfigured)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should require an access_key_id on retrieve" do
|
178
|
+
@data_store.access_key_id = nil
|
179
|
+
proc{ @data_store.retrieve('asdf') }.should raise_error(Dragonfly::Configurable::NotConfigured)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should require a secret access key on retrieve" do
|
183
|
+
@data_store.secret_access_key = nil
|
184
|
+
proc{ @data_store.retrieve('asdf') }.should raise_error(Dragonfly::Configurable::NotConfigured)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "autocreating the bucket" do
|
189
|
+
it "should create the bucket on store if it doesn't exist" do
|
190
|
+
@data_store.bucket_name = "dragonfly-test-blah-blah-#{rand(100000000)}"
|
191
|
+
@data_store.store(Dragonfly::TempObject.new("asdfj"))
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should not try to create the bucket on retrieve if it doesn't exist" do
|
195
|
+
@data_store.bucket_name = "dragonfly-test-blah-blah-#{rand(100000000)}"
|
196
|
+
@data_store.send(:storage).should_not_receive(:put_bucket)
|
197
|
+
proc{ @data_store.retrieve("gungle") }.should raise_error(Dragonfly::DataStorage::DataNotFound)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "headers" do
|
202
|
+
before(:each) do
|
203
|
+
@temp_object = Dragonfly::TempObject.new('fjkdlsa')
|
204
|
+
@data_store.storage_headers = {'x-amz-foo' => 'biscuithead'}
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should allow configuring globally" do
|
208
|
+
@data_store.storage.should_receive(:put_object).with('test-bucket', anything, anything,
|
209
|
+
hash_including('x-amz-foo' => 'biscuithead')
|
210
|
+
)
|
211
|
+
@data_store.store(@temp_object)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should allow adding per-store" do
|
215
|
+
@data_store.storage.should_receive(:put_object).with('test-bucket', anything, anything,
|
216
|
+
hash_including('x-amz-foo' => 'biscuithead', 'hello' => 'there')
|
217
|
+
)
|
218
|
+
@data_store.store(@temp_object, :headers => {'hello' => 'there'})
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should let the per-store one take precedence" do
|
222
|
+
@data_store.storage.should_receive(:put_object).with('test-bucket', anything, anything,
|
223
|
+
hash_including('x-amz-foo' => 'override!')
|
224
|
+
)
|
225
|
+
@data_store.store(@temp_object, :headers => {'x-amz-foo' => 'override!'})
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should not mess with the meta" do
|
229
|
+
@data_store.storage.should_receive(:put_object) do |_, __, ___, headers|
|
230
|
+
headers['x-amz-meta-extra'].should =~ /^\w+$/
|
231
|
+
end
|
232
|
+
@data_store.store(@temp_object, :headers => {'hello' => 'there'})
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "urls for serving directly" do
|
237
|
+
|
238
|
+
before(:each) do
|
239
|
+
@uid = 'some/path/on/s3'
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should use the bucket subdomain" do
|
243
|
+
@data_store.url_for(@uid).should == "http://#{BUCKET_NAME}.s3.amazonaws.com/some/path/on/s3"
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should use the bucket subdomain for other regions too" do
|
247
|
+
@data_store.region = 'eu-west-1'
|
248
|
+
@data_store.url_for(@uid).should == "http://#{BUCKET_NAME}.s3.amazonaws.com/some/path/on/s3"
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should give an expiring url" do
|
252
|
+
@data_store.url_for(@uid, :expires => 1301476942).should =~
|
253
|
+
%r{^https://#{@data_store.domain}/#{BUCKET_NAME}/some/path/on/s3\?AWSAccessKeyId=#{@data_store.access_key_id}&Signature=[\w%]+&Expires=1301476942$}
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for "data_store" 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 meta" do
|
30
|
+
before(:each) do
|
31
|
+
uid = @data_store.store(@temp_object)
|
32
|
+
@obj, @meta = @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 "should return a meta hash (probably empty)" do
|
40
|
+
@meta.should be_a(Hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "when meta is given" do
|
46
|
+
before(:each) do
|
47
|
+
temp_object = Dragonfly::TempObject.new('gollum')
|
48
|
+
@uid = @data_store.store(temp_object, :meta => {:bitrate => '35', :name => 'danny.boy'})
|
49
|
+
@obj, @meta = @data_store.retrieve(@uid)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return the stored meta" do
|
53
|
+
@meta[:bitrate].should == '35'
|
54
|
+
@meta[:name].should == 'danny.boy'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should raise an exception if the data doesn't exist" do
|
59
|
+
lambda{
|
60
|
+
@data_store.retrieve('gooble/gubbub')
|
61
|
+
}.should raise_error(Dragonfly::DataStorage::DataNotFound)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "destroy" do
|
66
|
+
|
67
|
+
it "should destroy the stored data" do
|
68
|
+
uid = @data_store.store(@temp_object)
|
69
|
+
@data_store.destroy(uid)
|
70
|
+
lambda{
|
71
|
+
@data_store.retrieve(uid)
|
72
|
+
}.should raise_error(Dragonfly::DataStorage::DataNotFound)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :have_keys do |*keys|
|
4
|
+
match do |given|
|
5
|
+
given.keys.map{|sym| sym.to_s }.sort == keys.map{|sym| sym.to_s }.sort
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Dragonfly::FunctionManager do
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@fm = Dragonfly::FunctionManager.new
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "registering functions" do
|
16
|
+
|
17
|
+
describe "registering procs" do
|
18
|
+
|
19
|
+
let(:func){ proc{ "HELLO" } }
|
20
|
+
|
21
|
+
it "should allow registering procs" do
|
22
|
+
@fm.add :hello, func
|
23
|
+
@fm.functions.should == {:hello => [func]}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should allow registering using block syntax" do
|
27
|
+
@fm.add(:hello, &func)
|
28
|
+
@fm.functions.should == {:hello => [func]}
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "registering classes" do
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
@class = Class.new do
|
37
|
+
def doogie(buff)
|
38
|
+
"eggheads #{buff}"
|
39
|
+
end
|
40
|
+
def bumfries(smarmey)
|
41
|
+
"sharkboy"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
@fm.register(@class)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should add the methods" do
|
48
|
+
@fm.functions.should have_keys(:doogie, :bumfries)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should record the registered object" do
|
52
|
+
@fm.objects.length.should eql(1)
|
53
|
+
@fm.objects.first.should be_a(@class)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should work when calling" do
|
57
|
+
@fm.call_last(:doogie, 3).should == "eggheads 3"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return the object when registering" do
|
61
|
+
@fm.register(@class).should be_a(@class)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "configuring on registration" do
|
69
|
+
|
70
|
+
before(:each) do
|
71
|
+
@class = Class.new do
|
72
|
+
include Dragonfly::Configurable
|
73
|
+
configurable_attr :height, 183
|
74
|
+
def initialize(age=6)
|
75
|
+
@age = age
|
76
|
+
end
|
77
|
+
def height_and_age
|
78
|
+
[height, @age]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
@fm.register(@class)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should pass the args on register to the object initializer" do
|
85
|
+
@fm.register(@class, 43)
|
86
|
+
@fm.call_last(:height_and_age).should == [183, 43]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should run configure if a block given" do
|
90
|
+
@fm.register(@class){|c| c.height = 180 }
|
91
|
+
@fm.call_last(:height_and_age).should == [180, 6]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should not include configurable methods in the functions" do
|
95
|
+
@fm.functions.keys.should == [:height_and_age]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "calling" do
|
100
|
+
|
101
|
+
describe "errors" do
|
102
|
+
it "should raise an error for call_last if the function doesn't exist" do
|
103
|
+
lambda{
|
104
|
+
@fm.call_last(:i_dont_exist)
|
105
|
+
}.should raise_error(Dragonfly::FunctionManager::NotDefined)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should raise an error if the function is defined but unable to handle" do
|
109
|
+
@fm.add(:chicken){ throw :unable_to_handle }
|
110
|
+
lambda{
|
111
|
+
@fm.call_last(:chicken)
|
112
|
+
}.should raise_error(Dragonfly::FunctionManager::UnableToHandle)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "simple" do
|
117
|
+
it "should correctly call a registered block" do
|
118
|
+
@fm.add(:egg){|num| num + 1 }
|
119
|
+
@fm.call_last(:egg, 4).should == 5
|
120
|
+
end
|
121
|
+
it "should correctly call a registered class" do
|
122
|
+
klass = Class.new do
|
123
|
+
def dog(num)
|
124
|
+
num * 2
|
125
|
+
end
|
126
|
+
end
|
127
|
+
@fm.register(klass)
|
128
|
+
@fm.call_last(:dog, 4).should == 8
|
129
|
+
end
|
130
|
+
it "should correctly call an object that responds to 'call'" do
|
131
|
+
obj = Object.new
|
132
|
+
def obj.call(num); num - 3; end
|
133
|
+
@fm.add(:spoon, obj)
|
134
|
+
@fm.call_last(:spoon, 4).should == 1
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "with more than one implementation of same function" do
|
139
|
+
it "should use the last registered" do
|
140
|
+
@fm.add(:bingo){|num| num + 1 }
|
141
|
+
@fm.add(:bingo){|num| num - 1 }
|
142
|
+
@fm.call_last(:bingo, 4).should == 3
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should skip methods that throw :unable_to_handle" do
|
146
|
+
@fm.add(:bingo){|num| num + 1 }
|
147
|
+
@fm.add(:bingo){|num| throw :unable_to_handle }
|
148
|
+
@fm.call_last(:bingo, 4).should == 5
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|