dragonfly 1.3.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/History.md +16 -0
  4. data/README.md +5 -1
  5. data/dev/test.ru +1 -1
  6. data/dragonfly.gemspec +2 -1
  7. data/lib/dragonfly/content.rb +17 -18
  8. data/lib/dragonfly/image_magick/commands.rb +35 -0
  9. data/lib/dragonfly/image_magick/generators/plain.rb +13 -7
  10. data/lib/dragonfly/image_magick/generators/plasma.rb +10 -6
  11. data/lib/dragonfly/image_magick/generators/text.rb +67 -58
  12. data/lib/dragonfly/image_magick/plugin.rb +26 -25
  13. data/lib/dragonfly/image_magick/processors/encode.rb +16 -5
  14. data/lib/dragonfly/image_magick/processors/thumb.rb +37 -31
  15. data/lib/dragonfly/middleware.rb +2 -1
  16. data/lib/dragonfly/param_validators.rb +37 -0
  17. data/lib/dragonfly/response.rb +11 -11
  18. data/lib/dragonfly/routed_endpoint.rb +1 -1
  19. data/lib/dragonfly/server.rb +7 -7
  20. data/lib/dragonfly/version.rb +1 -1
  21. data/spec/dragonfly/app_spec.rb +1 -1
  22. data/spec/dragonfly/configurable_spec.rb +4 -4
  23. data/spec/dragonfly/content_spec.rb +1 -1
  24. data/spec/dragonfly/file_data_store_spec.rb +2 -2
  25. data/spec/dragonfly/image_magick/commands_spec.rb +98 -0
  26. data/spec/dragonfly/image_magick/generators/plain_spec.rb +39 -13
  27. data/spec/dragonfly/image_magick/generators/plasma_spec.rb +28 -9
  28. data/spec/dragonfly/image_magick/generators/text_spec.rb +51 -20
  29. data/spec/dragonfly/image_magick/plugin_spec.rb +45 -28
  30. data/spec/dragonfly/image_magick/processors/encode_spec.rb +30 -0
  31. data/spec/dragonfly/image_magick/processors/thumb_spec.rb +46 -45
  32. data/spec/dragonfly/job/fetch_url_spec.rb +1 -1
  33. data/spec/dragonfly/job_endpoint_spec.rb +26 -26
  34. data/spec/dragonfly/middleware_spec.rb +15 -6
  35. data/spec/dragonfly/model/active_record_spec.rb +2 -2
  36. data/spec/dragonfly/model/model_spec.rb +1 -1
  37. data/spec/dragonfly/param_validators_spec.rb +89 -0
  38. data/spec/dragonfly/server_spec.rb +4 -4
  39. data/spec/dragonfly/temp_object_spec.rb +5 -5
  40. data/spec/functional/shell_commands_spec.rb +6 -9
  41. data/spec/functional/to_response_spec.rb +2 -2
  42. data/spec/functional/urls_spec.rb +1 -1
  43. data/spec/spec_helper.rb +18 -14
  44. data/spec/support/image_matchers.rb +1 -1
  45. metadata +27 -12
  46. data/lib/dragonfly/image_magick/generators/convert.rb +0 -19
  47. data/lib/dragonfly/image_magick/processors/convert.rb +0 -33
  48. data/spec/dragonfly/image_magick/generators/convert_spec.rb +0 -19
  49. data/spec/dragonfly/image_magick/processors/convert_spec.rb +0 -88
@@ -1,32 +1,40 @@
1
+ require "dragonfly/image_magick/commands"
2
+
1
3
  module Dragonfly
2
4
  module ImageMagick
3
5
  module Processors
4
6
  class Thumb
7
+ include ParamValidators
5
8
 
6
9
  GRAVITIES = {
7
- 'nw' => 'NorthWest',
8
- 'n' => 'North',
9
- 'ne' => 'NorthEast',
10
- 'w' => 'West',
11
- 'c' => 'Center',
12
- 'e' => 'East',
13
- 'sw' => 'SouthWest',
14
- 's' => 'South',
15
- 'se' => 'SouthEast'
10
+ "nw" => "NorthWest",
11
+ "n" => "North",
12
+ "ne" => "NorthEast",
13
+ "w" => "West",
14
+ "c" => "Center",
15
+ "e" => "East",
16
+ "sw" => "SouthWest",
17
+ "s" => "South",
18
+ "se" => "SouthEast",
16
19
  }
