dragonfly 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dragonfly might be problematic. Click here for more details.

data/Gemfile CHANGED
@@ -14,7 +14,7 @@ gem 'mongo'
14
14
  gem 'nokogiri', '1.5.0.beta.2' # 1.4.3.1 segfaults on Ruby 1.9.2
15
15
  gem 'rack', '~>1.1'
16
16
  gem 'rack-cache'
17
- gem 'rails', '3.0.0.rc', :require => nil
17
+ gem 'rails', '3.0.0', :require => nil
18
18
  gem 'rake'
19
19
  gem 'rmagick', '2.12.2', :require => nil
20
20
  gem 'rspec', '~> 1.3'
data/History.md CHANGED
@@ -1,3 +1,17 @@
1
+ 0.7.5 (2010-09-01)
2
+ ==================
3
+ Changes
4
+ --------
5
+ - RMagick processor, encoder, analyser and generator all use the filesystem now
6
+ They can be configured to use in-memory strings with the use_filesystem config option.
7
+ - Upgraded support from Rails 3.0.0.rc -> Rails.3.0.0
8
+
9
+ 0.7.4 (2010-08-28)
10
+ ==================
11
+ Features
12
+ --------
13
+ - Gave model accessors bang methods process! and encode!
14
+
1
15
  0.7.3 (2010-08-27)
2
16
  ==================
3
17
  Fixes
data/README.md CHANGED
@@ -11,7 +11,7 @@ For the lazy Rails user...
11
11
 
12
12
  gem 'rmagick', :require => 'RMagick'
13
13
  gem 'rack-cache', :require => 'rack/cache'
14
- gem 'dragonfly', '~>0.7.3'
14
+ gem 'dragonfly', '~>0.7.4'
15
15
 
16
16
  **Initializer** (e.g. config/initializers/dragonfly.rb):
17
17
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.4
1
+ 0.7.5
data/dragonfly.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dragonfly}
8
- s.version = "0.7.4"
8
+ s.version = "0.7.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mark Evans"]
12
- s.date = %q{2010-08-28}
12
+ s.date = %q{2010-09-01}
13
13
  s.email = %q{mark@new-bamboo.co.uk}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -50,7 +50,7 @@ Gem::Specification.new do |s|
50
50
  "features/images.feature",
51
51
  "features/no_processing.feature",
52
52
  "features/rails_2.3.5.feature",
53
- "features/rails_3.0.0.rc.feature",
53
+ "features/rails_3.0.0.feature",
54
54
  "features/steps/common_steps.rb",
55
55
  "features/steps/dragonfly_steps.rb",
56
56
  "features/steps/rails_steps.rb",
@@ -64,7 +64,7 @@ Gem::Specification.new do |s|
64
64
  "fixtures/files/features/support/paths.rb",
65
65
  "fixtures/files/features/text_images.feature",
66
66
  "fixtures/rails_2.3.5/template.rb",
67
- "fixtures/rails_3.0.0.rc/template.rb",
67
+ "fixtures/rails_3.0.0/template.rb",
68
68
  "irbrc.rb",
69
69
  "lib/dragonfly.rb",
70
70
  "lib/dragonfly/active_model_extensions.rb",
@@ -122,6 +122,7 @@ Gem::Specification.new do |s|
122
122
  "spec/dragonfly/analysis/file_command_analyser_spec.rb",
123
123
  "spec/dragonfly/analysis/r_magick_analyser_spec.rb",
124
124
  "spec/dragonfly/app_spec.rb",
125
+ "spec/dragonfly/config/r_magick_spec.rb",
125
126
  "spec/dragonfly/configurable_spec.rb",
126
127
  "spec/dragonfly/core_ext/string_spec.rb",
127
128
  "spec/dragonfly/core_ext/symbol_spec.rb",
@@ -170,6 +171,7 @@ Gem::Specification.new do |s|
170
171
  "spec/dragonfly/analysis/file_command_analyser_spec.rb",
171
172
  "spec/dragonfly/analysis/r_magick_analyser_spec.rb",
172
173
  "spec/dragonfly/app_spec.rb",
174
+ "spec/dragonfly/config/r_magick_spec.rb",
173
175
  "spec/dragonfly/configurable_spec.rb",
174
176
  "spec/dragonfly/core_ext/string_spec.rb",
175
177
  "spec/dragonfly/core_ext/symbol_spec.rb",
@@ -70,6 +70,11 @@ The {Dragonfly::Config::RMagick RMagick configuration} registers the app with th
70
70
 
71
71
  The file 'dragonfly/rails/images' does this for you.
72
72
 
73
+ By default the processor, analyser, encoder and generator pass data around using tempfiles.
74
+ You can make it pass data around using in-memory strings using
75
+
76
+ app.configure_with(:rmagick, :use_filesystem => false)
77
+
73
78
  Rails
74
79
  -----
75
80
 
data/extra_docs/Rails2.md CHANGED
@@ -34,7 +34,7 @@ Gems
34
34
  ----
35
35
  environment.rb
36
36
 
37
- config.gem 'dragonfly', '~>0.7.3'
37
+ config.gem 'dragonfly', '~>0.7.4'
38
38
  config.gem 'rmagick', :lib => 'RMagick'
39
39
  config.gem 'rack-cache', :lib => 'rack/cache'
40
40
 
data/extra_docs/Rails3.md CHANGED
@@ -33,7 +33,7 @@ application.rb:
33
33
  Gemfile
34
34
  -------
35
35
 
36
- gem 'dragonfly', '~>0.7.3'
36
+ gem 'dragonfly', '~>0.7.4'
37
37
  gem 'rmagick', :require => 'RMagick'
