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.

Files changed (155) hide show
  1. data/{.specopts → .rspec} +0 -1
  2. data/.yardopts +6 -2
  3. data/Gemfile +14 -13
  4. data/History.md +47 -9
  5. data/README.md +25 -5
  6. data/Rakefile +37 -79
  7. data/VERSION +1 -1
  8. data/dragonfly.gemspec +140 -89
  9. data/extra_docs/Analysers.md +8 -48
  10. data/extra_docs/Configuration.md +40 -25
  11. data/extra_docs/Couch.md +49 -0
  12. data/extra_docs/DataStorage.md +94 -24
  13. data/extra_docs/Encoding.md +6 -35
  14. data/extra_docs/ExampleUseCases.md +113 -0
  15. data/extra_docs/GeneralUsage.md +7 -23
  16. data/extra_docs/Generators.md +15 -49
  17. data/extra_docs/Heroku.md +7 -8
  18. data/extra_docs/ImageMagick.md +126 -0
  19. data/extra_docs/MimeTypes.md +3 -3
  20. data/extra_docs/Models.md +163 -0
  21. data/extra_docs/Mongo.md +1 -4
  22. data/extra_docs/Processing.md +7 -60
  23. data/extra_docs/Rails2.md +3 -1
  24. data/extra_docs/Rails3.md +2 -10
  25. data/extra_docs/ServingRemotely.md +83 -0
  26. data/extra_docs/Sinatra.md +3 -3
  27. data/extra_docs/URLs.md +60 -33
  28. data/features/rails_3.0.5.feature +8 -0
  29. data/features/steps/rails_steps.rb +7 -18
  30. data/features/support/env.rb +10 -37
  31. data/features/support/setup.rb +32 -0
  32. data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
  33. data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
  34. data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
  35. data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -0
  36. data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
  37. data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
  38. data/fixtures/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
  39. data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
  40. data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
  41. data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
  42. data/irbrc.rb +2 -1
  43. data/lib/dragonfly.rb +7 -0
  44. data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
  45. data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
  46. data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
  47. data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
  48. data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
  49. data/lib/dragonfly/analyser.rb +0 -1
  50. data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
  51. data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
  52. data/lib/dragonfly/app.rb +64 -55
  53. data/lib/dragonfly/config/heroku.rb +1 -1
  54. data/lib/dragonfly/config/image_magick.rb +2 -37
  55. data/lib/dragonfly/config/rails.rb +5 -2
  56. data/lib/dragonfly/configurable.rb +115 -35
  57. data/lib/dragonfly/core_ext/object.rb +1 -1
  58. data/lib/dragonfly/core_ext/string.rb +1 -1
  59. data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
  60. data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
  61. data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
  62. data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
  63. data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
  64. data/lib/dragonfly/function_manager.rb +4 -2
  65. data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
  66. data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
  67. data/lib/dragonfly/image_magick/analyser.rb +51 -0
  68. data/lib/dragonfly/image_magick/config.rb +44 -0
  69. data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
  70. data/lib/dragonfly/image_magick/generator.rb +145 -0
  71. data/lib/dragonfly/image_magick/processor.rb +104 -0
  72. data/lib/dragonfly/image_magick/utils.rb +72 -0
  73. data/lib/dragonfly/image_magick_utils.rb +2 -79
  74. data/lib/dragonfly/job.rb +152 -90
  75. data/lib/dragonfly/middleware.rb +5 -19
  76. data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
  77. data/lib/dragonfly/rails/images.rb +15 -10
  78. data/lib/dragonfly/response.rb +26 -12
  79. data/lib/dragonfly/serializer.rb +1 -4
  80. data/lib/dragonfly/server.rb +103 -0
  81. data/lib/dragonfly/temp_object.rb +56 -101
  82. data/lib/dragonfly/url_mapper.rb +78 -0
  83. data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
  84. data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
  85. data/spec/dragonfly/analyser_spec.rb +1 -1
  86. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
  87. data/spec/dragonfly/app_spec.rb +35 -180
  88. data/spec/dragonfly/configurable_spec.rb +259 -18
  89. data/spec/dragonfly/core_ext/string_spec.rb +2 -2
  90. data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
  91. data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
  92. data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
  93. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
  94. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
  95. data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
  96. data/spec/dragonfly/function_manager_spec.rb +2 -2
  97. data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
  98. data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
  99. data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
  100. data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
  101. data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
  102. data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
  103. data/spec/dragonfly/job_builder_spec.rb +1 -1
  104. data/spec/dragonfly/job_definitions_spec.rb +1 -1
  105. data/spec/dragonfly/job_endpoint_spec.rb +26 -3
  106. data/spec/dragonfly/job_spec.rb +426 -208
  107. data/spec/dragonfly/loggable_spec.rb +2 -2
  108. data/spec/dragonfly/middleware_spec.rb +5 -26
  109. data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
  110. data/spec/dragonfly/serializer_spec.rb +1 -14
  111. data/spec/dragonfly/server_spec.rb +261 -0
  112. data/spec/dragonfly/simple_cache_spec.rb +1 -1
  113. data/spec/dragonfly/temp_object_spec.rb +84 -130
  114. data/spec/dragonfly/url_mapper_spec.rb +130 -0
  115. data/spec/functional/deprecations_spec.rb +51 -0
  116. data/spec/functional/image_magick_app_spec.rb +27 -0
  117. data/spec/functional/model_urls_spec.rb +85 -0
  118. data/spec/functional/remote_on_the_fly_spec.rb +51 -0
  119. data/spec/functional/to_response_spec.rb +31 -0
  120. data/spec/spec_helper.rb +12 -22
  121. data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
  122. data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
  123. data/spec/support/simple_matchers.rb +53 -0
  124. data/yard/handlers/configurable_attr_handler.rb +2 -2
  125. data/yard/templates/default/fulldoc/html/css/common.css +12 -10
  126. data/yard/templates/default/layout/html/layout.erb +6 -0
  127. metadata +267 -308
  128. data/Gemfile.rails.2.3.5 +0 -20
  129. data/features/3.0.3.feature +0 -8
  130. data/features/rails_2.3.5.feature +0 -7
  131. data/fixtures/files/app/models/album.rb +0 -3
  132. data/fixtures/files/app/views/albums/new.html.erb +0 -4
  133. data/fixtures/files/features/manage_album_images.feature +0 -12
  134. data/fixtures/rails_2.3.5/template.rb +0 -10
  135. data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
  136. data/lib/dragonfly/config/r_magick.rb +0 -46
  137. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
  138. data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
  139. data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
  140. data/lib/dragonfly/r_magick_utils.rb +0 -48
  141. data/lib/dragonfly/simple_endpoint.rb +0 -76
  142. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
  143. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
  144. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
  145. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
  146. data/spec/dragonfly/config/r_magick_spec.rb +0 -29
  147. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
  148. data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
  149. data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
  150. data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
  151. data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
  152. data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
  153. data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
  154. data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
  155. data/spec/simple_matchers.rb +0 -44
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  # Matchers
4
- Spec::Matchers.define :match_steps do |steps|
4
+ RSpec::Matchers.define :match_steps do |steps|
5
5
  match do |given|
