1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
require 'spec_helper'
require 'puppet/util/command_line/puppet_option_parser'
describe Puppet::Util::CommandLine::PuppetOptionParser do
let(:option_parser) { described_class.new }
describe "an option with a value" do
it "parses a 'long' option with a value" do
parses(
:option => ["--angry", "Angry", :REQUIRED],
:from_arguments => ["--angry", "foo"],
:expects => "foo"
)
end
it "parses a 'short' option with a value" do
parses(
:option => ["--angry", "-a", "Angry", :REQUIRED],
:from_arguments => ["-a", "foo"],
:expects => "foo"
)
end
it "overrides a previous argument with a later one" do
parses(
:option => ["--later", "Later", :REQUIRED],
:from_arguments => ["--later", "tomorrow", "--later", "morgen"],
:expects => "morgen"
)
end
end
describe "an option without a value" do
it "parses a 'long' option" do
parses(
:option => ["--angry", "Angry", :NONE],
:from_arguments => ["--angry"],
:expects => true
)
end
it "parses a 'short' option" do
parses(
:option => ["--angry", "-a", "Angry", :NONE],
:from_arguments => ["-a"],
:expects => true
)
end
it "supports the '--no-blah' syntax" do
parses(
:option => ["--[no-]rage", "Rage", :NONE],
:from_arguments => ["--no-rage"],
:expects => false
)
end
it "overrides a previous argument with a later one" do
parses(
:option => ["--[no-]rage", "Rage", :NONE],
:from_arguments => ["--rage", "--no-rage"],
:expects => false
)
end
end
it "does not accept an unknown option specification" do
expect {
option_parser.on("not", "enough")
}.to raise_error(ArgumentError, /this method only takes 3 or 4 arguments/)
end
it "does not modify the original argument array" do
option_parser.on("--foo", "Foo", :NONE) { |val| }
args = ["--foo"]
option_parser.parse(args)
args.length.should == 1
end
# The ruby stdlib OptionParser has an awesome "feature" that you cannot disable, whereby if
# it sees a short option that you haven't specifically registered with it (e.g., "-r"), it
# will automatically attempt to expand it out to whatever long options that you might have
# registered. Since we need to do our option parsing in two passes (one pass against only
# the global/puppet-wide settings definitions, and then a second pass that includes the
# application or face settings--because we can't load the app/face until we've determined
# the libdir), it is entirely possible that we intend to define our "short" option as part
# of the second pass. Therefore, if the option parser attempts to expand it out into a
# long option during the first pass, terrible things will happen.
#
# A long story short: we need to have the ability to control this kind of behavior in our
# option parser, and this test simply affirms that we do.
it "does not try to expand short options that weren't explicitly registered" do
[
["--ridiculous", "This is ridiculous", :REQUIRED],
["--rage-inducing", "This is rage-inducing", :REQUIRED]
].each do |option|
option_parser.on(*option) {}
end
expect { option_parser.parse(["-r"]) }.to raise_error(Puppet::Util::CommandLine::PuppetOptionError)
end
it "respects :ignore_invalid_options" do
option_parser.ignore_invalid_options = true
expect { option_parser.parse(["--unknown-option"]) }.not_to raise_error
end
it "raises if there is an invalid option and :ignore_invalid_options is not set" do
expect { option_parser.parse(["--unknown-option"]) }.to raise_error(Puppet::Util::CommandLine::PuppetOptionError)
end
def parses(option_case)
option = option_case[:option]
expected_value = option_case[:expects]
arguments = option_case[:from_arguments]
seen_value = nil
option_parser.on(*option) do |val|
seen_value = val
end
option_parser.parse(arguments)
seen_value.should == expected_value
end
end
|