38
38
  gem 'rack-cache', :require => 'rack/cache'
39
39
 
@@ -0,0 +1,8 @@
1
+ Feature: champion uses dragonfly in his Rails 3.0.0 application
2
+ In order to be a champion
3
+ A user uses dragonfly in his Rails 3.0.0 application
4
+
5
+ Scenario: Set up dragonfly using initializer
6
+ Given a Rails 3.0.0 application set up for using dragonfly
7
+ Then the manage_album_images cucumber features in my Rails 3.0.0 app should pass
8
+ And the text_images cucumber features in my Rails 3.0.0 app should pass
@@ -2,7 +2,7 @@ RAILS_APP_NAME = 'tmp_app'
2
2
  FIXTURES_PATH = ROOT_PATH + "/fixtures"
3
3
  GEMFILES = {
4
4
  '2.3.5' => ROOT_PATH + '/Gemfile.rails.2.3.5',
5
- '3.0.0.rc' => ROOT_PATH + '/Gemfile',
5
+ '3.0.0' => ROOT_PATH + '/Gemfile',
6
6
  }
7
7
 
8
8
  def fixture_path(version)
@@ -17,7 +17,7 @@ end
17
17
 
18
18
  {
19
19
  '2.3.5' => "BUNDLE_GEMFILE=#{GEMFILES['2.3.5']} rails #{RAILS_APP_NAME} -m template.rb",
20
- '3.0.0.rc' => "BUNDLE_GEMFILE=#{GEMFILES['3.0.0.rc']} bundle exec rails new #{RAILS_APP_NAME} -m template.rb"
20
+ '3.0.0' => "BUNDLE_GEMFILE=#{GEMFILES['3.0.0']} bundle exec rails new #{RAILS_APP_NAME} -m template.rb"
21
21
  }.each do |version, rails_command|
22
22
 
23
23
  Given /^a Rails #{version} application set up for using dragonfly$/ do
@@ -6,33 +6,36 @@ module Dragonfly
6
6
 
7
7
  include Loggable
8
8
  include RMagickUtils
9
+ include Configurable
10
+
11
+ configurable_attr :use_filesystem, true
9
12
 
10
13
  def width(temp_object)
11
- rmagick_image(temp_object) do |image|
14
+ ping_rmagick_image(temp_object) do |image|
12
15
  image.columns
13
16
  end
14
17
  end
15
18
 
16
19
  def height(temp_object)
17
- rmagick_image(temp_object) do |image|
20
+ ping_rmagick_image(temp_object) do |image|
18
21
  image.rows
19
22
  end
20
23
  end
21
24
 
22
25
  def aspect_ratio(temp_object)
23
- rmagick_image(temp_object) do |image|
26
+ ping_rmagick_image(temp_object) do |image|
24
27
  image.columns.to_f / image.rows
25
28
  end
26
29
  end
27
30
 
28
31
  def portrait?(temp_object)
29
- rmagick_image(temp_object) do |image|
32
+ ping_rmagick_image(temp_object) do |image|
30
33
  image.columns <= image.rows
31
34
  end
32
35
  end
33
36
 
34
37
  def landscape?(temp_object)
35
- rmagick_image(temp_object) do |image|
38
+ ping_rmagick_image(temp_object) do |image|
36
39
  image.columns >= image.rows
37
40
  end
38
41
  end
@@ -51,7 +54,7 @@ module Dragonfly
51
54
  alias number_of_colors number_of_colours
52
55
 
53
56
  def format(temp_object)
54
- rmagick_image(temp_object) do |image|
57
+ ping_rmagick_image(temp_object) do |image|
55
58
  image.format.downcase.to_sym
56
59
  end
57
60
  end
@@ -9,12 +9,21 @@ module Dragonfly
9
9
  # Look at the source code for apply_configuration to see exactly how it configures the app.
10
10
  module RMagick
11
11
 
12
- def self.apply_configuration(app)
12
+ def self.apply_configuration(app, opts={})
13
+ use_filesystem = opts.has_key?(:use_filesystem) ? opts[:use_filesystem] : true
13
14
  app.configure do |c|
14
- c.analyser.register(Analysis::RMagickAnalyser)
15
- c.processor.register(Processing::RMagickProcessor)
16
- c.encoder.register(Encoding::RMagickEncoder)
17
- c.generator.register(Generation::RMagickGenerator)
15
+ c.analyser.register(Analysis::RMagickAnalyser) do |a|
16
+ a.use_filesystem = use_filesystem
17
+ end
18
+ c.processor.register(Processing::RMagickProcessor) do |p|
19
+ p.use_filesystem = use_filesystem
20
+ end
21
+ c.encoder.register(Encoding::RMagickEncoder) do |e|
22
+ e.use_filesystem = use_filesystem
23
+ end
24
+ c.generator.register(Generation::RMagickGenerator) do |g|
25
+ g.use_filesystem = use_filesystem
26
+ end
18
27
  c.job :thumb do |geometry, format|
19
28
  process :thumb, geometry
20
29
  encode format if format
@@ -41,6 +41,7 @@ module Dragonfly
41
41
  :xpm,
42
42
  :xwd
43
43
  ]
44
+ configurable_attr :use_filesystem, true
44
45
 
45
46
  def encode(temp_object, format, encoding={})
46
47
  format = format.to_s.downcase
@@ -1,17 +1,17 @@
1
1
  module Dragonfly
2
2
  class FunctionManager
3
-
3
+
4
4
  # Exceptions
5
5
  class NotDefined < NoMethodError; end