6
6
  given.map{|step| step.class } == steps
7
7
  end
@@ -16,7 +16,8 @@ describe Dragonfly::Job do
16
16
  Dragonfly::Job::Process => :process,
17
17
  Dragonfly::Job::Encode => :encode,
18
18
  Dragonfly::Job::Generate => :generate,
19
- Dragonfly::Job::FetchFile => :fetch_file
19
+ Dragonfly::Job::FetchFile => :fetch_file,
20
+ Dragonfly::Job::FetchUrl => :fetch_url
20
21
  }.each do |klass, step_name|
21
22
  it "should return the correct step name for #{klass}" do
22
23
  klass.step_name.should == step_name
@@ -28,7 +29,8 @@ describe Dragonfly::Job do
28
29
  Dragonfly::Job::Process => :p,
29
30
  Dragonfly::Job::Encode => :e,
30
31
  Dragonfly::Job::Generate => :g,
31
- Dragonfly::Job::FetchFile => :ff
32
+ Dragonfly::Job::FetchFile => :ff,
33
+ Dragonfly::Job::FetchUrl => :fu
32
34
  }.each do |klass, abbreviation|
33
35
  it "should return the correct abbreviation for #{klass}" do
34
36
  klass.abbreviation.should == abbreviation
@@ -37,13 +39,13 @@ describe Dragonfly::Job do
37
39
 
38
40
  describe "step_names" do
39
41
  it "should return the available step names" do
40
- Dragonfly::Job.step_names.should == [:fetch, :process, :encode, :generate, :fetch_file]
42
+ Dragonfly::Job.step_names.should == [:fetch, :process, :encode, :generate, :fetch_file, :fetch_url]
41
43
  end
42
44
  end
43
45
 
44
46
  end
45
47
 
46
- describe "without temp_object" do
48
+ describe "without content" do
47
49
 
48
50
  before(:each) do
49
51
  @app = mock_app
@@ -51,8 +53,8 @@ describe Dragonfly::Job do
51
53
  end
52
54
 
53
55
  it "should allow initializing with content" do
54
- job = Dragonfly::Job.new(@app, Dragonfly::TempObject.new('eggheads'))
55
- job.temp_object.data.should == 'eggheads'
56
+ job = Dragonfly::Job.new(@app, 'eggheads')
57
+ job.data.should == 'eggheads'
56
58
  end
57
59
 
58
60
  describe "fetch" do
@@ -64,16 +66,13 @@ describe Dragonfly::Job do
64
66
 
65
67
  it "should retrieve from the app's datastore when applied" do
66
68
  @app.datastore.should_receive(:retrieve).with('some_uid').and_return('HELLO')
67
- @job.apply
68
- @job.temp_object.data.should == 'HELLO'
69
+ @job.data.should == 'HELLO'
69
70
  end
70
71
 
71
72
  it "should set extra data if returned from the datastore" do
72
- @app.datastore.should_receive(:retrieve).with('some_uid').and_return(['HELLO', {:name => 'test.txt', :meta => {1=>2}}])
73
- @job.apply
74
- @job.temp_object.data.should == 'HELLO'
75
- @job.temp_object.name.should == 'test.txt'
76
- @job.temp_object.meta.should == {1 => 2}
73
+ @app.datastore.should_receive(:retrieve).with('some_uid').and_return(['HELLO', {:name => 'test.txt'}])
74
+ @job.data.should == 'HELLO'
75
+ @job.meta.should == {:name => 'test.txt'}
77
76
  end
