bulldog 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/DESCRIPTION.txt +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +64 -0
- data/VERSION +1 -0
- data/bulldog.gemspec +157 -0
- data/lib/bulldog.rb +95 -0
- data/lib/bulldog/attachment.rb +49 -0
- data/lib/bulldog/attachment/base.rb +167 -0
- data/lib/bulldog/attachment/has_dimensions.rb +94 -0
- data/lib/bulldog/attachment/image.rb +63 -0
- data/lib/bulldog/attachment/maybe.rb +229 -0
- data/lib/bulldog/attachment/none.rb +37 -0
- data/lib/bulldog/attachment/pdf.rb +63 -0
- data/lib/bulldog/attachment/unknown.rb +11 -0
- data/lib/bulldog/attachment/video.rb +143 -0
- data/lib/bulldog/error.rb +5 -0
- data/lib/bulldog/has_attachment.rb +214 -0
- data/lib/bulldog/interpolation.rb +73 -0
- data/lib/bulldog/missing_file.rb +12 -0
- data/lib/bulldog/processor.rb +5 -0
- data/lib/bulldog/processor/argument_tree.rb +116 -0
- data/lib/bulldog/processor/base.rb +124 -0
- data/lib/bulldog/processor/ffmpeg.rb +172 -0
- data/lib/bulldog/processor/image_magick.rb +134 -0
- data/lib/bulldog/processor/one_shot.rb +19 -0
- data/lib/bulldog/reflection.rb +234 -0
- data/lib/bulldog/saved_file.rb +19 -0
- data/lib/bulldog/stream.rb +186 -0
- data/lib/bulldog/style.rb +38 -0
- data/lib/bulldog/style_set.rb +101 -0
- data/lib/bulldog/tempfile.rb +28 -0
- data/lib/bulldog/util.rb +92 -0
- data/lib/bulldog/validations.rb +68 -0
- data/lib/bulldog/vector2.rb +18 -0
- data/rails/init.rb +9 -0
- data/script/console +8 -0
- data/spec/data/empty.txt +0 -0
- data/spec/data/test.jpg +0 -0
- data/spec/data/test.mov +0 -0
- data/spec/data/test.pdf +0 -0
- data/spec/data/test.png +0 -0
- data/spec/data/test2.jpg +0 -0
- data/spec/helpers/image_creation.rb +8 -0
- data/spec/helpers/temporary_directory.rb +25 -0
- data/spec/helpers/temporary_models.rb +76 -0
- data/spec/helpers/temporary_values.rb +102 -0
- data/spec/helpers/test_upload_files.rb +108 -0
- data/spec/helpers/time_travel.rb +20 -0
- data/spec/integration/data/test.jpg +0 -0
- data/spec/integration/lifecycle_hooks_spec.rb +213 -0
- data/spec/integration/processing_image_attachments.rb +72 -0
- data/spec/integration/processing_video_attachments_spec.rb +82 -0
- data/spec/integration/saving_an_attachment_spec.rb +31 -0
- data/spec/matchers/file_operations.rb +159 -0
- data/spec/spec_helper.rb +76 -0
- data/spec/unit/attachment/base_spec.rb +311 -0
- data/spec/unit/attachment/image_spec.rb +128 -0
- data/spec/unit/attachment/maybe_spec.rb +126 -0
- data/spec/unit/attachment/pdf_spec.rb +137 -0
- data/spec/unit/attachment/video_spec.rb +176 -0
- data/spec/unit/attachment_spec.rb +61 -0
- data/spec/unit/has_attachment_spec.rb +700 -0
- data/spec/unit/interpolation_spec.rb +108 -0
- data/spec/unit/processor/argument_tree_spec.rb +159 -0
- data/spec/unit/processor/ffmpeg_spec.rb +467 -0
- data/spec/unit/processor/image_magick_spec.rb +260 -0
- data/spec/unit/processor/one_shot_spec.rb +70 -0
- data/spec/unit/reflection_spec.rb +338 -0
- data/spec/unit/stream_spec.rb +234 -0
- data/spec/unit/style_set_spec.rb +44 -0
- data/spec/unit/style_spec.rb +51 -0
- data/spec/unit/validations_spec.rb +491 -0
- data/spec/unit/vector2_spec.rb +27 -0
- data/tasks/bulldog_tasks.rake +4 -0
- metadata +193 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
module TemporaryValues
|
2
|
+
def self.included(mod)
|
3
|
+
mod.extend ClassMethods
|
4
|
+
end
|
5
|
+
|
6
|
+
#
|
7
|
+
# Use +value+ for the value of the constant +mod::name+ for the
|
8
|
+
# duration of the block.
|
9
|
+
#
|
10
|
+
def with_temporary_constant_value(mod, name, value)
|
11
|
+
save_and_set_constant(mod, name, value)
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
restore_constant(mod, name)
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Use +value+ for the value of the +name+ attribute of the given
|
19
|
+
# +object+ for the duration of the block.
|
20
|
+
#
|
21
|
+
def with_temporary_attribute_value(object, name, value)
|
22
|
+
save_and_set_attribute(object, name, value)
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
restore_attribute(object, name)
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
#
|
30
|
+
# Use +value+ for the value of the constant +mod::name+ for the
|
31
|
+
# duration of each example in this example group.
|
32
|
+
#
|
33
|
+
# If the value should be recalculated for each example, pass a
|
34
|
+
# block instead of a value argument.
|
35
|
+
#
|
36
|
+
def use_temporary_constant_value(mod, name, value=nil, &block)
|
37
|
+
before do
|
38
|
+
value = block ? instance_eval(&block) : value
|
39
|
+
save_and_set_constant(mod, name, value)
|
40
|
+
end
|
41
|
+
after do
|
42
|
+
restore_constant(mod, name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Use +value+ for the value of the +name+ attribute of the given
|
48
|
+
# +object+ for the duration of each example in this example group.
|
49
|
+
#
|
50
|
+
# If the value should be recalculated for each example, pass a
|
51
|
+
# block instead of a value argument.
|
52
|
+
#
|
53
|
+
def use_temporary_attribute_value(object, name, value=nil, &block)
|
54
|
+
before do
|
55
|
+
value = block ? instance_eval(&block) : value
|
56
|
+
save_and_set_attribute(object, name, value)
|
57
|
+
end
|
58
|
+
after do
|
59
|
+
restore_attribute(object, name)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private # ---------------------------------------------------------
|
65
|
+
|
66
|
+
UNDEFINED = Object.new
|
67
|
+
|
68
|
+
def original_attribute_values
|
69
|
+
@original_attribute_values ||= Hash.new{|h,k| h[k] = Hash.new{|h2,k2| h2[k2] = {}}}
|
70
|
+
end
|
71
|
+
|
72
|
+
def save_and_set_attribute(object, name, value)
|
73
|
+
original_attribute_values[object.__id__][name] = object.send(name)
|
74
|
+
object.send("#{name}=", value)
|
75
|
+
end
|
76
|
+
|
77
|
+
def restore_attribute(object, name)
|
78
|
+
value = original_attribute_values[object.__id__].delete(name)
|
79
|
+
object.send("#{name}=", value)
|
80
|
+
end
|
81
|
+
|
82
|
+
def original_constant_values
|
83
|
+
@original_constant_values ||= Hash.new{|h,k| h[k] = Hash.new{|h2,k2| h2[k2] = {}}}
|
84
|
+
end
|
85
|
+
|
86
|
+
def save_and_set_constant(mod, name, value)
|
87
|
+
if mod.const_defined?(name)
|
88
|
+
original_constant_values[mod.name][name] = mod.send(:remove_const, name)
|
89
|
+
else
|
90
|
+
original_constant_values[mod.name][name] = UNDEFINED
|
91
|
+
end
|
92
|
+
mod.const_set(name, value)
|
93
|
+
end
|
94
|
+
|
95
|
+
def restore_constant(mod, name)
|
96
|
+
mod.send(:remove_const, name)
|
97
|
+
original_value = original_constant_values[mod.name].delete(name)
|
98
|
+
unless original_value.equal?(UNDEFINED)
|
99
|
+
mod.const_set(name, original_value)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module TestUploadFiles
|
2
|
+
def self.included(mod)
|
3
|
+
mod.before{init_test_upload_files}
|
4
|
+
mod.after{close_test_upload_files}
|
5
|
+
end
|
6
|
+
|
7
|
+
def autoclose(file)
|
8
|
+
@files_to_close << file
|
9
|
+
file
|
10
|
+
end
|
11
|
+
|
12
|
+
def small_uploaded_file(path=unused_temp_path, test_file='test.jpg')
|
13
|
+
content = content_for_uploaded_file(test_file)
|
14
|
+
io = ActionController::UploadedStringIO.new(content)
|
15
|
+
io.original_path = path
|
16
|
+
io.content_type = Rack::Mime::MIME_TYPES[File.extname(path)]
|
17
|
+
io
|
18
|
+
end
|
19
|
+
|
20
|
+
def large_uploaded_file(path=unused_temp_path, test_file='test.jpg')
|
21
|
+
content = content_for_uploaded_file(test_file)
|
22
|
+
file = ActionController::UploadedTempfile.new(path)
|
23
|
+
file.write(content)
|
24
|
+
file.rewind
|
25
|
+
file.original_path = path
|
26
|
+
file.content_type = Rack::Mime::MIME_TYPES[File.extname(path)]
|
27
|
+
autoclose(file)
|
28
|
+
end
|
29
|
+
|
30
|
+
def uploaded_file_with_content(basename, content)
|
31
|
+
io = ActionController::UploadedStringIO.new(content)
|
32
|
+
io.original_path = basename
|
33
|
+
io.content_type = Rack::Mime::MIME_TYPES[File.extname(basename)]
|
34
|
+
io
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_file(basename)
|
38
|
+
path = test_path(basename)
|
39
|
+
file = open(path)
|
40
|
+
autoclose(file)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_path(basename)
|
44
|
+
"#{ROOT}/spec/data/#{basename}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# For when it doesn't matter if it's small or large.
|
48
|
+
alias uploaded_file small_uploaded_file
|
49
|
+
|
50
|
+
def test_image_file(basename='test.jpg')
|
51
|
+
path = test_image_path(basename)
|
52
|
+
file = open(path)
|
53
|
+
autoclose(file)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_image_path(basename='test.jpg')
|
57
|
+
test_path(basename)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_video_file(basename='test.mov')
|
61
|
+
path = test_video_path(basename)
|
62
|
+
file = open(path)
|
63
|
+
autoclose(file)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_video_path(basename='test.mov')
|
67
|
+
test_path(basename)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_pdf_file(basename='test.pdf')
|
71
|
+
path = test_pdf_path(basename)
|
72
|
+
file = open(path)
|
73
|
+
autoclose(file)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_pdf_path(basename='test.pdf')
|
77
|
+
test_path(basename)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_empty_file
|
81
|
+
file = open(test_path('empty.txt'))
|
82
|
+
autoclose(file)
|
83
|
+
end
|
84
|
+
|
85
|
+
private # ---------------------------------------------------------
|
86
|
+
|
87
|
+
def init_test_upload_files
|
88
|
+
@files_to_close = []
|
89
|
+
end
|
90
|
+
|
91
|
+
def close_test_upload_files
|
92
|
+
@files_to_close.each(&:close)
|
93
|
+
end
|
94
|
+
|
95
|
+
def content_for_uploaded_file(test_file)
|
96
|
+
path = test_path("test#{File.extname(test_file)}")
|
97
|
+
File.read(path)
|
98
|
+
end
|
99
|
+
|
100
|
+
def unused_temp_path
|
101
|
+
i = 0
|
102
|
+
path = nil
|
103
|
+
begin
|
104
|
+
path = File.join(temporary_directory, "test-#{i}.jpg")
|
105
|
+
end while File.exist?(path)
|
106
|
+
path
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TimeTravel
|
2
|
+
def self.included(mod)
|
3
|
+
mod.before{stop_time}
|
4
|
+
end
|
5
|
+
|
6
|
+
def stop_time
|
7
|
+
warp_to Time.now
|
8
|
+
end
|
9
|
+
|
10
|
+
def warp_to(time)
|
11
|
+
time = Time.parse(time) if time.is_a?(String)
|
12
|
+
Time.stubs(:now).returns(time)
|
13
|
+
end
|
14
|
+
|
15
|
+
def warp_ahead(duration)
|
16
|
+
new_now = Time.now + duration
|
17
|
+
Time.stubs(:now).returns(new_now)
|
18
|
+
new_now
|
19
|
+
end
|
20
|
+
end
|
Binary file
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Lifecycle hooks" do
|
4
|
+
use_model_class(:Thing,
|
5
|
+
:attachment_file_name => :string,
|
6
|
+
:value => :integer)
|
7
|
+
|
8
|
+
before do
|
9
|
+
@file = open("#{ROOT}/spec/integration/data/test.jpg")
|
10
|
+
Bulldog.default_url_template = "/attachments/:class/:id.:style.:extension"
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
@file.close
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should run before-validation hooks before validating the record" do
|
18
|
+
checks = []
|
19
|
+
Thing.validates_presence_of :value
|
20
|
+
Thing.has_attachment :attachment do
|
21
|
+
style :normal
|
22
|
+
process :before => :validation do
|
23
|
+
checks << record.errors.empty?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
thing = Thing.new(:attachment => @file)
|
27
|
+
checks.should == []
|
28
|
+
thing.valid?.should be_false
|
29
|
+
checks.should == [true]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should run after-validation hooks after validating the record" do
|
33
|
+
checks = []
|
34
|
+
Thing.validates_presence_of :value
|
35
|
+
Thing.has_attachment :attachment do
|
36
|
+
style :normal
|
37
|
+
process :after => :validation do
|
38
|
+
checks << record.errors.empty?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
thing = Thing.new(:attachment => @file)
|
42
|
+
checks.should == []
|
43
|
+
thing.valid?.should be_false
|
44
|
+
checks.should == [false]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should run before-save hooks before saving the record" do
|
48
|
+
checks = []
|
49
|
+
Thing.has_attachment :attachment do
|
50
|
+
style :normal
|
51
|
+
process :before => :save do
|
52
|
+
checks << record.new_record?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
thing = Thing.new(:attachment => @file)
|
56
|
+
checks.should == []
|
57
|
+
thing.save.should be_true
|
58
|
+
checks.should == [true]
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should run after-save hooks after saving the record" do
|
62
|
+
checks = []
|
63
|
+
Thing.has_attachment :attachment do
|
64
|
+
style :normal
|
65
|
+
process :after => :save do
|
66
|
+
checks << record.new_record?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
thing = Thing.new(:attachment => @file)
|
70
|
+
checks.should == []
|
71
|
+
thing.save.should be_true
|
72
|
+
checks.should == [false]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should run before-create hooks before creating the record" do
|
76
|
+
checks = []
|
77
|
+
Thing.has_attachment :attachment do
|
78
|
+
style :normal
|
79
|
+
process :before => :create do
|
80
|
+
checks << record.new_record?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
thing = Thing.new(:attachment => @file)
|
84
|
+
checks.should == []
|
85
|
+
thing.save.should be_true
|
86
|
+
checks.should == [true]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should run after-create hooks after creating the record" do
|
90
|
+
checks = []
|
91
|
+
Thing.has_attachment :attachment do
|
92
|
+
style :normal
|
93
|
+
process :after => :create do
|
94
|
+
checks << record.new_record?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
thing = Thing.new(:attachment => @file)
|
98
|
+
checks.should == []
|
99
|
+
thing.save.should be_true
|
100
|
+
checks.should == [false]
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should run before-update hooks before updating the record" do
|
104
|
+
checks = []
|
105
|
+
Thing.has_attachment :attachment do
|
106
|
+
style :normal
|
107
|
+
process :before => :update do
|
108
|
+
checks << Thing.count(:conditions => {:value => 2})
|
109
|
+
end
|
110
|
+
end
|
111
|
+
Thing.create(:attachment => @file, :value => 1)
|
112
|
+
thing = Thing.first
|
113
|
+
checks.should == []
|
114
|
+
thing.update_attributes(:value => 2).should be_true
|
115
|
+
checks.should == [0]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should run after-update hooks after updating the record" do
|
119
|
+
checks = []
|
120
|
+
Thing.has_attachment :attachment do
|
121
|
+
style :normal
|
122
|
+
process :after => :update do
|
123
|
+
checks << Thing.count(:conditions => {:value => 2})
|
124
|
+
end
|
125
|
+
end
|
126
|
+
Thing.create(:attachment => @file, :value => 1)
|
127
|
+
thing = Thing.first
|
128
|
+
checks.should == []
|
129
|
+
thing.update_attributes(:value => 2).should be_true
|
130
|
+
checks.should == [1]
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should not run create hooks when updating the record" do
|
134
|
+
checks = []
|
135
|
+
Thing.has_attachment :attachment do
|
136
|
+
style :normal
|
137
|
+
process :before => :update do
|
138
|
+
checks << [:fail]
|
139
|
+
end
|
140
|
+
|
141
|
+
process :after => :update do |thing|
|
142
|
+
checks << [:fail]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
Thing.create(:attachment => @file)
|
146
|
+
checks.should == []
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should not run update hooks when creating the record" do
|
150
|
+
checks = []
|
151
|
+
Thing.has_attachment :attachment do
|
152
|
+
style :normal
|
153
|
+
process :before => :create do
|
154
|
+
checks << [:fail]
|
155
|
+
end
|
156
|
+
|
157
|
+
process :after => :create do
|
158
|
+
checks << [:fail]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
thing = Thing.create(:attachment => @file, :value => 1)
|
162
|
+
checks = []
|
163
|
+
thing.update_attributes(:value => 2)
|
164
|
+
checks.should == []
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should run callbacks for the given attachment types if given" do
|
168
|
+
runs = 0
|
169
|
+
Thing.has_attachment :attachment do
|
170
|
+
style :normal
|
171
|
+
process(:types => :image, :on => :test_event){runs += 1}
|
172
|
+
end
|
173
|
+
thing = Thing.new(:attachment => @file)
|
174
|
+
thing.process_attachment(:attachment, :test_event)
|
175
|
+
runs.should == 1
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should not run callbacks if the attachment is of the wrong type" do
|
179
|
+
runs = 0
|
180
|
+
Thing.has_attachment :attachment do
|
181
|
+
style :normal
|
182
|
+
process(:types => :video, :on => :test_event){runs += 1}
|
183
|
+
end
|
184
|
+
thing = Thing.new(:attachment => @file)
|
185
|
+
thing.process_attachment(:attachment, :test_event)
|
186
|
+
runs.should == 0
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should allow specifying more than one type" do
|
190
|
+
runs = 0
|
191
|
+
Thing.has_attachment :attachment do
|
192
|
+
style :normal
|
193
|
+
process(:types => [:image, :video], :on => :test_event){runs += 1}
|
194
|
+
end
|
195
|
+
thing = Thing.new(:attachment => @file)
|
196
|
+
thing.process_attachment(:attachment, :test_event)
|
197
|
+
thing.attachment = uploaded_file_with_content('test.avi', "RIFF AVI ")
|
198
|
+
thing.process_attachment(:attachment, :test_event)
|
199
|
+
runs.should == 2
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should run multiple callbacks if given" do
|
203
|
+
checks = []
|
204
|
+
Thing.has_attachment :attachment do
|
205
|
+
style :normal
|
206
|
+
process(:on => :test_event){checks << 1}
|
207
|
+
process(:on => :test_event){checks << 2}
|
208
|
+
end
|
209
|
+
thing = Thing.new(:attachment => @file)
|
210
|
+
thing.process_attachment(:attachment, :test_event)
|
211
|
+
checks.should == [1, 2]
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Processing image attachments" do
|
4
|
+
use_model_class(:Thing,
|
5
|
+
:width => :integer,
|
6
|
+
:height => :integer)
|
7
|
+
|
8
|
+
def identify
|
9
|
+
Bulldog::Processor::ImageMagick.identify_command
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
tmp = temporary_directory
|
14
|
+
Thing.has_attachment :photo do
|
15
|
+
path "#{tmp}/:id.:style.png"
|
16
|
+
style :small, {:size => '10x10!'}
|
17
|
+
style :large, {:size => '1000x1000!'}
|
18
|
+
|
19
|
+
process :before => :save do
|
20
|
+
width, height = dimensions
|
21
|
+
record.width = width
|
22
|
+
record.height = height
|
23
|
+
end
|
24
|
+
|
25
|
+
process :on => :resize do
|
26
|
+
resize
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@thing = Thing.new
|
30
|
+
@thing.stubs(:id).returns(5)
|
31
|
+
@file = small_uploaded_file(:size => "40x30")
|
32
|
+
end
|
33
|
+
|
34
|
+
def small_uploaded_file(options={})
|
35
|
+
tmp_path = "#{temporary_directory}/small_uploaded_file.tmp.png"
|
36
|
+
create_image(tmp_path, options)
|
37
|
+
content = File.read(tmp_path)
|
38
|
+
File.unlink(tmp_path)
|
39
|
+
|
40
|
+
io = ActionController::UploadedStringIO.new(content)
|
41
|
+
io.original_path = "tmp.png"
|
42
|
+
io.content_type = 'image/png'
|
43
|
+
io
|
44
|
+
end
|
45
|
+
|
46
|
+
after do
|
47
|
+
@file.close
|
48
|
+
end
|
49
|
+
|
50
|
+
def path(style)
|
51
|
+
"#{temporary_directory}/5.#{style}.png"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should run the after_save process after saving" do
|
55
|
+
@thing.update_attributes(:photo => @file)
|
56
|
+
@thing.width.should == 40
|
57
|
+
@thing.height.should == 30
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should process the attachment when the processor is run" do
|
61
|
+
File.exist?(path(:original)).should be_false
|
62
|
+
File.exist?(path(:small)).should be_false
|
63
|
+
File.exist?(path(:large)).should be_false
|
64
|
+
|
65
|
+
@thing.update_attributes(:photo => @file).should be_true
|
66
|
+
@thing.process_attachment(:photo, :resize)
|
67
|
+
|
68
|
+
`"#{identify}" -format "%w %h" "#{path(:original)}"`.chomp.should == '40 30'
|
69
|
+
`"#{identify}" -format "%w %h" "#{path(:small)}"`.chomp.should == '10 10'
|
70
|
+
`"#{identify}" -format "%w %h" "#{path(:large)}"`.chomp.should == '1000 1000'
|
71
|
+
end
|
72
|
+
end
|