scale_down 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ pkg/*
3
3
  .bundle
4
4
  gen_tags
5
5
  public
6
+ config.ru
data/README.rdoc CHANGED
@@ -49,10 +49,7 @@ Create a rackup file (config.ru)
49
49
  # The length of the HMAC signature to use
50
50
  config.hmac_length = 8
51
51
 
52
- # The root path to the images. Use a symlink if it is helpful
53
- config.root_path = File.expand_path(File.dirname(__FILE__))+"/public"
54
-
55
- # The public path for serving static(scaled) images, probably identical to the above.
52
+ # The path to the public directory
56
53
  config.public_path = File.expand_path(File.dirname(__FILE__))+"/public"
57
54
 
58
55
  end
@@ -68,16 +65,20 @@ Start the server using whatever server you want.
68
65
 
69
66
  In your application with the images you will need to generate the URL for the image source.
70
67
 
68
+ Filenames can have characters (# ? /) which may need to be escaped. So it is important that you CGI escape them.
69
+
70
+ They should be CGI escaped AFTER the HMAC is generated, and only escape the filename, not the path or options.
71
+
72
+ # Example ruby function to generate signed URL
71
73
  require 'HMAC::SHA1'
74
+ require 'cgi'
72
75
 
73
- # ie scaled_image_src('/images/picture.png/400x300-cropped')
74
- def scaled_image_src(url)
75
- hmac = HMAC::SHA1.new("secret").update(url).to_s[0...8]
76
- "http://images.myserver.com#{URI.encode(url)}/#{hmac}"
76
+ # ie signed_image_url('/images/picture.png/400x300-cropped')
77
+ def signed_image_url(path, filename, options)
78
+ hmac = HMAC::SHA1.new("secret").update([path, filename, options].join("/")).to_s[0...8]
79
+ "http://images.myserver.com#{[path, CGI.escape(filename), options, hmac].join("/")}"
77
80
  end
78
81
 
79
- Files names might require URI encoding. This should be done after generating the HMAC.
80
-
81
82
  Of course this could be done in PHP, Python, or whatever language your application is running.
82
83
 
83
84
  == TODO
data/config_sample.ru CHANGED
@@ -12,9 +12,6 @@ ScaleDown.tap do |config|
12
12
  # The length of the HMAC signature to use
13
13
  config.hmac_length = 8
14
14
 
15
- # The root path to the images
16
- config.root_path = File.expand_path(File.dirname(__FILE__))+"/public"
17
-
18
15
  # The location of the public directory for serving static files
19
16
  # This might be redudant since it will always, maybe, maybe not, be the same as root_path
20
17
  config.public_path = "#{File.expand_path(File.dirname(__FILE__))}/public"
@@ -29,9 +29,6 @@ module ScaleDown
29
29
  ScaleDown::Controller.public = str
30
30
  end
31
31
 
32
- # The path the root of the images directory
33
- attr_accessor :root_path
34
-
35
32
  # Defaults
36
33
  ScaleDown.max_file_size = 10 * 1_048_576
37
34
  ScaleDown.max_dimensions = [1200,1200]
@@ -9,7 +9,7 @@ class ScaleDown::Controller < Sinatra::Application
9
9
  end
10
10
 
11
11
  get '/*/info' do
12
- info = ScaleDown::Scaler.info(params[:splat].join("/"))
12
+ info = ScaleDown::Dispatcher.info(params[:splat].join("/"))
13
13
  if info
14
14
  [200, info]
15
15
  else
@@ -28,7 +28,7 @@ class ScaleDown::Controller < Sinatra::Application
28
28
  :filename => parts.pop,
29
29
  :splat => parts
30
30
  }
31
- path, status = scaler(params)
31
+ path, status = dispatch(params)
32
32
 
33
33
  # TODO Eh? Shouldn't it be if 301
34
34
  unless status == 403
@@ -40,8 +40,8 @@ class ScaleDown::Controller < Sinatra::Application
40
40
  end
41
41
 
42
42
  protected
43
- def scaler(params)
44
- ScaleDown::Scaler.process \
43
+ def dispatch(params)
44
+ ScaleDown::Dispatcher.process \
45
45
  :path => params[:splat].join("/"),
