norman-has_image 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,24 +9,32 @@ module HasImage
9
9
 
10
10
  class << self
11
11
 
12
- # "The form of an {extended geometry
13
- # string}[http://www.imagemagick.org/script/command-line-options.php?#resize] is
14
- # <width>x<height>{+-}<xoffset>{+-}<yoffset>{%}{!}{<}{>}"
12
+ # The form of an {extended geometry string}[http://www.imagemagick.org/script/command-line-options.php?#resize] is:
13
+ #
14
+ # <width>x<height>{+-}<xoffset>{+-}<yoffset>{%}{!}{<}{>}
15
15
  def geometry_string_valid?(string)
16
16
  string =~ /\A[\d]*x[\d]*([+-][0-9][+-][0-9])?[%@!<>^]?\Z/
17
17
  end
18
18
 
19
- # Arg should be either a file, or a path. This runs ImageMagick's
20
- # "identify" command and looks for an exit status indicating an error. If
21
- # there is no error, then ImageMagick has identified the file as something
22
- # it can work with and it will be converted to the desired output format.
19
+ # Arg should be either a file or a path. This runs ImageMagick's
20
+ # "identify" command and looks for an exit status indicating an error.
21
+ # If there is no error, then ImageMagick has identified the file as
22
+ # something it can work with and it will be converted to the desired
23
+ # output format.
24
+ #
25
+ # Note that this is used in place of any mimetype checks. HasImage
26
+ # assumes that is ImageMagick is able to process the file, then it's OK.
27
+ # Since ImageMagick can be compiled with many different options for
28
+ # supporting various file types (or not) this is safer and more complete
29
+ # than checking the mime type.
23
30
  def valid?(arg)
24
31
  arg.close if arg.respond_to?(:close) && !arg.closed?
25
32
  silence_stderr do
26
33
  `identify #{arg.respond_to?(:path) ? arg.path : arg.to_s}`
27
34
  $? == 0
28
35
  end
29
- end
36
+ end
37
+
30
38
  end
31
39
 
32
40
  # The constuctor should be invoked with the options set by has_image.
@@ -34,25 +42,47 @@ module HasImage
34
42
  @options = options
35
43
  end
36
44
 
37
- # Create the resized image, and transforms it to the desired output
38
- # format if necessary. The size should be a valid ImageMagick {geometry
39
- # string}[http://www.imagemagick.org/script/command-line-options.php#resize].
40
- def resize(file, size)
41
- unless Processor.geometry_string_valid?(size)
45
+ # Creates the resized image, and transforms it to the desired output
46
+ # format if necessary.
47
+ #
48
+ # +size+ should be a valid ImageMagick {geometry string}[http://www.imagemagick.org/script/command-line-options.php#resize].
49
+ # +format+ should be an image format supported by ImageMagick, e.g. "PNG", "JPEG"
50
+ # If a block is given, it yields the processed image file as a file-like object using IO#read.
51
+ def process(file, size = options[:resize_to], format = options[:convert_to])
52
+ unless size.blank? || Processor.geometry_string_valid?(size)
42
53
  raise InvalidGeometryError.new('"%s" is not a valid ImageMagick geometry string' % size)
43
54
  end
44
- silence_stderr do
45
- path = file.respond_to?(:path) ? file.path : file
46
- file.close if file.respond_to?(:close) && !file.closed?
47
- @image = MiniMagick::Image.from_file(path)
48
- convert_image
49
- resize_image(size)
50
- return @image
55
+ with_image(file) do |image|
56
+ convert_image(image, format) if format
57
+ resize_image(image, size) if size
58
+ yield IO.read(image.path) if block_given?
59
+ image
51
60
  end
52
- rescue MiniMagick::MiniMagickError
53
- raise ProcessorError.new("That doesn't look like an image file.")
54
61
  end
62
+ alias_method :resize, :process #Backwards-compat
55
63
 
