tdd-attachment_fu 0.9.6
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.
- data/CHANGELOG +44 -0
- data/LICENSE +20 -0
- data/README +197 -0
- data/Rakefile +22 -0
- data/amazon_s3.yml.tpl +17 -0
- data/init.rb +16 -0
- data/install.rb +7 -0
- data/lib/geometry.rb +96 -0
- data/lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb +211 -0
- data/lib/technoweenie/attachment_fu/backends/db_file_backend.rb +39 -0
- data/lib/technoweenie/attachment_fu/backends/file_system_backend.rb +126 -0
- data/lib/technoweenie/attachment_fu/backends/s3_backend.rb +394 -0
- data/lib/technoweenie/attachment_fu/processors/core_image_processor.rb +65 -0
- data/lib/technoweenie/attachment_fu/processors/gd2_processor.rb +62 -0
- data/lib/technoweenie/attachment_fu/processors/image_science_processor.rb +80 -0
- data/lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb +138 -0
- data/lib/technoweenie/attachment_fu/processors/rmagick_processor.rb +65 -0
- data/lib/technoweenie/attachment_fu.rb +514 -0
- data/rackspace_cloudfiles.yml.tpl +14 -0
- data/test/backends/db_file_test.rb +16 -0
- data/test/backends/file_system_test.rb +143 -0
- data/test/backends/remote/cloudfiles_test.rb +102 -0
- data/test/backends/remote/s3_test.rb +119 -0
- data/test/base_attachment_tests.rb +77 -0
- data/test/basic_test.rb +70 -0
- data/test/database.yml +18 -0
- data/test/extra_attachment_test.rb +67 -0
- data/test/fixtures/attachment.rb +249 -0
- data/test/fixtures/files/fake/rails.png +0 -0
- data/test/fixtures/files/foo.txt +1 -0
- data/test/fixtures/files/rails.jpg +0 -0
- data/test/fixtures/files/rails.png +0 -0
- data/test/geometry_test.rb +114 -0
- data/test/processors/core_image_test.rb +50 -0
- data/test/processors/gd2_test.rb +44 -0
- data/test/processors/image_science_test.rb +47 -0
- data/test/processors/mini_magick_test.rb +116 -0
- data/test/processors/rmagick_test.rb +267 -0
- data/test/schema.rb +134 -0
- data/test/test_helper.rb +153 -0
- data/test/validation_test.rb +55 -0
- data/vendor/red_artisan/core_image/filters/color.rb +27 -0
- data/vendor/red_artisan/core_image/filters/effects.rb +31 -0
- data/vendor/red_artisan/core_image/filters/perspective.rb +25 -0
- data/vendor/red_artisan/core_image/filters/quality.rb +25 -0
- data/vendor/red_artisan/core_image/filters/scale.rb +47 -0
- data/vendor/red_artisan/core_image/filters/watermark.rb +32 -0
- data/vendor/red_artisan/core_image/processor.rb +123 -0
- metadata +103 -0
@@ -0,0 +1,249 @@
|
|
1
|
+
class Attachment < ActiveRecord::Base
|
2
|
+
@@saves = 0
|
3
|
+
cattr_accessor :saves
|
4
|
+
has_attachment :processor => :rmagick
|
5
|
+
validates_as_attachment
|
6
|
+
after_attachment_saved do |record|
|
7
|
+
self.saves += 1
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class LowerQualityAttachment < Attachment
|
12
|
+
set_table_name 'attachments'
|
13
|
+
has_attachment :resize_to => [55,55], :jpeg_quality => 50
|
14
|
+
end
|
15
|
+
|
16
|
+
class SmallAttachment < Attachment
|
17
|
+
has_attachment :max_size => 1.kilobyte
|
18
|
+
end
|
19
|
+
|
20
|
+
class BigAttachment < Attachment
|
21
|
+
has_attachment :size => 1.megabyte..2.megabytes
|
22
|
+
end
|
23
|
+
|
24
|
+
class PdfAttachment < Attachment
|
25
|
+
has_attachment :content_type => 'pdf'
|
26
|
+
end
|
27
|
+
|
28
|
+
class DocAttachment < Attachment
|
29
|
+
has_attachment :content_type => %w(pdf doc txt)
|
30
|
+
end
|
31
|
+
|
32
|
+
class ImageAttachment < Attachment
|
33
|
+
has_attachment :content_type => :image, :resize_to => [50,50]
|
34
|
+
end
|
35
|
+
|
36
|
+
class ImageOrPdfAttachment < Attachment
|
37
|
+
has_attachment :content_type => ['pdf', :image], :resize_to => 'x50'
|
38
|
+
end
|
39
|
+
|
40
|
+
class ImageWithThumbsAttachment < Attachment
|
41
|
+
has_attachment :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }, :resize_to => [55,55]
|
42
|
+
# after_resize do |record, img|
|
43
|
+
# record.aspect_ratio = img.columns.to_f / img.rows.to_f
|
44
|
+
# end
|
45
|
+
end
|
46
|
+
|
47
|
+
class FileAttachment < ActiveRecord::Base
|
48
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick
|
49
|
+
validates_as_attachment
|
50
|
+
end
|
51
|
+
|
52
|
+
class FileAttachmentWithStringId < ActiveRecord::Base
|
53
|
+
set_table_name 'file_attachments_with_string_id'
|
54
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick
|
55
|
+
validates_as_attachment
|
56
|
+
|
57
|
+
before_validation :auto_generate_id
|
58
|
+
before_save :auto_generate_id
|
59
|
+
@@last_id = 0
|
60
|
+
|
61
|
+
private
|
62
|
+
def auto_generate_id
|
63
|
+
@@last_id += 1
|
64
|
+
self.id = "id_#{@@last_id}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class FileAttachmentWithUuid < ActiveRecord::Base
|
69
|
+
set_table_name 'file_attachments_with_string_id'
|
70
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick, :uuid_primary_key => true
|
71
|
+
validates_as_attachment
|
72
|
+
|
73
|
+
before_validation :auto_generate_id
|
74
|
+
before_save :auto_generate_id
|
75
|
+
@@last_id = 0
|
76
|
+
|
77
|
+
private
|
78
|
+
def auto_generate_id
|
79
|
+
@@last_id += 1
|
80
|
+
self.id = "%0127dx" % @@last_id
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class ImageFileAttachment < FileAttachment
|
85
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
86
|
+
:content_type => :image, :resize_to => [50,50]
|
87
|
+
end
|
88
|
+
|
89
|
+
class ImageWithThumbsFileAttachment < FileAttachment
|
90
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
91
|
+
:thumbnails => { :thumb => [50, 50], :geometry => 'x50' }, :resize_to => [55,55]
|
92
|
+
# after_resize do |record, img|
|
93
|
+
# record.aspect_ratio = img.columns.to_f / img.rows.to_f
|
94
|
+
# end
|
95
|
+
end
|
96
|
+
|
97
|
+
class ImageWithThumbsClassFileAttachment < FileAttachment
|
98
|
+
# use file_system_path to test backwards compatibility
|
99
|
+
has_attachment :file_system_path => 'vendor/plugins/attachment_fu/test/files',
|
100
|
+
:thumbnails => { :thumb => [50, 50] }, :resize_to => [55,55],
|
101
|
+
:thumbnail_class => 'ImageThumbnail'
|
102
|
+
end
|
103
|
+
|
104
|
+
class ImageThumbnail < FileAttachment
|
105
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files/thumbnails'
|
106
|
+
end
|
107
|
+
|
108
|
+
# no parent
|
109
|
+
class OrphanAttachment < ActiveRecord::Base
|
110
|
+
has_attachment :processor => :rmagick
|
111
|
+
validates_as_attachment
|
112
|
+
end
|
113
|
+
|
114
|
+
# no filename, no size, no content_type
|
115
|
+
class MinimalAttachment < ActiveRecord::Base
|
116
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files', :processor => :rmagick
|
117
|
+
validates_as_attachment
|
118
|
+
|
119
|
+
def filename
|
120
|
+
"#{id}.file"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
begin
|
125
|
+
class ImageScienceAttachment < ActiveRecord::Base
|
126
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
127
|
+
:processor => :image_science, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55
|
128
|
+
end
|
129
|
+
|
130
|
+
class ImageScienceLowerQualityAttachment < ActiveRecord::Base
|
131
|
+
set_table_name 'image_science_attachments'
|
132
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
133
|
+
:processor => :image_science, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,
|
134
|
+
:jpeg_quality => 75
|
135
|
+
end
|
136
|
+
rescue MissingSourceFile
|
137
|
+
puts $!.message
|
138
|
+
puts "no ImageScience"
|
139
|
+
end
|
140
|
+
|
141
|
+
begin
|
142
|
+
class CoreImageAttachment < ActiveRecord::Base
|
143
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
144
|
+
:processor => :core_image, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55
|
145
|
+
end
|
146
|
+
|
147
|
+
class LowerQualityCoreImageAttachment < CoreImageAttachment
|
148
|
+
set_table_name 'core_image_attachments'
|
149
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
150
|
+
:processor => :core_image, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,
|
151
|
+
:jpeg_quality => 50
|
152
|
+
end
|
153
|
+
rescue MissingSourceFile
|
154
|
+
puts $!.message
|
155
|
+
puts "no CoreImage"
|
156
|
+
end
|
157
|
+
|
158
|
+
begin
|
159
|
+
class MiniMagickAttachment < ActiveRecord::Base
|
160
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
161
|
+
:processor => :mini_magick, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55
|
162
|
+
end
|
163
|
+
|
164
|
+
class ImageThumbnailCrop < MiniMagickAttachment
|
165
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
166
|
+
:thumbnails => { :square => "50x50c", :vertical => "30x60c", :horizontal => "60x30c"}
|
167
|
+
|
168
|
+
# TODO this is a bad duplication, this method is in the MiniMagick Processor
|
169
|
+
def self.calculate_offset(image_width,image_height,image_aspect,thumb_width,thumb_height,thumb_aspect)
|
170
|
+
# only crop if image is not smaller in both dimensions
|
171
|
+
|
172
|
+
# special cases, image smaller in one dimension then thumbsize
|
173
|
+
if image_width < thumb_width
|
174
|
+
offset = (image_height / 2) - (thumb_height / 2)
|
175
|
+
command = "#{image_width}x#{thumb_height}+0+#{offset}"
|
176
|
+
elsif image_height < thumb_height
|
177
|
+
offset = (image_width / 2) - (thumb_width / 2)
|
178
|
+
command = "#{thumb_width}x#{image_height}+#{offset}+0"
|
179
|
+
|
180
|
+
# normal thumbnail generation
|
181
|
+
# calculate height and offset y, width is fixed
|
182
|
+
elsif (image_aspect <= thumb_aspect or image_width < thumb_width) and image_height > thumb_height
|
183
|
+
height = image_width / thumb_aspect
|
184
|
+
offset = (image_height / 2) - (height / 2)
|
185
|
+
command = "#{image_width}x#{height}+0+#{offset}"
|
186
|
+
# calculate width and offset x, height is fixed
|
187
|
+
else
|
188
|
+
width = image_height * thumb_aspect
|
189
|
+
offset = (image_width / 2) - (width / 2)
|
190
|
+
command = "#{width}x#{image_height}+#{offset}+0"
|
191
|
+
end
|
192
|
+
# crop image
|
193
|
+
command
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class LowerQualityMiniMagickAttachment < MiniMagickAttachment
|
198
|
+
set_table_name 'mini_magick_attachments'
|
199
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
200
|
+
:processor => :mini_magick, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,
|
201
|
+
:jpeg_quality => 50
|
202
|
+
end
|
203
|
+
|
204
|
+
rescue MissingSourceFile
|
205
|
+
puts $!.message
|
206
|
+
puts "no Mini Magick"
|
207
|
+
end
|
208
|
+
|
209
|
+
begin
|
210
|
+
class GD2Attachment < ActiveRecord::Base
|
211
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
212
|
+
:processor => :gd2, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55
|
213
|
+
end
|
214
|
+
|
215
|
+
class LowerQualityGD2Attachment < GD2Attachment
|
216
|
+
has_attachment :path_prefix => 'vendor/plugins/attachment_fu/test/files',
|
217
|
+
:processor => :gd2, :thumbnails => { :thumb => [50, 51], :geometry => '31>', :aspect => '25x25!' }, :resize_to => 55,
|
218
|
+
:jpeg_quality => 50
|
219
|
+
end
|
220
|
+
rescue MissingSourceFile
|
221
|
+
puts $!.message
|
222
|
+
puts "no GD2"
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
begin
|
227
|
+
class S3Attachment < ActiveRecord::Base
|
228
|
+
has_attachment :storage => :s3, :processor => :rmagick, :s3_config_path => File.join(File.dirname(__FILE__), '../amazon_s3.yml')
|
229
|
+
validates_as_attachment
|
230
|
+
end
|
231
|
+
|
232
|
+
class CloudFilesAttachment < ActiveRecord::Base
|
233
|
+
has_attachment :storage => :cloud_files, :processor => :rmagick, :cloudfiles_config_path => File.join(File.dirname(__FILE__), '../rackspace_cloudfiles.yml')
|
234
|
+
validates_as_attachment
|
235
|
+
end
|
236
|
+
|
237
|
+
class S3WithPathPrefixAttachment < S3Attachment
|
238
|
+
has_attachment :storage => :s3, :path_prefix => 'some/custom/path/prefix', :processor => :rmagick
|
239
|
+
validates_as_attachment
|
240
|
+
end
|
241
|
+
|
242
|
+
class CloudFilesWithPathPrefixAttachment < CloudFilesAttachment
|
243
|
+
has_attachment :storage => :cloud_files, :path_prefix => 'some/custom/path/prefix', :processor => :rmagick
|
244
|
+
validates_as_attachment
|
245
|
+
end
|
246
|
+
|
247
|
+
rescue
|
248
|
+
puts "S3 error: #{$!}"
|
249
|
+
end
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
foo
|
Binary file
|
Binary file
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/geometry')) unless Object.const_defined?(:Geometry)
|
3
|
+
|
4
|
+
class GeometryTest < Test::Unit::TestCase
|
5
|
+
def test_should_resize
|
6
|
+
assert_geometry 50, 64,
|
7
|
+
"50x50" => [39, 50],
|
8
|
+
"60x60" => [47, 60],
|
9
|
+
"100x100" => [78, 100]
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_resize_no_width
|
13
|
+
assert_geometry 50, 64,
|
14
|
+
"x50" => [39, 50],
|
15
|
+
"x60" => [47, 60],
|
16
|
+
"x100" => [78, 100]
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_resize_no_height
|
20
|
+
assert_geometry 50, 64,
|
21
|
+
"50" => [50, 64],
|
22
|
+
"60" => [60, 77],
|
23
|
+
"100" => [100, 128]
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_resize_no_height_with_x
|
27
|
+
assert_geometry 50, 64,
|
28
|
+
"50x" => [50, 64],
|
29
|
+
"60x" => [60, 77],
|
30
|
+
"100x" => [100, 128]
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_resize_with_percent
|
34
|
+
assert_geometry 50, 64,
|
35
|
+
"50x50%" => [25, 32],
|
36
|
+
"60x60%" => [30, 38],
|
37
|
+
"120x112%" => [60, 72]
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_resize_with_percent_and_no_width
|
41
|
+
assert_geometry 50, 64,
|
42
|
+
"x50%" => [50, 32],
|
43
|
+
"x60%" => [50, 38],
|
44
|
+
"x112%" => [50, 72]
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_should_resize_with_percent_and_no_height
|
48
|
+
assert_geometry 50, 64,
|
49
|
+
"50%" => [25, 32],
|
50
|
+
"60%" => [30, 38],
|
51
|
+
"120%" => [60, 77]
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_should_resize_with_less
|
55
|
+
assert_geometry 50, 64,
|
56
|
+
"50x50<" => [50, 64],
|
57
|
+
"60x60<" => [50, 64],
|
58
|
+
"100x100<" => [78, 100],
|
59
|
+
"100x112<" => [88, 112],
|
60
|
+
"40x70<" => [50, 64]
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_resize_with_less_and_no_width
|
64
|
+
assert_geometry 50, 64,
|
65
|
+
"x50<" => [50, 64],
|
66
|
+
"x60<" => [50, 64],
|
67
|
+
"x100<" => [78, 100]
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_should_resize_with_less_and_no_height
|
71
|
+
assert_geometry 50, 64,
|
72
|
+
"50<" => [50, 64],
|
73
|
+
"60<" => [60, 77],
|
74
|
+
"100<" => [100, 128]
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_should_resize_with_greater
|
78
|
+
assert_geometry 50, 64,
|
79
|
+
"50x50>" => [39, 50],
|
80
|
+
"60x60>" => [47, 60],
|
81
|
+
"100x100>" => [50, 64],
|
82
|
+
"100x112>" => [50, 64],
|
83
|
+
"40x70>" => [40, 51]
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_should_resize_with_greater_and_no_width
|
87
|
+
assert_geometry 50, 64,
|
88
|
+
"x40>" => [31, 40],
|
89
|
+
"x60>" => [47, 60],
|
90
|
+
"x100>" => [50, 64]
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_resize_with_greater_and_no_height
|
94
|
+
assert_geometry 50, 64,
|
95
|
+
"40>" => [40, 51],
|
96
|
+
"60>" => [50, 64],
|
97
|
+
"100>" => [50, 64]
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_should_resize_with_aspect
|
101
|
+
assert_geometry 50, 64,
|
102
|
+
"35x35!" => [35, 35],
|
103
|
+
"70x70!" => [70, 70]
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
def assert_geometry(width, height, values)
|
108
|
+
values.each do |geo, result|
|
109
|
+
# run twice to verify the Geometry string isn't modified after a run
|
110
|
+
geo = Geometry.from_s(geo)
|
111
|
+
2.times { assert_equal result, [width, height] / geo }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
class CoreImageTest < Test::Unit::TestCase
|
4
|
+
attachment_model CoreImageAttachment
|
5
|
+
|
6
|
+
if Object.const_defined?(:OSX)
|
7
|
+
def test_should_resize_image
|
8
|
+
attachment = upload_file :filename => '/files/rails.png'
|
9
|
+
assert_valid attachment
|
10
|
+
assert attachment.image?
|
11
|
+
# test core image thumbnail
|
12
|
+
assert_equal 42, attachment.width
|
13
|
+
assert_equal 55, attachment.height
|
14
|
+
|
15
|
+
thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }
|
16
|
+
geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }
|
17
|
+
aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }
|
18
|
+
|
19
|
+
# test exact resize dimensions
|
20
|
+
assert_equal 50, thumb.width
|
21
|
+
assert_equal 51, thumb.height
|
22
|
+
|
23
|
+
# test geometry strings
|
24
|
+
assert_equal 31, geo.width
|
25
|
+
assert_equal 41, geo.height
|
26
|
+
assert_equal 25, aspect.width
|
27
|
+
assert_equal 25, aspect.height
|
28
|
+
|
29
|
+
# This makes sure that we didn't overwrite the original file
|
30
|
+
# and will end up with a thumbnail instead of the original
|
31
|
+
assert_equal 42, attachment.width
|
32
|
+
assert_equal 55, attachment.height
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_handle_jpeg_quality
|
37
|
+
attachment_model CoreImageAttachment
|
38
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
39
|
+
full_size = attachment.size
|
40
|
+
attachment_model LowerQualityCoreImageAttachment
|
41
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
42
|
+
lq_size = attachment.size
|
43
|
+
assert lq_size <= full_size * 0.9, 'Lower-quality JPEG filesize should be congruently smaller'
|
44
|
+
end
|
45
|
+
else
|
46
|
+
def test_flunk
|
47
|
+
puts "CoreImage not loaded, tests not running"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
class GD2Test < Test::Unit::TestCase
|
4
|
+
attachment_model GD2Attachment
|
5
|
+
|
6
|
+
if Object.const_defined?(:GD2)
|
7
|
+
def test_should_resize_image
|
8
|
+
attachment = upload_file :filename => '/files/rails.png'
|
9
|
+
assert_valid attachment
|
10
|
+
assert attachment.image?
|
11
|
+
# test gd2 thumbnail
|
12
|
+
assert_equal 43, attachment.width
|
13
|
+
assert_equal 55, attachment.height
|
14
|
+
|
15
|
+
thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }
|
16
|
+
geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }
|
17
|
+
aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }
|
18
|
+
|
19
|
+
# test exact resize dimensions
|
20
|
+
assert_equal 50, thumb.width
|
21
|
+
assert_equal 51, thumb.height
|
22
|
+
|
23
|
+
# test geometry strings
|
24
|
+
assert_equal 31, geo.width
|
25
|
+
assert_equal 40, geo.height
|
26
|
+
assert_equal 25, aspect.width
|
27
|
+
assert_equal 25, aspect.height
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_handle_jpeg_quality
|
31
|
+
attachment_model GD2Attachment
|
32
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
33
|
+
full_size = attachment.size
|
34
|
+
attachment_model LowerQualityGD2Attachment
|
35
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
36
|
+
lq_size = attachment.size
|
37
|
+
assert lq_size <= full_size * 0.9, 'Lower-quality JPEG filesize should be congruently smaller'
|
38
|
+
end
|
39
|
+
else
|
40
|
+
def test_flunk
|
41
|
+
puts "GD2 not loaded, tests not running"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
class ImageScienceTest < Test::Unit::TestCase
|
4
|
+
attachment_model ImageScienceAttachment
|
5
|
+
|
6
|
+
if Object.const_defined?(:ImageScience)
|
7
|
+
def test_should_resize_image
|
8
|
+
attachment = upload_file :filename => '/files/rails.png'
|
9
|
+
assert_valid attachment
|
10
|
+
assert attachment.image?
|
11
|
+
# test image science thumbnail
|
12
|
+
assert_equal 42, attachment.width
|
13
|
+
assert_equal 55, attachment.height
|
14
|
+
|
15
|
+
thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }
|
16
|
+
geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }
|
17
|
+
aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }
|
18
|
+
|
19
|
+
# test exact resize dimensions
|
20
|
+
assert_equal 50, thumb.width
|
21
|
+
assert_equal 51, thumb.height
|
22
|
+
|
23
|
+
# test geometry strings
|
24
|
+
assert_equal 31, geo.width
|
25
|
+
assert_equal 41, geo.height
|
26
|
+
assert_equal 25, aspect.width
|
27
|
+
assert_equal 25, aspect.height
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_handle_jpeg_quality
|
31
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
32
|
+
full_size = attachment.size
|
33
|
+
attachment_model ImageScienceLowerQualityAttachment
|
34
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
35
|
+
lq_size = attachment.size
|
36
|
+
if ImageScience.instance_method(:save).arity == -2 # tdd-image_science: JPEG quality processing
|
37
|
+
assert lq_size <= full_size * 0.75, 'Lower-quality JPEG filesize should be congruently smaller'
|
38
|
+
else
|
39
|
+
assert_equal full_size, lq_size, 'Unsupported lower-quality JPEG should yield exact same file size'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
else
|
43
|
+
def test_flunk
|
44
|
+
puts "ImageScience not loaded, tests not running"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
class MiniMagickTest < Test::Unit::TestCase
|
4
|
+
attachment_model MiniMagickAttachment
|
5
|
+
|
6
|
+
if Object.const_defined?(:MiniMagick)
|
7
|
+
def test_should_resize_image
|
8
|
+
attachment = upload_file :filename => '/files/rails.png'
|
9
|
+
assert_valid attachment
|
10
|
+
assert attachment.image?
|
11
|
+
# test MiniMagick thumbnail
|
12
|
+
assert_equal 43, attachment.width
|
13
|
+
assert_equal 55, attachment.height
|
14
|
+
|
15
|
+
thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }
|
16
|
+
geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }
|
17
|
+
aspect = attachment.thumbnails.detect { |t| t.filename =~ /_aspect/ }
|
18
|
+
|
19
|
+
# test exact resize dimensions
|
20
|
+
assert_equal 50, thumb.width
|
21
|
+
assert_equal 51, thumb.height
|
22
|
+
|
23
|
+
# test geometry strings
|
24
|
+
assert_equal 31, geo.width
|
25
|
+
assert_equal 40, geo.height
|
26
|
+
assert_equal 25, aspect.width
|
27
|
+
assert_equal 25, aspect.height
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_crop_image(klass = ImageThumbnailCrop)
|
31
|
+
attachment_model klass
|
32
|
+
attachment = upload_file :filename => '/files/rails.png'
|
33
|
+
assert_valid attachment
|
34
|
+
assert attachment.image?
|
35
|
+
# has_attachment :thumbnails => { :square => "50x50c", :vertical => "30x60c", :horizontal => "60x30c"}
|
36
|
+
|
37
|
+
square = attachment.thumbnails.detect { |t| t.filename =~ /_square/ }
|
38
|
+
vertical = attachment.thumbnails.detect { |t| t.filename =~ /_vertical/ }
|
39
|
+
horizontal = attachment.thumbnails.detect { |t| t.filename =~ /_horizontal/ }
|
40
|
+
|
41
|
+
# test excat resize
|
42
|
+
assert_equal 50, square.width
|
43
|
+
assert_equal 50, square.height
|
44
|
+
|
45
|
+
assert_equal 30, vertical.width
|
46
|
+
assert_equal 60, vertical.height
|
47
|
+
|
48
|
+
assert_equal 60, horizontal.width
|
49
|
+
assert_equal 30, horizontal.height
|
50
|
+
end
|
51
|
+
|
52
|
+
# tests the first step in resize, crop the image in original size to right format
|
53
|
+
def test_should_crop_image_right(klass = ImageThumbnailCrop)
|
54
|
+
@@testcases.collect do |testcase|
|
55
|
+
image_width, image_height, thumb_width, thumb_height = testcase[:data]
|
56
|
+
image_aspect, thumb_aspect = image_width/image_height, thumb_width/thumb_height
|
57
|
+
crop_comand = klass.calculate_offset(image_width, image_height, image_aspect, thumb_width, thumb_height,thumb_aspect)
|
58
|
+
# pattern matching on crop command
|
59
|
+
if testcase.has_key?(:height)
|
60
|
+
assert crop_comand.match(/^#{image_width}x#{testcase[:height]}\+0\+#{testcase[:yoffset]}$/)
|
61
|
+
else
|
62
|
+
assert crop_comand.match(/^#{testcase[:width]}x#{image_height}\+#{testcase[:xoffset]}\+0$/)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_should_handle_jpeg_quality
|
68
|
+
attachment_model MiniMagickAttachment
|
69
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
70
|
+
full_size = attachment.size
|
71
|
+
attachment_model LowerQualityMiniMagickAttachment
|
72
|
+
attachment = upload_file :filename => '/files/rails.jpg'
|
73
|
+
lq_size = attachment.size
|
74
|
+
puts "FULL: #{full_size} - LQ: #{lq_size}"
|
75
|
+
assert lq_size <= full_size * 0.9, 'Lower-quality JPEG filesize should be congruently smaller'
|
76
|
+
end
|
77
|
+
else
|
78
|
+
def test_flunk
|
79
|
+
puts "MiniMagick not loaded, tests not running"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
@@testcases = [
|
84
|
+
# image_aspect <= 1 && thumb_aspect >= 1
|
85
|
+
{:data => [10.0,40.0,2.0,1.0], :height => 5.0, :yoffset => 17.5}, # 1b
|
86
|
+
{:data => [10.0,40.0,1.0,1.0], :height => 10.0, :yoffset => 15.0}, # 1b
|
87
|
+
|
88
|
+
# image_aspect < 1 && thumb_aspect < 1
|
89
|
+
{:data => [10.0,40.0,1.0,2.0], :height => 20.0, :yoffset => 10.0}, # 1a
|
90
|
+
{:data => [2.0,3.0,1.0,2.0], :width => 1.5, :xoffset => 0.25}, # 1a
|
91
|
+
|
92
|
+
# image_aspect = thumb_aspect
|
93
|
+
{:data => [10.0,10.0,1.0,1.0], :height => 10.0, :yoffset => 0.0}, # QUADRAT 1c
|
94
|
+
|
95
|
+
# image_aspect >= 1 && thumb_aspect > 1 && image_aspect < thumb_aspect
|
96
|
+
{:data => [6.0,3.0,4.0,1.0], :height => 1.5, :yoffset => 0.75}, # 2b
|
97
|
+
{:data => [6.0,6.0,4.0,1.0], :height => 1.5, :yoffset => 2.25}, # 2b
|
98
|
+
|
99
|
+
# image_aspect > 1 && thumb_aspect > 1 && image_aspect > thumb_aspect
|
100
|
+
{:data => [9.0,3.0,2.0,1.0], :width => 6.0, :xoffset => 1.5}, # 2a
|
101
|
+
|
102
|
+
# image_aspect > 1 && thumb_aspect < 1 && image_aspect < thumb_aspect
|
103
|
+
{:data => [10.0,5.0,0.1,2.0], :width => 0.25, :xoffset => 4.875}, # 4
|
104
|
+
{:data => [10.0,5.0,1.0,2.0], :width => 2.5, :xoffset => 3.75}, # 4
|
105
|
+
|
106
|
+
# image_aspect > 1 && thumb_aspect > 1 && image_aspect > thumb_aspect
|
107
|
+
{:data => [9.0,3.0,2.0,1.0], :width => 6.0, :xoffset => 1.5}, # 3a
|
108
|
+
# image_aspect > 1 && thumb_aspect > 1 && image_aspect < thumb_aspect
|
109
|
+
{:data => [9.0,3.0,5.0,1.0], :height => 1.8, :yoffset => 0.6} # 3a
|
110
|
+
]
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
end
|