getopt 1.6.0 → 1.7.1

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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #####################################################################
2
4
  # getopt_long_spec.rb
3
5
  #
@@ -12,57 +14,63 @@ RSpec.describe Getopt::Long do
12
14
  @opts = nil
13
15
  end
14
16
 
15
- example "version" do
16
- expect(Getopt::Long::VERSION).to eq('1.6.0')
17
+ after do
18
+ @opts = nil
19
+ ARGV.clear
20
+ end
21
+
22
+ example 'version' do
23
+ expect(Getopt::Long::VERSION).to eq('1.7.1')
17
24
  expect(Getopt::Long::VERSION).to be_frozen
18
25
  end
19
26
 
20
- example "constants" do
27
+ example 'constants' do
21
28
  expect(Getopt::BOOLEAN).not_to be_nil
22
29
  expect(Getopt::OPTIONAL).not_to be_nil
23
30
  expect(Getopt::REQUIRED).not_to be_nil
24
31
  expect(Getopt::INCREMENT).not_to be_nil
32
+ expect(Getopt::NEGATABLE).not_to be_nil
25
33
  end
26
34
 
27
- example "getopts long basic functionality" do
28
- expect(Getopt::Long).to respond_to(:getopts)
35
+ example 'getopts long basic functionality' do
36
+ expect(described_class).to respond_to(:getopts)
29
37
 
30
- expect{ Getopt::Long.getopts(["--test"],["--help"],["--foo"]) }.not_to raise_error
31
- expect{ Getopt::Long.getopts(["--test", "-x"],["--help", "-y"],["--foo", "-z"]) }.not_to raise_error
38
+ expect{ described_class.getopts(['--test'], ['--help'], ['--foo']) }.not_to raise_error
39
+ expect{ described_class.getopts(['--test', '-x'], ['--help', '-y'], ['--foo', '-z']) }.not_to raise_error
32
40
 