64
+ # Gets the given +dimension+ (width/height) from the image file at +path+.
65
+ def measure(path, dimension)
66
+ MiniMagick::Image.from_file(path)[dimension.to_sym]
67
+ end
68
+
69
+ private
70
+ # Operates on the image with MiniMagick. Yields a MiniMagick::Image object.
71
+ def with_image(file)
72
+ path = file.respond_to?(:path) ? file.path : file
73
+ file.close if file.respond_to?(:close) && !file.closed?
74
+ silence_stderr do
75
+ begin
76
+ image = MiniMagick::Image.from_file(path)
77
+ yield image
78
+ rescue MiniMagick::MiniMagickError
79
+ raise ProcessorError.new("#{path} doesn't look like an image file.")
80
+ ensure
81
+ image.tempfile.close! if defined?(image) && image
82
+ end
83
+ end
84
+ end
85
+
56
86
  # Image resizing is placed in a separate method for easy monkey-patching.
57
87
  # This is intended to be invoked from resize, rather than directly.
58
88
  # By default, the following ImageMagick functionality is invoked:
@@ -62,8 +92,10 @@ module HasImage
62
92
  # * gravity[http://www.imagemagick.org/script/command-line-options.php#gravity]
63
93
  # * extent[http://www.imagemagick.org/script/command-line-options.php#extent]
64
94
  # * quality[http://www.imagemagick.org/script/command-line-options.php#quality]
65
- def resize_image(size)
66
- @image.combine_options do |commands|
95
+ #
96
+ # +image+ should be a MiniMagick::Image. +size+ should be a geometry string.
97
+ def resize_image(image, size)
98
+ image.combine_options do |commands|
67
99
  commands.send("auto-orient".to_sym)
68
100
  commands.strip
69
101
  # Fixed-dimension images
@@ -79,13 +111,8 @@ module HasImage
79
111
  end
80
112
  end
81
113
 
82
- private
83
-
84
- # This was placed in a separate method largely to facilitate debugging
85
- # and profiling.
86
- def convert_image
87
- return if @image[:format] == options[:convert_to]
88
- @image.format(options[:convert_to])
114
+ def convert_image(image, format=options[:convert_to])
115
+ image.format(format) unless image[:format] == format
89
116
  end
90
117
 
91
118
  end
@@ -11,6 +11,8 @@ module HasImage
11
11
  # storage mechanism for Amazon AWS, Photobucket, DBFile, SFTP, or whatever
12
12
  # you want.
13
13
  class Storage
14
+ class_inheritable_accessor :thumbnail_separator
15
+ write_inheritable_attribute :thumbnail_separator, '_'
14
16
 
15
17
  attr_accessor :image_data, :options, :temp_file
16
18
 
@@ -21,17 +23,29 @@ module HasImage
21
23
  # to this problem fails with high ids, such as those created by
22
24
  # db:fixture:load. This version scales to large ids more gracefully.
23
25
  # Thanks to Adrian Mugnolo for the fix.
26
+ #++
27
+ # FIXME: collides with IDs with more than 8 digits
28
+ #--
24
29
  def partitioned_path(id, *args)
25
30
  ["%04d" % ((id.to_i / 1e4) % 1e4), "%04d" % (id.to_i % 1e4)].concat(args)
26
31
  end
27
-
32
+
33
+ def id_from_partitioned_path(partitioned_path)
34
+ partitioned_path.join.to_i
35
+ end
36
+
37
+ def id_from_path(path)
38
+ path = path.split('/') if path.is_a?(String)
39
+ path_partitions = 2
40
+ id_from_partitioned_path(path.first(path_partitions))
41
+ end
42
+
28
43
  # By default, simply accepts and returns the id of the object. This is
29
44
  # here to allow you to monkey patch this method, for example, if you
30
45
  # wish instead to generate and return a UUID.
31
46
  def generated_file_name(*args)
32
47
  return args.first.to_param.to_s
33
48
  end
34
-
35
49
  end
36
50
 
37
51
  # The constuctor should be invoked with the options set by has_image.
@@ -49,7 +63,7 @@ module HasImage
49
63
  else
50
64
  image_data.rewind
51
65
  @temp_file = Tempfile.new 'has_image_data_%s' % Storage.generated_file_name
52
- @temp_file.write(image_data.read)
66
+ @temp_file.write(image_data.read)
53
67
  end
54
68
  end
55
69
 
@@ -65,24 +79,23 @@ module HasImage
65
79
  @temp_file.size > options[:max_size]
66
80
  end
67
81
 
68
- # A tip of the hat to attachment_fu.
69
- alias uploaded_data= image_data=
70
-
71
- # A tip of the hat to attachment_fu.
72
- alias uploaded_data image_data
73
-
74
82
  # Invokes the processor to resize the image(s) and the installs them to