46
46
  :filename => params[:filename],
47
47
  :geometry => params[:geometry],
@@ -1,22 +1,24 @@
1
- class ScaleDown::Scaler
1
+ class ScaleDown::Dispatcher
2
+
3
+ # Controls flow to ensure that the file exists and has the proper HMAC signature.
2
4
 
3
5
  class << self
4
6
 
5
7
  def process(params)
6
- scaler = new(params)
8
+ dispatcher = new(params)
7
9
 
8
- return ["Missing file", 404] unless scaler.root_file_exists?
9
- return [scaler.redirect_path, 301] if scaler.scaled_file_exists?
10
+ return ["Missing file", 404] unless dispatcher.root_file_exists?
11
+ return [dispatcher.redirect_path, 301] if dispatcher.scaled_file_exists?
10
12
 
11
- if scaler.valid_hmac? && scaler.scale
12
- [scaler.redirect_path, 301]
13
- else
14
- ["Error message", 403]
15
- end
13
+ return ["Invalid HMAC signature", 403] unless dispatcher.valid_hmac?
14
+ return ["File failed to scale. The file may be corrupt.", 500] unless dispatcher.scale
15
+
16
+ [dispatcher.redirect_path, 301]
16
17
  end
17
18
 
19
+ # TODO return a JSON response with a full set of image details
18
20
  def info(relative_path)
19
- path = [ScaleDown.root_path, relative_path].join("/")
21
+ path = [ScaleDown.public_path, relative_path].join("/")
20
22
  if File.exists?(path)
21
23
  image = MiniMagick::Image.open(path)
22
24
  [image[:width],image[:height]].join('x')
@@ -62,11 +64,11 @@ class ScaleDown::Scaler
62
64
  end
63
65
 
64
66
  def root_path
65
- File.join(ScaleDown.root_path, @params[:path], @params[:filename])
67
+ File.join(ScaleDown.public_path, @params[:path], @params[:filename])
66
68
  end
67
69
 
68
70
  def scaled_file_path
69
- File.join(ScaleDown.root_path, redirect_path)
71
+ File.join(ScaleDown.public_path, redirect_path)
70
72
  end
71
73
 
72
74
  def scaled_filename
@@ -2,6 +2,14 @@ require 'pathname'
2
2
 
3
3
  class ScaleDown::Image
4
4
 
5
+ # This class should only
6
+ # load an image
7
+ # ensure an RGB colorspace
8
+ # correct the orientation
9
+ # scale the image to the dimensions
10
+ # save the scaled image to the specified path
11
+ #
12
+ # This is not the place for any other logic.
5
13
  include Magick
6
14
 
7
15
  class << self
@@ -31,24 +39,23 @@ class ScaleDown::Image
31
39
  end
32
40
 
33
41
  def initialize(properties = {})
34
- @file = load_file(properties[:file])
35
- @out = properties[:out]
36
- @geometry = geometry(properties[:options])
37
- @options = properties[:options]
38
- @wrote = false
39
-
40
- if @file
41
- save
42
- @file.destroy! #release the memory
42
+ load_file(properties[:file]) do |file|
43
+ resize(file, properties[:options])
44
+ fix_color_space(file)
45
+
46
+ @valid = write(file, properties[:out])
43
47
  end
44
48
  end
45
49
 
46
50
  def load_file(file_path)
47
51
  self.class.validate_file_size(file_path)
48
52
  begin
49
- Magick::Image.read(file_path).first
53
+ file = Magick::Image.read(file_path).first
54
+ unless file.nil?
55
+ yield file
56
+ file.destroy!
57
+ end
50
58
  rescue Magick::ImageMagickError => e
51
- return nil
52
59
  end
53
60
  end
54
61
 
@@ -57,37 +64,33 @@ class ScaleDown::Image
57
64
  end
58
65
 
59
66
  def valid?
60
- @wrote
67
+ @valid ||= false
61
68
  end
62
69
 
63
70
  protected
64
71
 
