image_optim 0.29.0 → 0.30.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.
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
@@ -21,7 +21,7 @@ class ImageOptim
21
21
  4
22
22
  end
23
23
 
24
- def optimize(src, dst)
24
+ def optimize(src, dst, options = {})
25
25
  src.copy(dst)
26
26
  args = %W[
27
27
  --recompress
@@ -30,7 +30,7 @@ class ImageOptim
30
30
  --
31
31
  #{dst}
32
32
  ]
33
- execute(:advpng, *args) && optimized?(src, dst)
33
+ execute(:advpng, args, options) && optimized?(src, dst)
34
34
  end
35
35
  end
36
36
  end
@@ -12,7 +12,7 @@ class ImageOptim
12
12
  return super if options.key?(:interlace)
13
13
 
14
14
  [false, true].map do |interlace|
15
- new(image_optim, options.merge(:interlace => interlace))
15
+ new(image_optim, options.merge(interlace: interlace))
16
16
  end
17
17
  end
18
18
 
@@ -37,7 +37,7 @@ class ImageOptim
37
37
  CAREFUL_OPTION =
38
38
  option(:careful, false, 'Avoid bugs with some software'){ |v| !!v }
39
39
 
40
- def optimize(src, dst)
40
+ def optimize(src, dst, options = {})
41
41
  args = %W[
42
42
  --output=#{dst}
43
43
  --no-comments
@@ -58,7 +58,7 @@ class ImageOptim
58
58
  end
59
59
  args.unshift '--careful' if careful
60
60
  args.unshift "--optimize=#{level}" if level
61
- execute(:gifsicle, *args) && optimized?(src, dst)
61
+ execute(:gifsicle, args, options) && optimized?(src, dst)
62
62
  end
63
63
  end
64
64
  end
@@ -25,7 +25,7 @@ class ImageOptim
25
25
  [:jhead, :jpegtran]
26
26
  end
27
27
 
28
- def optimize(src, dst)
28
+ def optimize(src, dst, options = {})
29
29
  return false unless oriented?(src)
30
30
 
31
31
  src.copy(dst)
@@ -34,7 +34,7 @@ class ImageOptim
34
34
  #{dst}
35
35
  ]
36
36
  resolve_bin!(:jpegtran)
37
- execute(:jhead, *args) && dst.size?
37
+ execute(:jhead, args, options) && dst.size?
38
38
  end
39
39
 
40
40
  private
@@ -47,7 +47,7 @@ class ImageOptim
47
47
  max_quality < 100 ? -1 : 0
48
48
  end
49
49
 
50
- def optimize(src, dst)
50
+ def optimize(src, dst, options = {})
51
51
  src.copy(dst)