78
77
  end
79
78
 
@@ -112,16 +111,13 @@ describe Dragonfly::Job do
112
111
 
113
112
  it "should use the generator when applied" do
114
113
  @app.generator.should_receive(:generate).with(:plasma, 20, 30).and_return('hi')
115
- @job.apply.data.should == 'hi'
114
+ @job.data.should == 'hi'
116
115
  end
117
116
 
118
117
  it "should save extra data if the generator returns it" do
119
- @app.generator.should_receive(:generate).with(:plasma, 20, 30).and_return(['hi', {:name => 'plasma.png', :format => :png, :meta => {:a => :b}}])
120
- @job.apply
121
- @job.temp_object.data.should == 'hi'
122
- @job.temp_object.name.should == 'plasma.png'
123
- @job.temp_object.format.should == :png
124
- @job.temp_object.meta.should == {:a => :b}
118
+ @app.generator.should_receive(:generate).with(:plasma, 20, 30).and_return(['hi', {:name => 'plasma.png'}])
119
+ @job.data.should == 'hi'
120
+ @job.meta.should == {:name => 'plasma.png'}
125
121
  end
126
122
  end
127
123
 
@@ -133,21 +129,61 @@ describe Dragonfly::Job do
133
129
  it { @job.steps.should match_steps([Dragonfly::Job::FetchFile]) }
134
130
 
135
131
  it "should fetch the specified file when applied" do
136
- @job.apply
137
- @job.temp_object.size.should == 62664
132
+ @job.size.should == 62664
133
+ end
134
+
135
+ it "should set the name" do
136
+ @job.meta[:name].should == 'egg.png'
137
+ end
138
+ end
139
+
140
+ describe "fetch_url" do
141
+ before(:each) do
142
+ stub_request(:get, 'http://some.place.com').to_return(:body => 'result!')
143
+ stub_request(:get, 'https://some.place.com').to_return(:body => 'secure result!')
144
+ end
145
+
146
+ it {
147
+ @job.fetch_url!('some.url')
148
+ @job.steps.should match_steps([Dragonfly::Job::FetchUrl])
149
+ }
150
+
151
+ it "should fetch the specified url when applied" do
152
+ @job.fetch_url!('http://some.place.com')
153
+ @job.data.should == "result!"
154
+ end
155
+
156
+ it "should default to http" do
157
+ @job.fetch_url!('some.place.com')
158
+ @job.data.should == "result!"
138
159
  end
139
160
 
161
+ it "should also work with https" do
162
+ @job.fetch_url!('https://some.place.com')
163
+ @job.data.should == "secure result!"
164
+ end
165
+
166
+ it "should set the name if there is one" do
167
+ @job.fetch_url!('some.place.com/dung.beetle')
168
+ @job.meta[:name].should == 'dung.beetle'
169
+ end
170
+
171
+ ["some.place.com", "some.place.com/", "some.place.com/eggs/"].each do |url|
172
+ it "should not set the name if there isn't one, e.g. #{url}" do
173
+ @job.fetch_url!(url)
174
+ @job.meta[:name].should be_nil
175
+ end
176
+ end
140
177
  end
141
178
 
142
179
  end
143
180
 
144
- describe "with temp_object already there" do
181
+ describe "with content already there" do
145
182
 
146
183
  before(:each) do
147
184
  @app = mock_app
148
- @temp_object = Dragonfly::TempObject.new('HELLO', :name => 'hello.txt', :meta => {:a => :b}, :format => :txt)
149
- @job = Dragonfly::Job.new(@app)
150
- @job.temp_object = @temp_object
185
+ @job = Dragonfly::Job.new(@app, 'HELLO', :name => 'hello.txt', :a => :b)
186
+ @temp_object = @job.temp_object
151
187
  end
152
188
 
153
189
  describe "apply" do
@@ -165,25 +201,19 @@ describe Dragonfly::Job do
165
201
 
166
202
  it "should use the processor when applied" do
167
203
  @app.processor.should_receive(:process).with(@temp_object, :resize, '20x30').and_return('hi')
168
- @job.apply.data.should == 'hi'
204
+ @job.data.should == 'hi'
169
205
  end
170
206
 
171
- it "should maintain the temp object attributes" do
207
+ it "should maintain the meta attributes" do
172
208
  @app.processor.should_receive(:process).with(@temp_object, :resize, '20x30').and_return('hi')
173
- temp_object = @job.apply.temp_object
174
- temp_object.data.should == 'hi'
175
- temp_object.name.should == 'hello.txt'
176
- temp_object.meta.should == {:a => :b}
177
- temp_object.format.should == :txt
209
+ @job.data.should == 'hi'
210
+ @job.meta.should == {:name => 'hello.txt', :a => :b}
178
211
  end
179
212
 
180
213
  it "should allow returning an array with extra attributes from the processor" do
181
- @app.processor.should_receive(:process).with(@temp_object, :resize, '20x30').and_return(['hi', {:name => 'hello_20x30.txt', :meta => {:eggs => 'asdf'}}])
182
- temp_object = @job.apply.temp_object
183
- temp_object.data.should == 'hi'
184
- temp_object.name.should == 'hello_20x30.txt'
185
- temp_object.meta.should == {:a => :b, :eggs => 'asdf'}
186
- temp_object.format.should == :txt
214
+ @app.processor.should_receive(:process).with(@temp_object, :resize, '20x30').and_return(['hi', {:name => 'hello_20x30.txt', :eggs => 'asdf'}])
215
+ @job.data.should == 'hi'
216
+ @job.meta.should == {:name => 'hello_20x30.txt', :a => :b, :eggs => 'asdf'}
187
217
  end
188
218
  end
189
219
 
@@ -196,34 +226,29 @@ describe Dragonfly::Job do
196
226
 
197
227
  it "should use the encoder when applied" do
198
228
  @app.encoder.should_receive(:encode).with(@temp_object, :gif, :bitrate => 'mumma').and_return('alo')
199
- @job.apply.data.should == 'alo'
229
+ @job.data.should == 'alo'
200
230
  end
201
231
 
202
- it "should maintain the temp object attributes (except format)" do
232
+ it "should maintain the meta and update the format" do
203
233
  @app.encoder.should_receive(:encode).with(@temp_object, :gif, :bitrate => 'mumma').and_return('alo')
204
- temp_object = @job.apply.temp_object
205
- temp_object.data.should == 'alo'
206
- temp_object.name.should == 'hello.txt'
207
- temp_object.meta.should == {:a => :b}
234
+ @job.data.should == 'alo'
235
+ @job.meta.should == {:name => 'hello.txt', :a => :b, :format => :gif}
208
236
  end
209
237
 
210
- it "should update the format" do
211
- @app.encoder.should_receive(:encode).with(@temp_object, :gif, :bitrate => 'mumma').and_return('alo')
212
- @job.apply.temp_object.format.should == :gif
238
+ it "should update the format even when not applied" do
239
+ @app.encoder.should_not_receive(:encode)
240
+ @job.meta[:format].should == :gif
213
241
  end
214
242
 
215
243
  it "should allow returning an array with extra attributes form the encoder" do
216
- @app.encoder.should_receive(:encode).with(@temp_object, :gif, :bitrate => 'mumma').and_return(['alo', {:name => 'doobie', :meta => {:eggs => 'fish'}}])
217
- temp_object = @job.apply.temp_object
218
- temp_object.data.should == 'alo'
219
- temp_object.name.should == 'doobie'
220
- temp_object.meta.should == {:a => :b, :eggs => 'fish'}
244
+ @app.encoder.should_receive(:encode).with(@temp_object, :gif, :bitrate => 'mumma').and_return(['alo', {:name => 'doobie', :eggs => 'fish'}])
245
+ @job.data.should == 'alo'
246
+ @job.meta.should == {:name => 'doobie', :a => :b, :eggs => 'fish', :format => :gif}
221
247
  end
222
248
 
223
249
  it "not allow overriding the format" do
224
250
  @app.encoder.should_receive(:encode).with(@temp_object, :gif, :bitrate => 'mumma').and_return(['alo', {:format => :png}])
225
- temp_object = @job.apply.temp_object
226
- temp_object.format.should == :gif
251
+ @job.apply.meta[:format].should == :gif
227
252
  end
228
253
  end
229
254
  end
@@ -231,7 +256,7 @@ describe Dragonfly::Job do
231
256
  describe "analysis" do
232
257
  before(:each) do
233
258
  @app = test_app
234
- @job = Dragonfly::Job.new(@app, Dragonfly::TempObject.new('HELLO'))
259
+ @job = @app.new_job('HELLO')
235
260
  @app.analyser.add(:num_letters){|temp_object, letter| temp_object.data.count(letter) }
236
261
  end
237
262
  it "should return correctly when calling analyse" do
@@ -254,71 +279,6 @@ describe Dragonfly::Job do
254
279
  end
255
280
  end
256
281
 
257
- describe "adding jobs" do
258
-
259
- before(:each) do
260
- @app = mock_app
261
- end
262
-
263
- it "should raise an error if the app is different" do
264
- job1 = Dragonfly::Job.new(@app)
265
- job2 = Dragonfly::Job.new(mock_app)
266
- lambda {
267
- job1 + job2
268
- }.should raise_error(Dragonfly::Job::AppDoesNotMatch)
269
- end
270
-
271
- describe "both belonging to the same app" do
272
- before(:each) do
273
- @job1 = Dragonfly::Job.new(@app, Dragonfly::TempObject.new('hello'))
274
- @job1.process! :resize
275
- @job2 = Dragonfly::Job.new(@app, Dragonfly::TempObject.new('hola'))
276
- @job2.encode! :png
277
- end
278
-
279
- it "should concatenate jobs" do
280
- job3 = @job1 + @job2
281
- job3.steps.should match_steps([
282
- Dragonfly::Job::Process,
283
- Dragonfly::Job::Encode
284
- ])
285
- end
286
-
287
- it "should raise an error if the second job has applied steps" do
288
- @job2.apply
289
- lambda {
290
- @job1 + @job2
291
- }.should raise_error(Dragonfly::Job::JobAlreadyApplied)
292
- end
293
-
294
- it "should not raise an error if the first job has applied steps" do
295
- @job1.apply
296
- lambda {
297
- @job1 + @job2
298
- }.should_not raise_error
299
- end
300
-
301
- it "should have the first job's temp_object" do
302
- (@job1 + @job2).temp_object.data.should == 'hello'
303
- end
304
-
305
- it "should have the correct applied steps" do
306
- @job1.apply
307
- (@job1 + @job2).applied_steps.should match_steps([
308
- Dragonfly::Job::Process
309
- ])
310
- end
311
-
312
- it "should have the correct pending steps" do
313
- @job1.apply
314
- (@job1 + @job2).pending_steps.should match_steps([
315
- Dragonfly::Job::Encode
316
- ])
317
- end
318
- end
319
-
320
- end
321
-
322
282
  describe "defining extra steps after applying" do
323
283
  before(:each) do
324
284
  @app = mock_app
@@ -426,6 +386,23 @@ describe Dragonfly::Job do
426
386
 
427
387
  end
428
388
 
389
+ describe "applied?" do
390
+ before(:each) do
391
+ @app = test_app
392
+ end
393
+ it "should return true when empty" do
394
+ @app.new_job.should be_applied
395
+ end
396
+ it "should return false when not applied" do
397
+ @app.fetch('eggs').should_not be_applied
398
+ end
399
+ it "should return true when applied" do
400
+ @app.datastore.should_receive(:retrieve).with('eggs').and_return("cracked")
401
+ job = @app.fetch('eggs').apply
402
+ job.should be_applied
403
+ end
404
+ end
405
+
429
406
  describe "to_a" do
430
407
  before(:each) do
431
408
  @app = mock_app
@@ -501,32 +478,6 @@ describe Dragonfly::Job do
501
478
  end
502
479
  end
503
480
 
504
- describe "from_path" do
505
- before(:each) do
506
- @app = test_app
507
- @serialized = @app.fetch('eggs').serialize
508
- end
509
- it "should work with a simple path" do
510
- Dragonfly::Job.from_path("/#{@serialized}", @app).should be_a(Dragonfly::Job)
511
- end
512
- it "should work with no slash" do
513
- Dragonfly::Job.from_path(@serialized, @app).should be_a(Dragonfly::Job)
514
- end
515
- it "should ignore the app's url_path_prefix" do
516
- @app.url_path_prefix = '/images/yo'
517
- Dragonfly::Job.from_path("/images/yo/#{@serialized}", @app).should be_a(Dragonfly::Job)
518
- end
519
- it "should not work with an incorrect url_path_prefix" do
520
- @app.url_path_prefix = '/images/yo'
521
- lambda{
522
- Dragonfly::Job.from_path("/images/#{@serialized}", @app).should be_a(Dragonfly::Job)
523
- }.should raise_error(Dragonfly::Serializer::BadString)
524
- end
525
- it "should ignore any suffix" do
526
- Dragonfly::Job.from_path("/#{@serialized}asdfJASKLDF*()!@$%{}|/GGG/.png.your.mum", @app).should be_a(Dragonfly::Job)
527
- end
528
- end
529
-
530
481
  describe "serialization" do
531
482
  before(:each) do
532
483
  @app = test_app
@@ -563,56 +514,115 @@ describe Dragonfly::Job do
563
514
 
564
515
  describe "url" do
565
516
  before(:each) do
566
- @app = mock_app(:url_for => 'hello')
517
+ @app = test_app
567
518
  @job = Dragonfly::Job.new(@app)
568
519
  end
569
- it "should return a url" do
570
- @job.generate!(:plasma)
571
- @job.url.should == 'hello'
572
- end
520
+
573
521
  it "should return nil if there are no steps" do
574
522
  @job.url.should be_nil
575
523
  end
