image_optim 0.1.0 → 0.2.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.
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