52
52
  args = %W[
53
53
  --quiet
@@ -58,7 +58,7 @@ class ImageOptim
58
58
  args.unshift "--strip-#{strip_marker}"
59
59
  end
60
60
  args.unshift "--max=#{max_quality}" if max_quality < 100
61
- execute(:jpegoptim, *args) && optimized?(src, dst)
61
+ execute(:jpegoptim, args, options) && optimized?(src, dst)
62
62
  end
63
63
  end
64
64
  end
@@ -49,7 +49,7 @@ class ImageOptim
49
49
  -5
50
50
  end
51
51
 
52
- def optimize(src, dst)
52
+ def optimize(src, dst, options = {})
53
53
  args = %W[
54
54
  --quality #{QUALITY_NAMES[quality]}
55
55
  --method #{method}
@@ -57,7 +57,7 @@ class ImageOptim
57
57
  #{src}
58
58
  #{dst}
59
59
  ]
60
- execute(:'jpeg-recompress', *args) && optimized?(src, dst)
60
+ execute(:'jpeg-recompress', args, options) && optimized?(src, dst)
61
61
  end
62
62
  end
63
63
  end
@@ -23,7 +23,7 @@ class ImageOptim
23
23
  jpegrescan ? [:jpegtran, :jpegrescan] : [:jpegtran]
24
24
  end
25
25
 
26
- def optimize(src, dst)
26
+ def optimize(src, dst, options = {})
27
27
  if jpegrescan
28
28
  args = %W[
29
29
  #{src}
@@ -31,7 +31,7 @@ class ImageOptim
31
31
  ]
32
32
  args.unshift '-s' unless copy_chunks
33
33
  resolve_bin!(:jpegtran)
34
- execute(:jpegrescan, *args) && optimized?(src, dst)
34
+ execute(:jpegrescan, args, options) && optimized?(src, dst)
35
35
  else
36
36
  args = %W[
37
37
  -optimize
@@ -40,7 +40,7 @@ class ImageOptim
40
40
  ]
41
41
  args.unshift '-copy', (copy_chunks ? 'all' : 'none')
42
42
  args.unshift '-progressive' if progressive
43
- execute(:jpegtran, *args) && optimized?(src, dst)
43
+ execute(:jpegtran, args, options) && optimized?(src, dst)
44
44
  end
45
45
  end
46
46
  end
@@ -30,7 +30,7 @@ class ImageOptim
30
30
  -4
31
31
  end
32
32
 
33
- def optimize(src, dst)
33
+ def optimize(src, dst, options = {})
34
34
  src.copy(dst)
35
35
  args = %W[
36
36
  -o #{level}
@@ -42,7 +42,7 @@ class ImageOptim
42
42
  if strip && resolve_bin!(:optipng).version >= '0.7'
43
43
  args.unshift '-strip', 'all'
44
44
  end
45
- execute(:optipng, *args) && optimized?(src, dst)
45
+ execute(:optipng, args, options) && optimized?(src, dst)
46
46
  end
47
47
 
48
48
  def optimized?(src, dst)
@@ -28,7 +28,7 @@ class ImageOptim
28
28
  -6
29
29
  end
30
30
 
31
- def optimize(src, dst)
31
+ def optimize(src, dst, options = {})
32
32
  flags = %w[
33
33
  -reduce
34
34
  -cc
@@ -49,7 +49,7 @@ class ImageOptim
49
49
  #{dst}
50
50
  ]
51
51
 
52
- execute(:pngcrush, *args) && optimized?(src, dst)
52
+ execute(:pngcrush, args, options) && optimized?(src, dst)
53
53
  end
54
54
  end
55
55
  end
@@ -24,7 +24,7 @@ class ImageOptim
24
24
  2
25
25
  end
26
26
 
27
- def optimize(src, dst)
27
+ def optimize(src, dst, options = {})
28
28
  args = %W[
29
29
  -k#{copy_chunks ? 1 : 0}
30
30
  -s#{strategy}
@@ -33,7 +33,7 @@ class ImageOptim
33
33
  #{src}
34
34
  #{dst}
35
35
  ]
36
- execute(:pngout, *args) && optimized?(src, dst)
36
+ execute(:pngout, args, options) && optimized?(src, dst)
37
37
  rescue SignalException => e
38
38
  raise unless Signal.list.key(e.signo) == 'SEGV'
39
39
  raise unless resolve_bin!(:pngout).version <= '20150920'
@@ -50,7 +50,7 @@ class ImageOptim
50
50
  -2
51
51
  end
52
52
 
53
- def optimize(src, dst)
53
+ def optimize(src, dst, options = {})
54
54
  args = %W[
55
55
  --quality=#{quality.begin}-#{quality.end}
56
56
  --speed=#{speed}
@@ -61,7 +61,7 @@ class ImageOptim
61
61
  --
62
62
  #{src}
63
63
  ]
64
- execute(:pngquant, *args) && optimized?(src, dst)
64
+ execute(:pngquant, args, options) && optimized?(src, dst)
65
65
  end
66
66
  end
67
67
  end
@@ -16,7 +16,7 @@ class ImageOptim
16
16
  Array(v).map(&:to_s)
17
17
  end
18
18
 
19
- def optimize(src, dst)
19
+ def optimize(src, dst, options = {})
20
20
  args = %W[
21
21
  --input #{src}
22
22
  --output #{dst}
@@ -27,7 +27,7 @@ class ImageOptim
27
27
  enable_plugins.each do |plugin_name|
28
28
  args.unshift "--enable=#{plugin_name}"
29
29
  end
30
- execute(:svgo, *args) && optimized?(src, dst)
30
+ execute(:svgo, args, options) && optimized?(src, dst)
31
31
  end
32
32
  end
33
33
  end
@@ -525,10 +525,10 @@ class Analyser
525
525
  stats = Stats.new('all', by_format[format], worker_ids2names)
526
526
  path = FSPath("#{DIR}/#{basenames[format]}")
527
527
  model = {
528
- :stats_format => format,
529
- :stats => stats,
530
- :format_links => basenames,
531
- :template_dir => template_path.dirname.relative_path_from(path.dirname),
528
+ stats_format: format,
529
+ stats: stats,
530
+ format_links: basenames,
531
+ template_dir: template_path.dirname.relative_path_from(path.dirname),
532
532
  }
533
533
  html = template.result(OpenStruct.new(model).instance_eval{ binding })
534
534
  path.write(html)
@@ -19,7 +19,7 @@ describe ImageOptim::BinResolver do
19
19
  allow(ENV).to receive(:[]).and_call_original
20
20
  end
21
21
 
22
- let(:image_optim){ double(:image_optim, :verbose => false, :pack => false) }
22
+ let(:image_optim){ double(:image_optim, verbose: false, pack: false) }
23
23
  let(:resolver){ BinResolver.new(image_optim) }
24
24
 
25
25
  describe '#full_path' do
@@ -130,7 +130,7 @@ describe ImageOptim::BinResolver do
130
130
  it 'resolves bin specified in ENV' do
131
131
  path = 'bin/the_optimizer'
132
132
  stub_env 'THE_OPTIMIZER_BIN', path
133
- tmpdir = double(:tmpdir, :to_str => 'tmpdir')
133
+ tmpdir = double(:tmpdir, to_str: 'tmpdir')
134
134
  symlink = double(:symlink)
135
135
 
136
136
  full_path = File.expand_path(path)
@@ -180,9 +180,9 @@ describe ImageOptim::BinResolver do
180
180
  stub_env 'THE_OPTIMIZER_BIN', path
181
181
  expect(FSPath).not_to receive(:temp_dir)
182
182
  expect(resolver).not_to receive(:at_exit)
183
- allow(File).to receive_messages(:exist? => exist?,
184
- :file? => file?,
185
- :executable? => executable?)
183
+ allow(File).to receive_messages(exist?: exist?,
184
+ file?: file?,
185
+ executable?: executable?)
186
186
  end
187
187
 
188
188
  after do
@@ -5,8 +5,6 @@ require 'image_optim/cache_path'
5
5
  require 'tempfile'
6
6
 
7
7
  describe ImageOptim::CachePath do
8
- include CapabilityCheckHelpers
9
-
10
8
  before do
11
9
  stub_const('Path', ImageOptim::Path)
12
10
  stub_const('CachePath', ImageOptim::CachePath)
@@ -32,8 +30,7 @@ describe ImageOptim::CachePath do
32
30
  expect(src).to exist
33
31
  end
34
32
 
35
- it 'preserves attributes of destination file' do
36
- skip 'full file modes are not support' unless any_file_modes_allowed?
33
+ it 'preserves attributes of destination file', skip: SkipConditions[:any_file_mode_allowed] do
37
34
  mode = 0o666
38
35
 
39
36
  dst.chmod(mode)
@@ -54,13 +51,12 @@ describe ImageOptim::CachePath do
54
51
  expect(dst.mtime).to be >= time
55
52
  end
56
53
 
57
- it 'changes inode of destination' do
58
- skip 'inodes are not supported' unless inodes_supported?
54
+ it 'changes inode of destination', skip: SkipConditions[:inodes_support] do
59
55
  expect{ src.replace(dst) }.to change{ dst.stat.ino }
60
56
  end
61
57
 
62
58
  it 'is using temporary file with .tmp extension' do
63
- expect(src).to receive(:copy).with(having_attributes(:extname => '.tmp')).at_least(:once)
59
+ expect(src).to receive(:copy).with(having_attributes(extname: '.tmp')).at_least(:once)
64
60
 
65
61
  src.replace(dst)
66
62
  end
@@ -11,7 +11,7 @@ describe ImageOptim::Cache do
11
11
  stub_const('CachePath', ImageOptim::CachePath)
12
12
  end
13
13
 
14
- let(:tmp_file){ double('/somewhere/tmp/foo/bar', :rename => 0) }
14
+ let(:tmp_file){ double('/somewhere/tmp/foo/bar', rename: 0) }
15
15
 
16
16
  let(:cache_dir) do
17
17
  dir = '/somewhere/cache'
@@ -24,7 +24,7 @@ describe ImageOptim::Cache do
24
24
  end
25
25
 
26
26
  let(:original) do
27
- original = double('/somewhere/original', :image_format => :ext)
27
+ original = double('/somewhere/original', image_format: :ext)
28
28
  allow(Digest::SHA1).to receive(:file).with(original) do
29
29
  Digest::SHA1.new << 'some content!'
30
30
  end
@@ -32,7 +32,7 @@ describe ImageOptim::Cache do
32
32
  end
33
33
 
34
34
  let(:optimized) do
35
- double('/somewhere/optimized', :format => :ext, :basename => 'optimized')
35
+ double('/somewhere/optimized', format: :ext, basename: 'optimized')
36
36
  end
37
37
 
38
38
  let(:cached) do
@@ -45,7 +45,7 @@ describe ImageOptim::Cache do
45
45
 
46
46
  context 'when cache is disabled (default)' do
47
47
  let(:image_optim) do
48
- double(:image_optim, :cache_dir => nil, :cache_worker_digests => false)
48
+ double(:image_optim, cache_dir: nil, cache_worker_digests: false, timeout: nil)
49
49
  end
50
50
  let(:cache){ Cache.new(image_optim, double) }
51
51
 
@@ -122,7 +122,7 @@ describe ImageOptim::Cache do
122
122
  context 'when cache is enabled (without worker digests)' do
123
123
  let(:image_optim) do
124
124
  double(:image_optim,
125
- :cache_dir => cache_dir, :cache_worker_digests => false)
125
+ cache_dir: cache_dir, cache_worker_digests: false, timeout: nil)
126
126
  end
127
127
  let(:cache) do
128
128
  cache = Cache.new(image_optim, {})
@@ -144,8 +144,8 @@ describe ImageOptim::Cache do
144
144
  context 'when cache is enabled (with worker digests)' do
145
145
  let(:image_optim) do
146
146
  double(:image_optim,
147
- :cache_dir => cache_dir,
148
- :cache_worker_digests => true)
147
+ cache_dir: cache_dir,
148
+ cache_worker_digests: true, timeout: nil)
149
149
  end
150
150
  let(:cache) do
151
151
  cache = Cache.new(image_optim, {})
@@ -4,8 +4,6 @@ require 'spec_helper'
4
4
  require 'image_optim/cmd'
5
5
 
6
6
  describe ImageOptim::Cmd do
7
- include CapabilityCheckHelpers
8
-
9
7
  before do
10
8
  stub_const('Cmd', ImageOptim::Cmd)
11
9
  end
@@ -35,12 +33,67 @@ describe ImageOptim::Cmd do
35
33
  expect($CHILD_STATUS.exitstatus).to eq(66)
36
34
  end
37
35
 
38
- it 'raises SignalException if process terminates after signal' do
39
- skip 'signals are not supported' unless signals_supported?
36
+ it 'raises SignalException if process terminates after signal', skip: SkipConditions[:signals_support] do
40
37
  expect_int_exception do
41
38
  Cmd.run('kill -s INT $$')
42
39
  end
43
40
  end
41
+
42
+ context 'with timeout' do
43
+ it 'returns process success status' do
44
+ expect(Cmd.run('sh -c "exit 0"', timeout: 1)).to eq(true)
45
+
46
+ expect(Cmd.run('sh -c "exit 1"', timeout: 1)).to eq(false)
47
+
48
+ expect(Cmd.run('sh -c "exit 66"', timeout: 1)).to eq(false)
49
+ end
50
+
51
+ it 'raises SignalException if process terminates after signal', skip: SkipConditions[:signals_support] do
52
+ expect_int_exception do
53
+ Cmd.run('kill -s INT $$', timeout: 1)
54
+ end
55
+ end
56
+
57
+ it 'raises TimeoutExceeded if process does not exit until timeout' do
58
+ expect do
59
+ Cmd.run('sleep 10', timeout: 0)
60
+ end.to raise_error(ImageOptim::Errors::TimeoutExceeded)
61
+ end
62
+
63
+ it 'does not leave zombie threads' do
64
+ expect do
65
+ begin
66
+ Cmd.run('sleep 10', timeout: 0)
67
+ rescue ImageOptim::Errors::TimeoutExceeded
68
+ # noop
69
+ end
70
+ end.not_to change{ Thread.list }
71
+ end
72
+
73
+ it 'receives TERM', skip: SkipConditions[:signals_support] do
74
+ waiter = double
75
+ allow(Process).to receive(:detach).once{ |pid| @pid = pid; waiter }
76
+ allow(waiter).to receive(:join){ sleep 0.1; nil }
77
+
78
+ expect do
79
+ Cmd.run('sleep 5', timeout: 0.1)
80
+ end.to raise_error(ImageOptim::Errors::TimeoutExceeded)
81
+
82
+ expect(Process.wait2(@pid).last.termsig).to eq(Signal.list['TERM'])
83
+ end
84
+
85
+ it 'receives KILL if it does not react on TERM', skip: SkipConditions[:signals_support] do
86
+ waiter = double
87
+ allow(Process).to receive(:detach).once{ |pid| @pid = pid; waiter }
88
+ allow(waiter).to receive(:join){ sleep 0.1; nil }
89
+
90
+ expect do
91
+ Cmd.run('trap "" TERM; sleep 5', timeout: 0.1)
92
+ end.to raise_error(ImageOptim::Errors::TimeoutExceeded)
93
+
94
+ expect(Process.wait2(@pid).last.termsig).to eq(Signal.list['KILL'])
95
+ end
96
+ end
44
97
  end
45
98
 
46
99
  describe '.capture' do
@@ -62,8 +115,7 @@ describe ImageOptim::Cmd do
62
115
  expect($CHILD_STATUS.exitstatus).to eq(66)
63
116
  end
64
117
 
65
- it 'raises SignalException if process terminates after signal' do
66
- skip 'signals are not supported' unless signals_supported?
118
+ it 'raises SignalException if process terminates after signal', skip: SkipConditions[:signals_support] do
67
119
  expect_int_exception do
68
120
  Cmd.capture('kill -s INT $$')
69
121
  end
@@ -19,7 +19,7 @@ describe ImageOptim::Config do
19
19
  end
20
20
 
21
21
  it 'raises when there are unused options' do
22
- config = IOConfig.new(:unused => true)
22
+ config = IOConfig.new(unused: true)
23
23
  expect do
24
24
  config.assert_no_unused_options!
25
25
  end.to raise_error(ImageOptim::ConfigurationError)
@@ -37,12 +37,12 @@ describe ImageOptim::Config do
37
37
  end
38
38
 
39
39
  it 'is 0 if disabled' do
40
- config = IOConfig.new(:nice => false)
40
+ config = IOConfig.new(nice: false)
41
41
  expect(config.nice).to eq(0)
42
42
  end
43
43
 
44
44
  it 'converts value to number' do
45
- config = IOConfig.new(:nice => '13')
45
+ config = IOConfig.new(nice: '13')
46
46
  expect(config.nice).to eq(13)
47
47
  end
48
48
  end
@@ -59,16 +59,32 @@ describe ImageOptim::Config do
59
59
  end
60
60
 
61
61
  it 'is 1 if disabled' do
62
- config = IOConfig.new(:threads => false)
62
+ config = IOConfig.new(threads: false)
63
63
  expect(config.threads).to eq(1)
64
64
  end
65
65
 
66
66
  it 'converts value to number' do
67
- config = IOConfig.new(:threads => '616')
67
+ config = IOConfig.new(threads: '616')
68
68
  expect(config.threads).to eq(616)
69
69
  end
70
70
  end
71
71
 
72
+ describe '#timeout' do
73
+ before do
74
+ allow(IOConfig).to receive(:read_options).and_return({})
75
+ end
76
+
77
+ it 'is nil by default' do
78
+ config = IOConfig.new({})
79
+ expect(config.timeout).to eq(nil)
80
+ end
81
+
82
+ it 'converts value to a float' do
83
+ config = IOConfig.new(timeout: '15.1')
84
+ expect(config.timeout).to eq(15.1)
85
+ end
86
+ end
87
+
72
88
  describe '#cache_dir' do
73
89
  before do
74
90
  allow(IOConfig).to receive(:read_options).and_return({})
@@ -80,7 +96,7 @@ describe ImageOptim::Config do
80
96
  end
81
97
 
82
98
  it 'is nil if set to the empty string' do
83
- config = IOConfig.new(:cache_dir => '')
99
+ config = IOConfig.new(cache_dir: '')
84
100
  expect(config.cache_dir).to be nil
85
101
  end
86
102
  end
@@ -112,17 +128,17 @@ describe ImageOptim::Config do
112
128
  end
113
129
 
114
130
  it 'returns passed hash' do
115
- config = IOConfig.new(:abc => {:option => true})
116
- expect(config.for_worker(Abc)).to eq(:option => true)
131
+ config = IOConfig.new(abc: {option: true})
132
+ expect(config.for_worker(Abc)).to eq(option: true)
117
133
  end
118
134
 
119
135
  it 'returns {:disable => true} for false' do
120
- config = IOConfig.new(:abc => false)
121
- expect(config.for_worker(Abc)).to eq(:disable => true)
136
+ config = IOConfig.new(abc: false)
137
+ expect(config.for_worker(Abc)).to eq(disable: true)
122
138
  end
123
139
 
124
140
  it 'raises on unknown option' do
125
- config = IOConfig.new(:abc => 13)
141
+ config = IOConfig.new(abc: 13)
126
142
  expect do
127
143
  config.for_worker(Abc)
128
144
  end.to raise_error(ImageOptim::ConfigurationError)
@@ -132,11 +148,11 @@ describe ImageOptim::Config do
132
148
  describe '#initialize' do
133
149
  it 'reads options from default locations' do
134
150
  expect(IOConfig).to receive(:read_options).
135
- with(IOConfig::GLOBAL_PATH).and_return(:a => 1, :b => 2, :c => 3)
151
+ with(IOConfig::GLOBAL_PATH).and_return(a: 1, b: 2, c: 3)
136
152
  expect(IOConfig).to receive(:read_options).
137
- with(IOConfig::LOCAL_PATH).and_return(:a => 10, :b => 20)
153
+ with(IOConfig::LOCAL_PATH).and_return(a: 10, b: 20)
138
154
 
139
- config = IOConfig.new(:a => 100)
155
+ config = IOConfig.new(a: 100)
140
156
  expect(config.get!(:a)).to eq(100)
141
157
  expect(config.get!(:b)).to eq(20)
142
158
  expect(config.get!(:c)).to eq(3)
@@ -146,17 +162,17 @@ describe ImageOptim::Config do
146
162
  it 'does not read options with empty config_paths' do
147
163
  expect(IOConfig).not_to receive(:read_options)
148
164
 
149
- config = IOConfig.new(:config_paths => [])
165
+ config = IOConfig.new(config_paths: [])
150
166
  config.assert_no_unused_options!
151
167
  end
152
168
 
153
169
  it 'reads options from specified paths' do
154
170
  expect(IOConfig).to receive(:read_options).
155
- with('/etc/image_optim.yml').and_return(:a => 1, :b => 2, :c => 3)
171
+ with('/etc/image_optim.yml').and_return(a: 1, b: 2, c: 3)
156
172
  expect(IOConfig).to receive(:read_options).
157
- with('config/image_optim.yml').and_return(:a => 10, :b => 20)
173
+ with('config/image_optim.yml').and_return(a: 10, b: 20)
158
174
 
159
- config = IOConfig.new(:a => 100, :config_paths => %w[
175
+ config = IOConfig.new(a: 100, config_paths: %w[
160
176
  /etc/image_optim.yml
161
177
  config/image_optim.yml
162
178
  ])
@@ -170,7 +186,7 @@ describe ImageOptim::Config do
170
186
  expect(IOConfig).to receive(:read_options).
171
187
  with('config/image_optim.yml').and_return({})
172
188
 
173
- config = IOConfig.new(:config_paths => 'config/image_optim.yml')
189
+ config = IOConfig.new(config_paths: 'config/image_optim.yml')
174
190
  config.assert_no_unused_options!
175
191
  end
176
192
  end
@@ -200,7 +216,7 @@ describe ImageOptim::Config do
200
216
 
201
217
  it 'returns hash with deep symbolised keys from reader' do
202
218
  stringified = {'config' => {'this' => true}}
203
- symbolized = {:config => {:this => true}}
219
+ symbolized = {config: {this: true}}
204
220
 
205
221
  expect(IOConfig).not_to receive(:warn)
206
222
  expect(File).to receive(:expand_path).