524
+
525
+ describe "using meta in the url" do
526
+ before(:each) do
527
+ @app.server.url_format = '/media/:job/:zoo'
528
+ @job.generate!(:fish)
529
+ end
530
+ it "should act as per usual if no params given" do
531
+ @job.url.should == "/media/#{@job.serialize}"
532
+ end
533
+ it "should add given params" do
534
+ @job.url(:zoo => 'jokes', :on => 'me').should == "/media/#{@job.serialize}/jokes?on=me"
535
+ end
536
+ it "should use the meta if it exists" do
537
+ @job.meta[:zoo] = 'hair'
538
+ @job.url.should == "/media/#{@job.serialize}/hair"
539
+ end
540
+ it "should not add an meta that isn't needed" do
541
+ @job.meta[:gump] = 'flub'
542
+ @job.url.should == "/media/#{@job.serialize}"
543
+ end
544
+ it "should override if a param is passed in" do
545
+ @job.meta[:zoo] = 'hair'
546
+ @job.url(:zoo => 'dare').should == "/media/#{@job.serialize}/dare"
547
+ end
548
+
549
+ describe "basename" do
550
+ before(:each) do
551
+ @app.server.url_format = '/:job/:basename'
552
+ @job.meta = {:name => 'hello.egg', :basename => 'hi'}
553
+ end
554
+ it "should use the meta if it exists" do
555
+ @job.url.should == "/#{@job.serialize}/hi"
556
+ end
557
+ it "should use the name if basename meta doesn't exist" do
558
+ @job.meta.delete(:basename)
559
+ @job.url.should == "/#{@job.serialize}/hello"
560
+ end
561
+ it "should not set if neither exist" do
562
+ @job.meta = {}
563
+ @job.url.should == "/#{@job.serialize}"
564
+ end
565
+ end
566
+
567
+ describe "ext" do
568
+ before(:each) do
569
+ @app.server.url_format = '/:job.:ext'
570
+ @job.meta = {:name => 'hello.egg', :ext => 'hi'}
571
+ end
572
+ it "should use the meta if it exists" do
573
+ @job.url.should == "/#{@job.serialize}.hi"
574
+ end
575
+ it "should use the name if ext meta doesn't exist" do
576
+ @job.meta.delete(:ext)
577
+ @job.url.should == "/#{@job.serialize}.egg"
578
+ end
579
+ it "should not set if neither exist" do
580
+ @job.meta = {}
581
+ @job.url.should == "/#{@job.serialize}"
582
+ end
583
+ end
584
+
585
+ describe "format" do
586
+ before(:each) do
587
+ @app.server.url_format = '/:job.:format'
588
+ @job.stub!(:ext).and_return("hi")
589
+ end
590
+ it "should use the meta if it exists" do
591
+ @job.meta = {:format => :txt}
592
+ @job.url.should == "/#{@job.serialize}.txt"
593
+ end
594
+ it "should use the ext if format meta doesn't exist" do
595
+ @job.url.should == "/#{@job.serialize}.hi"
596
+ end
597
+ it "should not use the ext if format meta doesn't exist and trust_file_extensions is switched off" do
598
+ @app.trust_file_extensions = false
599
+ @job.url.should == "/#{@job.serialize}"
600
+ end
601
+ it "should not set if neither exist" do
602
+ @job.should_receive(:ext).and_return nil
603
+ @job.url.should == "/#{@job.serialize}"
604
+ end
605
+ end
606
+ end
576
607
  end
577
608
 
578
609
  describe "to_fetched_job" do
610
+ before(:each) do
611
+ @app = test_app
612
+ @job = @app.create("HELLO")
613
+ end
579
614
  it "should maintain the same temp_object and be already applied" do
580
- app = mock_app
581
- job = Dragonfly::Job.new(app, Dragonfly::TempObject.new("HELLO"))
582
- new_job = job.to_fetched_job('some_uid')
583
- new_job.temp_object.data.should == 'HELLO'
615
+ new_job = @job.to_fetched_job('some_uid')
616
+ new_job.data.should == 'HELLO'
584
617
  new_job.to_a.should == [
585
618
  [:f, 'some_uid']
586
619
  ]
587
620
  new_job.pending_steps.should be_empty
588
621
  end
589
- end
590
-
591
- describe "format" do
592
- before(:each) do
593
- @app = test_app
594
- end
595
- it "should default to nil" do
596
- job = @app.new_job("HELLO")
597
- job.format.should be_nil
598
- end
599
- it "should use the temp_object format if it exists" do
600
- job = @app.new_job("HELLO", :format => :txt)
601
- job.format.should == :txt
602
- end
603
- it "should use the analyser format if it exists" do
604
- @app.analyser.add :format do |temp_object|
605
- :egg
606
- end
607
- job = @app.new_job("HELLO")
608
- job.format.should == :egg
609
- end
610
- it "should prefer the temp_object format if both exist" do
611
- @app.analyser.add :format do |temp_object|
612
- :egg
613
- end
614
- job = @app.new_job("HELLO", :format => :txt)
615
- job.format.should == :txt
622
+ it "should maintain the meta" do
623
+ @job.meta = {:right => 'said fred'}
624
+ new_job = @job.to_fetched_job('some_uid')
625
+ new_job.meta.should == {:right => 'said fred'}
616
626
  end
617
627
  end
618
628
 
@@ -676,7 +686,7 @@ describe Dragonfly::Job do
676
686
  describe "setting the meta" do
677
687
  before(:each) do
678
688
  @app = test_app
679
- @job = @app.new_job("HiThere", :meta => {:five => 'beans'})
689
+ @job = @app.new_job("HiThere", :five => 'beans')
680
690
  end
681
691
  it "should allow setting the meta" do
682
692
  @job.meta = {:doogie => 'ladders'}
@@ -713,7 +723,7 @@ describe Dragonfly::Job do
713
723
  step.uid.should == 'hello'
714
724
  end
715
725
  end
716
- describe "fetched uid" do
726
+ describe "uid" do
717
727
  describe "when there's no fetch step" do
718
728
  before(:each) do
719
729
  @job = @app.new_job("AGG")
@@ -721,12 +731,6 @@ describe Dragonfly::Job do
721
731
  it "should return nil for uid" do
722
732
  @job.uid.should be_nil
723
733
  end
724
- it "should return nil for uid_basename" do
725
- @job.uid_basename.should be_nil
726
- end
727
- it "should return nil for uid_extname" do
728
- @job.uid_extname.should be_nil
729
- end
730
734
  end
731
735
  describe "when there is a fetch step" do
732
736
  before(:each) do
@@ -735,12 +739,6 @@ describe Dragonfly::Job do
735
739
  it "should return the uid" do
736
740
  @job.uid.should == 'gungedin/innit.blud'
737
741
  end