17
20
 
18
21
  # Geometry string patterns
19
- RESIZE_GEOMETRY = /\A\d*x\d*[><%^!]?\z|\A\d+@\z/ # e.g. '300x200!'
22
+ RESIZE_GEOMETRY = /\A\d*x\d*[><%^!]?\z|\A\d+@\z/ # e.g. '300x200!'
20
23
  CROPPED_RESIZE_GEOMETRY = /\A(\d+)x(\d+)#(\w{1,2})?\z/ # e.g. '20x50#ne'
21
- CROP_GEOMETRY = /\A(\d+)x(\d+)([+-]\d+)?([+-]\d+)?(\w{1,2})?\z/ # e.g. '30x30+10+10'
24
+ CROP_GEOMETRY = /\A(\d+)x(\d+)([+-]\d+)?([+-]\d+)?(\w{1,2})?\z/ # e.g. '30x30+10+10'
22
25
 
23
- def update_url(url_attributes, geometry, opts={})
24
- format = opts['format']
26
+ def update_url(url_attributes, geometry, opts = {})
27
+ format = opts["format"]
25
28
  url_attributes.ext = format if format
26
29
  end
27
30
 
28
- def call(content, geometry, opts={})
29
- content.process!(:convert, args_for_geometry(geometry), opts)
31
+ def call(content, geometry, opts = {})
32
+ validate!(opts["format"], &is_word)
33
+ validate!(opts["frame"], &is_number)
34
+ Commands.convert(content, args_for_geometry(geometry), {
35
+ "format" => opts["format"],
36
+ "frame" => opts["frame"],
37
+ })
30
38
  end
31
39
 
32
40
  def args_for_geometry(geometry)
@@ -37,11 +45,11 @@ module Dragonfly
37
45
  resize_and_crop_args($1, $2, $3)
38
46
  when CROP_GEOMETRY
39
47
  crop_args(
40
- 'width' => $1,
41
- 'height' => $2,
42
- 'x' => $3,
43
- 'y' => $4,
44
- 'gravity' => $5
48
+ "width" => $1,
49
+ "height" => $2,
50
+ "x" => $3,
51
+ "y" => $4,
52
+ "gravity" => $5,
45
53
  )
46
54
  else raise ArgumentError, "Didn't recognise the geometry string #{geometry}"
47
55
  end
@@ -54,26 +62,24 @@ module Dragonfly
54
62
  end
55
63
 
56
64
  def crop_args(opts)
57
- raise ArgumentError, "you can't give a crop offset and gravity at the same time" if opts['x'] && opts['gravity']
65
+ raise ArgumentError, "you can't give a crop offset and gravity at the same time" if opts["x"] && opts["gravity"]
58
66
 
59
- width = opts['width']
60
- height = opts['height']
61
- gravity = GRAVITIES[opts['gravity']]
62
- x = "#{opts['x'] || 0}"
63
- x = '+' + x unless x[/\A[+-]/]
64
- y = "#{opts['y'] || 0}"
65
- y = '+' + y unless y[/\A[+-]/]
67
+ width = opts["width"]
68
+ height = opts["height"]
69
+ gravity = GRAVITIES[opts["gravity"]]
70
+ x = "#{opts["x"] || 0}"
71
+ x = "+" + x unless x[/\A[+-]/]
72
+ y = "#{opts["y"] || 0}"
73
+ y = "+" + y unless y[/\A[+-]/]
66
74
 
67
75
  "#{"-gravity #{gravity} " if gravity}-crop #{width}x#{height}#{x}#{y} +repage"
68
76
  end
69
77
 
70
78
  def resize_and_crop_args(width, height, gravity)