33
41
  expect{
34
- Getopt::Long.getopts(
35
- ["--test", "-x", Getopt::BOOLEAN],
36
- ["--help", "-y", Getopt::REQUIRED],
37
- ["--foo", "-z", Getopt::OPTIONAL],
38
- ["--more", "-m", Getopt::INCREMENT]
42
+ described_class.getopts(
43
+ ['--test', '-x', Getopt::BOOLEAN],
44
+ ['--help', '-y', Getopt::REQUIRED],
45
+ ['--foo', '-z', Getopt::OPTIONAL],
46
+ ['--more', '-m', Getopt::INCREMENT]
39
47
  )
40
48
  }.not_to raise_error
41
49
 
42
- expect(Getopt::Long.getopts("--test")).to be_kind_of(Hash)
50
+ expect(described_class.getopts('--test')).to be_a(Hash)
43
51
  end
44
52
 
45
- example "getopts long using equals sign works as expected" do
46
- ARGV.push("--foo=hello","-b","world")
53
+ example 'getopts long using equals sign works as expected' do
54
+ ARGV.push('--foo=hello', '-b', 'world')
47
55
 
48
56
  expect{
49
- @opts = Getopt::Long.getopts(
50
- ["--foo", "-f", Getopt::REQUIRED],
51
- ["--bar", "-b", Getopt::OPTIONAL]
57
+ @opts = described_class.getopts(
58
+ ['--foo', '-f', Getopt::REQUIRED],
59
+ ['--bar', '-b', Getopt::OPTIONAL]
52
60
  )
53
61
  }.not_to raise_error
54
62
 
55
- expect(@opts["foo"]).to eq("hello")
56
- expect(@opts["f"]).to eq("hello")
57
- expect(@opts["bar"]).to eq("world")
58
- expect(@opts["b"]).to eq("world")
63
+ expect(@opts['foo']).to eq('hello')
64
+ expect(@opts['f']).to eq('hello')
65
+ expect(@opts['bar']).to eq('world')
66
+ expect(@opts['b']).to eq('world')
59
67
  end
60
68
 
61
- example "getopts long with embedded hyphens works as expected" do
69
+ example 'getopts long with embedded hyphens works as expected' do
62
70
  ARGV.push('--foo-bar', 'hello', '--test1-test2-test3', 'world')
63
71
 
64
72
  expect{
65
- @opts = Getopt::Long.getopts(
73
+ @opts = described_class.getopts(
66
74
  ['--foo-bar', '-f', Getopt::REQUIRED],
67
75
  ['--test1-test2-test3', '-t', Getopt::REQUIRED]
68
76
  )
@@ -74,11 +82,11 @@ RSpec.describe Getopt::Long do
74
82
  expect(@opts['t']).to eq('world')
75
83
  end
76
84
 
77
- example "getopts long embedded hyphens using equals sign works as expected" do
85
+ example 'getopts long embedded hyphens using equals sign works as expected' do
78
86
  ARGV.push('--foo-bar=hello', '--test1-test2-test3=world')
79
87
 
80
88
  expect{
81
- @opts = Getopt::Long.getopts(
89
+ @opts = described_class.getopts(
82
90
  ['--foo-bar', '-f', Getopt::REQUIRED],
83
91
  ['--test1-test2-test3', '-t', Getopt::REQUIRED]
84
92
  )
@@ -90,180 +98,204 @@ RSpec.describe Getopt::Long do
90
98
  expect(@opts['t']).to eq('world')
91
99
  end
92
100
 
93
- example "getopts long with short switch squished works as expected" do
94
- ARGV.push("-f", "hello", "-bworld")
101
+ example 'getopts long with short switch squished works as expected' do
102
+ ARGV.push('-f', 'hello', '-bworld')
95
103
 
96
104
  expect{
97
- @opts = Getopt::Long.getopts(
98
- ["--foo", "-f", Getopt::REQUIRED],
99
- ["--bar", "-b", Getopt::OPTIONAL]
105
+ @opts = described_class.getopts(
106
+ ['--foo', '-f', Getopt::REQUIRED],
107
+ ['--bar', '-b', Getopt::OPTIONAL]
100
108
  )
101
109
  }.not_to raise_error
102
110
 
103
- expect(@opts["f"]).to eq("hello")
104
- expect(@opts["b"]).to eq("world")
111
+ expect(@opts['f']).to eq('hello')
112
+ expect(@opts['b']).to eq('world')
105
113
  end
106
114
 
107
- example "getopts long increment type works as expected" do
108
- ARGV.push("-m","-m")
115
+ example 'getopts long accepts question mark as a short switch' do
116
+ ARGV.push('-?')
109
117
 
110
- expect{ @opts = Getopt::Long.getopts(["--more", "-m", Getopt::INCREMENT]) }.not_to raise_error
118
+ expect{
119
+ @opts = described_class.getopts(
120
+ ['--help', '-?', Getopt::BOOLEAN]
121
+ )
122
+ }.not_to raise_error
111
123
 
112
- expect(@opts["more"]).to eq(2)
113
- expect(@opts["m"]).to eq(2)
124
+ expect(@opts['help']).to be(true)
125
+ expect(@opts['?']).to be(true)
114
126
  end
115
127
 
116
- example "switches are set as expected" do
117
- ARGV.push("--verbose","--test","--foo")
118
- expect{ @opts = Getopt::Long.getopts("--verbose --test --foo") }.not_to raise_error
119
- expect( @opts.has_key?("verbose")).to eq(true)
120
- expect( @opts.has_key?("test")).to eq(true)
121
- expect( @opts.has_key?("foo")).to eq(true)
128
+ example 'getopts long increment type works as expected' do
129
+ ARGV.push('-m', '-m')
130
+
131
+ expect{ @opts = described_class.getopts(['--more', '-m', Getopt::INCREMENT]) }.not_to raise_error
132
+
133
+ expect(@opts['more']).to eq(2)
134
+ expect(@opts['m']).to eq(2)
122
135
  end
123
136
 
124
- example "short switch synonyms work as expected" do
125
- ARGV.push("--verbose","--test","--foo")
126
- expect{ @opts = Getopt::Long.getopts("--verbose --test --foo") }.not_to raise_error
127
- expect(@opts.has_key?("v")).to eq(true)
128
- expect(@opts.has_key?("t")).to eq(true)
129
- expect(@opts.has_key?("f")).to eq(true)
137
+ example 'switches are set as expected' do
138
+ ARGV.push('--verbose', '--test', '--foo')
139
+ expect{ @opts = described_class.getopts('--verbose --test --foo') }.not_to raise_error
140
+ expect(@opts.key?('verbose')).to be(true)
141
+ expect(@opts.key?('test')).to be(true)
142
+ expect(@opts.key?('foo')).to be(true)
130
143
  end
131
144
 
132
- example "short_switch_synonyms_with_explicit_types" do
133
- ARGV.push("--verbose", "--test", "hello", "--foo")
145
+ example 'short switch synonyms work as expected' do
146
+ ARGV.push('--verbose', '--test', '--foo')
147
+ expect{ @opts = described_class.getopts('--verbose --test --foo') }.not_to raise_error
148
+ expect(@opts.key?('v')).to be(true)
149
+ expect(@opts.key?('t')).to be(true)
150
+ expect(@opts.key?('f')).to be(true)
151
+ end
152
+
153
+ example 'short_switch_synonyms_with_explicit_types' do
154
+ ARGV.push('--verbose', '--test', 'hello', '--foo')
134
155
 
135
156
  expect{
136
- @opts = Getopt::Long.getopts(
137
- ["--verbose", Getopt::BOOLEAN],
138
- ["--test", Getopt::REQUIRED],
139
- ["--foo", Getopt::BOOLEAN]
157
+ @opts = described_class.getopts(
158
+ ['--verbose', Getopt::BOOLEAN],
159
+ ['--test', Getopt::REQUIRED],
160
+ ['--foo', Getopt::BOOLEAN]
140
161
  )
141
162
  }.not_to raise_error
142
163
 
143
- expect(@opts.has_key?("v")).to be(true)
144
- expect(@opts.has_key?("t")).to be(true)
145
- expect(@opts.has_key?("f")).to be(true)
164
+ expect(@opts.key?('v')).to be(true)
165
+ expect(@opts.key?('t')).to be(true)
166
+ expect(@opts.key?('f')).to be(true)
146
167
  end
147
168
 
148
- example "switches with required arguments" do
149
- ARGV.push("--foo","1","--bar","hello")
169
+ example 'switches with required arguments when present' do
170
+ ARGV.push('--foo', '1', '--bar', 'hello')
150
171
 
151
172
  expect{
152
- @opts = Getopt::Long.getopts(
153
- ["--foo", "-f", Getopt::REQUIRED],
154
- ["--bar", "-b", Getopt::REQUIRED]
173
+ @opts = described_class.getopts(
174
+ ['--foo', '-f', Getopt::REQUIRED],
175
+ ['--bar', '-b', Getopt::REQUIRED]
155
176
  )
156
177
  }.not_to raise_error
157
178
 
158
- expect(@opts).to eq({"foo"=>"1", "bar"=>"hello", "f"=>"1", "b"=>"hello"})
179
+ expect(@opts).to eq({'foo' => '1', 'bar' => 'hello', 'f' => '1', 'b' => 'hello'})
159
180
  end
160
181
 
161
- example "compressed switches work as expected" do
162
- ARGV.push("-fb")
182
+ example "error is raised if argument isn't provided for switch that requires it" do
183
+ ARGV.push('-f', '1', '-b')
163
184
 
164
185
  expect{
165
- @opts = Getopt::Long.getopts(
166
- ["--foo", "-f", Getopt::BOOLEAN],
167
- ["--bar", "-b", Getopt::BOOLEAN]
186
+ @opts = described_class.getopts(
187
+ ['--foo', '-f', Getopt::REQUIRED],
188
+ ['--bar', '-b', Getopt::REQUIRED]
189
+ )
190
+ }.to raise_error(Getopt::Long::Error)
191
+ end
192
+
193
+ example 'compressed switches work as expected' do
194
+ ARGV.push('-fb')
195
+
196
+ expect{
197
+ @opts = described_class.getopts(
198
+ ['--foo', '-f', Getopt::BOOLEAN],
199
+ ['--bar', '-b', Getopt::BOOLEAN]
168
200
  )
169
201
  }.not_to raise_error
170
202
 
171
- expect(@opts).to eq({"foo"=>true, "f"=>true, "b"=>true, "bar"=>true})
203
+ expect(@opts).to eq({'foo' => true, 'f' => true, 'b' => true, 'bar' => true})
172
204
  end
173
205
 
174
- example "compress switches with required argument works as expected" do
175
- ARGV.push("-xf", "foo.txt")
206
+ example 'compress switches with required argument works as expected' do
207
+ ARGV.push('-xf', 'foo.txt')
176
208
 
177
209
  expect{
178
- @opts = Getopt::Long.getopts(
179
- ["--expand", "-x", Getopt::BOOLEAN],
180
- ["--file", "-f", Getopt::REQUIRED]
210
+ @opts = described_class.getopts(
211
+ ['--expand', '-x', Getopt::BOOLEAN],
212
+ ['--file', '-f', Getopt::REQUIRED]
181
213
  )
182
214
  }.not_to raise_error
183
215
 
184
- expect(@opts).to eq({"x"=>true, "expand"=>true, "f"=>"foo.txt", "file"=>"foo.txt"})
216
+ expect(@opts).to eq({'x' => true, 'expand' => true, 'f' => 'foo.txt', 'file' => 'foo.txt'})
185
217
  end
186
218
 
187
- example "compress switches with argument that is compressed works as expected" do
188
- ARGV.push("-xffoo.txt")
219
+ example 'compress switches with argument that is compressed works as expected' do
220
+ ARGV.push('-xffoo.txt')
189
221
 
190
222
  expect{
191
- @opts = Getopt::Long.getopts(
192
- ["--expand", "-x", Getopt::BOOLEAN],
193
- ["--file", "-f", Getopt::REQUIRED]
223
+ @opts = described_class.getopts(
224
+ ['--expand', '-x', Getopt::BOOLEAN],
225
+ ['--file', '-f', Getopt::REQUIRED]
194
226
  )
195
227
  }.not_to raise_error
196
228
 
197
- expect(@opts).to eq({"x"=>true, "expand"=>true, "f"=>"foo.txt", "file"=>"foo.txt"})
229
+ expect(@opts).to eq({'x' => true, 'expand' => true, 'f' => 'foo.txt', 'file' => 'foo.txt'})
198
230
  end
199
231
 
200
- example "compress switches with optional argument not defined works as expected" do
201
- ARGV.push("-xf")
232
+ example 'compress switches with optional argument not defined works as expected' do
233
+ ARGV.push('-xf')
202
234
 
203
235
  expect{
204
- @opts = Getopt::Long.getopts(
205
- ["--expand", "-x", Getopt::BOOLEAN],
206
- ["--file", "-f", Getopt::OPTIONAL]
236
+ @opts = described_class.getopts(
237
+ ['--expand', '-x', Getopt::BOOLEAN],
238
+ ['--file', '-f', Getopt::OPTIONAL]
207
239
  )
208
240
  }.not_to raise_error
209
241
 
210
- expect(@opts).to eq({"x"=>true, "expand"=>true, "f"=>nil, "file"=>nil})
242
+ expect(@opts).to eq({'x' => true, 'expand' => true, 'f' => nil, 'file' => nil})
211
243
  end
212
244
 
213
- example "compress switches with optional argument works as expected" do
214
- ARGV.push("-xf", "boo.txt")
245
+ example 'compress switches with optional argument works as expected' do
246
+ ARGV.push('-xf', 'boo.txt')
215
247
 
216
248
  expect{
217
- @opts = Getopt::Long.getopts(
218
- ["--expand", "-x", Getopt::BOOLEAN],
219
- ["--file", "-f", Getopt::OPTIONAL]
249
+ @opts = described_class.getopts(
250
+ ['--expand', '-x', Getopt::BOOLEAN],
251
+ ['--file', '-f', Getopt::OPTIONAL]
220
252
  )
221
253
  }.not_to raise_error
222
254
 
223
- expect(@opts).to eq({"x"=>true, "expand"=>true, "f"=>"boo.txt", "file"=>"boo.txt"})
255
+ expect(@opts).to eq({'x' => true, 'expand' => true, 'f' => 'boo.txt', 'file' => 'boo.txt'})
224
256
  end
225
257
 
226
- example "compress switches with compressed optional argument works as expected" do
227
- ARGV.push("-xfboo.txt")
258
+ example 'compress switches with compressed optional argument works as expected' do
259
+ ARGV.push('-xfboo.txt')
228
260
 
229
261
  expect{
230
- @opts = Getopt::Long.getopts(
231
- ["--expand", "-x", Getopt::BOOLEAN],
232
- ["--file", "-f", Getopt::OPTIONAL]
262
+ @opts = described_class.getopts(
263
+ ['--expand', '-x', Getopt::BOOLEAN],
264
+ ['--file', '-f', Getopt::OPTIONAL]
233
265
  )
234
266
  }.not_to raise_error
235
267
 
236
- expect(@opts).to eq({"x"=>true, "expand"=>true, "f"=>"boo.txt", "file"=>"boo.txt"})
268
+ expect(@opts).to eq({'x' => true, 'expand' => true, 'f' => 'boo.txt', 'file' => 'boo.txt'})
237
269
  end
238
270
 
239
- example "compressed_short_and_long_mixed" do
240
- ARGV.push("-xb", "--file", "boo.txt", "-v")
271
+ example 'compressed_short_and_long_mixed' do
272
+ ARGV.push('-xb', '--file', 'boo.txt', '-v')
241
273
 
242
274
  expect{
243
- @opts = Getopt::Long.getopts(
244
- ["--expand", "-x", Getopt::BOOLEAN],
245
- ["--verbose", "-v", Getopt::BOOLEAN],
246
- ["--file", "-f", Getopt::REQUIRED],
247
- ["--bar", "-b", Getopt::OPTIONAL]
275
+ @opts = described_class.getopts(
276
+ ['--expand', '-x', Getopt::BOOLEAN],
277
+ ['--verbose', '-v', Getopt::BOOLEAN],
278
+ ['--file', '-f', Getopt::REQUIRED],
279
+ ['--bar', '-b', Getopt::OPTIONAL]
248
280
  )
249
281
  }.not_to raise_error
250
282
 
251
283
  expect(@opts).to eq({
252
- "x"=>true, "expand"=>true,
253
- "v"=>true, "verbose"=>true,
254
- "f"=>"boo.txt", "file"=>"boo.txt",
255
- "b"=>nil, "bar"=>nil
284
+ 'x' => true, 'expand' => true,
285
+ 'v' => true, 'verbose' => true,
286
+ 'f' => 'boo.txt', 'file' => 'boo.txt',
287
+ 'b' => nil, 'bar' => nil
256
288
  })
257
289
  end
258
290
 
259
- example "multiple similar long switches with no short switches works as expected" do
260
- ARGV.push('--to','1','--too','2','--tooo','3')
291
+ example 'multiple similar long switches with no short switches works as expected' do
292
+ ARGV.push('--to', '1', '--too', '2', '--tooo', '3')
261
293
 
262
294
  expect{
263
- @opts = Getopt::Long.getopts(
264
- ["--to", Getopt::REQUIRED],
265
- ["--too", Getopt::REQUIRED],
266
- ["--tooo", Getopt::REQUIRED]
295
+ @opts = described_class.getopts(
296
+ ['--to', Getopt::REQUIRED],
297
+ ['--too', Getopt::REQUIRED],
298
+ ['--tooo', Getopt::REQUIRED]
267
299
  )
268
300
  }.not_to raise_error
269
301
 
@@ -272,8 +304,68 @@ RSpec.describe Getopt::Long do
272
304
  expect(@opts['tooo']).to eq('3')
273
305
  end
274
306
 
275
- after do
276
- @opts = nil
277
- ARGV.clear
307
+ example 'negatable switch set to true when positive form used' do
308
+ ARGV.push('--verbose')
309
+
310
+ expect{
311
+ @opts = described_class.getopts(
312
+ ['--verbose', '-v', Getopt::NEGATABLE]
313
+ )
314
+ }.not_to raise_error
315
+
316
+ expect(@opts['verbose']).to be(true)
317
+ expect(@opts['v']).to be(true)
318
+ end
319
+
320
+ example 'negatable switch set to false when --no- form used' do
321
+ ARGV.push('--no-verbose')
322
+
323
+ expect{
324
+ @opts = described_class.getopts(
325
+ ['--verbose', '-v', Getopt::NEGATABLE]
326
+ )
327
+ }.not_to raise_error
328
+
329
+ expect(@opts['verbose']).to be(false)
330
+ expect(@opts['v']).to be(false)
331
+ end
332
+
333
+ example 'negatable switch works with multiple switches' do
334
+ ARGV.push('--color', '--no-debug')
335
+
336
+ expect{
337
+ @opts = described_class.getopts(
338
+ ['--color', '-c', Getopt::NEGATABLE],
339
+ ['--debug', '-d', Getopt::NEGATABLE]
340
+ )
341
+ }.not_to raise_error
342
+
343
+ expect(@opts['color']).to be(true)
344
+ expect(@opts['c']).to be(true)
345
+ expect(@opts['debug']).to be(false)
346
+ expect(@opts['d']).to be(false)
347
+ end
348
+
349
+ example 'negatable switch raises error if set more than once' do
350
+ ARGV.push('--verbose', '--no-verbose')
351
+
352
+ expect{
353
+ @opts = described_class.getopts(
354
+ ['--verbose', '-v', Getopt::NEGATABLE]
355
+ )
356
+ }.to raise_error(Getopt::Long::Error, /negatable switch already set/)
357
+ end
358
+
359
+ example 'negatable switch with hyphenated name works as expected' do
360
+ ARGV.push('--no-dry-run')
361
+
362
+ expect{
363
+ @opts = described_class.getopts(
364
+ ['--dry-run', '-n', Getopt::NEGATABLE]
365
+ )
366
+ }.not_to raise_error
367
+
368
+ expect(@opts['dry-run']).to be(false)
369
+ expect(@opts['n']).to be(false)
278
370
  end
279
371
  end