75
83
  # the appropriate directory.
76
84
  def install_images(object)
77
85
  generated_name = Storage.generated_file_name(object)
78
86
  install_main_image(object.has_image_id, generated_name)
79
- install_thumbnails(object.has_image_id, generated_name) if !options[:thumbnails].empty?
87
+ generate_thumbnails(object.has_image_id, generated_name) if thumbnails_needed?
80
88
  return generated_name
81
89
  ensure
82
90
  @temp_file.close! if !@temp_file.closed?
83
91
  @temp_file = nil
84
92
  end
85
93
 
94
+ # Measures the given dimension using the processor
95
+ def measure(path, dimension)
96
+ processor.measure(path, dimension)
97
+ end
98
+
86
99
  # Gets the "web" path for an image. For example:
87
100
  #
88
101
  # /photos/0000/0001/3er0zs.jpg
@@ -108,10 +121,32 @@ module HasImage
108
121
  !(image_too_small? || image_too_big?)
109
122
  end
110
123
 
111
- def regenerate_thumbnails(id, name)
112
- install_thumbnails(id, name)
124
+ # Write the thumbnails to the install directory - probably somewhere under
125
+ # RAILS_ROOT/public.
126
+ def generate_thumbnails(id, name)
127
+ ensure_directory_exists!(id)
128
+ options[:thumbnails].keys.each { |thumb_name| generate_thumbnail(id, name, thumb_name) }
129
+ end
130
+ alias_method :regenerate_thumbnails, :generate_thumbnails #Backwards-compat
131
+
132
+ def generate_thumbnail(id, name, thumb_name)
133
+ size_spec = options[:thumbnails][thumb_name.to_sym]
134
+ raise StorageError unless size_spec
135
+ ensure_directory_exists!(id)
136
+ File.open absolute_path(id, name, thumb_name), "w" do |thumbnail_destination|
137
+ processor.process absolute_path(id, name), size_spec do |thumbnail_data|
138
+ thumbnail_destination.write thumbnail_data
139
+ end
140
+ end
113
141
  end
114
-
142
+
143
+ # Gets the full local filesystem path for an image. For example:
144
+ #
145
+ # /var/sites/example.com/production/public/photos/0000/0001/3er0zs.jpg
146
+ def filesystem_path_for(object, thumbnail = nil)
147
+ File.join(path_for(object.has_image_id), file_name_for(object.send(options[:column]), thumbnail))
148
+ end
149
+
115
150
  protected
116
151
 
117
152
  # Gets the extension to append to the image. Transforms "jpeg" to "jpg."
@@ -129,49 +164,42 @@ module HasImage
129
164
  #
130
165
  # "abc123_thumb.jpg"
131
166
  #
132
- #
167
+ # It uses an underscore to separatore parts by default, but that is configurable
168
+ # by setting HasImage::Storage.thumbnail_separator
133
169
  def file_name_for(*args)
134
- "%s.%s" % [args.compact.join("_"), extension]
170
+ "%s.%s" % [args.compact.join(self.class.thumbnail_separator), extension]
135
171
  end
136
172
 
137
- # Gets the full local filesystem path for an image. For example:
173
+ # Get the full path for the id. For example:
138
174
  #
139
- # /var/sites/example.com/production/public/photos/0000/0001/3er0zs.jpg
140
- def filesystem_path_for(object, thumbnail = nil)
141
- File.join(path_for(object.has_image_id), file_name_for(object.has_image_file, thumbnail))
175
+ # /var/sites/example.org/production/public/photos/0000/0001
176
+ def path_for(id)
177
+ debugger if $debug
178
+ File.join(options[:base_path], options[:path_prefix], Storage.partitioned_path(id))
142
179
  end
143
180
 
144
- # Write the main image to the install directory - probably somewhere under
145
- # RAILS_ROOT/public.
146
- def install_main_image(id, name)
181
+ def absolute_path(id, *args)
182
+ File.join(path_for(id), file_name_for(*args))
183
+ end
184
+
185
+ def ensure_directory_exists!(id)
147
186
  FileUtils.mkdir_p path_for(id)