738
- it "should return the uid_basename" do
739
- @job.uid_basename.should == 'innit'
740
- end
741
- it "should return the uid_extname" do
742
- @job.uid_extname.should == '.blud'
743
- end
744
742
  end
745
743
  end
746
744
 
@@ -755,6 +753,17 @@ describe Dragonfly::Job do
755
753
  end
756
754
  end
757
755
 
756
+ describe "fetch_url_step" do
757
+ it "should return nil if it doesn't exist" do
758
+ @app.generate(:ponies).fetch_url_step.should be_nil
759
+ end
760
+ it "should return the fetch_url step otherwise" do
761
+ step = @app.fetch_url('egg.heads').process(:cheese).fetch_url_step
762
+ step.should be_a(Dragonfly::Job::FetchUrl)
763
+ step.url.should == 'http://egg.heads'
764
+ end
765
+ end
766
+
758
767
  describe "generate_step" do
759
768
  it "should return nil if it doesn't exist" do
760
769
  @app.fetch('many/ponies').process(:jam).generate_step.should be_nil
@@ -786,21 +795,230 @@ describe Dragonfly::Job do
786
795
  step.format.should == :cheese
787
796
  end
788
797
  end
789
- describe "encoded_format" do
790
- it "should return nil if there's no encode step" do
791
- @app.new_job('asdf').encoded_format.should be_nil
798
+
799
+ describe "step_types" do
800
+ it "should return the step types" do
801
+ job = @app.fetch('eggs').process(:beat, 'strongly').encode(:meringue)
802
+ job.step_types.should == [:fetch, :process, :encode]
803
+ end
804
+ end
805
+ end
806
+
807
+ describe "meta" do
808
+ before(:each) do
809
+ @app = test_app
810
+ @job = @app.new_job
811
+ end
812
+ it "should default meta to an empty hash" do
813
+ @job.meta.should == {}
814
+ end
815
+ it "should allow setting" do
816
+ @job.meta = {:a => :b}
817
+ @job.meta.should == {:a => :b}
818
+ end
819
+ it "should not allow setting as anything other than a hash" do
820
+ lambda{
821
+ @job.meta = 3
822
+ }.should raise_error(ArgumentError)
823
+ end
824
+ it "should allow setting on initialize" do
825
+ job = @app.new_job('asdf', :b => :c)
826
+ job.meta.should == {:b => :c}
827
+ end
828
+ it "should keep them when chained" do
829
+ @job.meta[:darn] = 'it'
830
+ @job.generate(:gollum).meta.should == {:darn => 'it'}
831
+ end
832
+ end
833
+
834
+ describe "name" do
835
+ before(:each) do
836
+ @app = test_app
837
+ end
838
+ it "should default to nil" do
839
+ job = @app.new_job('HELLO')
840
+ job.name.should be_nil
841
+ end
842
+ it "should use the meta" do
843
+ job = @app.new_job('HELLO')
844
+ job.meta[:name] = 'monkey.egg'
845
+ job.name.should == 'monkey.egg'
846
+ end
847
+ it "should allow setting" do
848
+ job = @app.new_job('HELLO')
849
+ job.name = "jonny.briggs"
850
+ job.meta[:name].should == 'jonny.briggs'
851
+ end
852
+
853
+ describe "ext" do
854
+ before(:each) do
855
+ @job = @app.new_job('asdf')
856
+ end
857
+ it "should use the correct extension from name" do
858
+ @job.name = 'hello.there.mate'
859
+ @job.ext.should == 'mate'
860
+ end
861
+ it "should be nil if name has none" do
862
+ @job.name = 'hello'
863
+ @job.ext.should be_nil
864
+ end
865
+ it "should be nil if name is nil" do
866
+ @job.name = nil
867
+ @job.ext.should be_nil
868
+ end
869
+ it "should use the meta first if set" do
870
+ @job.meta[:ext] = 'duggs'
871
+ @job.name = 'hello.there.mate'
872
+ @job.ext.should == 'duggs'
873
+ end
874
+ end
875
+
876
+ describe "basename" do
877
+ before(:each) do
878
+ @job = @app.new_job('asdf')
879
+ end
880
+ it "should use the correct basename from name" do
881
+ @job.name = 'hello.there.mate'
882
+ @job.basename.should == 'hello.there'
883
+ end
884
+ it "should be the name if it has no ext" do
885
+ @job.name = 'hello'
886
+ @job.basename.should == 'hello'
887
+ end
888
+ it "should be nil if name is nil" do
889
+ @job.name = nil
890
+ @job.basename.should be_nil
891
+ end
892
+ it "should use the meta first if set" do
893
+ @job.meta[:basename] = 'duggs'
894
+ @job.name = 'hello.there.mate'
895
+ @job.basename.should == 'duggs'
896
+ end
897
+ end
898
+
899
+ describe "format" do
900
+ before(:each) do
901
+ @app = test_app
902
+ end
903
+ it "should default to nil" do
904
+ job = @app.new_job("HELLO")
905
+ job.format.should be_nil
906
+ end
907
+ it "should use the meta format if it exists" do
908
+ job = @app.new_job("HELLO")
909
+ job.meta[:format] = :txt
910
+ job.format.should == :txt
911
+ end
912
+ it "should use the analyser format if it exists" do
913
+ @app.analyser.add :format do |temp_object|
914
+ :egg
915
+ end
916
+ job = @app.new_job("HELLO")
917
+ job.format.should == :egg
918
+ end
919
+ it "should use the file extension if it has no format" do
920
+ @job = @app.new_job("HIMATE", :name => 'test.pdf')
921
+ @job.format.should == :pdf
792
922
  end