65
- def save
66
- path = Pathname.new(@out).dirname.to_s
67
- FileUtils.mkdir_p path unless FileTest.directory? path
68
- resize
69
- fix_color_space
70
- write
71
- end
72
-
73
- def fix_color_space
74
- if @file.colorspace == Magick::CMYKColorspace
75
- @file.add_profile "#{File.expand_path(File.dirname(__FILE__))}/../../color_profiles/sRGB.icm"
76
- @file = @file.quantize 2**24, Magick::RGBColorspace
72
+ def fix_color_space(file)
73
+ if file.colorspace == Magick::CMYKColorspace
74
+ file.add_profile "#{File.expand_path(File.dirname(__FILE__))}/../../color_profiles/sRGB.icm"
75
+ file = file.quantize 2**24, Magick::RGBColorspace
77
76
  end
78
77
  end
79
78
 
80
- def resize
81
- @file.auto_orient!
82
- if @options[:crop]
83
- @file.crop_resized!(@geometry.width, @geometry.height, Magick::CenterGravity)
79
+ def resize(file, properties)
80
+ geo = geometry(properties)
81
+ file.auto_orient!
82
+ if properties[:crop]
83
+ file.crop_resized!(geo.width, geo.height, Magick::CenterGravity)
84
84
  else
85
- @file.change_geometry!(@geometry) {|cols, rows, img| img.resize!(cols,rows)}
85
+ file.change_geometry!(geo) {|cols, rows, img| img.resize!(cols,rows)}
86
86
  end
87
87
  end
88
88
 
89
- def write
90
- @file.write(@out) { self.quality = 85 }
91
- @wrote = true
89
+ def write(file, file_out)
90
+ path = Pathname.new(file_out).dirname.to_s
91
+ FileUtils.mkdir_p path unless FileTest.directory? path
92
+
93
+ file.write(file_out) { self.quality = 85 }
94
+ true
92
95
  end
93
96
  end
@@ -1,3 +1,3 @@
1
1
  module ScaleDown
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/scale_down.rb CHANGED
@@ -11,7 +11,7 @@ module ScaleDown
11
11
  require 'scale_down/configuration'
12
12
  require 'scale_down/version'
13
13
  require 'scale_down/controller'
14
- require 'scale_down/scaler'
14
+ require 'scale_down/dispatcher'
15
15
  require 'scale_down/image'
16
16
 
17
17
  class InvalidGeometry < Exception; end
@@ -9,7 +9,7 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
9
9
 
10
10
  context "parsing a request" do
11
11
  should "have an image path" do