6
6
  class UnableToHandle < NotImplementedError; end
7
-
7
+
8
8
  include Loggable
9
-
9
+
10
10
  def initialize
11
11
  @functions = {}
12
12
  @objects = []
13
13
  end
14
-
14
+
15
15
  def add(name, callable_obj=nil, &block)
16
16
  functions[name] ||= []
17
17
  functions[name] << (callable_obj || block)
@@ -29,7 +29,7 @@ module Dragonfly
29
29
  objects << obj
30
30
  obj
31
31
  end
32
-
32
+
33
33
  def call_last(meth, *args)
34
34
  if functions[meth.to_sym]
35
35
  functions[meth.to_sym].reverse.each do |function|
@@ -45,12 +45,16 @@ module Dragonfly
45
45
  end
46
46
  end
47
47
 
48
+ def get_registered(klass)
49
+ objects.reverse.detect{|o| o.instance_of?(klass) }
50
+ end
51
+
48
52
  def inspect
49
53
  to_s.sub(/>$/, " with functions: #{functions.keys.map{|k| k.to_s }.sort.join(', ')} >")
50
54
  end
51
55
 
52
56
  private
53
-
57
+
54
58
  def methods_to_add(obj)
55
59
  if obj.is_a?(Configurable)
56
60
  obj.public_methods(false) -
@@ -3,13 +3,13 @@ require 'RMagick'
3
3
  module Dragonfly
4
4
  module Generation
5
5
  class RMagickGenerator
6
-
6
+
7
7
  FONT_STYLES = {
8
8
  'normal' => Magick::NormalStyle,
9
9
  'italic' => Magick::ItalicStyle,
10
10
  'oblique' => Magick::ObliqueStyle
11
11
  }
12
-
12
+
13
13
  FONT_STRETCHES = {
14
14
  'normal' => Magick::NormalStretch,
15
15
  'semi-condensed' => Magick::SemiCondensedStretch,
@@ -21,7 +21,7 @@ module Dragonfly
21
21
  'extra-expanded' => Magick::ExtraExpandedStretch,
22
22
  'ultra-expanded' => Magick::UltraExpandedStretch
23
23
  }
24
-
24
+
25
25
  FONT_WEIGHTS = {
26
26
  'normal' => Magick::NormalWeight,
27
27
  'bold' => Magick::BoldWeight,
@@ -37,7 +37,7 @@ module Dragonfly
37
37
  '800' => 800,
38
38
  '900' => 900
39
39
  }
40
-
40
+
41
41
  # HashWithCssStyleKeys is solely for being able to access a hash
42
42
  # which has css-style keys (e.g. 'font-size') with the underscore
43
43
  # symbol version
@@ -55,25 +55,29 @@ module Dragonfly
55
55
  )
56
56
  end
57
57
  end
58
-
58
+
59
+ include RMagickUtils
60
+ include Configurable
61
+ configurable_attr :use_filesystem, true
62
+
59
63
  def plasma(width, height, format='png')
60
64
  image = Magick::Image.read("plasma:fractal"){self.size = "#{width}x#{height}"}.first
61
65
  image.format = format.to_s
62
- data = image.to_blob
66
+ content = use_filesystem ? write_to_tempfile(image) : image.to_blob
63
67
  image.destroy!
64
68
  [
65
- data,
69
+ content,
66
70
  {:format => format.to_sym, :name => "plasma.#{format}"}
67
71
  ]
68
72
  end
69
-
73
+
70
74
  def text(text_string, opts={})
71
75
  opts = HashWithCssStyleKeys[opts]
72
-
76
+
73
77
  draw = Magick::Draw.new
74
78
  draw.gravity = Magick::CenterGravity
75
79
  draw.text_antialias = true
76
-
80
+
77
81
  # Font size
78
82
  font_size = (opts[:font_size] || 12).to_i
79
83
 
@@ -112,22 +116,22 @@ module Dragonfly
112
116
  }
113
117
  # Draw the text
114
118
  draw.annotate(image, width, height, padding_left, padding_top, text_string)
115
-
119
+
116
120
  # Scale back down again
117
121
  image.scale!(1/s)
118
-
122
+
119
123
  format = opts[:format] || :png
120
124
  image.format = format.to_s
121
125
 
122
- # Output image as string
123
- data = image.to_blob
126
+ # Output image either as a string or a tempfile
127
+ content = use_filesystem ? write_to_tempfile(image) : image.to_blob
124
128
  image.destroy!
125
129
  [
126
- data,
130
+ content,
127
131
  {:format => format, :name => "text.#{format}"}
128
132
  ]
129
133
  end
130
-
134
+
131
135
  private
132
136
 
133
137
  # Use css-style padding declaration, i.e.
@@ -152,7 +156,7 @@ module Dragonfly
152
156
  else raise ArgumentError, "Couldn't parse padding string '#{str}' - should be a css-style string"
153
157
  end
154
158
  end
155
-
159
+
156
160
  def scale_factor_for(font_size)
157
161
  # Scale approximately to 64 if below
158
162
  min_size = 64
@@ -23,6 +23,9 @@ module Dragonfly
23
23
  THUMB_GEOMETRY = Regexp.union RESIZE_GEOMETRY, CROPPED_RESIZE_GEOMETRY, CROP_GEOMETRY
24
24
 
25
25
  include RMagickUtils
26
+ include Configurable
27
+
28
+ configurable_attr :use_filesystem, true
26
29
 
27
30
  def crop(temp_object, opts={})
28
31
  x = opts[:x].to_i
@@ -1,24 +1,46 @@
1
+ require 'tempfile'
2
+
1
3
  module Dragonfly
