has_image 0.2.3 → 0.3.0

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.
@@ -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
@@ -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