71
- gravity = GRAVITIES[gravity || 'c']
79
+ gravity = GRAVITIES[gravity || "c"]
72
80
  "-resize #{width}x#{height}^^ -gravity #{gravity} -crop #{width}x#{height}+0+0 +repage"
73
81
  end
74
-
75
82
  end
76
83
  end
77
84
  end
78
85
  end
79
-
@@ -10,7 +10,8 @@ module Dragonfly
10
10
 
11
11
  def call(env)
12
12
  response = Dragonfly.app(@dragonfly_app_name).call(env)
13
- if response[1]['X-Cascade'] == 'pass'
13
+ headers = response[1].transform_keys(&:downcase)
14
+ if headers['x-cascade'] == 'pass'
14
15
  @app.call(env)
15
16
  else
16
17
  response
@@ -0,0 +1,37 @@
1
+ module Dragonfly
2
+ module ParamValidators
3
+ class InvalidParameter < RuntimeError; end
4
+
5
+ module_function
6
+
7
+ IS_NUMBER = ->(param) {
8
+ param.is_a?(Numeric) || /\A[\d\.]+\z/ === param
9
+ }
10
+
11
+ IS_WORD = ->(param) {
12
+ /\A\w+\z/ === param
13
+ }
14
+
15
+ IS_WORDS = ->(param) {
16
+ /\A[\w ]+\z/ === param
17
+ }
18
+
19
+ def is_number; IS_NUMBER; end
20
+ def is_word; IS_WORD; end
21
+ def is_words; IS_WORDS; end
22
+
23
+ def validate!(parameter, &validator)
24
+ return if parameter.nil?
25
+ raise InvalidParameter unless validator.(parameter)
26
+ end
27
+
28
+ def validate_all!(parameters, &validator)
29
+ parameters.each { |p| validate!(p, &validator) }
30
+ end
31
+
32
+ def validate_all_keys!(obj, keys, &validator)
33
+ parameters = keys.map { |key| obj[key] }
34
+ validate_all!(parameters, &validator)
35
+ end
36
+ end
37
+ end
@@ -1,4 +1,4 @@
1
- require 'uri'
1
+ require 'cgi'
2
2
  require 'rack'
3
3
 
4
4
  module Dragonfly
@@ -26,10 +26,10 @@ module Dragonfly
26
26
  end
27
27
  rescue Job::Fetch::NotFound => e
28
28
  Dragonfly.warn(e.message)
29
- [404, {"Content-Type" => "text/plain"}, ["Not found"]]
29
+ [404, {"content-type" => "text/plain"}, ["Not found"]]
30
30
  rescue RuntimeError => e
31
31
  Dragonfly.warn("caught error - #{e.message}")
32
- [500, {"Content-Type" => "text/plain"}, ["Internal Server Error"]]
32
+ [500, {"content-type" => "text/plain"}, ["Internal Server Error"]]
33
33
  end
34
34
  log_response(response)
35
35
  response
@@ -65,8 +65,8 @@ module Dragonfly
65
65
 
66
66
  def method_not_allowed_headers
67
67
  {
68
- 'Content-Type' => 'text/plain',
69
- 'Allow' => 'GET, HEAD'
68
+ 'content-type' => 'text/plain',
69
+ 'allow' => 'GET, HEAD'
70
70
  }
71
71
  end
72
72
 
@@ -78,16 +78,16 @@ module Dragonfly
78
78
 
79
79
  def standard_headers
80
80
  {
81
- "Content-Type" => job.mime_type,
82
- "Content-Length" => job.size.to_s,
83
- "Content-Disposition" => filename_string
81
+ "content-type" => job.mime_type,
82
+ "content-length" => job.size.to_s,
83
+ "content-disposition" => filename_string
84
84
  }
85
85
  end
86
86
 
87
87
  def cache_headers
88
88
  {
89
- "Cache-Control" => "public, max-age=31536000", # (1 year)
90
- "ETag" => %("#{job.signature}")
89
+ "cache-control" => "public, max-age=31536000", # (1 year)
90
+ "etag" => %("#{job.signature}")
91
91
  }
92
92
  end
93
93
 