2
4
  module RMagickUtils
3
-
5
+
4
6
  private
5
-
7
+
8
+ # Requires the extended object to respond to 'use_filesystem'
6
9
  def rmagick_image(temp_object, &block)
7
- image = Magick::Image.from_blob(temp_object.data).first
8
- result = block[image]
10
+ imagelist = use_filesystem ? Magick::Image.read(temp_object.path) : Magick::Image.from_blob(temp_object.data)
11
+ image = imagelist.first
12
+ result = block.call(image)
9
13
  case result
10
14
  when Magick::Image, Magick::ImageList
11
- content = result.to_blob
15
+ content = use_filesystem ? write_to_tempfile(result) : result.to_blob
12
16
  result.destroy!
13
17
  else
14
18
  content = result
15
19
  end
16
- image.destroy! unless image.destroyed?
20
+ image.destroy!
17
21
  content
18
22
  rescue Magick::ImageMagickError => e
19
23
  log.warn("Unable to handle content in #{self.class} - got:\n#{e}")
20
24
  throw :unable_to_handle
21
25
  end
22
-
26
+
27
+ def ping_rmagick_image(temp_object, &block)
28
+ imagelist = use_filesystem ? Magick::Image.ping(temp_object.path) : Magick::Image.from_blob(temp_object.data)
29
+ image = imagelist.first
30
+ result = block.call(image)
31
+ image.destroy!
32
+ result
33
+ rescue Magick::ImageMagickError => e
34
+ log.warn("Unable to handle content in #{self.class} - got:\n#{e}")
35
+ throw :unable_to_handle
36
+ end
37
+
38
+ def write_to_tempfile(rmagick_image)
39
+ tempfile = Tempfile.new('dragonfly')
40
+ tempfile.close
41
+ rmagick_image.write(tempfile.path)
42
+ tempfile
43
+ end
44
+
23
45
  end
24
46
  end
@@ -1,5 +1,4 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
- require 'active_support/core_ext/hash/except' # Needed for Rails 3.0.0.rc but subsequently fixed - TODO: remove when gem is updated
3
2
 
4
3
  describe Item do
5
4
 
@@ -9,36 +9,54 @@ describe Dragonfly::Analysis::RMagickAnalyser do
9
9
  @analyser.log = Logger.new(LOG_FILE)
10
10
  end
11
11
 
12
- it "should return the width" do
13
- @analyser.width(@beach).should == 280
14
- end
12
+ describe "analysis methods", :shared => true do
13
+
14
+ it "should return the width" do
15
+ @analyser.width(@beach).should == 280
16
+ end
15
17
 
16
- it "should return the height" do
17
- @analyser.height(@beach).should == 355
18
- end
18
+ it "should return the height" do
19
+ @analyser.height(@beach).should == 355
20
+ end
19
21
 
20
- it "should return the aspect ratio" do
21
- @analyser.aspect_ratio(@beach).should == (280.0/355.0)
22
- end
22
+ it "should return the aspect ratio" do
23
+ @analyser.aspect_ratio(@beach).should == (280.0/355.0)
24
+ end
23
25
 
24
- it "should say if it's portrait" do
25
- @analyser.portrait?(@beach).should be_true
26
- end
26
+ it "should say if it's portrait" do
27
+ @analyser.portrait?(@beach).should be_true
28
+ end
27
29
 
28
- it "should say if it's landscape" do
29
- @analyser.landscape?(@beach).should be_false
30
- end
30
+ it "should say if it's landscape" do
31
+ @analyser.landscape?(@beach).should be_false
32
+ end
33
+
34
+ it "should return the number of colours" do
35
+ @analyser.number_of_colours(@beach).should == 34703
36
+ end
37
+
38
+ it "should return the depth" do
39
+ @analyser.depth(@beach).should == 8
40
+ end
31
41
 
32
- it "should return the number of colours" do
33
- @analyser.number_of_colours(@beach).should == 34703
42
+ it "should return the format" do
43
+ @analyser.format(@beach).should == :png
44
+ end
45
+
34
46
  end
35
47
 
36
- it "should return the depth" do
37
- @analyser.depth(@beach).should == 8
48
+ describe "when using the filesystem" do
49
+ before(:each) do
50
+ @analyser.use_filesystem = true
51
+ end
52
+ it_should_behave_like "analysis methods"
38
53
  end
39
54
 
40
- it "should return the format" do
41
- @analyser.format(@beach).should == :png
55
+ describe "when not using the filesystem" do
56
+ before(:each) do
57
+ @analyser.use_filesystem = false
58
+ end
59
+ it_should_behave_like "analysis methods"
42
60
  end
43
61
 
44
62
  %w(width height aspect_ratio number_of_colours depth format portrait? landscape?).each do |meth|
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Dragonfly::Config::RMagick do
4
+
5
+ before(:each) do
6
+ @app = test_app
7
+ end
8
+
9
+ it "should configure all to use the filesystem by default" do
10
+ @app.configure_with(Dragonfly::Config::RMagick)
11
+ @app.analyser.get_registered(Dragonfly::Analysis::RMagickAnalyser).use_filesystem.should be_true
12
+ @app.processor.get_registered(Dragonfly::Processing::RMagickProcessor).use_filesystem.should be_true
13
+ @app.encoder.get_registered(Dragonfly::Encoding::RMagickEncoder).use_filesystem.should be_true
14
+ @app.generator.get_registered(Dragonfly::Generation::RMagickGenerator).use_filesystem.should be_true
15
+ end
16
+
17
+ it "should configure all not to use the filesystem if requested" do
18
+ @app.configure_with(Dragonfly::Config::RMagick, :use_filesystem => false)
19
+ @app.analyser.get_registered(Dragonfly::Analysis::RMagickAnalyser).use_filesystem.should be_false
20
+ @app.processor.get_registered(Dragonfly::Processing::RMagickProcessor).use_filesystem.should be_false
21
+ @app.encoder.get_registered(Dragonfly::Encoding::RMagickEncoder).use_filesystem.should be_false
22
+ @app.generator.get_registered(Dragonfly::Generation::RMagickGenerator).use_filesystem.should be_false
23
+ end
24
+
25
+ end
@@ -28,6 +28,13 @@ describe Dragonfly::Encoding::RMagickEncoder do
28
28
  image = @encoder.encode(@image, :png)