12
- ScaleDown::Scaler.expects(:process).with(
12
+ ScaleDown::Dispatcher.expects(:process).with(
13
13
  :path => "user/path",
14
14
  :filename => "filename.png",
15
15
  :geometry => "400x300-cropped-grayscale",
@@ -22,7 +22,7 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
22
22
 
23
23
  context "a valid request" do
24
24
  should "redirect to the image path" do
25
- ScaleDown::Scaler.expects(:process).returns ["/image-path", 301]
25
+ ScaleDown::Dispatcher.expects(:process).returns ["/image-path", 301]
26
26
  get "/path/filename/geo/hmac"
27
27
 
28
28
  assert_equal 301, last_response.status
@@ -33,7 +33,7 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
33
33
  context "an invalid request" do
34
34
 
35
35
  should "respond with a 403 and error message" do
36
- ScaleDown::Scaler.expects(:process).returns ["Error description", 403]
36
+ ScaleDown::Dispatcher.expects(:process).returns ["Error description", 403]
37
37
 
38
38
  get "/path/filename/geo/hmac"
39
39
 
@@ -45,7 +45,7 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
45
45
  context "get dimensions" do
46
46
  context "for image which exists" do
47
47
  setup do
48
- ScaleDown::Scaler.expects(:info).with("image/path/image.jpg").returns "400x300"
48
+ ScaleDown::Dispatcher.expects(:info).with("image/path/image.jpg").returns "400x300"
49
49
  end
50
50
 
51
51
  should "return the width and height as json" do
@@ -58,7 +58,7 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
58
58
 
59
59
  context "for a non-existant image" do
60
60
  setup do
61
- ScaleDown::Scaler.expects(:info).with("image/path/image.jpg").returns nil
61
+ ScaleDown::Dispatcher.expects(:info).with("image/path/image.jpg").returns nil
62
62
  end
63
63
 
64
64
  should "respond with a 404" do
@@ -1,13 +1,13 @@
1
1
  require File.expand_path(File.dirname(__FILE__))+'/../test_helper'
2
2
 
3
- class ScaleDown::Scaler::Test < Test::Unit::TestCase
3
+ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
4
4
 
5
- context "Scaler::Test" do
5
+ context "Dispatcher::Test" do
6
6
  setup do
7
7
  ScaleDown.hmac_key = "secret"
8
8
  ScaleDown.hmac_method = HMAC::SHA1
9
9
  ScaleDown.hmac_length = 8
10
- ScaleDown.root_path = "/tmp"
10
+ ScaleDown.public_path = "/tmp"
11
11
 
12
12
  hmac = HMAC::SHA1.new("secret").update("file/path/filename.png/400x300-crop").to_s
13
13
 
@@ -21,51 +21,51 @@ class ScaleDown::Scaler::Test < Test::Unit::TestCase
21
21
 
22
22
  context "instance" do
23
23
  setup do
24
- @scaler = ScaleDown::Scaler.new @params
24
+ @dispatcher = ScaleDown::Dispatcher.new @params
25
25
  end
26
26
 
27
27
  should "validate the HMAC" do
28
28
  ScaleDown.expects(:valid_hmac?).with(@params).returns true
29
- assert @scaler.valid_hmac?
29
+ assert @dispatcher.valid_hmac?
30
30
  end
31
31
 
32
32
  should "determine root file existance" do
33
33
  File.expects(:exists?).with("/tmp/file/path/filename.png").returns true
34
- assert @scaler.root_file_exists?
34
+ assert @dispatcher.root_file_exists?
35
35
  end
36
36
 
37
37
  should "deterimine the scaled image's existance" do
38
38
  File.expects(:exists?).with("/tmp/file/path/scaled/filename-400x300-crop.png").returns true
39
- assert @scaler.scaled_file_exists?
39
+ assert @dispatcher.scaled_file_exists?
40
40
  end
41
41
 
42
42
  should "parse the geometry params into options" do
43
- assert_equal({:width => 400, :height => 300, :crop => true}, @scaler.image_options)
43
+ assert_equal({:width => 400, :height => 300, :crop => true}, @dispatcher.image_options)
44
44
  end
45
45
 
46
46
  should "have a redirect path" do
47
- assert_equal "/file/path/scaled/filename-400x300-crop.png", @scaler.redirect_path
47
+ assert_equal "/file/path/scaled/filename-400x300-crop.png", @dispatcher.redirect_path
48
48
  end
49
49
 
50
50
  should "process the image" do
51
51
  ScaleDown::Image.expects(:scale).with(
52
- :file => @scaler.root_path,
53
- :out => @scaler.scaled_file_path,
54
- :options => @scaler.image_options).returns true
52
+ :file => @dispatcher.root_path,
53
+ :out => @dispatcher.scaled_file_path,
54
+ :options => @dispatcher.image_options).returns true
55
55
 
56
- assert @scaler.scale
56
+ assert @dispatcher.scale
57
57
  end
58
58
 
59
59
  should "default to a jpg out file" do
60
60
  ["jpg", "tga", "tif", "pdf", "psd"].each do |ext|
61
- scaler = ScaleDown::Scaler.new @params.merge(:filename => "test.#{ext}")
62
- assert_match /\.jpg$/, scaler.scaled_file_path
61
+ dispatcher = ScaleDown::Dispatcher.new @params.merge(:filename => "test.#{ext}")
62
+ assert_match /\.jpg$/, dispatcher.scaled_file_path
63
63
  end
64
64
  end
65
65
 
66
66
  should "use a png for png graphics" do
67
- scaler = ScaleDown::Scaler.new @params.merge(:filename => "test.png")
68
- assert_match /\.png$/, scaler.scaled_file_path
67
+ dispatcher = ScaleDown::Dispatcher.new @params.merge(:filename => "test.png")
68
+ assert_match /\.png$/, dispatcher.scaled_file_path
69
69
  end
70
70
  end
71
71
 
@@ -84,18 +84,18 @@ class ScaleDown::Scaler::Test < Test::Unit::TestCase
84
84
  end
85
85
 
86
86
  should "scale the image" do
87
- ScaleDown::Scaler.process(@params)
87
+ ScaleDown::Dispatcher.process(@params)
88
88
  end
89
89
 
90
90
  should "return a 301 redirect to the processed image's URL" do
91
- assert_equal ["/file/path/scaled/filename-400x300-crop.png", 301], ScaleDown::Scaler.process(@params)
91
+ assert_equal ["/file/path/scaled/filename-400x300-crop.png", 301], ScaleDown::Dispatcher.process(@params)
92
92
  end
93
93
  end
94
94
 
95
95
  context "without a valid HMAC" do
96
96
  should "return a 403 Forbidden response" do
97
97
  ScaleDown.expects(:valid_hmac?).returns false
98
- assert_equal 403, ScaleDown::Scaler.process(@params)[1]
98
+ assert_equal 403, ScaleDown::Dispatcher.process(@params)[1]
99
99
  end
100
100
  end
101
101
  end
@@ -107,7 +107,7 @@ class ScaleDown::Scaler::Test < Test::Unit::TestCase
107
107
  end
108
108
 
109
109
  should "return a 301 redirect to the processed image's URL" do
110
- assert_equal ["/file/path/scaled/filename-400x300-crop.png", 301], ScaleDown::Scaler.process(@params)
110
+ assert_equal ["/file/path/scaled/filename-400x300-crop.png", 301], ScaleDown::Dispatcher.process(@params)
111
111
  end
112
112
  end
113
113
 
@@ -117,7 +117,7 @@ class ScaleDown::Scaler::Test < Test::Unit::TestCase
117
117
  end
118
118
 
119
119
  should "return a 404" do
120
- assert_equal 404, ScaleDown::Scaler.process(@params)[1]
120
+ assert_equal 404, ScaleDown::Dispatcher.process(@params)[1]
121
121
  end
122
122
  end
123
123
  end
@@ -125,15 +125,15 @@ class ScaleDown::Scaler::Test < Test::Unit::TestCase
125
125
 
126
126
  context "#info" do
127
127
  setup do
128
- ScaleDown.root_path = File.join(File.expand_path(File.dirname(__FILE__)), "..")
128
+ ScaleDown.public_path = File.join(File.expand_path(File.dirname(__FILE__)), "..")
129
129
  end
130
130
 
131
131
  should "return the width x height for an image" do
132
- assert_equal "200x400", ScaleDown::Scaler.info("files/graphic.png")
132
+ assert_equal "200x400", ScaleDown::Dispatcher.info("files/graphic.png")
133
133
  end
134
134
 
135
135
  should "return nil for a non-existant image" do
136
- assert_equal nil, ScaleDown::Scaler.info("files/notthere.jpg")
136
+ assert_equal nil, ScaleDown::Dispatcher.info("files/notthere.jpg")
137
137
  end
138
138
  end
139
139
 
@@ -16,7 +16,7 @@ class ScaleDown::Test < Test::Unit::TestCase
16
16
  ScaleDown.hmac_key = "secret"
17
17
  ScaleDown.hmac_method = HMAC::SHA1
18
18
  ScaleDown.hmac_length = 8
19
- ScaleDown.root_path = "/tmp/scale_down"
19
+ ScaleDown.public_path = "/tmp/scale_down"
20
20
  end
21
21
 
22
22
  context "HMAC" do
@@ -40,7 +40,6 @@ class ScaleDown::Test < Test::Unit::TestCase
40
40
  end
41
41
  end
42
42
 
43
-
44
43
  context "integration test" do
45
44
  setup do
46
45
  FileUtils.mkdir_p("/tmp/scale_down/test_images/example_1")
@@ -65,10 +64,10 @@ class ScaleDown::Test < Test::Unit::TestCase
65
64
  assert_equal 404, last_response.status
66
65
  end
67
66
 
68
- should "get an invalid image and return a 403" do
67
+ should "get an invalid image and return a 500" do
69
68
  valid_get '/test_images/example_2/invalid_jpeg.jpg/400x300-cropped'
70
69
 
71
- assert_equal 403, last_response.status
70
+ assert_equal 500, last_response.status
72
71
  assert !File.exists?("/tmp/scale_down/test_images/example_2/scaled/invalid_jpeg-400x300-cropped.jpg")
73
72
  end
74
73
  end
@@ -1,21 +1,33 @@
1
1
  require File.expand_path(File.dirname(__FILE__))+'/test_helper'
2
2
 
3
+ require 'cgi'
4
+
3
5
  class ScaleDown::Test < Test::Unit::TestCase
4
6
 
5
- def scaled_image_src(url)
6
- hmac = HMAC::SHA1.new("secret").update(url).to_s[0...8]
7
- "http://images.myserver.com#{url}/#{hmac}"
7
+ def signed_image_url(path, filename, options)
8
+ hmac = HMAC::SHA1.new("secret").update([path, filename, options].join("/")).to_s[0...8]
9
+ "http://images.myserver.com#{[path, CGI.escape(filename), options, hmac].join("/")}"
8
10
  end
9
11
 
10
12
  setup do
11
13
  ScaleDown.hmac_key = "secret"
12
14
  ScaleDown.hmac_method = HMAC::SHA1
13
15
  ScaleDown.hmac_length = 8
14
- ScaleDown.root_path = "/tmp"
16
+ ScaleDown.public_path = "/tmp"
15
17
  end
16
18
 
17
19
  should "create a URL with the HMAC signature" do
18
20
  hmac = ScaleDown.hmac("/images/graphic.png/400x300-cropped")
19
- assert_equal "http://images.myserver.com/images/graphic.png/400x300-cropped/#{hmac}", scaled_image_src("/images/graphic.png/400x300-cropped")
21
+ assert_equal\
22
+ "http://images.myserver.com/images/graphic.png/400x300-cropped/#{hmac}",
23
+ signed_image_url("/images","graphic.png","400x300-cropped")
24
+ end
25
+
26
+ should "create a URL when the filename has URI break characters" do
27
+ filename = "# !%23?.png"
28
+ hmac = ScaleDown.hmac("/images/#{filename}/400x300-cropped")
29
+ assert_equal\
30
+ "http://images.myserver.com/images/#{CGI.escape filename}/400x300-cropped/#{hmac}",
31
+ signed_image_url("/images", filename, "400x300-cropped")
20
32
  end
21
33
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scale_down
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Weir
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-01 00:00:00 -04:00
18
+ date: 2010-11-05 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -148,8 +148,8 @@ files:
148
148
  - lib/scale_down.rb
149
149
  - lib/scale_down/configuration.rb
150
150
  - lib/scale_down/controller.rb
151
+ - lib/scale_down/dispatcher.rb
151
152
  - lib/scale_down/image.rb
152
- - lib/scale_down/scaler.rb
153
153
  - lib/scale_down/version.rb
154
154
  - scale_down.gemspec
155
155
  - test/files/cmyk.tif
@@ -158,8 +158,8 @@ files:
158
158
  - test/files/orient.jpg
159
159
  - test/scale_down/configuration_test.rb
160
160
  - test/scale_down/controller_test.rb
161
+ - test/scale_down/dispatcher_test.rb
161
162
  - test/scale_down/image_test.rb
162
- - test/scale_down/scaler_test.rb
163
163
  - test/scale_down_test.rb
164
164
  - test/scaled_image_tag_test.rb
165
165
  - test/test_helper.rb
@@ -204,8 +204,8 @@ test_files:
204
204
  - test/files/orient.jpg
205
205
  - test/scale_down/configuration_test.rb
206
206
  - test/scale_down/controller_test.rb
207
+ - test/scale_down/dispatcher_test.rb
207
208
  - test/scale_down/image_test.rb
208
- - test/scale_down/scaler_test.rb
209
209
  - test/scale_down_test.rb
210
210
  - test/scaled_image_tag_test.rb
211
211
  - test/test_helper.rb