openstreetmap-image_optim 0.21.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rubocop.yml +65 -0
- data/.travis.yml +42 -0
- data/CHANGELOG.markdown +272 -0
- data/CONTRIBUTING.markdown +10 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +344 -0
- data/Vagrantfile +33 -0
- data/bin/image_optim +28 -0
- data/image_optim.gemspec +29 -0
- data/lib/image_optim.rb +228 -0
- data/lib/image_optim/bin_resolver.rb +144 -0
- data/lib/image_optim/bin_resolver/bin.rb +105 -0
- data/lib/image_optim/bin_resolver/comparable_condition.rb +60 -0
- data/lib/image_optim/bin_resolver/error.rb +6 -0
- data/lib/image_optim/bin_resolver/simple_version.rb +31 -0
- data/lib/image_optim/cmd.rb +49 -0
- data/lib/image_optim/config.rb +205 -0
- data/lib/image_optim/configuration_error.rb +3 -0
- data/lib/image_optim/handler.rb +57 -0
- data/lib/image_optim/hash_helpers.rb +45 -0
- data/lib/image_optim/image_meta.rb +25 -0
- data/lib/image_optim/image_path.rb +68 -0
- data/lib/image_optim/non_negative_integer_range.rb +11 -0
- data/lib/image_optim/option_definition.rb +32 -0
- data/lib/image_optim/option_helpers.rb +17 -0
- data/lib/image_optim/railtie.rb +38 -0
- data/lib/image_optim/runner.rb +139 -0
- data/lib/image_optim/runner/glob_helpers.rb +45 -0
- data/lib/image_optim/runner/option_parser.rb +227 -0
- data/lib/image_optim/space.rb +29 -0
- data/lib/image_optim/true_false_nil.rb +16 -0
- data/lib/image_optim/worker.rb +159 -0
- data/lib/image_optim/worker/advpng.rb +35 -0
- data/lib/image_optim/worker/class_methods.rb +91 -0
- data/lib/image_optim/worker/gifsicle.rb +63 -0
- data/lib/image_optim/worker/jhead.rb +43 -0
- data/lib/image_optim/worker/jpegoptim.rb +58 -0
- data/lib/image_optim/worker/jpegrecompress.rb +44 -0
- data/lib/image_optim/worker/jpegtran.rb +46 -0
- data/lib/image_optim/worker/optipng.rb +45 -0
- data/lib/image_optim/worker/pngcrush.rb +54 -0
- data/lib/image_optim/worker/pngout.rb +38 -0
- data/lib/image_optim/worker/pngquant.rb +51 -0
- data/lib/image_optim/worker/svgo.rb +32 -0
- data/script/template/jquery-2.1.3.min.js +4 -0
- data/script/template/sortable-0.6.0.min.js +2 -0
- data/script/template/worker_analysis.erb +254 -0
- data/script/update_worker_options_in_readme +60 -0
- data/script/worker_analysis +599 -0
- data/spec/image_optim/bin_resolver/comparable_condition_spec.rb +37 -0
- data/spec/image_optim/bin_resolver/simple_version_spec.rb +57 -0
- data/spec/image_optim/bin_resolver_spec.rb +272 -0
- data/spec/image_optim/cmd_spec.rb +66 -0
- data/spec/image_optim/config_spec.rb +217 -0
- data/spec/image_optim/handler_spec.rb +95 -0
- data/spec/image_optim/hash_helpers_spec.rb +76 -0
- data/spec/image_optim/image_path_spec.rb +54 -0
- data/spec/image_optim/railtie_spec.rb +121 -0
- data/spec/image_optim/runner/glob_helpers_spec.rb +25 -0
- data/spec/image_optim/runner/option_parser_spec.rb +99 -0
- data/spec/image_optim/space_spec.rb +25 -0
- data/spec/image_optim/worker_spec.rb +192 -0
- data/spec/image_optim_spec.rb +242 -0
- data/spec/images/comparison.png +0 -0
- data/spec/images/decompressed.jpeg +0 -0
- data/spec/images/icecream.gif +0 -0
- data/spec/images/image.jpg +0 -0
- data/spec/images/invisiblepixels/generate +24 -0
- data/spec/images/invisiblepixels/image.png +0 -0
- data/spec/images/lena.jpg +0 -0
- data/spec/images/orient/0.jpg +0 -0
- data/spec/images/orient/1.jpg +0 -0
- data/spec/images/orient/2.jpg +0 -0
- data/spec/images/orient/3.jpg +0 -0
- data/spec/images/orient/4.jpg +0 -0
- data/spec/images/orient/5.jpg +0 -0
- data/spec/images/orient/6.jpg +0 -0
- data/spec/images/orient/7.jpg +0 -0
- data/spec/images/orient/8.jpg +0 -0
- data/spec/images/orient/generate +23 -0
- data/spec/images/orient/original.jpg +0 -0
- data/spec/images/quant/64.png +0 -0
- data/spec/images/quant/generate +25 -0
- data/spec/images/rails.png +0 -0
- data/spec/images/test.svg +3 -0
- data/spec/images/transparency1.png +0 -0
- data/spec/images/transparency2.png +0 -0
- data/spec/images/vergroessert.jpg +0 -0
- data/spec/spec_helper.rb +64 -0
- data/vendor/jpegrescan +143 -0
- metadata +308 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'image_optim/handler'
|
3
|
+
|
4
|
+
describe ImageOptim::Handler do
|
5
|
+
before do
|
6
|
+
stub_const('Handler', ImageOptim::Handler)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'uses original as source for first conversion '\
|
10
|
+
'and two temp files for further conversions' do
|
11
|
+
original = double(:original)
|
12
|
+
allow(original).to receive(:temp_path) do
|
13
|
+
fail 'temp_path called unexpectedly'
|
14
|
+
end
|
15
|
+
|
16
|
+
handler = Handler.new(original)
|
17
|
+
temp_a = double(:temp_a)
|
18
|
+
temp_b = double(:temp_b)
|
19
|
+
expect(original).to receive(:temp_path).once.and_return(temp_a)
|
20
|
+
expect(original).to receive(:temp_path).once.and_return(temp_b)
|
21
|
+
|
22
|
+
# first unsuccessful run
|
23
|
+
handler.process do |src, dst|
|
24
|
+
expect([src, dst]).to eq([original, temp_a]); false
|
25
|
+
end
|
26
|
+
expect(handler.result).to be_nil
|
27
|
+
|
28
|
+
# first successful run
|
29
|
+
handler.process do |src, dst|
|
30
|
+
expect([src, dst]).to eq([original, temp_a]); true
|
31
|
+
end
|
32
|
+
expect(handler.result).to eq(temp_a)
|
33
|
+
|
34
|
+
# second unsuccessful run
|
35
|
+
handler.process do |src, dst|
|
36
|
+
expect([src, dst]).to eq([temp_a, temp_b]); false
|
37
|
+
end
|
38
|
+
expect(handler.result).to eq(temp_a)
|
39
|
+
|
40
|
+
# second successful run
|
41
|
+
handler.process do |src, dst|
|
42
|
+
expect([src, dst]).to eq([temp_a, temp_b]); true
|
43
|
+
end
|
44
|
+
expect(handler.result).to eq(temp_b)
|
45
|
+
|
46
|
+
# third successful run
|
47
|
+
handler.process do |src, dst|
|
48
|
+
expect([src, dst]).to eq([temp_b, temp_a]); true
|
49
|
+
end
|
50
|
+
expect(handler.result).to eq(temp_a)
|
51
|
+
|
52
|
+
# forth successful run
|
53
|
+
handler.process do |src, dst|
|
54
|
+
expect([src, dst]).to eq([temp_a, temp_b]); true
|
55
|
+
end
|
56
|
+
expect(handler.result).to eq(temp_b)
|
57
|
+
|
58
|
+
expect(temp_a).to receive(:unlink).once
|
59
|
+
handler.cleanup
|
60
|
+
handler.cleanup
|
61
|
+
end
|
62
|
+
|
63
|
+
describe :open do
|
64
|
+
it 'yields instance, runs cleanup and returns result' do
|
65
|
+
original = double
|
66
|
+
handler = double
|
67
|
+
result = double
|
68
|
+
|
69
|
+
expect(Handler).to receive(:new).
|
70
|
+
with(original).and_return(handler)
|
71
|
+
expect(handler).to receive(:process)
|
72
|
+
expect(handler).to receive(:cleanup)
|
73
|
+
expect(handler).to receive(:result).and_return(result)
|
74
|
+
|
75
|
+
expect(Handler.for(original) do |h|
|
76
|
+
h.process
|
77
|
+
end).to eq(result)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'cleans up if exception is raised' do
|
81
|
+
original = double
|
82
|
+
handler = double
|
83
|
+
|
84
|
+
expect(Handler).to receive(:new).
|
85
|
+
with(original).and_return(handler)
|
86
|
+
expect(handler).to receive(:cleanup)
|
87
|
+
|
88
|
+
expect do
|
89
|
+
Handler.for(original) do
|
90
|
+
fail 'hello'
|
91
|
+
end
|
92
|
+
end.to raise_error 'hello'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'image_optim/hash_helpers'
|
3
|
+
|
4
|
+
describe ImageOptim::HashHelpers do
|
5
|
+
before do
|
6
|
+
stub_const('HashHelpers', ImageOptim::HashHelpers)
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'stringify/simbolyze' do
|
10
|
+
symbol_keys = {
|
11
|
+
:a => 1,
|
12
|
+
:b => {
|
13
|
+
:c => [:a, 'a'],
|
14
|
+
:d => {},
|
15
|
+
},
|
16
|
+
}
|
17
|
+
|
18
|
+
string_keys = {
|
19
|
+
'a' => 1,
|
20
|
+
'b' => {
|
21
|
+
'c' => [:a, 'a'],
|
22
|
+
'd' => {},
|
23
|
+
},
|
24
|
+
}
|
25
|
+
|
26
|
+
it 'deep stringifies hash keys' do
|
27
|
+
expect(HashHelpers.deep_stringify_keys(symbol_keys)).to eq(string_keys)
|
28
|
+
expect(HashHelpers.deep_stringify_keys(string_keys)).to eq(string_keys)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'deep symbolises hash keys' do
|
32
|
+
expect(HashHelpers.deep_symbolise_keys(string_keys)).to eq(symbol_keys)
|
33
|
+
expect(HashHelpers.deep_symbolise_keys(symbol_keys)).to eq(symbol_keys)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'deep merges hashes' do
|
38
|
+
merge_a = {
|
39
|
+
:a => {
|
40
|
+
:b => 1,
|
41
|
+
:c => {
|
42
|
+
:d => 2,
|
43
|
+
:e => {
|
44
|
+
:f => true,
|
45
|
+
},
|
46
|
+
},
|
47
|
+
},
|
48
|
+
:y => 10,
|
49
|
+
}
|
50
|
+
|
51
|
+
merge_b = {
|
52
|
+
:a => {
|
53
|
+
:b => 2,
|
54
|
+
:c => {
|
55
|
+
:d => 3,
|
56
|
+
:e => false,
|
57
|
+
},
|
58
|
+
},
|
59
|
+
'z' => 20,
|
60
|
+
}
|
61
|
+
|
62
|
+
merge_result = {
|
63
|
+
:a => {
|
64
|
+
:b => 2,
|
65
|
+
:c => {
|
66
|
+
:d => 3,
|
67
|
+
:e => false,
|
68
|
+
},
|
69
|
+
},
|
70
|
+
:y => 10,
|
71
|
+
'z' => 20,
|
72
|
+
}
|
73
|
+
|
74
|
+
expect(HashHelpers.deep_merge(merge_a, merge_b)).to eq(merge_result)
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'image_optim/image_path'
|
3
|
+
|
4
|
+
describe ImageOptim::ImagePath do
|
5
|
+
before do
|
6
|
+
stub_const('ImagePath', ImageOptim::ImagePath)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe :convert do
|
10
|
+
it 'returns ImagePath for string' do
|
11
|
+
path = 'a'
|
12
|
+
|
13
|
+
expect(ImagePath.convert(path)).to be_a(ImagePath)
|
14
|
+
expect(ImagePath.convert(path)).to eq(ImagePath.new(path))
|
15
|
+
|
16
|
+
expect(ImagePath.convert(path)).not_to eq(path)
|
17
|
+
expect(ImagePath.convert(path)).not_to be(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns ImagePath for Pathname' do
|
21
|
+
pathname = Pathname.new('a')
|
22
|
+
|
23
|
+
expect(ImagePath.convert(pathname)).to be_a(ImagePath)
|
24
|
+
expect(ImagePath.convert(pathname)).to eq(ImagePath.new(pathname))
|
25
|
+
|
26
|
+
expect(ImagePath.convert(pathname)).to eq(pathname)
|
27
|
+
expect(ImagePath.convert(pathname)).not_to be(pathname)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns same instance for ImagePath' do
|
31
|
+
image_path = ImagePath.new('a')
|
32
|
+
|
33
|
+
expect(ImagePath.convert(image_path)).to be_a(ImagePath)
|
34
|
+
expect(ImagePath.convert(image_path)).to eq(ImagePath.new(image_path))
|
35
|
+
|
36
|
+
expect(ImagePath.convert(image_path)).to eq(image_path)
|
37
|
+
expect(ImagePath.convert(image_path)).to be(image_path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe :binread do
|
42
|
+
it 'reads binary data' do
|
43
|
+
data = (0..255).to_a.pack('c*')
|
44
|
+
|
45
|
+
path = ImagePath.temp_file_path
|
46
|
+
path.write(data)
|
47
|
+
|
48
|
+
expect(path.binread).to eq(data)
|
49
|
+
if ''.respond_to?(:encoding)
|
50
|
+
expect(path.binread.encoding).to eq(Encoding.find('ASCII-8BIT'))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ImageOptim::Railtie' do
|
4
|
+
require 'rails/all'
|
5
|
+
require 'image_optim/railtie'
|
6
|
+
|
7
|
+
def init_rails_app
|
8
|
+
Class.new(Rails::Application) do
|
9
|
+
# Rails 4 requires application class to have name
|
10
|
+
def self.name
|
11
|
+
'Dummy'
|
12
|
+
end
|
13
|
+
|
14
|
+
config.active_support.deprecation = :stderr
|
15
|
+
config.eager_load = false
|
16
|
+
|
17
|
+
config.logger = Logger.new('/dev/null')
|
18
|
+
|
19
|
+
config.assets.tap do |assets|
|
20
|
+
assets.enabled = true
|
21
|
+
assets.version = '1.0'
|
22
|
+
assets.cache_store = :null_store
|
23
|
+
assets.paths = %w[spec/images]
|
24
|
+
|
25
|
+
assets.delete(:compress)
|
26
|
+
assets.delete(:image_optim)
|
27
|
+
end
|
28
|
+
|
29
|
+
yield config if block_given?
|
30
|
+
end.initialize!
|
31
|
+
end
|
32
|
+
|
33
|
+
after do
|
34
|
+
Rails.application = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
describe :initialization do
|
38
|
+
it 'initializes by default' do
|
39
|
+
expect(ImageOptim).to receive(:new)
|
40
|
+
init_rails_app
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'initializes if config.assets.image_optim is nil' do
|
44
|
+
expect(ImageOptim).to receive(:new)
|
45
|
+
init_rails_app do |config|
|
46
|
+
config.assets.image_optim = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'does not initialize if config.assets.image_optim is false' do
|
51
|
+
expect(ImageOptim).not_to receive(:new)
|
52
|
+
init_rails_app do |config|
|
53
|
+
config.assets.image_optim = false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'does not initialize if config.assets.compress is false' do
|
58
|
+
expect(ImageOptim).not_to receive(:new)
|
59
|
+
init_rails_app do |config|
|
60
|
+
config.assets.compress = false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'options' do
|
65
|
+
it 'initializes with empty hash by default' do
|
66
|
+
expect(ImageOptim).to receive(:new).with({})
|
67
|
+
init_rails_app
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'initializes with empty hash if config.assets.image_optim is true' do
|
71
|
+
expect(ImageOptim).to receive(:new).with({}).and_call_original
|
72
|
+
init_rails_app do |config|
|
73
|
+
config.assets.image_optim = true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'initializes with empty hash if config.assets.image_optim is nil' do
|
78
|
+
expect(ImageOptim).to receive(:new).with({}).and_call_original
|
79
|
+
init_rails_app do |config|
|
80
|
+
config.assets.image_optim = nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'initializes with hash assigned to config.assets.image_optim' do
|
85
|
+
hash = double
|
86
|
+
expect(ImageOptim).to receive(:new).with(hash)
|
87
|
+
init_rails_app do |config|
|
88
|
+
config.assets.image_optim = hash
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe :assets do
|
95
|
+
before do
|
96
|
+
stub_const('ImagePath', ImageOptim::ImagePath)
|
97
|
+
end
|
98
|
+
|
99
|
+
%w[
|
100
|
+
icecream.gif
|
101
|
+
lena.jpg
|
102
|
+
rails.png
|
103
|
+
test.svg
|
104
|
+
].each do |asset_name|
|
105
|
+
it "optimizes #{asset_name}" do
|
106
|
+
asset = init_rails_app.assets.find_asset(asset_name)
|
107
|
+
|
108
|
+
asset_data = asset.source
|
109
|
+
original = ImagePath.convert(asset.pathname)
|
110
|
+
|
111
|
+
expect(asset_data).to be_smaller_than(original)
|
112
|
+
|
113
|
+
ImagePath.temp_file_path %W[spec .#{original.format}] do |temp|
|
114
|
+
temp.write(asset_data)
|
115
|
+
|
116
|
+
expect(temp).to be_similar_to(original, 0)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end if ENV['RAILS_VERSION']
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'image_optim/runner/glob_helpers'
|
3
|
+
|
4
|
+
describe ImageOptim::Runner::GlobHelpers do
|
5
|
+
before do
|
6
|
+
stub_const('GlobHelpers', ImageOptim::Runner::GlobHelpers)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe :expand_braces do
|
10
|
+
{
|
11
|
+
'hello.world' => %w[hello.world],
|
12
|
+
'{hello,.world}' => %w[hello .world],
|
13
|
+
'hello{.,!}world' => %w[hello.world hello!world],
|
14
|
+
'{a,b},{c,d}' => %w[a,c b,c a,d b,d],
|
15
|
+
'{{a,b},{c,d}}' => %w[a b c d],
|
16
|
+
'{a,b,{c,d}}' => %w[a b c d],
|
17
|
+
'{\{a,b\},\{c,d\}}' => %w[\\{a b\\} \\{c d\\}],
|
18
|
+
'test{ing,}' => %w[testing test],
|
19
|
+
}.each do |glob, expected|
|
20
|
+
it "expands #{glob}" do
|
21
|
+
expect(GlobHelpers.expand_braces(glob)).to match_array(expected)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'image_optim/runner/option_parser'
|
3
|
+
|
4
|
+
describe ImageOptim::Runner::OptionParser do
|
5
|
+
before do
|
6
|
+
stub_const('OptionParser', ImageOptim::Runner::OptionParser)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe :parse! do
|
10
|
+
it 'returns empty hash for arguments without options' do
|
11
|
+
args = %w[foo bar]
|
12
|
+
expect(OptionParser.parse!(args)).to eq({})
|
13
|
+
expect(args).to eq(%w[foo bar])
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'removes options from arguments' do
|
17
|
+
args = %w[-r foo bar]
|
18
|
+
OptionParser.parse!(args)
|
19
|
+
expect(args).to eq(%w[foo bar])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'stops parsing optiosn after --' do
|
23
|
+
args = %w[-- -r foo bar]
|
24
|
+
OptionParser.parse!(args)
|
25
|
+
expect(args).to eq(%w[-r foo bar])
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'boolean option recursive' do
|
29
|
+
%w[-r -R --recursive].each do |flag|
|
30
|
+
it "is parsed from #{flag}" do
|
31
|
+
args = %W[#{flag} foo bar]
|
32
|
+
expect(OptionParser.parse!(args)).to eq(:recursive => true)
|
33
|
+
expect(args).to eq(%w[foo bar])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'numeric option threads' do
|
39
|
+
it 'is parsed with space separator' do
|
40
|
+
args = %w[--threads 616 foo bar]
|
41
|
+
expect(OptionParser.parse!(args)).to eq(:threads => 616)
|
42
|
+
expect(args).to eq(%w[foo bar])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'is parsed with equal separator' do
|
46
|
+
args = %w[--threads=616 foo bar]
|
47
|
+
expect(OptionParser.parse!(args)).to eq(:threads => 616)
|
48
|
+
expect(args).to eq(%w[foo bar])
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'is parsed with no- prefix' do
|
52
|
+
args = %w[--no-threads 616 foo bar]
|
53
|
+
expect(OptionParser.parse!(args)).to eq(:threads => false)
|
54
|
+
expect(args).to eq(%w[616 foo bar])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'help option' do
|
59
|
+
it 'prints help text to stdout and exits' do
|
60
|
+
parser = OptionParser.new({})
|
61
|
+
expect(OptionParser).to receive(:new).and_return(parser)
|
62
|
+
|
63
|
+
help = double
|
64
|
+
expect(parser).to receive(:help).and_return(help)
|
65
|
+
|
66
|
+
expect do
|
67
|
+
OptionParser.parse!(%w[--help])
|
68
|
+
end.to output("#{help}\n").to_stdout &
|
69
|
+
raise_error(SystemExit){ |e| expect(e.status).to eq(0) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'wrong option' do
|
74
|
+
it 'prints help text to stdout and exits' do
|
75
|
+
parser = OptionParser.new({})
|
76
|
+
expect(OptionParser).to receive(:new).and_return(parser)
|
77
|
+
|
78
|
+
help = double
|
79
|
+
expect(parser).to receive(:help).and_return(help)
|
80
|
+
|
81
|
+
expect do
|
82
|
+
OptionParser.parse!(%w[--unknown-option])
|
83
|
+
end.to output("invalid option: --unknown-option\n\n#{help}\n").
|
84
|
+
to_stderr & raise_error(SystemExit){ |e| expect(e.status).to eq(1) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe :help do
|
90
|
+
it 'returns wrapped text' do
|
91
|
+
parser = OptionParser.new({})
|
92
|
+
|
93
|
+
allow(parser).to receive(:terminal_columns).and_return(80)
|
94
|
+
|
95
|
+
expect(parser.help.split("\n")).
|
96
|
+
to all(satisfy{ |line| line.length <= 80 })
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|