29
29
  image.should == @image
30
30
  end
31
+
32
+ it "should work when not using the filesystem" do
33
+ @encoder.use_filesystem = false
34
+ image = @encoder.encode(@image, :gif)
35
+ image.should have_format('gif')
36
+ end
37
+
31
38
  end
32
39
 
33
40
  end
@@ -6,7 +6,7 @@ describe Dragonfly::Generation::RMagickGenerator do
6
6
  before(:each) do
7
7
  @generator = Dragonfly::Generation::RMagickGenerator.new
8
8
  end
9
-
9
+
10
10
  describe "generating an image with the given dimensions" do
11
11
  before(:each) do
12
12
  @image, @extra = @generator.plasma(23,12)
@@ -16,7 +16,7 @@ describe Dragonfly::Generation::RMagickGenerator do
16
16
  it {@image.should have_format('png')}
17
17
  it {@extra.should == {:format => :png, :name => 'plasma.png'}}
18
18
  end
19
-
19
+
20
20
  describe "specifying the format" do
21
21
  before(:each) do
22
22
  @image, @extra = @generator.plasma(23, 12, :gif)
@@ -24,6 +24,14 @@ describe Dragonfly::Generation::RMagickGenerator do
24
24
  it {@image.should have_format('gif')}
25
25
  it {@extra.should == {:format => :gif, :name => 'plasma.gif'}}
26
26
  end
27
+
28
+ describe "when not using the filesystem" do
29
+ it "should still work" do
30
+ @generator.use_filesystem = false
31
+ image, extra = @generator.plasma(4, 6)
32
+ image.should have_width(4)
33
+ end
34
+ end
27
35
  end
28
36
 
29
37
  describe "text" do
@@ -50,6 +58,14 @@ describe Dragonfly::Generation::RMagickGenerator do
50
58
  it {@extra.should == {:format => :gif, :name => 'text.gif'}}
51
59
  end
52
60
 
61
+ describe "when not using the filesystem" do
62
+ it "should still work" do
63
+ @generator.use_filesystem = false
64
+ image, extra = @generator.text(@text, :font_size => 12)
65
+ image.should have_width(20..40)
66
+ end
67
+ end
68
+
53
69
  # it "should ignore percent characters used by rmagick"
54
70
 
55
71
  describe "padding" do
@@ -1,218 +1,236 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe Dragonfly::Processing::RMagickProcessor do
4
+
5
+ describe "processing methods", :shared => true do
4
6
 
5
- before(:each) do
6
- sample_file = File.dirname(__FILE__) + '/../../../samples/beach.png' # 280x355
7
- @image = Dragonfly::TempObject.new(File.new(sample_file))
8
- @processor = Dragonfly::Processing::RMagickProcessor.new
9
- end
7
+ describe "resize" do
10
8
 
11
- describe "resize" do
12
-
13
- it "should work correctly with xNN" do
14
- image = @processor.resize(@image, 'x30')
15
- image.should have_width(24)
16
- image.should have_height(30)
17
- end
18
-
19
- it "should work correctly with NNx" do
20
- image = @processor.resize(@image, '30x')
21
- image.should have_width(30)
22
- image.should have_height(38)
23
- end
24
-
25
- it "should work correctly with NNxNN" do
26
- image = @processor.resize(@image, '30x30')
27
- image.should have_width(24)
28
- image.should have_height(30)
29
- end
30
-
31
- it "should work correctly with NNxNN!" do
32
- image = @processor.resize(@image, '30x30!')
33
- image.should have_width(30)
34
- image.should have_height(30)
35
- end
36
-
37
- it "should work correctly with NNxNN%" do
38
- image = @processor.resize(@image, '25x50%')
39
- image.should have_width(70)
40
- image.should have_height(178)
41
- end
42
-
43
- describe "NNxNN>" do
44
-
45
- it "should not resize if the image is smaller than specified" do
46
- image = @processor.resize(@image, '1000x1000>')
47
- image.should have_width(280)
48
- image.should have_height(355)
9
+ it "should work correctly with xNN" do
10
+ image = @processor.resize(@image, 'x30')
11
+ image.should have_width(24)
12
+ image.should have_height(30)
49
13
  end
50
-
51
- it "should resize if the image is larger than specified" do
52
- image = @processor.resize(@image, '30x30>')
14
+
15
+ it "should work correctly with NNx" do
16
+ image = @processor.resize(@image, '30x')
17
+ image.should have_width(30)
18
+ image.should have_height(38)
19
+ end
20
+
21
+ it "should work correctly with NNxNN" do
22
+ image = @processor.resize(@image, '30x30')
53
23
  image.should have_width(24)
54
24
  image.should have_height(30)
55
25
  end
