image_optim 0.29.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -3
  3. data/CHANGELOG.markdown +4 -0
  4. data/README.markdown +2 -1
  5. data/Vagrantfile +1 -1
  6. data/image_optim.gemspec +1 -1
  7. data/lib/image_optim.rb +15 -3
  8. data/lib/image_optim/bin_resolver/bin.rb +7 -7
  9. data/lib/image_optim/cache.rb +6 -0
  10. data/lib/image_optim/cmd.rb +45 -6
  11. data/lib/image_optim/config.rb +9 -1
  12. data/lib/image_optim/elapsed_time.rb +26 -0
  13. data/lib/image_optim/errors.rb +9 -0
  14. data/lib/image_optim/runner/option_parser.rb +4 -0
  15. data/lib/image_optim/timer.rb +25 -0
  16. data/lib/image_optim/worker.rb +24 -12
  17. data/lib/image_optim/worker/advpng.rb +2 -2
  18. data/lib/image_optim/worker/gifsicle.rb +3 -3
  19. data/lib/image_optim/worker/jhead.rb +2 -2
  20. data/lib/image_optim/worker/jpegoptim.rb +2 -2
  21. data/lib/image_optim/worker/jpegrecompress.rb +2 -2
  22. data/lib/image_optim/worker/jpegtran.rb +3 -3
  23. data/lib/image_optim/worker/optipng.rb +2 -2
  24. data/lib/image_optim/worker/pngcrush.rb +2 -2
  25. data/lib/image_optim/worker/pngout.rb +2 -2
  26. data/lib/image_optim/worker/pngquant.rb +2 -2
  27. data/lib/image_optim/worker/svgo.rb +2 -2
  28. data/script/worker_analysis +4 -4
  29. data/spec/image_optim/bin_resolver_spec.rb +5 -5
  30. data/spec/image_optim/cache_path_spec.rb +3 -7
  31. data/spec/image_optim/cache_spec.rb +7 -7
  32. data/spec/image_optim/cmd_spec.rb +58 -6
  33. data/spec/image_optim/config_spec.rb +36 -20
  34. data/spec/image_optim/elapsed_time_spec.rb +14 -0
  35. data/spec/image_optim/hash_helpers_spec.rb +18 -18
  36. data/spec/image_optim/option_definition_spec.rb +6 -6
  37. data/spec/image_optim/path_spec.rb +4 -8
  38. data/spec/image_optim/runner/option_parser_spec.rb +4 -4
  39. data/spec/image_optim/timer_spec.rb +32 -0
  40. data/spec/image_optim/worker/jpegrecompress_spec.rb +2 -2
  41. data/spec/image_optim/worker/optipng_spec.rb +11 -11
  42. data/spec/image_optim/worker/pngquant_spec.rb +5 -5
  43. data/spec/image_optim/worker_spec.rb +17 -17
  44. data/spec/image_optim_spec.rb +46 -9
  45. data/spec/spec_helper.rb +16 -15
  46. metadata +11 -4
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'image_optim/elapsed_time'
5
+
6
+ describe ImageOptim::ElapsedTime do
7
+ let(:timeout){ 0.01 }
8
+
9
+ describe '.now' do
10
+ it 'returns incrementing value' do
11
+ expect{ sleep timeout }.to change{ described_class.now }.by_at_least(timeout)
12
+ end
13
+ end
14
+ end
@@ -10,10 +10,10 @@ describe ImageOptim::HashHelpers do
10
10
 
11
11
  context 'stringify/simbolyze' do