148
- main = processor.resize(@temp_file, @options[:resize_to])
149
- file = File.open(File.join(path_for(id), file_name_for(name)), "w")
150
- file.write(IO.read(main.path))
151
- file.close
152
- main.tempfile.close!
153
187
  end
154
188
 
155
- # Write the thumbnails to the install directory - probably somewhere under
189
+ # Write the main image to the install directory - probably somewhere under
156
190
  # RAILS_ROOT/public.
157
- def install_thumbnails(id, name)
158
- FileUtils.mkdir_p path_for(id)
159
- path = File.join(path_for(id), file_name_for(name))
160
- options[:thumbnails].each do |thumb_name, size|
161
- thumb = processor.resize(path, size)
162
- thumb.tempfile.close
163
- file = File.open(File.join(path_for(id), file_name_for(name, thumb_name)), "w")
164
- file.write(IO.read(thumb.tempfile.path))
165
- file.close
166
- thumb.tempfile.close!
191
+ def install_main_image(id, name)
192
+ ensure_directory_exists!(id)
193
+ File.open absolute_path(id, name), "w" do |final_destination|
194
+ processor.process(@temp_file) do |processed_image|
195
+ final_destination.write processed_image
196
+ end
167
197
  end
168
198
  end
169
-
170
- # Get the full path for the id. For example:
171
- #
172
- # /var/sites/example.org/production/public/photos/0000/0001
173
- def path_for(id)
174
- File.join(options[:base_path], options[:path_prefix], Storage.partitioned_path(id))
199
+
200
+ # used in #install_images
201
+ def thumbnails_needed?
202
+ !options[:thumbnails].empty? && options[:auto_generate_thumbnails]
175
203
  end
176
204
 
177
205
  # Instantiates the processor using the options set in my contructor (if
@@ -180,7 +208,6 @@ module HasImage
180
208
  def processor
181
209
  @processor ||= Processor.new(options)
182
210
  end
183
-
184
211
  end
185
212
 
186
213
  end
data/test/storage_test.rb CHANGED
@@ -11,7 +11,9 @@ class StorageTest < Test::Unit::TestCase
11
11
  end
12
12
 
13
13
  def default_options
14
- HasImage.default_options_for("tests").merge(
14
+ mock_class = "test"
15
+ mock_class.stubs(:table_name).returns('tests')
16
+ HasImage.default_options_for(mock_class).merge(
15
17
  :base_path => File.join(File.dirname(__FILE__), '..', 'tmp')
16
18
  )
17
19
  end
@@ -23,6 +25,25 @@ class StorageTest < Test::Unit::TestCase
23
25
  def test_partitioned_path_doesnt_collide_with_high_ids
24
26
  assert_not_equal HasImage::Storage.partitioned_path(867792732),
25
27
  HasImage::Storage.partitioned_path(867792731)
28
+ # FIXME: collisions when IDs have more than 8 digits
29
+ # assert_not_equal HasImage::Storage.partitioned_path(967792731),
30
+ # HasImage::Storage.partitioned_path(967792731)
31
+ end
32
+
33
+ def test_id_from_partitioned_path
34
+ assert_equal 123, HasImage::Storage.id_from_partitioned_path(HasImage::Storage.partitioned_path(123))
35
+ assert_equal 56, HasImage::Storage.id_from_partitioned_path(HasImage::Storage.partitioned_path(56))
36
+ assert_equal 67792732, HasImage::Storage.id_from_partitioned_path(HasImage::Storage.partitioned_path(67792732))
37
+ # FIXME: for IDs with more than 8 digits partitioned path is destructive
38
+ # assert_equal 867792731, HasImage::Storage.id_from_partitioned_path(HasImage::Storage.partitioned_path(867792731))
39
+ end
40
+
41
+ def test_id_from_path_accepts_array
42
+ assert_equal 123, HasImage::Storage.id_from_path(['0000','0123','image_something.jpg'])
43
+ end
44
+
45
+ def test_id_from_path_accepts_path
46
+ assert_equal 12345, HasImage::Storage.id_from_path('0001/2345/0123/image_something.jpg')
26
47
  end
27
48
 
28
49
  def test_generated_file_name
@@ -45,6 +66,17 @@ class StorageTest < Test::Unit::TestCase
45
66
  pic = stub(:has_image_file => "my+pic", :has_image_id => 1)
46
67
  assert_equal "/tests/0000/0001/my%2Bpic_square.jpg", @storage.public_path_for(pic, :square)
47
68
  end
69
+
70
+ def test_name_generation_takes_into_account_thumbnail_separator_constant
71
+ old_separator = HasImage::Storage.thumbnail_separator
72
+
73
+ @storage = HasImage::Storage.new(default_options.merge(:thumbnails => {:schick => '22x22'}, :base_path => '/public'))
74
+ HasImage::Storage.thumbnail_separator = '.'
75
+ pic = stub(:has_image_file => "pic", :has_image_id => 1)
76
+ assert_equal "/tests/0000/0001/pic.schick.jpg", @storage.public_path_for(pic, :schick)
77
+
78
+ HasImage::Storage.thumbnail_separator = old_separator
79
+ end
48
80
 
49
81
  def test_escape_file_name_for_http
50
82
  @storage = HasImage::Storage.new(default_options.merge(:base_path => '/public'))
@@ -83,7 +115,17 @@ class StorageTest < Test::Unit::TestCase
83
115
  :one => "100x100", :two => "200x200"}))
