fog-dragonfly 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. data/.specopts +2 -0
  2. data/.yardopts +23 -0
  3. data/Gemfile +23 -0
  4. data/Gemfile.rails.2.3.5 +14 -0
  5. data/History.md +266 -0
  6. data/LICENSE +20 -0
  7. data/README.md +88 -0
  8. data/Rakefile +92 -0
  9. data/VERSION +1 -0
  10. data/config.ru +13 -0
  11. data/docs.watchr +1 -0
  12. data/dragonfly.gemspec +293 -0
  13. data/extra_docs/Analysers.md +108 -0
  14. data/extra_docs/Caching.md +23 -0
  15. data/extra_docs/Configuration.md +138 -0
  16. data/extra_docs/DataStorage.md +136 -0
  17. data/extra_docs/Encoding.md +96 -0
  18. data/extra_docs/GeneralUsage.md +121 -0
  19. data/extra_docs/Generators.md +102 -0
  20. data/extra_docs/Heroku.md +50 -0
  21. data/extra_docs/Index.md +36 -0
  22. data/extra_docs/MimeTypes.md +40 -0
  23. data/extra_docs/Models.md +266 -0
  24. data/extra_docs/Mongo.md +45 -0
  25. data/extra_docs/Processing.md +130 -0
  26. data/extra_docs/Rack.md +52 -0
  27. data/extra_docs/Rails2.md +55 -0
  28. data/extra_docs/Rails3.md +62 -0
  29. data/extra_docs/Sinatra.md +25 -0
  30. data/extra_docs/URLs.md +169 -0
  31. data/features/3.0.3.feature +8 -0
  32. data/features/images.feature +47 -0
  33. data/features/no_processing.feature +14 -0
  34. data/features/rails_2.3.5.feature +7 -0
  35. data/features/steps/common_steps.rb +8 -0
  36. data/features/steps/dragonfly_steps.rb +66 -0
  37. data/features/steps/rails_steps.rb +39 -0
  38. data/features/support/env.rb +40 -0
  39. data/fixtures/files/app/models/album.rb +3 -0
  40. data/fixtures/files/app/views/albums/new.html.erb +4 -0
  41. data/fixtures/files/app/views/albums/show.html.erb +4 -0
  42. data/fixtures/files/config/initializers/dragonfly.rb +4 -0
  43. data/fixtures/files/features/manage_album_images.feature +12 -0
  44. data/fixtures/files/features/step_definitions/image_steps.rb +15 -0
  45. data/fixtures/files/features/support/paths.rb +15 -0
  46. data/fixtures/files/features/text_images.feature +7 -0
  47. data/fixtures/rails_2.3.5/template.rb +10 -0
  48. data/fixtures/rails_3.0.3/template.rb +20 -0
  49. data/irbrc.rb +17 -0
  50. data/lib/dragonfly.rb +45 -0
  51. data/lib/dragonfly/active_model_extensions.rb +13 -0
  52. data/lib/dragonfly/active_model_extensions/attachment.rb +169 -0
  53. data/lib/dragonfly/active_model_extensions/class_methods.rb +45 -0
  54. data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
  55. data/lib/dragonfly/active_model_extensions/validations.rb +37 -0
  56. data/lib/dragonfly/analyser.rb +59 -0
  57. data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
  58. data/lib/dragonfly/analysis/image_magick_analyser.rb +47 -0
  59. data/lib/dragonfly/analysis/r_magick_analyser.rb +63 -0
  60. data/lib/dragonfly/app.rb +182 -0
  61. data/lib/dragonfly/config/heroku.rb +19 -0
  62. data/lib/dragonfly/config/image_magick.rb +41 -0
  63. data/lib/dragonfly/config/r_magick.rb +46 -0
  64. data/lib/dragonfly/config/rails.rb +17 -0
  65. data/lib/dragonfly/configurable.rb +119 -0
  66. data/lib/dragonfly/core_ext/object.rb +8 -0
  67. data/lib/dragonfly/core_ext/string.rb +9 -0
  68. data/lib/dragonfly/core_ext/symbol.rb +9 -0
  69. data/lib/dragonfly/data_storage.rb +9 -0
  70. data/lib/dragonfly/data_storage/file_data_store.rb +114 -0
  71. data/lib/dragonfly/data_storage/mongo_data_store.rb +82 -0
  72. data/lib/dragonfly/data_storage/s3data_store.rb +115 -0
  73. data/lib/dragonfly/encoder.rb +13 -0
  74. data/lib/dragonfly/encoding/image_magick_encoder.rb +57 -0
  75. data/lib/dragonfly/encoding/r_magick_encoder.rb +61 -0
  76. data/lib/dragonfly/function_manager.rb +69 -0
  77. data/lib/dragonfly/generation/hash_with_css_style_keys.rb +23 -0
  78. data/lib/dragonfly/generation/image_magick_generator.rb +140 -0
  79. data/lib/dragonfly/generation/r_magick_generator.rb +155 -0
  80. data/lib/dragonfly/generator.rb +9 -0
  81. data/lib/dragonfly/image_magick_utils.rb +81 -0
  82. data/lib/dragonfly/job.rb +371 -0
  83. data/lib/dragonfly/job_builder.rb +39 -0
  84. data/lib/dragonfly/job_definitions.rb +26 -0
  85. data/lib/dragonfly/job_endpoint.rb +15 -0
  86. data/lib/dragonfly/loggable.rb +28 -0
  87. data/lib/dragonfly/middleware.rb +34 -0
  88. data/lib/dragonfly/processing/image_magick_processor.rb +99 -0
  89. data/lib/dragonfly/processing/r_magick_processor.rb +126 -0
  90. data/lib/dragonfly/processor.rb +9 -0
  91. data/lib/dragonfly/r_magick_utils.rb +48 -0
  92. data/lib/dragonfly/rails/images.rb +22 -0
  93. data/lib/dragonfly/response.rb +82 -0
  94. data/lib/dragonfly/routed_endpoint.rb +40 -0
  95. data/lib/dragonfly/serializer.rb +32 -0
  96. data/lib/dragonfly/simple_cache.rb +23 -0
  97. data/lib/dragonfly/simple_endpoint.rb +63 -0
  98. data/lib/dragonfly/temp_object.rb +220 -0
  99. data/samples/beach.png +0 -0
  100. data/samples/egg.png +0 -0
  101. data/samples/round.gif +0 -0
  102. data/samples/sample.docx +0 -0
  103. data/samples/taj.jpg +0 -0
  104. data/spec/argument_matchers.rb +19 -0
  105. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
  106. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
  107. data/spec/dragonfly/active_model_extensions/model_spec.rb +723 -0
  108. data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
  109. data/spec/dragonfly/analyser_spec.rb +123 -0
  110. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +57 -0
  111. data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +15 -0
  112. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +27 -0
  113. data/spec/dragonfly/analysis/shared_analyser_spec.rb +51 -0
  114. data/spec/dragonfly/app_spec.rb +280 -0
  115. data/spec/dragonfly/config/r_magick_spec.rb +25 -0
  116. data/spec/dragonfly/configurable_spec.rb +220 -0
  117. data/spec/dragonfly/core_ext/string_spec.rb +17 -0
  118. data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
  119. data/spec/dragonfly/data_storage/data_store_spec.rb +76 -0
  120. data/spec/dragonfly/data_storage/file_data_store_spec.rb +169 -0
  121. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +38 -0
  122. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +94 -0
  123. data/spec/dragonfly/deprecation_spec.rb +20 -0
  124. data/spec/dragonfly/encoding/image_magick_encoder_spec.rb +41 -0
  125. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +37 -0
  126. data/spec/dragonfly/function_manager_spec.rb +154 -0
  127. data/spec/dragonfly/generation/hash_with_css_style_keys_spec.rb +24 -0
  128. data/spec/dragonfly/generation/image_magick_generator_spec.rb +12 -0
  129. data/spec/dragonfly/generation/r_magick_generator_spec.rb +24 -0
  130. data/spec/dragonfly/generation/shared_generator_spec.rb +91 -0
  131. data/spec/dragonfly/image_magick_utils_spec.rb +16 -0
  132. data/spec/dragonfly/job_builder_spec.rb +37 -0
  133. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  134. data/spec/dragonfly/job_endpoint_spec.rb +120 -0
  135. data/spec/dragonfly/job_spec.rb +773 -0
  136. data/spec/dragonfly/loggable_spec.rb +80 -0
  137. data/spec/dragonfly/middleware_spec.rb +68 -0
  138. data/spec/dragonfly/processing/image_magick_processor_spec.rb +29 -0
  139. data/spec/dragonfly/processing/r_magick_processor_spec.rb +26 -0
  140. data/spec/dragonfly/processing/shared_processing_spec.rb +215 -0
  141. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  142. data/spec/dragonfly/serializer_spec.rb +61 -0
  143. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  144. data/spec/dragonfly/simple_endpoint_spec.rb +89 -0
  145. data/spec/dragonfly/temp_object_spec.rb +352 -0
  146. data/spec/image_matchers.rb +47 -0
  147. data/spec/simple_matchers.rb +44 -0
  148. data/spec/spec_helper.rb +58 -0
  149. data/yard/handlers/configurable_attr_handler.rb +38 -0
  150. data/yard/setup.rb +15 -0
  151. data/yard/templates/default/fulldoc/html/css/common.css +107 -0
  152. data/yard/templates/default/layout/html/layout.erb +87 -0
  153. data/yard/templates/default/module/html/configuration_summary.erb +31 -0
  154. data/yard/templates/default/module/setup.rb +17 -0
  155. metadata +550 -0
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class Testoast
4
+ include Dragonfly::Loggable
5
+ end
6
+
7
+ describe Dragonfly::Loggable do
8
+
9
+ before(:each) do
10
+ @object = Testoast.new
11
+ end
12
+
13
+ describe "common", :shared => true do
14
+ it "should return a log" do
15
+ @object.log.should be_a(Logger)
16
+ end
17
+ it "should cache the log" do
18
+ @object.log.should == @object.log
19
+ end
20
+ end
21
+
22
+ describe "without being set" do
23
+ it "should return the log object as nil" do
24
+ @object.log_object.should be_nil
25
+ end
26
+ it_should_behave_like 'common'
27
+ end
28
+
29
+ describe "when set" do
30
+ before(:each) do
31
+ @log = Logger.new($stdout)
32
+ @object.log = @log
33
+ end
34
+ it "should return the new log" do
35
+ @object.log.should == @log
36
+ end
37
+ it "should return the log object" do
38
+ @object.log_object.should == @log
39
+ end
40
+ it_should_behave_like 'common'
41
+ end
42
+
43
+ describe "when set as a proc" do
44
+ before(:each) do
45
+ @log = Logger.new($stdout)
46
+ @object.log = proc{ @log }
47
+ end
48
+ it "should return the new log" do
49
+ @object.log.should == @log
50
+ end
51
+ it "should return the log object" do
52
+ @object.log_object.should be_a(Proc)
53
+ end
54
+ it "should allow for changing logs" do
55
+ logs = [@log]
56
+ @object.log = proc{ logs[0] }
57
+ @object.log.should == @log
58
+
59
+ new_log = Logger.new($stdout)
60
+ logs[0] = new_log
61
+
62
+ @object.log.should == new_log
63
+ end
64
+ it_should_behave_like 'common'
65
+ end
66
+
67
+ describe "sharing logs" do
68
+ before(:each) do
69
+ @log = Logger.new($stdout)
70
+ @obj1 = Testoast.new
71
+ @obj2 = Testoast.new
72
+ end
73
+ it "should enable sharing logs" do
74
+ @obj1.log = proc{ @log }
75
+ @obj2.use_same_log_as(@obj1)
76
+ @obj2.log.should == @log
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'rack'
3
+
4
+ def dummy_rack_app
5
+ lambda{|env| [200, {"Content-Type" => "text/html"}, ["dummy_rack_app body"]] }
6
+ end
7
+
8
+ describe Dragonfly::Middleware do
9
+
10
+ def make_request(app, url)
11
+ Rack::MockRequest.new(app).get(url)
12
+ end
13
+
14
+ before(:each) do
15
+ @stack = Rack::Builder.new do
16
+ use Dragonfly::Middleware, :images, '/media'
17
+ run dummy_rack_app
18
+ end
19
+ end
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
29
+ Dragonfly[:images].should_receive(:call).and_return(
30
+ [404, {"Content-Type" => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
31
+ )
32
+ response = make_request(@stack, '/media/hello.png?howare=you')
33
+ response.body.should == 'dummy_rack_app body'
34
+ end
35
+
36
+ it "should return a 404 if the app returns a 404 for that url but no X-Cascade: pass" do
37
+ Dragonfly[:images].should_receive(:call).and_return(
38
+ [404, {"Content-Type" => 'text/plain'}, ['Not found']]
39
+ )
40
+ response = make_request(@stack, '/media/hello.png?howare=you')
41
+ response.status.should == 404
42
+ end
43
+
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
+ it "should return as per the dragonfly app if the app returns a 200" do
60
+ Dragonfly[:images].should_receive(:call).and_return(
61
+ [200, {"Content-Type" => 'text/plain'}, ['ABCD']]
62
+ )
63
+ response = make_request(@stack, '/media/hello.png?howare=you')
64
+ response.status.should == 200
65
+ response.body.should == 'ABCD'
66
+ end
67
+
68
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'dragonfly/processing/shared_processing_spec'
3
+
4
+ describe Dragonfly::Processing::ImageMagickProcessor do
5
+
6
+ before(:each) do
7
+ sample_file = File.dirname(__FILE__) + '/../../../samples/beach.png' # 280x355
8
+ @image = Dragonfly::TempObject.new(File.new(sample_file))
9
+ @processor = Dragonfly::Processing::ImageMagickProcessor.new
10
+ end
11
+
12
+ it_should_behave_like "processing methods"
13
+
14
+ describe "convert" do
15
+ it "should allow for general convert commands" do
16
+ image = @processor.convert(@image, '-scale 56x71')
17
+ image.should have_width(56)
18
+ image.should have_height(71)
19
+ end
20
+ it "should allow for general convert commands with added format" do
21
+ image, extra = @processor.convert(@image, '-scale 56x71', :gif)
22
+ image.should have_width(56)
23
+ image.should have_height(71)
24
+ image.should have_format('gif')
25
+ extra[:format].should == :gif
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'dragonfly/processing/shared_processing_spec'
3
+
4
+ describe Dragonfly::Processing::RMagickProcessor do
5
+
6
+ before(:each) do
7
+ sample_file = File.dirname(__FILE__) + '/../../../samples/beach.png' # 280x355
8
+ @image = Dragonfly::TempObject.new(File.new(sample_file))
9
+ @processor = Dragonfly::Processing::RMagickProcessor.new
10
+ end
11
+
12
+ describe "when using the filesystem" do
13
+ before(:each) do
14
+ @processor.use_filesystem = true
15
+ end
16
+ it_should_behave_like "processing methods"
17
+ end
18
+
19
+ describe "when not using the filesystem" do
20
+ before(:each) do
21
+ @processor.use_filesystem = false
22
+ end
23
+ it_should_behave_like "processing methods"
24
+ end
25
+
26
+ end
@@ -0,0 +1,215 @@
1
+ # NEEDS:
2
+ #
3
+ # @image
4
+ # @processor
5
+ #
6
+ describe "processing methods", :shared => true do
7
+
8
+ describe "resize" do
9
+
10
+ it "should work correctly with xNN" do
11
+ image = @processor.resize(@image, 'x30')
12
+ image.should have_width(24)
13
+ image.should have_height(30)
14
+ end
15
+
16
+ it "should work correctly with NNx" do
17
+ image = @processor.resize(@image, '30x')
18
+ image.should have_width(30)
19
+ image.should have_height(38)
20
+ end
21
+
22
+ it "should work correctly with NNxNN" do
23
+ image = @processor.resize(@image, '30x30')
24
+ image.should have_width(24)
25
+ image.should have_height(30)
26
+ end
27
+
28
+ it "should work correctly with NNxNN!" do
29
+ image = @processor.resize(@image, '30x30!')
30
+ image.should have_width(30)
31
+ image.should have_height(30)
32
+ end
33
+
34
+ it "should work correctly with NNxNN%" do
35
+ image = @processor.resize(@image, '25x50%')
36
+ image.should have_width(70)
37
+ image.should have_height(178)
38
+ end
39
+
40
+ describe "NNxNN>" do
41
+
42
+ it "should not resize if the image is smaller than specified" do
43
+ image = @processor.resize(@image, '1000x1000>')
44
+ image.should have_width(280)
45
+ image.should have_height(355)
46
+ end
47
+
48
+ it "should resize if the image is larger than specified" do
49
+ image = @processor.resize(@image, '30x30>')
50
+ image.should have_width(24)
51
+ image.should have_height(30)
52
+ end
53
+
54
+ end
55
+
56
+ describe "NNxNN<" do
57
+
58
+ it "should not resize if the image is larger than specified" do
59
+ image = @processor.resize(@image, '10x10<')
60
+ image.should have_width(280)
61
+ image.should have_height(355)
62
+ end
63
+
64
+ it "should resize if the image is smaller than specified" do
65
+ image = @processor.resize(@image, '400x400<')
66
+ image.should have_width(315)
67
+ image.should have_height(400)
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ describe "crop" do # Difficult to test here other than dimensions
75
+
76
+ it "should not crop if no args given" do
77
+ image = @processor.crop(@image)
78
+ image.should have_width(280)
79
+ image.should have_height(355)
80
+ end
81
+
82
+ it "should crop using the offset given" do
83
+ image = @processor.crop(@image, :x => '7', :y => '12')
84
+ image.should have_width(273)
85
+ image.should have_height(343)
86
+ end
87
+
88
+ it "should crop using the dimensions given" do
89
+ image = @processor.crop(@image, :width => '10', :height => '20')
90
+ image.should have_width(10)
91
+ image.should have_height(20)
92
+ end
93
+
94
+ it "should crop in one dimension if given" do
95
+ image = @processor.crop(@image, :width => '10')
96
+ image.should have_width(10)
97
+ image.should have_height(355)
98
+ end
99
+
100
+ it "should take into account the gravity given" do
101
+ image1 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'nw')
102
+ image2 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'se')
103
+ image1.should_not == image2
104
+ end
105
+
106
+ it "should clip bits of the image outside of the requested crop area when not nw gravity" do
107
+ # Rmagick was previously throwing an error when the cropping area was outside the image size, when
108
+ # using a gravity other than nw
109
+ image = @processor.crop(@image, :width => '500', :height => '1000', :x => '100', :y => '200', :gravity => 'se')
110
+ image.should have_width(180)
111
+ image.should have_height(155)
112
+ end
113
+
114
+ end
115
+
116
+ describe "greyscale" do
117
+ it "should not raise an error" do
118
+ # Bit tricky to test
119
+ @processor.greyscale(@image)
120
+ end
121
+ end
122
+
123
+ describe "resize_and_crop" do
124
+
125
+ it "should do nothing if no args given" do
126
+ image = @processor.resize_and_crop(@image)
127
+ image.should have_width(280)
128
+ image.should have_height(355)
129
+ end
130
+
131
+ it "should crop to the correct dimensions" do
132
+ image = @processor.resize_and_crop(@image, :width => '100', :height => '100')
133
+ image.should have_width(100)
134
+ image.should have_height(100)
135
+ end
136
+
137
+ it "should allow cropping in one dimension" do
138
+ image = @processor.resize_and_crop(@image, :width => '100')
139
+ image.should have_width(100)
140
+ image.should have_height(355)
141
+ end
142
+
143
+ it "should take into account the gravity given" do
144
+ image1 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'nw')
145
+ image2 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'se')
146
+ image1.should_not == image2
147
+ end
148
+
149
+ end
150
+
151
+ describe "rotate" do
152
+
153
+ it "should rotate by 90 degrees" do
154
+ image = @processor.rotate(@image, 90)
155
+ image.should have_width(355)
156
+ image.should have_height(280)
157
+ end
158
+
159
+ it "should not rotate given a larger height and the '>' qualifier" do
160
+ image = @processor.rotate(@image, 90, :qualifier => '>')
161
+ image.should have_width(280)
162
+ image.should have_height(355)
163
+ end
164
+
165
+ it "should rotate given a larger height and the '<' qualifier" do
166
+ image = @processor.rotate(@image, 90, :qualifier => '<')
167
+ image.should have_width(355)
168
+ image.should have_height(280)
169
+ end
170
+
171
+ end
172
+
173
+ describe "thumb" do
174
+ it "should call resize if the correct string given" do
175
+ @processor.should_receive(:resize).with(@image, '30x40').and_return(image = mock)
176
+ @processor.thumb(@image, '30x40').should == image
177
+ end
178
+ it "should call resize_and_crop if the correct string given" do
179
+ @processor.should_receive(:resize_and_crop).with(@image, :width => '30', :height => '40', :gravity => 'se').and_return(image = mock)
180
+ @processor.thumb(@image, '30x40#se').should == image
181
+ end
182
+ it "should call crop if x and y given" do
183
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '+10', :y => '+20', :gravity => nil).and_return(image = mock)
184
+ @processor.thumb(@image, '30x40+10+20').should == image
185
+ end
186
+ it "should call crop if just gravity given" do
187
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => nil, :y => nil, :gravity => 'sw').and_return(image = mock)
188
+ @processor.thumb(@image, '30x40sw').should == image
189
+ end
190
+ it "should call crop if x, y and gravity given" do
191
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '-10', :y => '-20', :gravity => 'se').and_return(image = mock)
192
+ @processor.thumb(@image, '30x40-10-20se').should == image
193
+ end
194
+ it "should raise an argument error if an unrecognized string is given" do
195
+ lambda{ @processor.thumb(@image, '30x40#ne!') }.should raise_error(ArgumentError)
196
+ end
197
+ end
198
+
199
+ describe "flip" do
200
+ it "should flip the image, leaving the same dimensions" do
201
+ image = @processor.flip(@image)
202
+ image.should have_width(280)
203
+ image.should have_height(355)
204
+ end
205
+ end
206
+
207
+ describe "flop" do
208
+ it "should flop the image, leaving the same dimensions" do
209
+ image = @processor.flop(@image)
210
+ image.should have_width(280)
211
+ image.should have_height(355)
212
+ end
213
+ end
214
+
215
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ def response_for(array)
4
+ Rack::MockResponse.new(*array)
5
+ end
6
+
7
+ describe Dragonfly::RoutedEndpoint do
8
+
9
+ def env_for(url, opts={})
10
+ Rack::MockRequest.env_for(url, opts)
11
+ end
12
+
13
+ before(:each) do
14
+ @app = test_app
15
+ @endpoint = Dragonfly::RoutedEndpoint.new(@app) {|params, app|
16
+ app.fetch(params[:uid])
17
+ }
18
+ @app.datastore.stub!(:retrieve).with('some_uid').and_return Dragonfly::TempObject.new('wassup')
19
+ end
20
+
21
+ it "should raise an error when there are no routing parameters" do
22
+ lambda{
23
+ @endpoint.call(env_for('/blah'))
24
+ }.should raise_error(Dragonfly::RoutedEndpoint::NoRoutingParams)
25
+ end
26
+
27
+ {
28
+ 'Rails' => 'action_dispatch.request.path_parameters',
29
+ 'Usher' => 'usher.params',
30
+ 'HTTP Router' => 'router.params',
31
+ 'Rack-Mount' => 'rack.routing_args',
32
+ 'Dragonfly' => 'dragonfly.params'
33
+ }.each do |name, key|
34
+
35
+ it "should work with #{name} routing args" do
36
+ response = response_for @endpoint.call(env_for('/blah', key => {:uid => 'some_uid'}))
37
+ response.body.should == 'wassup'
38
+ end
39
+
40
+ end
41
+
42
+ it "should merge with query parameters" do
43
+ env = Rack::MockRequest.env_for('/big/buns?uid=some_uid', 'dragonfly.params' => {:something => 'else'})
44
+ response = response_for @endpoint.call(env)
45
+ response.body.should == 'wassup'
46
+ end
47
+
48
+ end