56
-
26
+
27
+ it "should work correctly with NNxNN!" do
28
+ image = @processor.resize(@image, '30x30!')
29
+ image.should have_width(30)
30
+ image.should have_height(30)
31
+ end
32
+
33
+ it "should work correctly with NNxNN%" do
34
+ image = @processor.resize(@image, '25x50%')
35
+ image.should have_width(70)
36
+ image.should have_height(178)
37
+ end
38
+
39
+ describe "NNxNN>" do
40
+
41
+ it "should not resize if the image is smaller than specified" do
42
+ image = @processor.resize(@image, '1000x1000>')
43
+ image.should have_width(280)
44
+ image.should have_height(355)
45
+ end
46
+
47
+ it "should resize if the image is larger than specified" do
48
+ image = @processor.resize(@image, '30x30>')
49
+ image.should have_width(24)
50
+ image.should have_height(30)
51
+ end
52
+
53
+ end
54
+
55
+ describe "NNxNN<" do
56
+
57
+ it "should not resize if the image is larger than specified" do
58
+ image = @processor.resize(@image, '10x10<')
59
+ image.should have_width(280)
60
+ image.should have_height(355)
61
+ end
62
+
63
+ it "should resize if the image is smaller than specified" do
64
+ image = @processor.resize(@image, '400x400<')
65
+ image.should have_width(315)
66
+ image.should have_height(400)
67
+ end
68
+
69
+ end
70
+
57
71
  end
58
-
59
- describe "NNxNN<" do
60
-
61
- it "should not resize if the image is larger than specified" do
62
- image = @processor.resize(@image, '10x10<')
72
+
73
+ describe "crop" do # Difficult to test here other than dimensions
74
+
75
+ it "should not crop if no args given" do
76
+ image = @processor.crop(@image)
63
77
  image.should have_width(280)
64
78
  image.should have_height(355)
65
79
  end
66
-
67
- it "should resize if the image is smaller than specified" do
68
- image = @processor.resize(@image, '400x400<')
69
- image.should have_width(315)
70
- image.should have_height(400)
80
+
81
+ it "should crop using the offset given" do
82
+ image = @processor.crop(@image, :x => '7', :y => '12')
83
+ image.should have_width(273)
84
+ image.should have_height(343)
71
85
  end
72
-
73
- end
74
-
75
- end
76
86
 
77
- describe "crop" do # Difficult to test here other than dimensions
78
-
79
- it "should not crop if no args given" do
80
- image = @processor.crop(@image)
81
- image.should have_width(280)
82
- image.should have_height(355)
83
- end
84
-
85
- it "should crop using the offset given" do
86
- image = @processor.crop(@image, :x => '7', :y => '12')
87
- image.should have_width(273)
88
- image.should have_height(343)
89
- end
90
-
91
- it "should crop using the dimensions given" do
92
- image = @processor.crop(@image, :width => '10', :height => '20')
93
- image.should have_width(10)
94
- image.should have_height(20)
95
- end
96
-
97
- it "should crop in one dimension if given" do
98
- image = @processor.crop(@image, :width => '10')
99
- image.should have_width(10)
100
- image.should have_height(355)
101
- end
102
-
103
- it "should take into account the gravity given" do
104
- image1 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'nw')
105
- image2 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'se')
106
- image1.should_not == image2
107
- end
108
-
109
- it "should clip bits of the image outside of the requested crop area when not nw gravity" do
110
- # Rmagick was previously throwing an error when the cropping area was outside the image size, when
111
- # using a gravity other than nw
112
- image = @processor.crop(@image, :width => '500', :height => '1000', :x => '100', :y => '200', :gravity => 'se')
113
- image.should have_width(180)
114
- image.should have_height(155)
115
- end
116
-
117
- end
87
+ it "should crop using the dimensions given" do
88
+ image = @processor.crop(@image, :width => '10', :height => '20')
89
+ image.should have_width(10)
90
+ image.should have_height(20)
91
+ end
118
92
 
119
- describe "greyscale" do
120
- it "should not raise an error" do
121
- # Bit tricky to test
122
- @processor.greyscale(@image)
123
- end
124
- end
93
+ it "should crop in one dimension if given" do
94
+ image = @processor.crop(@image, :width => '10')
95
+ image.should have_width(10)
96
+ image.should have_height(355)
97
+ end
98
+
99
+ it "should take into account the gravity given" do
100
+ image1 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'nw')
101
+ image2 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'se')
102
+ image1.should_not == image2
103
+ end
104
+
105
+ it "should clip bits of the image outside of the requested crop area when not nw gravity" do
106
+ # Rmagick was previously throwing an error when the cropping area was outside the image size, when
107
+ # using a gravity other than nw
108
+ image = @processor.crop(@image, :width => '500', :height => '1000', :x => '100', :y => '200', :gravity => 'se')
109
+ image.should have_width(180)
110
+ image.should have_height(155)
111
+ end
125
112
 
126
- describe "resize_and_crop" do
127
-
128
- it "should do nothing if no args given" do
129
- image = @processor.resize_and_crop(@image)
130
- image.should have_width(280)
131
- image.should have_height(355)
132
113
  end
133
-
134
- it "should crop to the correct dimensions" do
135
- image = @processor.resize_and_crop(@image, :width => '100', :height => '100')
136
- image.should have_width(100)
137
- image.should have_height(100)
114
+
115
+ describe "greyscale" do
116
+ it "should not raise an error" do
117
+ # Bit tricky to test
118
+ @processor.greyscale(@image)
119
+ end
138
120
  end
