image_optim 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/image_optim.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'image_optim'
5
- s.version = '0.1.0'
5
+ s.version = '0.2.0'
6
6
  s.summary = %q{Optimize images (jpeg, png, gif) using external utilities (advpng, gifsicle, jpegoptim, jpegtran, optipng, pngcrush, pngout)}
7
7
  s.homepage = "http://github.com/toy/#{s.name}"
8
8
  s.authors = ['Ivan Kuchin']
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_paths = %w[lib]
17
17
 
18
- s.add_dependency 'fspath', '~> 2.0.1'
18
+ s.add_dependency 'fspath', '~> 2.0.3'
19
19
  s.add_dependency 'image_size', '~> 1.0.4'
20
20
  s.add_dependency 'progress', '~> 2.4.0'
21
21
  s.add_dependency 'in_threads', '~> 1.1.1'
@@ -44,13 +44,8 @@ class ImageOptim
44
44
  end
45
45
 
46
46
  # Optimize file, return new path or nil if optimization failed
47
- def optimize(src)
48
- dst = src.temp_path
49
- if Util.run bin, *command_args(src, dst)
50
- if dst.size? && dst.size < src.size
51
- dst
52
- end
53
- end
47
+ def optimize(src, dst)
48
+ Util.run(bin, *command_args(src, dst)) && dst.size? && dst.size < src.size
54
49
  end
55
50
 
56
51
  # Name of binary determined from class name
data/lib/image_optim.rb CHANGED
@@ -43,11 +43,11 @@ class ImageOptim
43
43
  end
44
44
  worker = klass.new(worker_options)
45
45
  klass.image_formats.each do |format|
46
- workers_by_format[format] ||= []
47
- workers_by_format[format] << worker
46
+ @workers_by_format[format] ||= []
47
+ @workers_by_format[format] << worker
48
48
  end
49
49
  end
50
- workers_by_format.each do |format, workers|
50
+ @workers_by_format.each do |format, workers|
51
51
  workers.replace workers.sort_by(&:run_priority)
52
52
  end
53
53
 
@@ -64,14 +64,29 @@ class ImageOptim
64
64
  assert_options_empty!(options)
65
65
  end
66
66
 
67
+ # Get workers for image
68
+ def workers_for_image(path)
69
+ @workers_by_format[ImagePath.new(path).format]
70
+ end
71
+
67
72
  # Optimize one file, return new path or nil if optimization failed
68
73
  def optimize_image(original)
69
74
  original = ImagePath.new(original)
70
- if workers = workers_by_format[original.format]
71
- result = workers.inject(original) do |current, worker|
72
- worker.optimize(current) || current
75
+ if workers = workers_for_image(original)
76
+ result = nil
77
+ ts = [original, original.temp_path]
78
+ workers.each do |worker|
79
+ if result && ts.length < 3
80
+ ts << original.temp_path
81
+ end
82
+ if worker.optimize(*ts.last(2))
83
+ result = ts.last
84
+ if ts.length == 3
85
+ ts[-2, 2] = ts[-1], ts[-2]
86
+ end
87
+ end
73
88
  end
74
- result == original ? nil : result
89
+ result
75
90
  end
76
91
  end
77
92
 
@@ -17,26 +17,68 @@ def temp_copy_path(original)
17
17
  end
18
18
  end
19
19
 
20
+ Tempfile.class_eval do
21
+ alias_method :initialize_orig, :initialize
22
+
23
+ def initialize(*args, &block)
24
+ self.class.initialize_called
25
+ initialize_orig(*args, &block)
26
+ end
27
+
28
+ def self.initialize_called
29
+ @@call_count ||= 0
30
+ @@call_count += 1
31
+ end
32
+
33
+ def self.reset_call_count
34
+ @@call_count = 0
35
+ end
36
+
37
+ def self.call_count
38
+ @@call_count
39
+ end
40
+ end
41
+
42
+ Fixnum.class_eval do
43
+ def in_range?(range)
44
+ range.include?(self)
45
+ end
46
+ end
47
+
20
48
  describe ImageOptim do
21
49
  image_dir.glob('*') do |original|
22
50
  describe "optimizing #{original}" do
23
51
  it "should optimize image" do
24
52
  temp_copy_path(original) do |unoptimized|
25
- optimized = ImageOptim.optimize_image(unoptimized)
53
+ Tempfile.reset_call_count
54
+ io = ImageOptim.new
55
+ optimized = io.optimize_image(unoptimized)
26
56
  optimized.should be_a(FSPath)
27
57
  unoptimized.read.should == original.read
28
58
  optimized.size.should > 0
29
59
  optimized.size.should < unoptimized.size
30
60
  optimized.read.should_not == unoptimized.read
61
+ if io.workers_for_image(unoptimized).length > 1
62
+ Tempfile.call_count.should be_in_range(1..2)
63
+ else
64
+ Tempfile.call_count.should === 1
65
+ end
31
66
  end
32
67
  end
33
68
 
34
69
  it "should optimize image in place" do
35
70
  temp_copy_path(original) do |path|
36
- ImageOptim.optimize_image!(path).should be_true
71
+ Tempfile.reset_call_count
72
+ io = ImageOptim.new
73
+ io.optimize_image!(path).should be_true
37
74
  path.size.should > 0
38
75
  path.size.should < original.size
39
76
  path.read.should_not == original.read
77
+ if io.workers_for_image(path).length > 1
78
+ Tempfile.call_count.should be_in_range(2..3)
79
+ else
80
+ Tempfile.call_count.should === 2
81
+ end
40
82
  end
41
83
  end
42
84
 
@@ -58,7 +100,9 @@ describe ImageOptim do
58
100
 
59
101
  it "should ignore" do
60
102
  temp_copy_path(original) do |unoptimized|
103
+ Tempfile.reset_call_count
61
104
  optimized = ImageOptim.optimize_image(unoptimized)
105
+ Tempfile.call_count.should == 0
62
106
  optimized.should be_nil
63
107
  unoptimized.read.should == original.read
64
108
  end
@@ -66,7 +110,9 @@ describe ImageOptim do
66
110
 
67
111
  it "should ignore in place" do
68
112
  temp_copy_path(original) do |unoptimized|
113
+ Tempfile.reset_call_count
69
114
  ImageOptim.optimize_image!(unoptimized).should_not be_true
115
+ Tempfile.call_count.should == 0
70
116
  unoptimized.read.should == original.read
71
117
  end
72
118
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: image_optim
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ivan Kuchin
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-09 00:00:00 Z
18
+ date: 2012-01-10 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: fspath
@@ -25,12 +25,12 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- hash: 13
28
+ hash: 9
29
29
  segments:
30
30
  - 2
31
31
  - 0
32
- - 1
33
- version: 2.0.1
32
+ - 3
33
+ version: 2.0.3
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency