dragonfly 0.8.6 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dragonfly might be problematic. Click here for more details.
- data/{.specopts → .rspec} +0 -1
- data/.yardopts +6 -2
- data/Gemfile +14 -13
- data/History.md +47 -9
- data/README.md +25 -5
- data/Rakefile +37 -79
- data/VERSION +1 -1
- data/dragonfly.gemspec +140 -89
- data/extra_docs/Analysers.md +8 -48
- data/extra_docs/Configuration.md +40 -25
- data/extra_docs/Couch.md +49 -0
- data/extra_docs/DataStorage.md +94 -24
- data/extra_docs/Encoding.md +6 -35
- data/extra_docs/ExampleUseCases.md +113 -0
- data/extra_docs/GeneralUsage.md +7 -23
- data/extra_docs/Generators.md +15 -49
- data/extra_docs/Heroku.md +7 -8
- data/extra_docs/ImageMagick.md +126 -0
- data/extra_docs/MimeTypes.md +3 -3
- data/extra_docs/Models.md +163 -0
- data/extra_docs/Mongo.md +1 -4
- data/extra_docs/Processing.md +7 -60
- data/extra_docs/Rails2.md +3 -1
- data/extra_docs/Rails3.md +2 -10
- data/extra_docs/ServingRemotely.md +83 -0
- data/extra_docs/Sinatra.md +3 -3
- data/extra_docs/URLs.md +60 -33
- data/features/rails_3.0.5.feature +8 -0
- data/features/steps/rails_steps.rb +7 -18
- data/features/support/env.rb +10 -37
- data/features/support/setup.rb +32 -0
- data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
- data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -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/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
- data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
- data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
- data/irbrc.rb +2 -1
- data/lib/dragonfly.rb +7 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
- data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
- data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
- data/lib/dragonfly/analyser.rb +0 -1
- data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
- data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
- data/lib/dragonfly/app.rb +64 -55
- data/lib/dragonfly/config/heroku.rb +1 -1
- data/lib/dragonfly/config/image_magick.rb +2 -37
- data/lib/dragonfly/config/rails.rb +5 -2
- data/lib/dragonfly/configurable.rb +115 -35
- data/lib/dragonfly/core_ext/object.rb +1 -1
- data/lib/dragonfly/core_ext/string.rb +1 -1
- data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
- data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
- data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
- data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
- data/lib/dragonfly/function_manager.rb +4 -2
- data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
- 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 +44 -0
- data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
- data/lib/dragonfly/image_magick/generator.rb +145 -0
- data/lib/dragonfly/image_magick/processor.rb +104 -0
- data/lib/dragonfly/image_magick/utils.rb +72 -0
- data/lib/dragonfly/image_magick_utils.rb +2 -79
- data/lib/dragonfly/job.rb +152 -90
- data/lib/dragonfly/middleware.rb +5 -19
- data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
- data/lib/dragonfly/rails/images.rb +15 -10
- data/lib/dragonfly/response.rb +26 -12
- data/lib/dragonfly/serializer.rb +1 -4
- data/lib/dragonfly/server.rb +103 -0
- data/lib/dragonfly/temp_object.rb +56 -101
- data/lib/dragonfly/url_mapper.rb +78 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
- data/spec/dragonfly/analyser_spec.rb +1 -1
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
- data/spec/dragonfly/app_spec.rb +35 -180
- data/spec/dragonfly/configurable_spec.rb +259 -18
- data/spec/dragonfly/core_ext/string_spec.rb +2 -2
- data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
- data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
- data/spec/dragonfly/function_manager_spec.rb +2 -2
- data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
- data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
- data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
- data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
- data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
- data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
- data/spec/dragonfly/job_builder_spec.rb +1 -1
- data/spec/dragonfly/job_definitions_spec.rb +1 -1
- data/spec/dragonfly/job_endpoint_spec.rb +26 -3
- data/spec/dragonfly/job_spec.rb +426 -208
- data/spec/dragonfly/loggable_spec.rb +2 -2
- data/spec/dragonfly/middleware_spec.rb +5 -26
- data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
- data/spec/dragonfly/serializer_spec.rb +1 -14
- data/spec/dragonfly/server_spec.rb +261 -0
- data/spec/dragonfly/simple_cache_spec.rb +1 -1
- data/spec/dragonfly/temp_object_spec.rb +84 -130
- data/spec/dragonfly/url_mapper_spec.rb +130 -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 +12 -22
- data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
- data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
- data/spec/support/simple_matchers.rb +53 -0
- data/yard/handlers/configurable_attr_handler.rb +2 -2
- data/yard/templates/default/fulldoc/html/css/common.css +12 -10
- data/yard/templates/default/layout/html/layout.erb +6 -0
- metadata +267 -308
- data/Gemfile.rails.2.3.5 +0 -20
- data/features/3.0.3.feature +0 -8
- data/features/rails_2.3.5.feature +0 -7
- data/fixtures/files/app/models/album.rb +0 -3
- data/fixtures/files/app/views/albums/new.html.erb +0 -4
- data/fixtures/files/features/manage_album_images.feature +0 -12
- data/fixtures/rails_2.3.5/template.rb +0 -10
- data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
- data/lib/dragonfly/config/r_magick.rb +0 -46
- data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
- data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
- data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
- data/lib/dragonfly/r_magick_utils.rb +0 -48
- data/lib/dragonfly/simple_endpoint.rb +0 -76
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
- data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
- data/spec/dragonfly/config/r_magick_spec.rb +0 -29
- data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
- data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
- data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
- data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
- data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
- data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
- data/spec/simple_matchers.rb +0 -44
@@ -1,11 +1,91 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_model'
|
3
|
+
|
4
|
+
# --------------------------------------------------------------- #
|
5
|
+
# MODELS
|
6
|
+
# --------------------------------------------------------------- #
|
7
|
+
class MyModel
|
8
|
+
|
9
|
+
# Callbacks
|
10
|
+
extend ActiveModel::Callbacks
|
11
|
+
define_model_callbacks :save, :destroy
|
12
|
+
|
13
|
+
include ActiveModel::Validations
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def create!(attrs={})
|
17
|
+
new(attrs).save!
|
18
|
+
end
|
19
|
+
|
20
|
+
def find(id)
|
21
|
+
new(instances[id])
|
22
|
+
end
|
23
|
+
|
24
|
+
def instances
|
25
|
+
@instances ||= {}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(attrs={})
|
30
|
+
attrs.each do |key, value|
|
31
|
+
send("#{key}=", value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :id
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
self.class::ATTRIBUTES.inject({}) do |hash, attr|
|
39
|
+
hash[attr] = send(attr)
|
40
|
+
hash
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def save
|
45
|
+
_run_save_callbacks {
|
46
|
+
self.id ||= rand(1000)
|
47
|
+
self.class.instances[id] = self.to_hash
|
48
|
+
}
|
49
|
+
end
|
50
|
+
def save!
|
51
|
+
save
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def destroy
|
56
|
+
_run_destroy_callbacks {}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Item < MyModel
|
61
|
+
|
62
|
+
ATTRIBUTES = [
|
63
|
+
:title,
|
64
|
+
:preview_image_uid,
|
65
|
+
:preview_image_some_analyser_method,
|
66
|
+
:preview_image_size,
|
67
|
+
:preview_image_name,
|
68
|
+
:preview_image_blah_blah,
|
69
|
+
:other_image_uid,
|
70
|
+
:yet_another_image_uid,
|
71
|
+
:otra_imagen_uid,
|
72
|
+
:trailer_video_uid,
|
73
|
+
:created_at,
|
74
|
+
:updated_at
|
75
|
+
]
|
76
|
+
attr_accessor *ATTRIBUTES
|
77
|
+
end
|
78
|
+
|
79
|
+
class Car < MyModel
|
80
|
+
ATTRIBUTES = [
|
81
|
+
:image_uid,
|
82
|
+
:reliant_image_uid,
|
83
|
+
:type
|
84
|
+
]
|
85
|
+
attr_accessor *ATTRIBUTES
|
86
|
+
end
|
87
|
+
|
88
|
+
class Photo < MyModel
|
89
|
+
ATTRIBUTES = [:image_uid]
|
90
|
+
attr_accessor *ATTRIBUTES
|
11
91
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
png_path = File.dirname(__FILE__) + '/../../../samples/egg.png'
|
4
4
|
|
@@ -36,20 +36,11 @@ describe Dragonfly::Analysis::FileCommandAnalyser do
|
|
36
36
|
@analyser.mime_type(@temp_object)
|
37
37
|
@temp_object.instance_eval{@tempfile}.should be_nil
|
38
38
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
:gif => 'image/gif',
|
44
|
-
:tif => 'image/tiff'
|
45
|
-
}.each do |format, mime_type|
|
46
|
-
it "should work properly (without a broken pipe error) for big files of format #{format}" do
|
47
|
-
data = Dragonfly::Generation::ImageMagickGenerator.new.plasma(1000, 1000, format).first
|
48
|
-
temp_object = Dragonfly::TempObject.new(data)
|
49
|
-
@analyser.mime_type(temp_object).should == mime_type
|
50
|
-
end
|
39
|
+
it "should work properly (without a broken pipe error) for big files of format jpg" do
|
40
|
+
data = Dragonfly::ImageMagick::Generator.new.plasma(1000, 1000, :jpg).first
|
41
|
+
temp_object = Dragonfly::TempObject.new(data)
|
42
|
+
@analyser.mime_type(temp_object).should == "image/jpeg"
|
51
43
|
end
|
52
|
-
|
53
44
|
end
|
54
45
|
|
55
46
|
end
|
data/spec/dragonfly/app_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'rack/mock'
|
3
3
|
|
4
4
|
def request(app, path)
|
@@ -69,189 +69,21 @@ describe Dragonfly::App do
|
|
69
69
|
other_app.mime_type_for(:mark).should == 'second/one'
|
70
70
|
end
|
71
71
|
end
|
72
|
-
|
73
|
-
describe "#resolve_mime_type" do
|
74
|
-
before(:each) do
|
75
|
-
@app = test_app
|
76
|
-
@app.analyser.add :format do |temp_object|
|
77
|
-
:png
|
78
|
-
end
|
79
|
-
@app.analyser.add :mime_type do |temp_object|
|
80
|
-
'image/jpeg'
|
81
|
-
end
|
82
|
-
@app.encoder.add do |temp_object|
|
83
|
-
'ENCODED DATA YO'
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should return the correct mime_type if the temp_object has a format" do
|
88
|
-
temp_object = Dragonfly::TempObject.new("HIMATE", :format => :tiff, :name => 'test.pdf')
|
89
|
-
@app.resolve_mime_type(temp_object).should == 'image/tiff'
|
90
|
-
end
|
91
|
-
|
92
|
-
it "should use the file extension if it has no format" do
|
93
|
-
temp_object = Dragonfly::TempObject.new("HIMATE", :name => 'test.pdf')
|
94
|
-
@app.resolve_mime_type(temp_object).should == 'application/pdf'
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should not use the file extension if it's been switched off (fall back to mime_type analyser)" do
|
98
|
-
@app.infer_mime_type_from_file_ext = false
|
99
|
-
temp_object = Dragonfly::TempObject.new("HIMATE", :name => 'test.pdf')
|
100
|
-
@app.resolve_mime_type(temp_object).should == 'image/jpeg'
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should fall back to the mime_type analyser if the temp_object has no ext" do
|
104
|
-
temp_object = Dragonfly::TempObject.new("HIMATE", :name => 'test')
|
105
|
-
@app.resolve_mime_type(temp_object).should == 'image/jpeg'
|
106
|
-
end
|
107
|
-
|
108
|
-
describe "when the temp_object has no name" do
|
109
|
-
|
110
|
-
before(:each) do
|
111
|
-
@temp_object = Dragonfly::TempObject.new("HIMATE")
|
112
|
-
end
|
113
|
-
|
114
|
-
it "should fall back to the mime_type analyser" do
|
115
|
-
@app.resolve_mime_type(@temp_object).should == 'image/jpeg'
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should fall back to the format analyser if the mime_type analyser doesn't exist" do
|
119
|
-
@app.analyser.functions.delete(:mime_type)
|
120
|
-
@app.resolve_mime_type(@temp_object).should == 'image/png'
|
121
|
-
end
|
122
|
-
|
123
|
-
it "should fall back to the app's fallback mime_type if no mime_type/format analyser exists" do
|
124
|
-
@app.analyser.functions.delete(:mime_type)
|
125
|
-
@app.analyser.functions.delete(:format)
|
126
|
-
@app.resolve_mime_type(@temp_object).should == 'application/octet-stream'
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
132
|
-
|
133
|
-
end
|
134
|
-
|
135
|
-
describe "without path prefix or DOS protection" do
|
136
|
-
before(:each) do
|
137
|
-
@app = test_app
|
138
|
-
@job = Dragonfly::Job.new(@app).fetch('some_uid')
|
139
|
-
@app.datastore.stub!(:retrieve).with('some_uid').and_return "Hi there"
|
140
|
-
@app.configure{|c| c.protect_from_dos_attacks = false }
|
141
|
-
end
|
142
|
-
it "should correctly respond with the job data" do
|
143
|
-
response = request(@app, "/#{@job.serialize}")
|
144
|
-
response.status.should == 200
|
145
|
-
response.body.should == "Hi there"
|
146
|
-
end
|
147
|
-
it "should generate the correct url" do
|
148
|
-
@app.url_for(@job).should == "/#{@job.serialize}"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
describe "url_path_prefix" do
|
153
|
-
before(:each) do
|
154
|
-
@app = test_app
|
155
|
-
@job = Dragonfly::Job.new(@app)
|
156
|
-
end
|
157
|
-
it "should add the path prefix to the url if configured" do
|
158
|
-
@app.url_path_prefix = '/media'
|
159
|
-
@app.url_for(@job).should =~ %r{^/media/\w+$}
|
160
|
-
end
|
161
|
-
it "should add the path prefix to the url if passed in" do
|
162
|
-
@app.url_for(@job, :path_prefix => '/eggs').should =~ %r{^/eggs/\w+$}
|
163
|
-
end
|
164
|
-
it "should favour the passed in one" do
|
165
|
-
@app.url_path_prefix = '/media'
|
166
|
-
@app.url_for(@job, :path_prefix => '/bacon').should =~ %r{^/bacon/\w+$}
|
167
|
-
end
|
168
72
|
end
|
169
73
|
|
170
|
-
describe "
|
74
|
+
describe "remote_url_for" do
|
171
75
|
before(:each) do
|
172
76
|
@app = test_app
|
173
|
-
@
|
77
|
+
@app.datastore = Object.new
|
174
78
|
end
|
175
|
-
it "should
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
it "should add the host to the url if passed in" do
|
180
|
-
@app.url_for(@job, :host => 'https://bungle.com').should =~ %r{^https://bungle\.com/\w+$}
|
181
|
-
end
|
182
|
-
it "should favour the passed in one" do
|
183
|
-
@app.url_host = 'http://some.server:4000'
|
184
|
-
@app.url_for(@job, :host => 'https://smeedy').should =~ %r{^https://smeedy/\w+$}
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
describe "url_suffix" do
|
189
|
-
before(:each) do
|
190
|
-
@app = test_app
|
191
|
-
@job = Dragonfly::Job.new(@app)
|
192
|
-
end
|
193
|
-
it "should add the suffix to the url if configured" do
|
194
|
-
@app.url_suffix = 'hellodudes'
|
195
|
-
@app.url_for(@job).should =~ /\w+hellodudes$/
|
196
|
-
end
|
197
|
-
it "should add the suffix to the url if passed in" do
|
198
|
-
@app.url_for(@job, :suffix => '/howdy.pardner').should =~ /\w+\/howdy\.pardner$/
|
199
|
-
end
|
200
|
-
it "should favour the passed in one" do
|
201
|
-
@app.url_suffix = 'hellodudes'
|
202
|
-
@app.url_for(@job, :suffix => '/howdy.pardner').should =~ /\w+\/howdy\.pardner$/
|
203
|
-
end
|
204
|
-
it "should accept a proc yielding the job" do
|
205
|
-
@app.url_suffix = proc{|job| job.uid }
|
206
|
-
@job.fetch!('some_uid')
|
207
|
-
@app.url_for(@job).should =~ /\w+some_uid$/
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
describe "url params" do
|
212
|
-
before(:each) do
|
213
|
-
@app = test_app
|
214
|
-
@job = Dragonfly::Job.new(@app)
|
215
|
-
end
|
216
|
-
it "should add extra params to the url query string" do
|
217
|
-
@app.url_for(@job, :suffix => '/suffix', :a => 'thing', :b => 'nuther').should =~ /\w+\/suffix\?a=thing&b=nuther$/
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
describe "Denial of Service protection" do
|
222
|
-
before(:each) do
|
223
|
-
@app = test_app
|
224
|
-
@app.protect_from_dos_attacks = true
|
225
|
-
@job = Dragonfly::Job.new(@app).fetch('some_uid')
|
226
|
-
end
|
227
|
-
it "should generate the correct url" do
|
228
|
-
@app.url_for(@job).should == "/#{@job.serialize}?s=#{@job.sha}"
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
describe "configuring with saved configurations" do
|
233
|
-
before(:each) do
|
234
|
-
@app = test_app
|
235
|
-
end
|
236
|
-
|
237
|
-
{
|
238
|
-
:imagemagick => Dragonfly::Config::ImageMagick,
|
239
|
-
:image_magick => Dragonfly::Config::ImageMagick,
|
240
|
-
:rmagick => Dragonfly::Config::RMagick,
|
241
|
-
:r_magick => Dragonfly::Config::RMagick,
|
242
|
-
:rails => Dragonfly::Config::Rails,
|
243
|
-
:heroku => Dragonfly::Config::Heroku,
|
244
|
-
}.each do |key, klass|
|
245
|
-
it "should map #{key} to #{klass}" do
|
246
|
-
klass.should_receive(:apply_configuration).with(@app)
|
247
|
-
@app.configure_with(key)
|
248
|
-
end
|
79
|
+
it "should raise an error if the datastore doesn't provide it" do
|
80
|
+
lambda{
|
81
|
+
@app.remote_url_for('some_uid')
|
82
|
+
}.should raise_error(NotImplementedError)
|
249
83
|
end
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
@app.configure_with(:eggs)
|
254
|
-
}.should raise_error(ArgumentError)
|
84
|
+
it "should correctly call it if the datastore provides it" do
|
85
|
+
@app.datastore.should_receive(:url_for).with('some_uid', :some => :opts).and_return 'http://egg.head'
|
86
|
+
@app.remote_url_for('some_uid', :some => :opts).should == 'http://egg.head'
|
255
87
|
end
|
256
88
|
end
|
257
89
|
|
@@ -270,11 +102,34 @@ describe Dragonfly::App do
|
|
270
102
|
end
|
271
103
|
it "should allow storing with extra stuff" do
|
272
104
|
@app.datastore.should_receive(:store).with(
|
273
|
-
a_temp_object_with_data("HELLO", :meta => {:egg => :head}
|
274
|
-
{:option => :blarney}
|
105
|
+
a_temp_object_with_data("HELLO"), :meta => {:egg => :head}, :option => :blarney
|
275
106
|
)
|
276
107
|
@app.store("HELLO", :meta => {:egg => :head}, :option => :blarney)
|
277
108
|
end
|
278
109
|
end
|
279
110
|
|
111
|
+
describe "url_for" do
|
112
|
+
before(:each) do
|
113
|
+
@app = test_app
|
114
|
+
@job = @app.fetch('eggs')
|
115
|
+
end
|
116
|
+
it "should give the server url by default" do
|
117
|
+
@app.url_for(@job).should =~ %r{^/\w+$}
|
118
|
+
end
|
119
|
+
it "should allow configuring" do
|
120
|
+
@app.configure do |c|
|
121
|
+
c.define_url do |app, job, opts|
|
122
|
+
"doogies"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
@app.url_for(@job).should == 'doogies'
|
126
|
+
end
|
127
|
+
it "should yield the correct dooberries" do
|
128
|
+
@app.define_url do |app, job, opts|
|
129
|
+
[app, job, opts]
|
130
|
+
end
|
131
|
+
@app.url_for(@job, {'chuddies' => 'margate'}).should == [@app, @job, {'chuddies' => 'margate'}]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
280
135
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Dragonfly::Configurable do
|
4
4
|
|
@@ -30,6 +30,11 @@ describe Dragonfly::Configurable do
|
|
30
30
|
@car.colour.should be_nil
|
31
31
|
end
|
32
32
|
|
33
|
+
it "should allow setting to nil" do
|
34
|
+
@car.top_speed = nil
|
35
|
+
@car.top_speed.should be_nil
|
36
|
+
end
|
37
|
+
|
33
38
|
it "should allow specifying configurable attrs as strings" do
|
34
39
|
class Bike
|
35
40
|
include Dragonfly::Configurable
|
@@ -61,12 +66,12 @@ describe Dragonfly::Configurable do
|
|
61
66
|
end
|
62
67
|
|
63
68
|
describe "getting configuration" do
|
64
|
-
it "should return the configuration
|
65
|
-
@car.configuration.should == {
|
69
|
+
it "should return the configuration when nothing is set" do
|
70
|
+
@car.configuration.should == {}
|
66
71
|
end
|
67
|
-
it "should
|
68
|
-
@car.
|
69
|
-
@car.
|
72
|
+
it "should return the configuration when something is set" do
|
73
|
+
@car.top_speed = 10
|
74
|
+
@car.configuration.should == {:top_speed => 10}
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
@@ -79,8 +84,8 @@ describe Dragonfly::Configurable do
|
|
79
84
|
car1.configure{|c| c.colour = 'green'}
|
80
85
|
car2 = Car.new
|
81
86
|
car2.configure{|c| c.colour = 'yellow'}
|
82
|
-
car1.configuration.should == {:colour => 'green'
|
83
|
-
car2.configuration.should == {:colour => 'yellow'
|
87
|
+
car1.configuration.should == {:colour => 'green'}
|
88
|
+
car2.configuration.should == {:colour => 'yellow'}
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
@@ -153,32 +158,50 @@ describe Dragonfly::Configurable do
|
|
153
158
|
|
154
159
|
describe "nested configurable objects" do
|
155
160
|
|
156
|
-
|
157
|
-
|
161
|
+
before(:each) do
|
158
162
|
class NestedThing
|
159
163
|
include Dragonfly::Configurable
|
160
164
|
configurable_attr :age, 29
|
165
|
+
def some_method(val)
|
166
|
+
@some_thing = val
|
167
|
+
end
|
168
|
+
configuration_method :some_method
|
169
|
+
attr_reader :some_thing
|
161
170
|
end
|
162
171
|
|
163
172
|
class Car
|
164
173
|
def nested_thing
|
165
174
|
@nested_thing ||= NestedThing.new
|
166
175
|
end
|
176
|
+
nested_configurable :nested_thing
|
167
177
|
end
|
168
178
|
|
169
179
|
@car.configure do |c|
|
170
180
|
c.nested_thing.configure do |nt|
|
171
181
|
nt.age = 50
|
182
|
+
nt.some_method('yo')
|
172
183
|
end
|
173
184
|
end
|
185
|
+
end
|
174
186
|
|
187
|
+
it "should allow configuring nested configurable accessors" do
|
175
188
|
@car.nested_thing.age.should == 50
|
176
|
-
|
177
189
|
end
|
178
190
|
|
191
|
+
it "should allow configuring nested configurable normal methods" do
|
192
|
+
@car.nested_thing.some_thing.should == 'yo'
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should not allow configuring directly on the config object" do
|
196
|
+
expect{
|
197
|
+
@car.configure do |c|
|
198
|
+
c.some_method('other')
|
199
|
+
end
|
200
|
+
}.to raise_error(Dragonfly::Configurable::BadConfigAttribute)
|
201
|
+
end
|
179
202
|
end
|
180
203
|
|
181
|
-
describe "configuring with a
|
204
|
+
describe "configuring with a saved config" do
|
182
205
|
before(:each) do
|
183
206
|
@cool_configuration = Object.new
|
184
207
|
def @cool_configuration.apply_configuration(car, colour=nil)
|
@@ -188,13 +211,13 @@ describe Dragonfly::Configurable do
|
|
188
211
|
end
|
189
212
|
end
|
190
213
|
|
191
|
-
it "should allow configuration by a
|
214
|
+
it "should allow configuration by a saved config" do
|
192
215
|
@car.configure_with(@cool_configuration)
|
193
216
|
@car.colour.should == 'vermelho'
|
194
217
|
@car.top_speed.should == 216
|
195
218
|
end
|
196
219
|
|
197
|
-
it "should pass any args through to the
|
220
|
+
it "should pass any args through to the saved config" do
|
198
221
|
@car.configure_with(@cool_configuration, 'preto')
|
199
222
|
@car.colour.should == 'preto'
|
200
223
|
end
|
@@ -210,11 +233,229 @@ describe Dragonfly::Configurable do
|
|
210
233
|
@car.configure_with(@cool_configuration).should == @car
|
211
234
|
end
|
212
235
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
236
|
+
describe "using a symbol to specify the config" do
|
237
|
+
|
238
|
+
before(:all) do
|
239
|
+
@rally_config = Object.new
|
240
|
+
Car.register_configuration(:rally, @rally_config)
|
241
|
+
@long_journey_config = Object.new
|
242
|
+
Car.register_configuration(:long_journey){ @long_journey_config }
|
243
|
+
Car.register_configuration(:some_library){ SomeLibrary }
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should map the symbol to the correct configuration" do
|
247
|
+
@rally_config.should_receive(:apply_configuration).with(@car)
|
248
|
+
@car.configure_with(:rally)
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should map the symbol to the correct configuration lazily" do
|
252
|
+
@long_journey_config.should_receive(:apply_configuration).with(@car)
|
253
|
+
@car.configure_with(:long_journey)
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should throw an error if an unknown symbol is passed in" do
|
257
|
+
lambda {
|
258
|
+
@car.configure_with(:eggs)
|
259
|
+
}.should raise_error(ArgumentError)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should only try to load the library when asked to" do
|
263
|
+
lambda{
|
264
|
+
@car.configure_with(:some_library)
|
265
|
+
}.should raise_error(NameError, /uninitialized constant.*SomeLibrary/)
|
266
|
+
end
|
217
267
|
end
|
268
|
+
|
218
269
|
end
|
219
270
|
|
271
|
+
describe "falling back to another config" do
|
272
|
+
before(:each) do
|
273
|
+
@garage = Object.new
|
274
|
+
class << @garage
|
275
|
+
include Dragonfly::Configurable
|
276
|
+
configurable_attr :top_speed, 100
|
277
|
+
end
|
278
|
+
@car.use_as_fallback_config(@garage)
|
279
|
+
end
|
280
|
+
|
281
|
+
describe "when nothing set" do
|
282
|
+
it "should use its default" do
|
283
|
+
@car.top_speed.should == 216
|
284
|
+
end
|
285
|
+
it "shouldn't affect the fallback config object" do
|
286
|
+
@garage.top_speed.should == 100
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe "if set" do
|
291
|
+
before(:each) do
|
292
|
+
@car.top_speed = 444
|
293
|
+
end
|
294
|
+
it "should work normally" do
|
295
|
+
@car.top_speed.should == 444
|
296
|
+
end
|
297
|
+
it "shouldn't affect the fallback config object" do
|
298
|
+
@garage.top_speed.should == 100
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe "both set" do
|
303
|
+
before(:each) do
|
304
|
+
@car.top_speed = 444
|
305
|
+
@garage.top_speed = 3000
|
306
|
+
end
|
307
|
+
it "should prefer its own setting" do
|
308
|
+
@car.top_speed.should == 444
|
309
|
+
end
|
310
|
+
it "shouldn't affect the fallback config object" do
|
311
|
+
@garage.top_speed.should == 3000
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
describe "the fallback config is set" do
|
316
|
+
before(:each) do
|
317
|
+
@garage.top_speed = 3000
|
318
|
+
end
|
319
|
+
it "should use the fallback config" do
|
320
|
+
@car.top_speed.should == 3000
|
321
|
+
end
|
322
|
+
it "shouldn't affect the fallback config object" do
|
323
|
+
@garage.top_speed.should == 3000
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe "falling back multiple levels" do
|
328
|
+
before(:each) do
|
329
|
+
@klass = Class.new
|
330
|
+
@klass.class_eval do
|
331
|
+
include Dragonfly::Configurable
|
332
|
+
configurable_attr :veg, 'carrot'
|
333
|
+
end
|
334
|
+
@a = @klass.new
|
335
|
+
@b = @klass.new
|
336
|
+
@b.use_as_fallback_config(@a)
|
337
|
+
@c = @klass.new
|
338
|
+
@c.use_as_fallback_config(@b)
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should be the default if nothing set" do
|
342
|
+
@c.veg.should == 'carrot'
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should fall all the way back to the top one if necessary" do
|
346
|
+
@a.veg = 'turnip'
|
347
|
+
@c.veg.should == 'turnip'
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should prefer the closer one over the further away one" do
|
351
|
+
@b.veg = 'tatty'
|
352
|
+
@a.veg = 'turnip'
|
353
|
+
@c.veg.should == 'tatty'
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should work properly with nils" do
|
357
|
+
@a.veg = nil
|
358
|
+
@c.veg = 'broc'
|
359
|
+
@a.veg.should be_nil
|
360
|
+
@b.veg.should be_nil
|
361
|
+
@c.veg.should == 'broc'
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe "objects with different methods" do
|
366
|
+
before(:each) do
|
367
|
+
@dad = Object.new
|
368
|
+
class << @dad
|
369
|
+
include Dragonfly::Configurable
|
370
|
+
end
|
371
|
+
@kid = Object.new
|
372
|
+
class << @kid
|
373
|
+
include Dragonfly::Configurable
|
374
|
+
configurable_attr :lug, 'default-lug'
|
375
|
+
end
|
376
|
+
@kid.use_as_fallback_config(@dad)
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should not allow setting on the fallback obj directly" do
|
380
|
+
lambda{
|
381
|
+
@dad.lug = 'leg'
|
382
|
+
}.should raise_error(NoMethodError)
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should not have the fallback obj respond to the method" do
|
386
|
+
@dad.should_not respond_to(:lug=)
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should allow configuring through the fallback object even if it doesn't have that method" do
|
390
|
+
@dad.configure do |c|
|
391
|
+
c.lug = 'leg'
|
392
|
+
end
|
393
|
+
@kid.lug.should == 'leg'
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should work when a grandchild config is added later" do
|
397
|
+
grandkid = Object.new
|
398
|
+
class << grandkid
|
399
|
+
include Dragonfly::Configurable
|
400
|
+
configurable_attr :oogie, 'boogie'
|
401
|
+
end
|
402
|
+
grandkid.use_as_fallback_config(@kid)
|
403
|
+
@dad.configure{|c| c.oogie = 'duggen' }
|
404
|
+
grandkid.oogie.should == 'duggen'
|
405
|
+
end
|
406
|
+
|
407
|
+
it "should allow configuring twice through the fallback object" do
|
408
|
+
@dad.configure{|c| c.lug = 'leg' }
|
409
|
+
@dad.configure{|c| c.lug = 'blug' }
|
410
|
+
@kid.lug.should == 'blug'
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
describe "clashing with configurable modules" do
|
415
|
+
before(:each) do
|
416
|
+
@mod = mod = Module.new
|
417
|
+
@mod.module_eval do
|
418
|
+
include Dragonfly::Configurable
|
419
|
+
configurable_attr :team, 'spurs'
|
420
|
+
end
|
421
|
+
@class = Class.new
|
422
|
+
@class.class_eval do
|
423
|
+
include mod
|
424
|
+
include Dragonfly::Configurable
|
425
|
+
configurable_attr :tree, 'elm'
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should not override the defaults from the module" do
|
430
|
+
obj = @class.new
|
431
|
+
obj.team.should == 'spurs'
|
432
|
+
end
|
433
|
+
|
434
|
+
it "should still use its own defaults" do
|
435
|
+
obj = @class.new
|
436
|
+
obj.tree.should == 'elm'
|
437
|
+
end
|
438
|
+
|
439
|
+
describe "when the configurable_attr is specified in a subclass that doesn't include Configurable" do
|
440
|
+
before(:each) do
|
441
|
+
@subclass = Class.new(@class)
|
442
|
+
@subclass.class_eval do
|
443
|
+
configurable_attr :car, 'mazda'
|
444
|
+
configurable_attr :tree, 'oak'
|
445
|
+
end
|
446
|
+
@obj = @subclass.new
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should still work with default values" do
|
450
|
+
@obj.car.should == 'mazda'
|
451
|
+
end
|
452
|
+
|
453
|
+
it "should override the default from the parent" do
|
454
|
+
@obj.tree.should == 'oak'
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
end
|
459
|
+
|
460
|
+
end
|
220
461
|
end
|