139
-
140
- it "should allow cropping in one dimension" do
141
- image = @processor.resize_and_crop(@image, :width => '100')
142
- image.should have_width(100)
143
- image.should have_height(355)
121
+
122
+ describe "resize_and_crop" do
123
+
124
+ it "should do nothing if no args given" do
125
+ image = @processor.resize_and_crop(@image)
126
+ image.should have_width(280)
127
+ image.should have_height(355)
128
+ end
129
+
130
+ it "should crop to the correct dimensions" do
131
+ image = @processor.resize_and_crop(@image, :width => '100', :height => '100')
132
+ image.should have_width(100)
133
+ image.should have_height(100)
134
+ end
135
+
136
+ it "should allow cropping in one dimension" do
137
+ image = @processor.resize_and_crop(@image, :width => '100')
138
+ image.should have_width(100)
139
+ image.should have_height(355)
140
+ end
141
+
142
+ it "should take into account the gravity given" do
143
+ image1 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'nw')
144
+ image2 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'se')
145
+ image1.should_not == image2
146
+ end
147
+
144
148
  end
145
-
146
- it "should take into account the gravity given" do
147
- image1 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'nw')
148
- image2 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'se')
149
- image1.should_not == image2
149
+
150
+ describe "rotate" do
151
+
152
+ it "should rotate by 90 degrees" do
153
+ image = @processor.rotate(@image, 90)
154
+ image.should have_width(355)
155
+ image.should have_height(280)
156
+ end
157
+
158
+ it "should not rotate given a larger height and the '>' qualifier" do
159
+ image = @processor.rotate(@image, 90, :qualifier => '>')
160
+ image.should have_width(280)
161
+ image.should have_height(355)
162
+ end
163
+
164
+ it "should rotate given a larger height and the '<' qualifier" do
165
+ image = @processor.rotate(@image, 90, :qualifier => '<')
166
+ image.should have_width(355)
167
+ image.should have_height(280)
168
+ end
169
+
150
170
  end
151
-
152
- end
153
171
 
154
- describe "rotate" do
155
-
156
- it "should rotate by 90 degrees" do
157
- image = @processor.rotate(@image, 90)
158
- image.should have_width(355)
159
- image.should have_height(280)
172
+ describe "thumb" do
173
+ it "should call resize if the correct string given" do
174
+ @processor.should_receive(:resize).with(@image, '30x40').and_return(image = mock)
175
+ @processor.thumb(@image, '30x40').should == image
176
+ end
177
+ it "should call resize_and_crop if the correct string given" do
178
+ @processor.should_receive(:resize_and_crop).with(@image, :width => '30', :height => '40', :gravity => 'se').and_return(image = mock)
179
+ @processor.thumb(@image, '30x40#se').should == image
180
+ end
181
+ it "should call crop if x and y given" do
182
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '+10', :y => '+20', :gravity => nil).and_return(image = mock)
183
+ @processor.thumb(@image, '30x40+10+20').should == image
184
+ end
185
+ it "should call crop if just gravity given" do
186
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => nil, :y => nil, :gravity => 'sw').and_return(image = mock)
187
+ @processor.thumb(@image, '30x40sw').should == image
188
+ end
189
+ it "should call crop if x, y and gravity given" do
190
+ @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '-10', :y => '-20', :gravity => 'se').and_return(image = mock)
191
+ @processor.thumb(@image, '30x40-10-20se').should == image
192
+ end
193
+ it "should raise an argument error if an unrecognized string is given" do
194
+ lambda{ @processor.thumb(@image, '30x40#ne!') }.should raise_error(ArgumentError)
195
+ end
160
196
  end
161
-
162
- it "should not rotate given a larger height and the '>' qualifier" do
163
- image = @processor.rotate(@image, 90, :qualifier => '>')
164
- image.should have_width(280)
165
- image.should have_height(355)
197
+
198
+ describe "flip" do
199
+ it "should flip the image, leaving the same dimensions" do
200
+ image = @processor.flip(@image)
201
+ image.should have_width(280)
202
+ image.should have_height(355)
203
+ end
166
204
  end
167
-
168
- it "should rotate given a larger height and the '<' qualifier" do
169
- image = @processor.rotate(@image, 90, :qualifier => '<')
170
- image.should have_width(355)
171
- image.should have_height(280)
205
+
206
+ describe "flop" do
207
+ it "should flop the image, leaving the same dimensions" do
208
+ image = @processor.flop(@image)
209
+ image.should have_width(280)
210
+ image.should have_height(355)
211
+ end
172
212
  end
173
-
213
+
174
214
  end
175
215
 
176
- describe "thumb" do
177
- it "should call resize if the correct string given" do
178
- @processor.should_receive(:resize).with(@image, '30x40').and_return(image = mock)
179
- @processor.thumb(@image, '30x40').should == image
180
- end
181
- it "should call resize_and_crop if the correct string given" do
182
- @processor.should_receive(:resize_and_crop).with(@image, :width => '30', :height => '40', :gravity => 'se').and_return(image = mock)
183
- @processor.thumb(@image, '30x40#se').should == image
184
- end
185
- it "should call crop if x and y given" do
186
- @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '+10', :y => '+20', :gravity => nil).and_return(image = mock)
187
- @processor.thumb(@image, '30x40+10+20').should == image
188
- end
189
- it "should call crop if just gravity given" do
190
- @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => nil, :y => nil, :gravity => 'sw').and_return(image = mock)
191
- @processor.thumb(@image, '30x40sw').should == image
192
- end
193
- it "should call crop if x, y and gravity given" do
194
- @processor.should_receive(:crop).with(@image, :width => '30', :height => '40', :x => '-10', :y => '-20', :gravity => 'se').and_return(image = mock)
195
- @processor.thumb(@image, '30x40-10-20se').should == image
196
- end
197
- it "should raise an argument error if an unrecognized string is given" do
198
- lambda{ @processor.thumb(@image, '30x40#ne!') }.should raise_error(ArgumentError)
199
- end
216
+ before(:each) do
217
+ sample_file = File.dirname(__FILE__) + '/../../../samples/beach.png' # 280x355
218
+ @image = Dragonfly::TempObject.new(File.new(sample_file))
219
+ @processor = Dragonfly::Processing::RMagickProcessor.new
200
220
  end