84
116
  @storage.image_data = temp_file("image.jpg")
85
117
  @name = @storage.install_images(stub(:has_image_id => 1))
86
- assert @storage.remove_images(stub(:has_image_id => 1), @name)
118
+ assert @storage.remove_images(stub(:has_image_id => 1), @name)
119
+ end
120
+
121
+ def test_install_images_doesnt_automatically_generate_thumbnails_if_that_option_is_set
122
+ @storage = HasImage::Storage.new(default_options.merge(
123
+ :thumbnails => {:two => "200x200"},
124
+ :auto_generate_thumbnails => false
125
+ ))
126
+ @storage.image_data = temp_file("image.jpg")
127
+ @storage.expects(:generate_thumbnails).never
128
+ @storage.install_images(stub(:has_image_id => 1))
87
129
  end
88
130
 
89
131
  def test_image_not_too_small
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class ComplexPic < ActiveRecord::Base
4
+ has_image
5
+ end
6
+
7
+ class ComplexPicTest < Test::Unit::TestCase
8
+ def setup
9
+ # Note: Be sure to not set the whole options hash in your tests below
10
+ ComplexPic.has_image_options = HasImage.default_options_for(ComplexPic)
11
+ ComplexPic.has_image_options[:column] = :filename
12
+ ComplexPic.has_image_options[:base_path] = File.join(RAILS_ROOT, 'tmp')
13
+ ComplexPic.has_image_options[:resize_to] = nil
14
+ end
15
+
16
+ def teardown
17
+ FileUtils.rm_rf(File.join(RAILS_ROOT, 'tmp', 'complex_pics'))
18
+ end
19
+
20
+ def test_should_save_width_to_db_on_create
21
+ @pic = ComplexPic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
22
+ assert_equal 1916, @pic[:width]
23
+ end
24
+
25
+ def test_should_save_height_to_db_on_create
26
+ @pic = ComplexPic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
27
+ assert_equal 1990, @pic[:height]
28
+ end
29
+
30
+ def test_should_use_value_from_db_in_height_reader
31
+ @pic = ComplexPic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
32
+ @pic[:height] = 60_000
33
+ assert_equal 60_000, @pic.height
34
+ end
35
+
36
+ def test_should_use_value_from_db_in_width_reader
37
+ @pic = ComplexPic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
38
+ @pic[:width] = 60_000
39
+ assert_equal 60_000, @pic.width
40
+ end
41
+
42
+ end
@@ -1,16 +1,24 @@
1
1
  require 'test_helper'
2
2
 
3
+ class Pic < ActiveRecord::Base
4
+ has_image
5
+ end
6
+
7
+ class PicWithDifferentTableName < ActiveRecord::Base
8
+ set_table_name 'pics'
9
+ end
10
+
3
11
  class PicTest < Test::Unit::TestCase
4
-
5
12
  def setup
13
+ # Note: Be sure to not set the whole options hash in your tests below
6
14
  Pic.has_image_options = HasImage.default_options_for(Pic)
7
- Pic.has_image_options[:base_path] = File.join(RAILS_ROOT, '/tmp')
15
+ Pic.has_image_options[:base_path] = File.join(RAILS_ROOT, 'tmp')
8
16
  end
