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,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  class Testoast
4
4
  include Dragonfly::Loggable
@@ -10,7 +10,7 @@ describe Dragonfly::Loggable do
10
10
  @object = Testoast.new
11
11
  end
12
12
 
13
- describe "common", :shared => true do
13
+ shared_examples_for "common" do
14
14
  it "should return a log" do
15
15
  @object.log.should be_a(Logger)
16
16
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
  require 'rack'
3
3
 
4
4
  def dummy_rack_app
@@ -13,27 +13,21 @@ describe Dragonfly::Middleware do
13
13
 
14
14
  before(:each) do
15
15
  @stack = Rack::Builder.new do
16
- use Dragonfly::Middleware, :images, '/media'
16
+ use Dragonfly::Middleware, :images
17
17
  run dummy_rack_app
18
18
  end
19
19
  end
20
20
 
21
- it "should pass through for urls with incorrect prefix" do
22
- Dragonfly[:images].should_not_receive(:call)
23
- response = make_request(@stack, '/hello.png?howare=you')
24
- response.status.should == 200
25
- response.body.should == 'dummy_rack_app body'
26
- end
27
-
28
- it "should pass through if the app returns and X-Cascade: pass" do
21
+ it "should pass through if the app returns X-Cascade: pass" do
29
22
  Dragonfly[:images].should_receive(:call).and_return(
30
23
  [404, {"Content-Type" => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
31
24
  )
32
25
  response = make_request(@stack, '/media/hello.png?howare=you')
33
26
  response.body.should == 'dummy_rack_app body'
27
+ response.status.should == 200
34
28
  end
35
29
 
36
- it "should return a 404 if the app returns a 404 for that url but no X-Cascade: pass" do
30
+ it "should return a 404 if the app returns a 404" do
37
31
  Dragonfly[:images].should_receive(:call).and_return(
38
32
  [404, {"Content-Type" => 'text/plain'}, ['Not found']]
39
33
  )
@@ -41,21 +35,6 @@ describe Dragonfly::Middleware do
41
35
  response.status.should == 404
42
36
  end
43
37
 
44
- %w(0.1 0.9 0.10 1.0 1.0.0 1.0.1).each do |version|
45
- it "should pass through if the rack version is #{version} (i.e. no X-Cascade: pass) and the app returns 404" do
46
- Rack.should_receive(:version).and_return(version)
47
- Dragonfly[:images].should_receive(:call).and_return(
48
- [404, {"Content-Type" => 'text/plain'}, ['Not found']]
49
- )
50
- response = make_request(@stack, '/media/hello.png?howare=you')
51
- response.status.should == 200
52
- response.body.should == 'dummy_rack_app body'
53
- end
54
- end
55
-
56
- %w(1.1 1.1.1 2.9).each do |version|
57
- end
58
-
59
38
  it "should return as per the dragonfly app if the app returns a 200" do
60
39
  Dragonfly[:images].should_receive(:call).and_return(
61
40
  [200, {"Content-Type" => 'text/plain'}, ['ABCD']]
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  def response_for(array)
4
4
  Rack::MockResponse.new(*array)
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'spec_helper'
3
3
 
4
4
  describe Dragonfly::Serializer do
5
5
 
@@ -56,19 +56,6 @@ describe Dragonfly::Serializer do
56
56
  marshal_decode('ahasdkjfhasdkfjh')
57
57
  }.should raise_error(Dragonfly::Serializer::BadString)
58
58
  end
59
- describe "potentially harmful strings" do
60
- ['_', 'hello', 'h2', '__send__', 'F'].each do |variable_name|
61
- it "should raise an error if the string passed in is potentially harmful (e.g. contains instance variable #{variable_name})" do
62
- class C; end
63
- c = C.new
64
- c.instance_eval{ instance_variable_set("@#{variable_name}", 1) }
65
- string = Dragonfly::Serializer.b64_encode(Marshal.dump(c))
66
- lambda{
67
- marshal_decode(string)
68
- }.should raise_error(Dragonfly::Serializer::MaliciousString)
69
- end
70
- end
71
- end
72
59
  end
73
60
 
74
61
  end
@@ -0,0 +1,261 @@
1
+ require 'spec_helper'
2
+ require 'rack/mock'
3
+ require 'rack/cache'
4
+
5
+ def request(app, path)
6
+ Rack::MockRequest.new(app).get(path)
7
+ end
8
+
9
+ describe Dragonfly::Server do
10
+
11
+ describe "responses" do
12
+
13
+ before(:each) do
14
+ @app = test_app
15
+ @uid = @app.store('HELLO THERE')
16
+ @server = Dragonfly::Server.new(@app)
17
+ @server.url_format = '/media/:job'
18
+ @job = @app.fetch(@uid)
19
+ end
20
+
21
+ after(:each) do
22
+ @app.destroy(@uid)
23
+ end
24
+
25
+ describe "successful urls" do
26
+ before(:each) do
27
+ @server.url_format = '/media/:job/:name.:format'
28
+ end
29
+
30
+ [
31
+ '',
32
+ '/name',
33
+ '/name.ext'
34
+ ].each do |suffix|
35
+
36
+ it "should return successfully when given the url with suffix #{suffix.inspect}" do
37
+ url = "/media/#{@job.serialize}#{suffix}"
38
+ response = request(@server, url)
39
+ response.status.should == 200
40
+ response.body.should == 'HELLO THERE'
41
+ response.content_type.should == 'application/octet-stream'
42
+ end
43
+
44
+ end
45
+
46
+ it "should return successfully with the correct sha given and protection on" do
47
+ @server.protect_from_dos_attacks = true
48
+ url = "/media/#{@job.serialize}?sha=#{@job.sha}"
49
+ response = request(@server, url)
50
+ response.status.should == 200
51
+ response.body.should == 'HELLO THERE'
52
+ end
53
+
54
+
55
+ it "should work ok with + symbols" do
56
+ @app.processor.add(:thumb){|t, geometry| "eggs" }
57
+ @app.datastore.should_receive(:retrieve).with('2011/04/20/20_55_04_114_female_1.jpg').and_return "EGGS"
58
+ response = request(@server, '/media/BAhbB1sHOgZmSSIpMjAxMS8wNC8yMC8yMF81NV8wNF8xMTRfZmVtYWxlXzEuanBnBjoGRVRbCDoGcDoKdGh1bWJJIgwxMDB4NzU+BjsGVA')
59
+ response.status.should == 200
60
+ response.body.should == 'eggs'
61
+ end
62
+ end
63
+
64
+ it "should return successfully even if the job is in the query string" do
65
+ @server.url_format = '/'
66
+ url = "/?job=#{@job.serialize}"
67
+ response = request(@server, url)
68
+ response.status.should == 200
69
+ response.body.should == 'HELLO THERE'
70
+ end
71
+
72
+ it "should return a 400 if no sha given but protection on" do
73
+ @server.protect_from_dos_attacks = true
74
+ url = "/media/#{@job.serialize}"
75
+ response = request(@server, url)
76
+ response.status.should == 400
77
+ end
78
+
79
+ it "should return a 400 if wrong sha given and protection on" do
80
+ @server.protect_from_dos_attacks = true
81
+ url = "/media/#{@job.serialize}?sha=asdfs"
82
+ response = request(@server, url)
83
+ response.status.should == 400
84
+ end
85
+
86
+ ['/media', '/media/'].each do |url|
87
+ it "should return a 404 when no job given, e.g. #{url.inspect}" do
88
+ response = request(@server, url)
89
+ response.status.should == 404
90
+ response.body.should == 'Not found'
91
+ response.content_type.should == 'text/plain'
92
+ response.headers['X-Cascade'].should == 'pass'
93
+ end
94
+ end
95
+
96
+ it "should return a 404 when the url matches but doesn't correspond to a job" do
97
+ response = request(@server, '/media/sadhfasdfdsfsdf')
98
+ response.status.should == 404
99
+ response.body.should == 'Not found'
100
+ response.content_type.should == 'text/plain'
101
+ response.headers['X-Cascade'].should be_nil
102
+ end
103
+
104
+ it "should return a 404 when the url isn't known at all" do
105
+ response = request(@server, '/jfasd/dsfa')
106
+ response.status.should == 404
107
+ response.body.should == 'Not found'
108
+ response.content_type.should == 'text/plain'
109
+ response.headers['X-Cascade'].should == 'pass'
110
+ end
111
+
112
+ it "should return a 404 when the url is a well-encoded but bad array" do
113
+ url = "/media/#{Dragonfly::Serializer.marshal_encode([[:egg, {:some => 'args'}]])}"
114
+ response = request(@server, url)
115
+ response.status.should == 404
116
+ response.body.should == 'Not found'
117
+ response.content_type.should == 'text/plain'
118
+ response.headers['X-Cascade'].should be_nil
119
+ end
120
+
121
+ it "should return a cacheable response" do
122
+ url = "/media/#{@job.serialize}"
123
+ cache = Rack::Cache.new(@server, :entitystore => 'heap:/')
124
+ response = request(cache, url)
125
+ response.status.should == 200
126
+ response.headers['X-Rack-Cache'].should == "miss, store"
127
+ response = request(cache, url)
128
+ response.status.should == 200
129
+ response.headers['X-Rack-Cache'].should == "fresh"
130
+ end
131
+
132
+ end
133
+
134
+ describe "dragonfly response" do
135
+ before(:each) do
136
+ @app = test_app
137
+ @server = Dragonfly::Server.new(@app)
138
+ @server.url_format = '/media/:job'
139
+ end
140
+
141
+ it "should return a simple text response" do
142
+ request(@server, '/dragonfly').should be_a_text_response
143
+ end
144
+
145
+ it "should be configurable" do
146
+ @server.dragonfly_url = '/hello'
147
+ request(@server, '/hello').should be_a_text_response
148
+ request(@server, '/dragonfly').status.should == 404
149
+ end
150
+
151
+ it "should be possible to turn it off" do
152
+ @server.dragonfly_url = nil
153
+ request(@server, '/').status.should == 404
154
+ request(@server, '/dragonfly').status.should == 404
155
+ end
156
+ end
157
+
158
+ describe "urls" do
159
+
160
+ before(:each) do
161
+ @app = test_app
162
+ @server = Dragonfly::Server.new(@app)
163
+ @server.url_format = '/media/:job/:basename.:format'
164
+ @job = @app.fetch('some_uid')
165
+ end
166
+
167
+ it "should generate the correct url when no basename/format" do
168
+ @server.url_for(@job).should == "/media/#{@job.serialize}"
169
+ end
170
+
171
+ it "should generate the correct url when there is a basename and no format" do
172
+ @server.url_for(@job, :basename => 'hello').should == "/media/#{@job.serialize}/hello"
173
+ end
174
+
175
+ it "should generate the correct url when there is a basename and different format" do
176
+ @server.url_for(@job, :basename => 'hello', :format => 'gif').should == "/media/#{@job.serialize}/hello.gif"
177
+ end
178
+
179
+ it "should add extra params to the url query string" do
180
+ @server.url_for(@job, :a => 'thing', :b => 'nuther').should == "/media/#{@job.serialize}?a=thing&b=nuther"
181
+ end
182
+
183
+ it "should add the host to the url if configured" do
184
+ @server.url_host = 'http://some.server:4000'
185
+ @server.url_for(@job).should == "http://some.server:4000/media/#{@job.serialize}"
186
+ end
187
+
188
+ it "should add the host to the url if passed in" do
189
+ @server.url_for(@job, :host => 'https://bungle.com').should == "https://bungle.com/media/#{@job.serialize}"
190
+ end
191
+
192
+ it "should favour the passed in host" do
193
+ @server.url_host = 'http://some.server:4000'
194
+ @server.url_for(@job, :host => 'https://smeedy').should == "https://smeedy/media/#{@job.serialize}"
195
+ end
196
+
197
+ describe "Denial of Service protection" do
198
+ before(:each) do
199
+ @app = test_app
200
+ @server = Dragonfly::Server.new(@app)
201
+ @server.protect_from_dos_attacks = true
202
+ @job = @app.fetch('some_uid')
203
+ end
204
+ it "should generate the correct url" do
205
+ @server.url_for(@job).should == "/#{@job.serialize}?sha=#{@job.sha}"
206
+ end
207
+ end
208
+
209
+ end
210
+
211
+ describe "before_serve callback" do
212
+
213
+ before(:each) do
214
+ @app = test_app
215
+ @app.generator.add(:test){ "TEST" }
216
+ @server = Dragonfly::Server.new(@app)
217
+ @job = @app.generate(:test)
218
+ end
219
+
220
+ context "with no stop in the callback" do
221
+ before(:each) do
222
+ @x = x = ""
223
+ @server.before_serve do |job, env|
224
+ x << job.data
225
+ end
226
+ end
227
+
228
+ it "should be called before serving" do
229
+ response = request(@server, "/#{@job.serialize}")
230
+ response.body.should == 'TEST'
231
+ @x.should == 'TEST'
232
+ end
233
+
234
+ it "should not be called before serving a 404 page" do
235
+ response = request(@server, "blah")
236
+ response.status.should == 404
237
+ @x.should == ""
238
+ end
239
+ end
240
+
241
+ context "with a throw :halt in the callback" do
242
+ before(:each) do
243
+ @server.before_serve do |job, env|
244
+ throw :halt, [200, {}, ['hello']]
245
+ end
246
+ end
247
+
248
+ it 'return the specified response instead of job.result' do
249
+ response = request(@server, "/#{@job.serialize}")
250
+ response.body.should == 'hello'
251
+ end
252
+
253
+ it "should not apply the job if not asked to" do
254
+ @app.generator.should_not_receive(:generate)
255
+ response = request(@server, "/#{@job.serialize}")
256
+ end
257
+ end
258
+
259
+ end
260
+
261
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Dragonfly::SimpleCache do
4
4
 
@@ -1,11 +1,11 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Dragonfly::TempObject do
4
4
 
5
5
  ####### Helper Methods #######
6
6
 
7
7
  def sample_path(filename)
8
- File.dirname(__FILE__) + '/../../samples/' + filename
8
+ File.join(SAMPLES_DIR, filename)
9
9
  end
10
10
 
11
11
  def new_tempfile(data='HELLO')
@@ -15,16 +15,22 @@ describe Dragonfly::TempObject do
15
15
  tempfile
16
16
  end
17
17
 
18
- def new_file(data='HELLO')
19
- File.open('/tmp/test_file', 'w') do |f|
18
+ def new_file(data='HELLO', path="/tmp/test_file")
19
+ File.open(path, 'w') do |f|
20
20
  f.write(data)
21
21
  end
22
- File.new('/tmp/test_file')
22
+ File.new(path)
23
23
  end
24
24
 
25
- def new_temp_object(data, opts={})
26
- klass = opts.delete(:class) || Dragonfly::TempObject
27
- klass.new(initialization_object(data), opts)
25
+ def new_pathname(data='HELLO', path="/tmp/test_file")
26
+ File.open(path, 'w') do |f|
27
+ f.write(data)
28
+ end
29
+ Pathname.new(path)
30
+ end
31
+
32
+ def new_temp_object(data, klass=Dragonfly::TempObject)
33
+ klass.new(initialization_object(data))
28
34
  end
29
35
 
30
36
  def initialization_object(data)
@@ -48,7 +54,7 @@ describe Dragonfly::TempObject do
48
54
  }.should raise_error(ArgumentError)
49
55
  end
50
56
 
51
- describe "common behaviour", :shared => true do
57
+ shared_examples_for "common behaviour" do
52
58
 
53
59
  describe "simple initialization" do
54
60
 
@@ -97,8 +103,8 @@ describe Dragonfly::TempObject do
97
103
  end
98
104
 
99
105
  describe "path" do
100
- it "should return the absolute file path" do
101
- @temp_object.path.should == @temp_object.tempfile.path
106
+ it "should return an absolute file path" do
107
+ @temp_object.path.should =~ %r{^/\w+}
102
108
  end
103
109
  end
104
110
 
@@ -133,26 +139,6 @@ describe Dragonfly::TempObject do
133
139
 
134
140
  end
135
141
 
136
- describe "initializing attributes too" do
137
- it "should set the name" do
138
- temp_object = Dragonfly::TempObject.new(initialization_object('HELLO'), :name => 'monkey.egg')
139
- temp_object.name.should == 'monkey.egg'
140
- end
141
- it "should set the meta" do
142
- temp_object = Dragonfly::TempObject.new(initialization_object('HELLO'), :meta => {:dr => 'doolittle'})
143
- temp_object.meta.should == {:dr => 'doolittle'}
144
- end
145
- it "should set the format" do
146
- temp_object = Dragonfly::TempObject.new(initialization_object('HELLO'), :format => :jpg)
147
- temp_object.format.should == :jpg
148
- end
149
- it "should raise an error if an invalid option is given" do
150
- lambda {
151
- Dragonfly::TempObject.new(initialization_object('HELLO'), :doobie => 'doo')
152
- }.should raise_error(ArgumentError)
153
- end
154
- end
155
-
156
142
  describe "each" do
157
143
  it "should yield 8192 bytes each time" do
158
144
  temp_object = new_temp_object(File.read(sample_path('round.gif')))
@@ -164,7 +150,7 @@ describe Dragonfly::TempObject do
164
150
  end
165
151
  it "should yield the number of bytes specified in the class configuration" do
166
152
  klass = Class.new(Dragonfly::TempObject)
167
- temp_object = new_temp_object(File.read(sample_path('round.gif')), :class => klass)
153
+ temp_object = new_temp_object(File.read(sample_path('round.gif')), klass)
168
154
  klass.block_size = 3001
169
155
  parts = get_parts(temp_object)
170
156
  parts[0...-1].each do |part|
@@ -204,6 +190,11 @@ describe Dragonfly::TempObject do
204
190
  temp_object.should_not_receive(:data)
205
191
  temp_object.each{}
206
192
  end
193
+
194
+ it "should return the tempfile's path" do
195
+ temp_object = new_temp_object('HELLO')
196
+ temp_object.path.should == temp_object.tempfile.path
197
+ end
207
198
  end
208
199
 
209
200
  describe "initializing from a file" do
@@ -219,133 +210,96 @@ describe Dragonfly::TempObject do
219
210
  temp_object.should_not_receive(:data)
220
211
  temp_object.each{}
221
212
  end
213
+
214
+ it "should return the file's path" do
215
+ file = new_file('HELLO')
216
+ temp_object = Dragonfly::TempObject.new(file)
217
+ temp_object.path.should == file.path
218
+ end
219
+
220
+ it "should return an absolute path even if the file wasn't instantiated like that" do
221
+ file = new_file('HELLO', 'testfile')
222
+ temp_object = Dragonfly::TempObject.new(file)
223
+ temp_object.path.should =~ %r{^/\w.*testfile}
224
+ file.close
225
+ FileUtils.rm(file.path)
226
+ end
227
+ end
228
+
229
+ describe "initializing from a pathname" do
230
+
231
+ def initialization_object(data)
232
+ new_pathname(data)
233
+ end
234
+
235
+ it_should_behave_like "common behaviour"
236
+
237
+ it "should not create a data string when calling each" do
238
+ temp_object = new_temp_object('HELLO')
239
+ temp_object.should_not_receive(:data)
240
+ temp_object.each{}
241
+ end
242
+
243
+ it "should return the file's path" do
244
+ pathname = new_pathname('HELLO')
245
+ temp_object = Dragonfly::TempObject.new(pathname)
246
+ temp_object.path.should == pathname.to_s
247
+ end
248
+
249
+ it "should return an absolute path even if the pathname is relative" do
250
+ pathname = new_pathname('HELLO', 'testfile')
251
+ temp_object = Dragonfly::TempObject.new(pathname)
252
+ temp_object.path.should =~ %r{^/\w.*testfile}
253
+ pathname.delete
254
+ end
222
255
  end
223
256
 
224
257
  describe "initializing from another temp object" do
258
+
259
+ def initialization_object(data)
260
+ Dragonfly::TempObject.new(data)
261
+ end
262
+
225
263
  before(:each) do
226
264
  @temp_object1 = Dragonfly::TempObject.new(new_tempfile('hello'))
227
265
  @temp_object2 = Dragonfly::TempObject.new(@temp_object1)
228
266
  end
267
+
268
+ it_should_behave_like "common behaviour"
269
+
229
270
  it "should not be the same object" do
230
271
  @temp_object1.should_not == @temp_object2
231
272
  end
232
273
  it "should have the same data" do
233
274
  @temp_object1.data.should == @temp_object2.data
234
275
  end
235
- it "should have a different file path" do
236
- @temp_object1.path.should_not == @temp_object2.path
276
+ it "should have the same file path" do
277
+ @temp_object1.path.should == @temp_object2.path
237
278
  end
238
279
  end
239
280
 
240
- describe "name" do
281
+ describe "original_filename" do
241
282
  before(:each) do
242
283
  @obj = new_tempfile
243
284
  end
244
- it "should set the name if the initial object responds to 'original filename'" do
285
+ it "should set the original_filename if the initial object responds to 'original filename'" do
245
286
  def @obj.original_filename
246
287
  'jimmy.page'
247
288
  end
248
- Dragonfly::TempObject.new(@obj).name.should == 'jimmy.page'
289
+ Dragonfly::TempObject.new(@obj).original_filename.should == 'jimmy.page'
249
290
  end
250
291
  it "should not set the name if the initial object doesn't respond to 'original filename'" do
251
- Dragonfly::TempObject.new(@obj).name.should be_nil
292
+ Dragonfly::TempObject.new(@obj).original_filename.should be_nil
252
293
  end
253
294
  it "should set the name if the initial object is a file object" do
254
295
  file = File.new(SAMPLES_DIR + '/round.gif')
255
296
  temp_object = Dragonfly::TempObject.new(file)
256
- temp_object.name.should == 'round.gif'
257
- end
258
- it "should still be nil if set to empty string on initialize" do
259
- temp_object = Dragonfly::TempObject.new('sdf', :name => '')
260
- temp_object.name.should be_nil
261
- end
262
- it "should allow setting" do
263
- temp_object = Dragonfly::TempObject.new('sdf')
264
- temp_object.name = "jonny.briggs"
265
- temp_object.name.should == 'jonny.briggs'
266
- end
267
- end
268
-
269
- describe "ext" do
270
- it "should use the correct extension from name" do
271
- temp_object = Dragonfly::TempObject.new('asfsadf', :name => 'hello.there.mate')
272
- temp_object.ext.should == 'mate'
273
- end
274
- it "should be nil if name has none" do
275
- temp_object = Dragonfly::TempObject.new('asfsadf', :name => 'hello')
276
- temp_object.ext.should be_nil
277
- end
278
- it "should be nil if name is nil" do
279
- temp_object = Dragonfly::TempObject.new('asfsadf')
280
- temp_object.ext.should be_nil
281
- end
282
- end
283
-
284
- describe "basename" do
285
- it "should use the correct basename from name" do
286
- temp_object = Dragonfly::TempObject.new('A', :name => 'hello.there.mate')
287
- temp_object.basename.should == 'hello.there'
288
- end
289
- it "should be the name if it has no ext" do
290
- temp_object = Dragonfly::TempObject.new('A', :name => 'hello')
291
- temp_object.basename.should == 'hello'
292
- end
293
- it "should be nil if name is nil" do
294
- temp_object = Dragonfly::TempObject.new('A', :name => nil)
295
- temp_object.basename.should be_nil
296
- end
297
- end
298
-
299
- describe "meta" do
300
- before(:each) do
301
- @temp_object = Dragonfly::TempObject.new('get outta here!')
302
- end
303
- it "should return an empty hash if not set" do
304
- @temp_object.meta.should == {}
305
- end
306
- it "should allow setting" do
307
- @temp_object.meta = {:teeth => 'many'}
308
- @temp_object.meta.should == {:teeth => 'many'}
309
- end
310
- end
311
-
312
- describe "format" do
313
- it "should return nil if not set" do
314
- temp_object = Dragonfly::TempObject.new('wassin my belly??!')
315
- temp_object.format.should be_nil
316
- end
317
- it "should allow setting on initialize" do
318
- temp_object = Dragonfly::TempObject.new('wassin my belly??!', :format => :jpg)
319
- temp_object.format.should == :jpg
320
- end
321
- it "should allow setting" do
322
- temp_object = Dragonfly::TempObject.new('jo*ida pero contenta')
323
- temp_object.format = :tiff
324
- temp_object.format.should == :tiff
325
- end
326
- end
327
-
328
- describe "extract_attributes_from" do
329
- before(:each) do
330
- @temp_object = Dragonfly::TempObject.new("ne'er gonna give you up",
331
- :meta => {:a => 4},
332
- :name => 'fred.txt',
333
- :format => :txt
334
- )
335
- @attributes = {:meta => {:b => 5}, :ogle => 'bogle', :format => :dungbats}
336
- @temp_object.extract_attributes_from(@attributes)
337
- end
338
- it "should overwrite its own attributes if specified" do
339
- @temp_object.format.should == :dungbats
340
- end
341
- it "should merge its own meta if specified" do
342
- @temp_object.meta.should == {:a => 4, :b => 5}
343
- end
344
- it "should leave non-specified attributes untouched" do
345
- @temp_object.name.should == 'fred.txt'
297
+ temp_object.original_filename.should == 'round.gif'
346
298
  end
347
- it "should remove attributes from the hash" do
348
- @attributes.should == {:ogle => 'bogle'}
299
+ it "should set the name if the initial object is a pathname" do
300
+ pathname = Pathname.new(SAMPLES_DIR + '/round.gif')
301
+ temp_object = Dragonfly::TempObject.new(pathname)
302
+ temp_object.original_filename.should == 'round.gif'
349
303
  end
350
304
  end
351
305