793
- it "should return the last encoded format if it exists" do
794
- @app.fetch('gungedin').encode(:a).encode(:b).encoded_format.should == :b
923
+ it "should not use the file extension if it's been switched off" do
924
+ @app.trust_file_extensions = false
925
+ @job = @app.new_job("HIMATE", :name => 'test.pdf')
926
+ @job.format.should be_nil
927
+ end
928
+ it "should prefer the set format over the file extension" do
929
+ job = @app.new_job("HELLO", :name => 'test.pdf', :format => :txt)
930
+ job.format.should == :txt
931
+ end
932
+ it "should prefer the file extension over the analysed format" do
933
+ @app.analyser.add :format do |temp_object|
934
+ :egg
935
+ end
936
+ job = @app.new_job("HELLO", :name => 'test.pdf')
937
+ job.format.should == :pdf
938
+ end
939
+ it "should apply the job" do
940
+ @app.generator.add(:test){ ["skid marks", {:name => 'terry.burton'}] }
941
+ job = @app.generate(:test)
942
+ job.format.should == :burton
943
+ job.should be_applied
795
944
  end
796
945
  end
797
- describe "encoded_extname" do
798
- it "should return nil if there's no encode step" do
799
- @app.new_job('asdf').encoded_extname.should be_nil
946
+
947
+ describe "mime_type" do
948
+ before(:each) do
949
+ @app = test_app
800
950
  end
801
- it "should return the last encoded format as an extname if it exists" do
802
- @app.fetch('gungedin').encode(:a).encode(:b).encoded_extname.should == '.b'
951
+ it "should return the correct mime_type if the format is given" do
952
+ @job = @app.new_job("HIMATE")
953
+ @job.should_receive(:format).and_return(:tiff)
954
+ @job.mime_type.should == 'image/tiff'
803
955
  end
956
+ it "should fall back to the mime_type analyser if the format is nil" do
957
+ @app.analyser.add :mime_type do |temp_object|
958
+ 'image/jpeg'
959
+ end
960
+ @job = @app.new_job("HIMATE")
961
+ @job.mime_type.should == 'image/jpeg'
962
+ end
963
+ it "should fall back to the fallback mime_type if neither format or analyser exist" do
964
+ @app.new_job("HIMATE").mime_type.should == 'application/octet-stream'
965
+ end
966
+ end
967
+
968
+ end
969
+
970
+ describe "store" do
971
+ before(:each) do
972
+ @app = test_app
973
+ @app.generator.add(:test){ ["Toes", {:name => 'doogie.txt'}] }
974
+ @job = @app.generate(:test)
975
+ end
976
+ it "should store its data along with the meta" do
977
+ @job.meta[:eggs] = 'doolally'
978
+ @app.datastore.should_receive(:store).with(a_temp_object_with_data("Toes"), :meta => {:name => 'doogie.txt', :eggs => 'doolally'})
979
+ @job.store
980
+ end
981
+ it "should add extra opts" do
982
+ @app.datastore.should_receive(:store).with(a_temp_object_with_data("Toes"), :meta => {:name => 'doogie.txt'}, :path => 'blah')
983
+ @job.store(:path => 'blah')
984
+ end
985
+ end
986
+
987
+ describe "dealing with original_filename" do
988
+ before(:each) do
989
+ @string = "terry"
990
+ @string.stub!(:original_filename).and_return("gum.tree")
991
+ @app = test_app
992
+ @app.generator.add(:test){ @string }
993
+ end
994
+ it "should set it as the name" do
995
+ @app.create(@string).name.should == 'gum.tree'
996
+ end
997
+ it "should prefer the initialized name over the original_filename" do
998
+ @app.create(@string, :name => 'doo.berry').name.should == 'doo.berry'
999
+ end
1000
+ it "should work with e.g. generators" do
1001
+ @app.generate(:test).apply.name.should == 'gum.tree'
1002
+ end
1003
+ it "should favour an e.g. generator returned name" do
1004
+ @app.generator.add(:test2){ [@string, {:name => 'gen.ome'}] }
1005
+ @app.generate(:test2).apply.name.should == 'gen.ome'
1006
+ end
1007
+ it "should not overwrite a set name" do
1008
+ job = @app.generate(:test)
1009
+ job.name = 'egg.mumma'
1010
+ job.apply.name.should == 'egg.mumma'
1011
+ end
1012
+ end
1013
+
1014
+ describe "deprecated meta format" do
1015
+ before(:each) do
1016
+ @app = test_app
1017
+ end
1018
+ it "should still work if the datastore/whatever returns meta nested in :meta key" do
1019
+ @app.datastore.should_receive(:retrieve).with('some_uid').and_return(['HELLO', {:name => 'test.txt', :meta => {:some => 'meta'}}])
1020
+ job = @app.fetch('some_uid').apply
1021
+ job.meta.should == {:name => 'test.txt', :some => 'meta'}
804
1022
  end
805
1023
  end
806
1024