9
-
17
+
10
18
  def teardown
11
19
  FileUtils.rm_rf(File.join(RAILS_ROOT, 'tmp', 'pics'))
12
20
  end
13
-
21
+
14
22
  def test_should_be_valid
15
23
  @pic = Pic.new(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
16
24
  assert @pic.valid? , "#{@pic.errors.full_messages.to_sentence}"
@@ -47,14 +55,37 @@ class PicTest < Test::Unit::TestCase
47
55
  assert @pic.save!
48
56
  end
49
57
 
50
- def test_regenerate_thumbnails
51
- Pic.has_image_options = HasImage.default_options_for(Pic).merge(
52
- :thumbnails => {:small => "100x100", :tiny => "16x16"})
58
+ def test_finding_from_url_path
53
59
  @pic = Pic.new(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
54
60
  @pic.save!
55
- assert @pic.regenerate_thumbnails
61
+ path = HasImage::Storage.partitioned_path @pic.id
62
+ assert_equal @pic, Pic.from_partitioned_path(path)
56
63
  end
57
64
 
65
+ def test_default_options_respect_table_name
66
+ assert_equal 'pics', HasImage.default_options_for(PicWithDifferentTableName)[:path_prefix]
67
+ end
68
+
69
+ def test_generate_thumbnails_on_create
70
+ Pic.has_image_options[:thumbnails] = {:tiny => "16x16"}
71
+ @pic = Pic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
72
+ assert File.exist?(@pic.absolute_path(:tiny))
73
+ end
74
+
75
+ def test_doesnt_generate_thumbnails_if_option_disabled
76
+ Pic.has_image_options[:thumbnails] = {:tiny => "16x16"}
77
+ Pic.has_image_options[:auto_generate_thumbnails] = false
78
+ @pic = Pic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
79
+ assert !File.exist?(@pic.absolute_path(:tiny))
80
+ end
81
+
82
+ def test_regenerate_thumbnails_succeeds
83
+ Pic.has_image_options[:thumbnails] = {:small => "100x100", :tiny => "16x16"}
84
+
85
+ @pic = Pic.new(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
86
+ @pic.save!
87
+ assert @pic.regenerate_thumbnails
88
+ end
58
89
 
59
90
  def test_create_model_without_setting_image_data
60
91
  assert Pic.new.save!
@@ -66,6 +97,13 @@ class PicTest < Test::Unit::TestCase
66
97
  assert @pic.destroy
67
98
  end
68
99
 
100
+ def test_destroy_should_not_remove_image_file_if_option_is_set
101
+ Pic.has_image_options[:delete] = false
102
+ @pic = Pic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
103
+ @pic.destroy
104
+ assert File.exist?(@pic.absolute_path)
105
+ end
106
+
69
107
  def test_destroy_model_with_images_already_deleted_from_filesystem
70
108
  @pic = Pic.new
71
109
  @pic.save!
@@ -86,5 +124,30 @@ class PicTest < Test::Unit::TestCase
86
124
  assert @pic.valid?
87
125
  end
88
126
 
89
- end
127
+ def test_dimension_getters
128
+ Pic.has_image_options[:resize_to] = "100x200"
129
+ pic = Pic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
130
+ assert_equal 100, pic.width
131
+ assert_equal 200, pic.height
132
+ assert_equal '100x200', pic.image_size
133
+ end
134
+
135
+ def test_image_isnt_resized_when_resize_to_set_to_nil
136
+ Pic.has_image_options[:resize_to] = nil
137
+ pic = Pic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
138
+
139
+ assert_equal 1916, pic.width
140
+ assert_equal 1990, pic.height
141
+ end
142
+
143
+ def test_image_isnt_resized_but_converted_when_resize_to_set_to_nil
144
+ Pic.has_image_options[:resize_to] = nil
145
+ Pic.has_image_options[:convert_to] = 'PNG'
146
+ pic = Pic.create!(:image_data => fixture_file_upload("/image.jpg", "image/jpeg"))
147
+
148
+ assert_equal 'PNG', MiniMagick::Image.from_file(pic.absolute_path)[:format]
149
+ assert_equal 1916, pic.width
150
+ assert_equal 1990, pic.height
151
+ end
90
152
 
153
+ end