201
221
 
202
- describe "flip" do
203
- it "should flip the image, leaving the same dimensions" do
204
- image = @processor.flip(@image)
205
- image.should have_width(280)
206
- image.should have_height(355)
222
+ describe "when using the filesystem" do
223
+ before(:each) do
224
+ @processor.use_filesystem = true
207
225
  end
226
+ it_should_behave_like "processing methods"
208
227
  end
209
228
 
210
- describe "flop" do
211
- it "should flop the image, leaving the same dimensions" do
212
- image = @processor.flop(@image)
213
- image.should have_width(280)
214
- image.should have_height(355)
229
+ describe "when not using the filesystem" do
230
+ before(:each) do
231
+ @processor.use_filesystem = false
215
232
  end
233
+ it_should_behave_like "processing methods"
216
234
  end
217
-
235
+
218
236
  end
@@ -1,11 +1,11 @@
1
1
  def image_properties(image)
2
- data = case image
3
- when Dragonfly::TempObject then image.data
4
- when String then image
2
+ if image.is_a?(Tempfile)
3
+ tempfile = image
4
+ else
5
+ tempfile = Tempfile.new('image')
6
+ tempfile.write(image.is_a?(Dragonfly::TempObject) ? image.data : image)
7
+ tempfile.close
5
8
  end
6
- tempfile = Tempfile.new('image')
7
- tempfile.write(data)
8
- tempfile.close
9
9
  details = `identify #{tempfile.path}`
10
10
  # example of details string:
11
11
  # myimage.png PNG 200x100 200x100+0+0 8-bit DirectClass 31.2kb
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dragonfly
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 7
9
- - 4
10
- version: 0.7.4
8
+ - 5
9
+ version: 0.7.5
11
10
  platform: ruby
12
11
  authors:
13
12
  - Mark Evans
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-08-28 00:00:00 +01:00
17
+ date: 2010-09-01 00:00:00 +01:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -26,7 +25,6 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 3
30
28
  segments:
31
29
  - 0
32
30
  version: "0"
@@ -76,7 +74,7 @@ files:
76
74
  - features/images.feature
77
75
  - features/no_processing.feature
78
76
  - features/rails_2.3.5.feature
79
- - features/rails_3.0.0.rc.feature
77
+ - features/rails_3.0.0.feature
80
78
  - features/steps/common_steps.rb
81
79
  - features/steps/dragonfly_steps.rb
82
80
  - features/steps/rails_steps.rb
@@ -90,7 +88,7 @@ files:
90
88
  - fixtures/files/features/support/paths.rb
91
89
  - fixtures/files/features/text_images.feature
92
90
  - fixtures/rails_2.3.5/template.rb
93
- - fixtures/rails_3.0.0.rc/template.rb
91
+ - fixtures/rails_3.0.0/template.rb
94
92
  - irbrc.rb
95
93
  - lib/dragonfly.rb
96
94
  - lib/dragonfly/active_model_extensions.rb
@@ -148,6 +146,7 @@ files:
148
146
  - spec/dragonfly/analysis/file_command_analyser_spec.rb
149
147
  - spec/dragonfly/analysis/r_magick_analyser_spec.rb
150
148
  - spec/dragonfly/app_spec.rb
149
+ - spec/dragonfly/config/r_magick_spec.rb
151
150
  - spec/dragonfly/configurable_spec.rb
152
151
  - spec/dragonfly/core_ext/string_spec.rb
153
152
  - spec/dragonfly/core_ext/symbol_spec.rb
@@ -194,7 +193,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
193
  requirements:
195
194
  - - ">="
196
195
  - !ruby/object:Gem::Version
197
- hash: 3
198
196
  segments:
199
197
  - 0
200
198
  version: "0"
@@ -203,7 +201,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
201
  requirements:
204
202
  - - ">="
205
203
  - !ruby/object:Gem::Version
206
- hash: 3
207
204
  segments:
208
205
  - 0
209
206
  version: "0"
@@ -224,6 +221,7 @@ test_files:
224
221
  - spec/dragonfly/analysis/file_command_analyser_spec.rb
225
222
  - spec/dragonfly/analysis/r_magick_analyser_spec.rb
226
223
  - spec/dragonfly/app_spec.rb
224
+ - spec/dragonfly/config/r_magick_spec.rb
227
225
  - spec/dragonfly/configurable_spec.rb
228
226
  - spec/dragonfly/core_ext/string_spec.rb
229
227
  - spec/dragonfly/core_ext/symbol_spec.rb
@@ -1,8 +0,0 @@
1
- Feature: champion uses dragonfly in his Rails 3.0.0.rc application
2
- In order to be a champion
3
- A user uses dragonfly in his Rails 3.0.0.rc application
4
-
5
- Scenario: Set up dragonfly using initializer
6
- Given a Rails 3.0.0.rc application set up for using dragonfly
7
- Then the manage_album_images cucumber features in my Rails 3.0.0.rc app should pass
8
- And the text_images cucumber features in my Rails 3.0.0.rc app should pass