@@ -99,7 +99,7 @@ module Dragonfly
99
99
 
100
100
  def filename_string
101
101
  return unless job.name
102
- filename = request_from_msie? ? URI.encode(job.name) : job.name
102
+ filename = request_from_msie? ? CGI.escape(job.name) : job.name
103
103
  %(filename="#{filename}")
104
104
  end
105
105
 
@@ -45,7 +45,7 @@ module Dragonfly
45
45
  end
46
46
 
47
47
  def plain_response(status, message)
48
- [status, {"Content-Type" => "text/plain"}, [message]]
48
+ [status, {"content-type" => "text/plain"}, [message]]
49
49
  end
50
50
  end
51
51
  end
@@ -59,18 +59,18 @@ module Dragonfly
59
59
  response.to_response
60
60
  end
61
61
  else
62
- [404, {'Content-Type' => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
62
+ [404, {'content-type' => 'text/plain', 'x-cascade' => 'pass'}, ['Not found']]
63
63
  end
64
64
  rescue Job::NoSHAGiven => e
65
- [400, {"Content-Type" => 'text/plain'}, ["You need to give a SHA parameter"]]
65
+ [400, {"content-type" => 'text/plain'}, ["You need to give a SHA parameter"]]
66
66
  rescue Job::IncorrectSHA => e
67
- [400, {"Content-Type" => 'text/plain'}, ["The SHA parameter you gave is incorrect"]]
67
+ [400, {"content-type" => 'text/plain'}, ["The SHA parameter you gave is incorrect"]]
68
68
  rescue JobNotAllowed => e
69
69
  Dragonfly.warn(e.message)
70
- [403, {"Content-Type" => 'text/plain'}, ["Forbidden"]]
70
+ [403, {"content-type" => 'text/plain'}, ["Forbidden"]]
71
71
  rescue Serializer::BadString, Serializer::MaliciousString, Job::InvalidArray => e
72
72
  Dragonfly.warn(e.message)
73
- [404, {'Content-Type' => 'text/plain'}, ['Not found']]
73
+ [404, {'content-type' => 'text/plain'}, ['Not found']]
74
74
  end
75
75
 
76
76
  def url_for(job, opts={})
@@ -111,8 +111,8 @@ module Dragonfly
111
111
  V
112
112
  DRAGONFLY
113
113
  [200, {
114
- 'Content-Type' => 'text/plain',
115
- 'Content-Size' => body.bytesize.to_s
114
+ 'content-type' => 'text/plain',
115
+ 'content-size' => body.bytesize.to_s
116
116
  },
117
117
  [body]
118
118
  ]
@@ -1,3 +1,3 @@
1
1
  module Dragonfly
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.1"
3
3
  end
@@ -138,7 +138,7 @@ describe Dragonfly::App do
138
138
  }.should raise_error(NotImplementedError)
139
139
  end
140
140
  it "should correctly call it if the datastore provides it" do
141
- @app.datastore.should_receive(:url_for).with('some_uid', :some => :opts).and_return 'http://egg.head'
141
+ @app.datastore.should_receive(:url_for).with('some_uid', {:some => :opts}).and_return 'http://egg.head'
142
142
  @app.remote_url_for('some_uid', :some => :opts).should == 'http://egg.head'
143
143
  end
144
144
  end
@@ -65,7 +65,7 @@ describe Dragonfly::Configurable do
65
65
  configurer = Dragonfly::Configurable::Configurer.new do
66
66
  meth :jobby, :nobby
67
67
  end
68
- obj.should_receive(:jobby).with('beans', :make => 5)
68
+ obj.should_receive(:jobby).with('beans', {:make => 5})
69
69
  obj.should_receive(:nobby).with(['nuts'])
70
70
  configurer.configure(obj) do
71
71
  jobby 'beans', :make => 5
@@ -79,7 +79,7 @@ describe Dragonfly::Configurable do
79
79
  end
80
80
  egg = double('egg')
81
81
  obj.should_receive(:egg).and_return(egg)
82
- egg.should_receive(:jobby).with('beans', :make => 5)
82
+ egg.should_receive(:jobby).with('beans', {:make => 5})
83
83
  configurer.configure(obj) do
84
84
  jobby 'beans', :make => 5
85
85
  end
@@ -93,7 +93,7 @@ describe Dragonfly::Configurable do
93
93
 
94
94
  it "provides 'plugin' for using plugins" do
95
95
  pluggy = double('plugin')
96
- pluggy.should_receive(:call).with(obj, :a, 'few' => ['args'])
96
+ pluggy.should_receive(:call).with(obj, :a, {'few' => ['args']})
97
97
  configurer.configure(obj) do
98
98
  plugin pluggy, :a, 'few' => ['args']
99
99
  end
@@ -101,7 +101,7 @@ describe Dragonfly::Configurable do
101
101
 
102
102
  it "allows using 'plugin' with symbols" do
103
103
  pluggy = double('plugin')
104
- pluggy.should_receive(:call).with(obj, :a, 'few' => ['args'])
104
+ pluggy.should_receive(:call).with(obj, :a, {'few' => ['args']})
105
105
  configurer.register_plugin(:pluggy){ pluggy }
106
106
  configurer.configure(obj) do
107
107
  plugin :pluggy, :a, 'few' => ['args']
@@ -320,7 +320,7 @@ describe Dragonfly::Content do
320
320
  end
321
321
 
322
322
  it "allows passing options" do
323
- app.datastore.should_receive(:write).with(content, :hello => 'there')
323
+ app.datastore.should_receive(:write).with(content, {:hello => 'there'})
324
324
  content.store(:hello => 'there')
325
325
  end
326
326
  end
@@ -9,11 +9,11 @@ describe Dragonfly::FileDataStore do
9
9
  end
10
10
 
11
11
  def assert_exists(path)
12
- File.exists?(path).should be_truthy
12
+ File.exist?(path).should be_truthy
13
13
  end
14
14
 
15
15
  def assert_does_not_exist(path)
16
- File.exists?(path).should be_falsey
16
+ File.exist?(path).should be_falsey
17
17
  end
18
18
 
19
19
  def assert_contains(dir, filepattern)
@@ -0,0 +1,98 @@
1
+ require "spec_helper"
2
+ require "dragonfly/image_magick/commands"
3
+
4
+ describe Dragonfly::ImageMagick::Commands do
5
+ include Dragonfly::ImageMagick::Commands
6
+
7
+ let(:app) { test_app }
8
+
9
+ def sample_content(name)
10
+ Dragonfly::Content.new(app, SAMPLES_DIR.join(name))
11
+ end
12
+
13
+ describe "convert" do
14
+ let(:image) { sample_content("beach.png") } # 280x355
15
+
16
+ it "should allow for general convert commands" do
17
+ convert(image, "-scale 56x71")
18
+ image.should have_width(56)
19
+ image.should have_height(71)
20
+ end
21
+
22
+ it "should allow for general convert commands with added format" do
23
+ convert(image, "-scale 56x71", "format" => "gif")
24
+ image.should have_width(56)
25
+ image.should have_height(71)
26
+ image.should have_format("gif")
27
+ image.meta["format"].should == "gif"
28
+ end
29
+
30
+ it "should work for commands with parenthesis" do
31
+ convert(image, "\\( +clone -sparse-color Barycentric '0,0 black 0,%[fx:h-1] white' -function polynomial 2,-2,0.5 \\) -compose Blur -set option:compose:args 15 -composite")
32
+ image.should have_width(280)
33
+ end
34
+
35
+ it "should work for files with spaces/apostrophes in the name" do
36
+ image = Dragonfly::Content.new(app, SAMPLES_DIR.join("mevs' white pixel.png"))
37
+ convert(image, "-resize 2x2!")
38
+ image.should have_width(2)
39
+ end
40
+
41
+ it "allows converting specific frames" do
42
+ gif = sample_content("gif.gif")
43
+ convert(gif, "-resize 50x50")
44
+ all_frames_size = gif.size
45
+
46
+ gif = sample_content("gif.gif")
47
+ convert(gif, "-resize 50x50", "frame" => 0)
48
+ one_frame_size = gif.size
49
+
50
+ one_frame_size.should < all_frames_size
51
+ end
52
+
53
+ it "accepts input arguments for convert commands" do
54
+ image2 = image.clone
55
+ convert(image, "")
56
+ convert(image2, "", "input_args" => "-extract 50x50+10+10")
57
+
58
+ image.should_not equal_image(image2)
59
+ image2.should have_width(50)
60
+ end
61
+
62
+ it "allows converting using specific delegates" do
63
+ expect {
64
+ convert(image, "", "format" => "jpg", "delegate" => "png")
65
+ }.to call_command(app.shell, %r{convert png:/[^']+?/beach\.png /[^']+?\.jpg})
66
+ end
67
+
68
+ it "maintains the mime_type meta if it exists already" do
69
+ convert(image, "-resize 10x")
70
+ image.meta["mime_type"].should be_nil
71
+
72
+ image.add_meta("mime_type" => "image/png")
73
+ convert(image, "-resize 5x")
74
+ image.meta["mime_type"].should == "image/png"
75
+ image.mime_type.should == "image/png" # sanity check
76
+ end
77
+
78
+ it "doesn't maintain the mime_type meta on format change" do
79
+ image.add_meta("mime_type" => "image/png")
80
+ convert(image, "", "format" => "gif")
81
+ image.meta["mime_type"].should be_nil
82
+ image.mime_type.should == "image/gif" # sanity check
83
+ end
84
+ end
85
+
86
+ describe "generate" do
87
+ let (:image) { Dragonfly::Content.new(app) }
88
+
89
+ before(:each) do
90
+ generate(image, "-size 1x1 xc:white", "png")
91
+ end
92
+
93
+ it { image.should have_width(1) }
94
+ it { image.should have_height(1) }
95
+ it { image.should have_format("png") }
96
+ it { image.meta.should == { "format" => "png" } }
97
+ end
98
+ end
@@ -1,4 +1,5 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
+ require "dragonfly/param_validators"
2
3
 
3
4
  describe Dragonfly::ImageMagick::Generators::Plain do
4
5
  let (:generator) { Dragonfly::ImageMagick::Generators::Plain.new }
@@ -9,32 +10,32 @@ describe Dragonfly::ImageMagick::Generators::Plain do
9
10
  before(:each) do
10
11
  generator.call(image, 3, 2)
11
12
  end
12
- it {image.should have_width(3)}
13
- it {image.should have_height(2)}
14
- it {image.should have_format('png')}
15
- it {image.meta.should == {'format' => 'png', 'name' => 'plain.png'}}
13
+ it { image.should have_width(3) }
14
+ it { image.should have_height(2) }
15
+ it { image.should have_format("png") }
16
+ it { image.meta.should == { "format" => "png", "name" => "plain.png" } }
16
17
  end
17
18
 
18
19
  describe "specifying the format" do
19
20
  before(:each) do
20
- generator.call(image, 1, 1, 'format'=> 'gif')
21
+ generator.call(image, 1, 1, "format" => "gif")
21
22
  end
22
- it {image.should have_format('gif')}
23
- it {image.meta.should == {'format' => 'gif', 'name' => 'plain.gif'}}
23
+ it { image.should have_format("gif") }
24
+ it { image.meta.should == { "format" => "gif", "name" => "plain.gif" } }
24
25
  end
25
26
 
26
27
  describe "specifying the colour" do
27
28
  it "works with English spelling" do
28
- generator.call(image, 1, 1, 'colour' => 'red')
29
+ generator.call(image, 1, 1, "colour" => "red")
29
30
  end
30
31
 
31
32
  it "works with American spelling" do
32
- generator.call(image, 1, 1, 'color' => 'red')
33
+ generator.call(image, 1, 1, "color" => "red")
33
34
  end
34
35
 
35
36
  it "blows up with a bad colour" do
36
37
  expect {
37
- generator.call(image, 1, 1, 'colour' => 'lardoin')
38
+ generator.call(image, 1, 1, "colour" => "lardoin")
38
39
  }.to raise_error(Dragonfly::Shell::CommandFailed)
39
40
  end
40
41
  end
@@ -42,9 +43,34 @@ describe Dragonfly::ImageMagick::Generators::Plain do
42
43
  describe "urls" do
43
44
  it "updates the url" do
44
45
  url_attributes = Dragonfly::UrlAttributes.new
45
- generator.update_url(url_attributes, 1, 1, 'format' => 'gif')
46
- url_attributes.name.should == 'plain.gif'
46
+ generator.update_url(url_attributes, 1, 1, "format" => "gif")
47
+ url_attributes.name.should == "plain.gif"
47
48
  end
48
49
  end
49
50
 
51
+ describe "param validations" do
52
+ {
53
+ "color" => "white -write bad.png",
54
+ "colour" => "white -write bad.png",
55
+ "format" => "png -write bad.png",
56
+ }.each do |opt, value|
57
+ it "validates bad opts like #{opt} = '#{value}'" do
58
+ expect {
59
+ generator.call(image, 1, 1, opt => value)
60
+ }.to raise_error(Dragonfly::ParamValidators::InvalidParameter)
61
+ end
62
+ end
63
+
64
+ it "validates width" do
65
+ expect {
66
+ generator.call(image, "1 -write bad.png", 1)
67
+ }.to raise_error(Dragonfly::ParamValidators::InvalidParameter)
68
+ end
69
+
70
+ it "validates height" do
71
+ expect {
72
+ generator.call(image, 1, "1 -write bad.png")
73
+ }.to raise_error(Dragonfly::ParamValidators::InvalidParameter)
74
+ end
75
+ end
50
76
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Dragonfly::ImageMagick::Generators::Plasma do
4
4
  let (:generator) { Dragonfly::ImageMagick::Generators::Plasma.new }
@@ -10,23 +10,42 @@ describe Dragonfly::ImageMagick::Generators::Plasma do
10
10
  generator.call(image, 5, 3)
11
11
  image.should have_width(5)
12
12
  image.should have_height(3)
13
- image.should have_format('png')
14
- image.meta.should == {'format' => 'png', 'name' => 'plasma.png'}
13
+ image.should have_format("png")
14
+ image.meta.should == { "format" => "png", "name" => "plasma.png" }
15
15
  end
16
16
 
17
17
  it "allows changing the format" do
18
- generator.call(image, 1, 1, 'format' => 'jpg')
19
- image.should have_format('jpeg')
20
- image.meta.should == {'format' => 'jpg', 'name' => 'plasma.jpg'}
18
+ generator.call(image, 1, 1, "format" => "jpg")
19
+ image.should have_format("jpeg")
20
+ image.meta.should == { "format" => "jpg", "name" => "plasma.jpg" }
21
21
  end
22
22
  end
23
23
 
24
24
  describe "urls" do
25
25
  it "updates the url" do
26
26
  url_attributes = Dragonfly::UrlAttributes.new
27
- generator.update_url(url_attributes, 1, 1, 'format' => 'jpg')
28
- url_attributes.name.should == 'plasma.jpg'
27
+ generator.update_url(url_attributes, 1, 1, "format" => "jpg")
28
+ url_attributes.name.should == "plasma.jpg"
29
29
  end
30
30
  end
31
- end
32
31
 
32
+ describe "param validations" do
33
+ it "validates format" do
34
+ expect {
35
+ generator.call(image, 1, 1, "format" => "png -write bad.png")
36
+ }.to raise_error(Dragonfly::ParamValidators::InvalidParameter)
37
+ end
38
+
39
+ it "validates width" do
40
+ expect {
41
+ generator.call(image, "1 -write bad.png", 1)
42
+ }.to raise_error(Dragonfly::ParamValidators::InvalidParameter)
43
+ end
44
+
45
+ it "validates height" do
46
+ expect {
47
+ generator.call(image, 1, "1 -write bad.png")
48
+ }.to raise_error(Dragonfly::ParamValidators::InvalidParameter)
49
+ end
50
+ end
51
+ end