12
12
  symbol_keys = {
13
- :a => 1,
14
- :b => {
15
- :c => [:a, 'a'],
16
- :d => {},
13
+ a: 1,
14
+ b: {
15
+ c: [:a, 'a'],
16
+ d: {},
17
17
  },
18
18
  }
19
19
 
@@ -38,22 +38,22 @@ describe ImageOptim::HashHelpers do
38
38
 
39
39
  it 'deep merges hashes' do
40
40
  merge_a = {
41
- :a => {
42
- :b => 1,
43
- :c => {
44
- :d => 2,
45
- :e => {:f => true},
41
+ a: {
42
+ b: 1,
43
+ c: {
44
+ d: 2,
45
+ e: {f: true},
46
46
  },
47
47
  },
48
- :y => 10,
48
+ y: 10,
49
49
  }
50
50
 
51
51
  merge_b = {
52
52
  :a => {
53
- :b => 2,
54
- :c => {
55
- :d => 3,
56
- :e => false,
53
+ b: 2,
54
+ c: {
55
+ d: 3,
56
+ e: false,
57
57
  },
58
58
  },
59
59
  'z' => 20,
@@ -61,10 +61,10 @@ describe ImageOptim::HashHelpers do
61
61
 
62
62
  merge_result = {
63
63
  :a => {
64
- :b => 2,
65
- :c => {
66
- :d => 3,
67
- :e => false,
64
+ b: 2,
65
+ c: {
66
+ d: 3,
67
+ e: false,
68
68
  },
69
69
  },
70
70
  :y => 10,
@@ -58,13 +58,13 @@ describe ImageOptim::OptionDefinition do
58
58
 
59
59
  context 'when option is nil' do
60
60
  it 'returns nil' do
61
- expect(subject.value(nil, :abc => nil)).to eq(nil)
61
+ expect(subject.value(nil, abc: nil)).to eq(nil)
62
62
  end
63
63
  end
64
64
 
65
65
  context 'when option is set' do
66
66
  it 'returns value' do
67
- expect(subject.value(nil, :abc => 123)).to eq(123)
67
+ expect(subject.value(nil, abc: 123)).to eq(123)
68
68
  end
69
69
  end
70
70
  end
@@ -84,13 +84,13 @@ describe ImageOptim::OptionDefinition do
84
84
 
85
85
  context 'when option is nil' do
86
86
  it 'returns nil passed through proc' do
87
- expect(subject.value(nil, :abc => nil)).to eq('nil')
87
+ expect(subject.value(nil, abc: nil)).to eq('nil')
88
88
  end
89
89
  end
90
90
 
91
91
  context 'when option is set' do
92
92
  it 'returns value passed through proc' do
93
- expect(subject.value(nil, :abc => 123)).to eq('123')
93
+ expect(subject.value(nil, abc: 123)).to eq('123')
94
94
  end
95
95
  end
96
96
  end
@@ -108,13 +108,13 @@ describe ImageOptim::OptionDefinition do
108
108
 
109
109
  context 'when option is nil' do
110
110
  it 'returns nil passed through proc' do
111
- expect(subject.value(nil, :abc => nil)).to eq(['nil', subject])
111
+ expect(subject.value(nil, abc: nil)).to eq(['nil', subject])
112
112
  end
113
113
  end
114
114
 
115
115
  context 'when option is set' do
116
116
  it 'returns value passed through proc' do
117
- expect(subject.value(nil, :abc => 123)).to eq(['123', subject])
117
+ expect(subject.value(nil, abc: 123)).to eq(['123', subject])
118
118
  end
119
119
  end
120
120
  end
@@ -5,8 +5,6 @@ require 'image_optim/path'
5
5
  require 'tempfile'
6
6
 
7
7
  describe ImageOptim::Path do
8
- include CapabilityCheckHelpers
9
-
10
8
  before do
11
9
  stub_const('Path', ImageOptim::Path)
12
10
  end
@@ -76,8 +74,7 @@ describe ImageOptim::Path do
76
74
  expect(src).to_not exist
77
75
  end
78
76
 
79
- it 'preserves attributes of destination file' do
80
- skip 'full file modes are not support' unless any_file_modes_allowed?
77
+ it 'preserves attributes of destination file', skip: SkipConditions[:any_file_mode_allowed] do
81
78
  mode = 0o666
82
79
 
83
80
  dst.chmod(mode)
@@ -98,8 +95,7 @@ describe ImageOptim::Path do
98
95
  expect(dst.mtime).to be >= time
99
96
  end
100
97
 
101
- it 'changes inode of destination' do
102
- skip 'inodes are not supported' unless inodes_supported?
98
+ it 'changes inode of destination', skip: SkipConditions[:inodes_support] do
103
99
  expect{ src.replace(dst) }.to change{ dst.stat.ino }
104
100
  end
105
101
  end
@@ -120,7 +116,7 @@ describe ImageOptim::Path do
120
116
  include_examples 'replaces file'
121
117
 
122
118
  it 'is using temporary file with .tmp extension' do
123
- expect(src).to receive(:move).with(having_attributes(:extname => '.tmp'))
119
+ expect(src).to receive(:move).with(having_attributes(extname: '.tmp'))
124
120
 
125
121
  src.replace(dst)
126
122
  end
@@ -135,7 +131,7 @@ describe ImageOptim::Path do
135
131
  include_examples 'replaces file'
136
132
 
137
133
  it 'is using temporary file with .tmp extension' do
138
- expect(src).to receive(:move).with(having_attributes(:extname => '.tmp'))
134
+ expect(src).to receive(:move).with(having_attributes(extname: '.tmp'))
139
135
 
140
136
  src.replace(dst)
141
137
  end
@@ -37,7 +37,7 @@ describe ImageOptim::Runner::OptionParser do
37
37
  %w[-r -R --recursive].each do |flag|
38
38
  it "is parsed from #{flag}" do
39
39
  args = %W[#{flag} foo bar]
40
- expect(OptionParser.parse!(args)).to eq(:recursive => true)
40
+ expect(OptionParser.parse!(args)).to eq(recursive: true)
41
41
  expect(args).to eq(%w[foo bar])
42
42
  end
43
43
  end
@@ -46,19 +46,19 @@ describe ImageOptim::Runner::OptionParser do
46
46
  describe 'numeric option threads' do
47
47
  it 'is parsed with space separator' do
48
48
  args = %w[--threads 616 foo bar]
49
- expect(OptionParser.parse!(args)).to eq(:threads => 616)
49
+ expect(OptionParser.parse!(args)).to eq(threads: 616)
50
50
  expect(args).to eq(%w[foo bar])
51
51
  end
52
52
 
53
53
  it 'is parsed with equal separator' do
54
54
  args = %w[--threads=616 foo bar]
55
- expect(OptionParser.parse!(args)).to eq(:threads => 616)
55
+ expect(OptionParser.parse!(args)).to eq(threads: 616)
56
56
  expect(args).to eq(%w[foo bar])
57
57
  end
58
58
 
59
59
  it 'is parsed with no- prefix' do
60
60
  args = %w[--no-threads 616 foo bar]
61
- expect(OptionParser.parse!(args)).to eq(:threads => false)
61
+ expect(OptionParser.parse!(args)).to eq(threads: false)
62
62
  expect(args).to eq(%w[616 foo bar])
63
63
  end
64
64
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'image_optim/timer'
5
+
6
+ describe ImageOptim::Timer do
7
+ let!(:timer){ described_class.new(1) }
8
+
9
+ describe '#elapsed' do
10
+ it 'returns elapsed time' do
11
+ sleep 0.01
12
+
13
+ expect(timer.elapsed).to be >= 0.01
14
+ end
15
+ end
16
+
17
+ describe '#left' do
18
+ it 'returns time left' do
19
+ sleep 0.01
20
+
21
+ expect(timer.left).to be <= 0.99
22
+ end
23
+ end
24
+
25
+ describe '#to_f' do
26
+ it 'returns time left' do
27
+ sleep 0.01
28
+
29
+ expect(timer.to_f).to be <= 0.99
30
+ end
31
+ end
32
+ end
@@ -14,7 +14,7 @@ describe ImageOptim::Worker::Jpegrecompress do
14
14
  end
15
15
 
16
16
  context 'uses default when invalid' do
17
- let(:method){ {:method => 'invalid'} }
17
+ let(:method){ {method: 'invalid'} }
18
18
 
19
19
  it 'warns and keeps default' do
20
20
  expect_any_instance_of(described_class).
@@ -24,7 +24,7 @@ describe ImageOptim::Worker::Jpegrecompress do
24
24
  end
25
25
 
26
26
  context 'can use a valid option' do
27
- let(:method){ {:method => 'smallfry'} }
27
+ let(:method){ {method: 'smallfry'} }
28
28
 
29
29
  it{ is_expected.to eq('smallfry') }
30
30
  end
@@ -10,7 +10,7 @@ describe ImageOptim::Worker::Optipng do
10
10
 
11
11
  let(:options){ {} }
12
12
  let(:optipng_version){ '0.7' }
13
- let(:src){ instance_double(ImageOptim::Path, :copy => nil) }
13
+ let(:src){ instance_double(ImageOptim::Path, copy: nil) }
14
14
  let(:dst){ instance_double(ImageOptim::Path) }
15
15
 
16
16
  before do
@@ -34,7 +34,7 @@ describe ImageOptim::Worker::Optipng do
34
34
  end
35
35
 
36
36
  context 'when strip is disabled' do
37
- let(:options){ {:strip => false} }
37
+ let(:options){ {strip: false} }
38
38
 
39
39
  it 'should not add -strip all to arguments' do
40
40
  expect(subject).to receive(:execute) do |_bin, *args|
@@ -61,42 +61,42 @@ describe ImageOptim::Worker::Optipng do
61
61
  describe '#optimized?' do
62
62
  let(:src){ instance_double(ImageOptim::Path, src_options) }
63
63
  let(:dst){ instance_double(ImageOptim::Path, dst_options) }
64
- let(:src_options){ {:size => 10} }
65
- let(:dst_options){ {:size? => 9} }
64
+ let(:src_options){ {size: 10} }
65
+ let(:dst_options){ {size?: 9} }
66
66
  let(:instance){ described_class.new(ImageOptim.new, instance_options) }
67
67
  let(:instance_options){ {} }
68
68
 
69
69
  subject{ instance.optimized?(src, dst) }
70
70
 
71
71
  context 'when interlace option is enabled' do
72
- let(:instance_options){ {:interlace => true} }
72
+ let(:instance_options){ {interlace: true} }
73
73
 
74
74
  context 'when dst is empty' do
75
- let(:dst_options){ {:size? => nil} }
75
+ let(:dst_options){ {size?: nil} }
76
76
  it{ is_expected.to be_falsy }
77
77
  end
78
78
 
79
79
  context 'when dst is not empty' do
80
- let(:dst_options){ {:size? => 20} }
80
+ let(:dst_options){ {size?: 20} }
81
81
  it{ is_expected.to be_truthy }
82
82
  end
83
83
  end
84
84
 
85
85
  context 'when interlace option is disabled' do
86
- let(:instance_options){ {:interlace => false} }
86
+ let(:instance_options){ {interlace: false} }
87
87
 
88
88
  context 'when dst is empty' do
89
- let(:dst_options){ {:size? => nil} }
89
+ let(:dst_options){ {size?: nil} }
90
90
  it{ is_expected.to be_falsy }
91
91
  end
92
92
 
93
93
  context 'when dst is greater than or equal to src' do
94
- let(:dst_options){ {:size? => 10} }
94
+ let(:dst_options){ {size?: 10} }
95
95
  it{ is_expected.to be_falsy }
96
96
  end
97
97
 
98
98
  context 'when dst is less than src' do
99
- let(:dst_options){ {:size? => 9} }
99
+ let(:dst_options){ {size?: 9} }
100
100
  it{ is_expected.to be_truthy }
101
101
  end
102
102
  end
@@ -22,7 +22,7 @@ describe ImageOptim::Worker::Pngquant do
22
22
  end
23
23
 
24
24
  context 'when value is passed through options' do
25
- let(:options){ {:quality => 10..90} }
25
+ let(:options){ {quality: 10..90} }
26
26
 
27
27
  it 'warns and keeps default' do
28
28
  expect_any_instance_of(described_class).
@@ -34,13 +34,13 @@ describe ImageOptim::Worker::Pngquant do
34
34
 
35
35
  context 'when lossy allowed' do
36
36
  context 'by default' do
37
- let(:options){ {:allow_lossy => true} }
37
+ let(:options){ {allow_lossy: true} }
38
38
 
39
39
  it{ is_expected.to eq(0..100) }
40
40
  end
41
41
 
42
42
  context 'when value is passed through options' do
43
- let(:options){ {:allow_lossy => true, :quality => 10..90} }
43
+ let(:options){ {allow_lossy: true, quality: 10..90} }
44
44
 
45
45
  it 'sets the value without warning' do
46
46
  expect_any_instance_of(described_class).not_to receive(:warn)
@@ -49,7 +49,7 @@ describe ImageOptim::Worker::Pngquant do
49
49
  end
50
50
 
51
51
  context 'when passed range begin is less than 0' do
52
- let(:options){ {:allow_lossy => true, :quality => -50..50} }
52
+ let(:options){ {allow_lossy: true, quality: -50..50} }
53
53
 
54
54
  it 'sets begin to 0' do
55
55
  is_expected.to eq(0..50)
@@ -57,7 +57,7 @@ describe ImageOptim::Worker::Pngquant do
57
57
  end
58
58
 
59
59
  context 'when passed range end is more than 100' do
60
- let(:options){ {:allow_lossy => true, :quality => 50..150} }
60
+ let(:options){ {allow_lossy: true, quality: 50..150} }
61
61
 
62
62
  it 'sets end to 100' do
63
63
  is_expected.to eq(50..100)
@@ -29,9 +29,9 @@ describe ImageOptim::Worker do
29
29
  option(:three, 3, 'Three')
30
30
  end
31
31
 
32
- worker = worker_class.new(ImageOptim.new, :three => '...')
32
+ worker = worker_class.new(ImageOptim.new, three: '...')
33
33
 
34
- expect(worker.options).to eq(:one => 1, :two => 2, :three => '...')
34
+ expect(worker.options).to eq(one: 1, two: 2, three: '...')
35
35
  end
36
36
  end
37
37
 
@@ -72,7 +72,7 @@ describe ImageOptim::Worker do
72
72
  option(:three, 3, 'Three')
73
73
  end)
74
74
 
75
- worker = DefOptim.new(ImageOptim.new, :three => '...')
75
+ worker = DefOptim.new(ImageOptim.new, three: '...')
76
76
 
77
77
  expect(worker.inspect).to eq('#<DefOptim @one=1, @two=2, @three="...">')
78
78
  end
@@ -104,17 +104,17 @@ describe ImageOptim::Worker do
104
104
 
105
105
  it 'create hash by format' do
106
106
  workers = [
107
- double(:image_formats => [:a]),
108
- double(:image_formats => [:a, :b]),
109
- double(:image_formats => [:b, :c]),
107
+ double(image_formats: [:a]),
108
+ double(image_formats: [:a, :b]),
109
+ double(image_formats: [:b, :c]),
110
110
  ]
111
111
 
112
112
  expect(Worker).to receive(:create_all).and_return(workers)
113
113
 
114
114
  worker_by_format = {
115
- :a => [workers[0], workers[1]],
116
- :b => [workers[1], workers[2]],
117
- :c => [workers[2]],
115
+ a: [workers[0], workers[1]],
116
+ b: [workers[1], workers[2]],
117
+ c: [workers[2]],
118
118
  }
119
119
 
120
120
  expect(Worker.create_all_by_format(double)).to eq(worker_by_format)
@@ -123,21 +123,21 @@ describe ImageOptim::Worker do
123
123
 
124
124
  describe '.create_all' do
125
125
  def worker_double(override = {})
126
- stubs = {:resolve_used_bins! => nil, :run_order => 0}.merge(override)
126
+ stubs = {resolve_used_bins!: nil, run_order: 0}.merge(override)
127
127
  instance_double(Worker, stubs)
128
128
  end
129
129
 
130
130
  def worker_class_doubles(workers)
131
- workers.map{ |worker| class_double(Worker, :init => worker) }
131
+ workers.map{ |worker| class_double(Worker, init: worker) }
132
132
  end
133
133
 
134
- let(:image_optim){ double(:allow_lossy => false) }
134
+ let(:image_optim){ double(allow_lossy: false) }
135
135
 
136
136
  it 'creates all workers for which options_proc returns true' do
137
137
  workers = Array.new(3){ worker_double }
138
138
  klasses = worker_class_doubles(workers)
139
139
  options_proc = proc do |klass|
140
- klass == klasses[1] ? {:disable => true} : {}
140
+ klass == klasses[1] ? {disable: true} : {}
141
141
  end
142
142
 
143
143
  allow(Worker).to receive(:klasses).and_return(klasses)
@@ -206,7 +206,7 @@ describe ImageOptim::Worker do
206
206
  it 'orders workers by run_order' do
207
207
  run_orders = [10, -10, 0, 0, 0, 10, -10]
208
208
  workers = run_orders.map do |run_order|
209
- worker_double(:run_order => run_order)
209
+ worker_double(run_order: run_order)
210
210
  end
211
211
  klasses_list = worker_class_doubles(workers)
212
212
 
@@ -243,16 +243,16 @@ describe ImageOptim::Worker do
243
243
  it 'allows overriding per worker' do
244
244
  klasses = worker_class_doubles([worker_double, worker_double])
245
245
  options_proc = proc do |klass|
246
- klass == klasses[1] ? {:allow_lossy => :b} : {}
246
+ klass == klasses[1] ? {allow_lossy: :b} : {}
247
247
  end
248
248
 
249
249
  allow(Worker).to receive(:klasses).and_return(klasses)
250
250
 
251
251
  klasses.each{ |klass| klass.send(:attr_reader, :allow_lossy) }
252
252
  expect(klasses[0]).to receive(:init).
253
- with(image_optim, hash_including(:allow_lossy => false))
253
+ with(image_optim, hash_including(allow_lossy: false))
254
254
  expect(klasses[1]).to receive(:init).
255
- with(image_optim, hash_including(:allow_lossy => :b))
255
+ with(image_optim, hash_including(allow_lossy: :b))
256
256
 
257
257
  Worker.create_all(image_optim, &options_proc)
258
258
  end