@@ -366,6 +366,98 @@ def arity_kw(x, y:1, z:2); end
366
366
end
367
367
end
368
368
369
+ if RubyFeatures . kw_args_supported?
370
+ describe 'a method with optional argument and keyword arguments' do
371
+ eval <<-RUBY
372
+ def arity_kw(x, y = {}, z:2); end
373
+ RUBY
374
+
375
+ let ( :test_method ) { method ( :arity_kw ) }
376
+
377
+ it 'does not require any of the arguments' do
378
+ expect ( valid? ( nil ) ) . to eq ( true )
379
+ expect ( valid? ( nil , nil ) ) . to eq ( true )
380
+ end
381
+
382
+ it 'does not allow an invalid keyword arguments' do
383
+ expect ( valid? ( nil , nil , :a => 1 ) ) . to eq ( false )
384
+ expect ( valid? ( nil , :a => 1 ) ) . to eq ( false )
385
+ end
386
+
387
+ it 'allows Hash containing strings as last argument' do
388
+ expect ( valid? ( nil , 'a' => 1 ) ) . to eq ( true )
389
+ end
390
+
391
+ it 'mentions the invalid keyword args in the error' , :pending => RSpec ::Support ::Ruby . jruby? && !RSpec ::Support ::Ruby . jruby_9000? do
392
+ expect ( error_for ( nil , nil , :a => 0 ) ) . to \
393
+ eq ( "Invalid keyword arguments provided: a" )
394
+ end
395
+
396
+ it 'describes invalid arity precisely' do
397
+ expect ( error_for ( ) ) . to \
398
+ eq ( "Wrong number of arguments. Expected 1 to 2, got 0." )
399
+ end
400
+
401
+ it 'does not blow up when given a BasicObject as the last arg' do
402
+ expect ( valid? ( BasicObject . new ) ) . to eq ( true )
403
+ end
404
+
405
+ it 'does not mutate the provided args array' do
406
+ args = [ nil , nil , { :y => 1 } ]
407
+ described_class . new ( signature , args ) . valid?
408
+ expect ( args ) . to eq ( [ nil , nil , { :y => 1 } ] )
409
+ end
410
+
411
+ it 'mentions the arity and optional kw args in the description' , :pending => RSpec ::Support ::Ruby . jruby? && !RSpec ::Support ::Ruby . jruby_9000? do
412
+ expect ( signature_description ) . to eq ( "arity of 1 to 2 and optional keyword args (:z)" )
413
+ end
414
+
415
+ it "indicates the optional keyword args" do
416
+ expect ( signature . optional_kw_args ) . to contain_exactly ( :z )
417
+ end
418
+
419
+ it "indicates it has no required keyword args" do
420
+ expect ( signature . required_kw_args ) . to eq ( [ ] )
421
+ end
422
+
423
+ describe 'with an expectation object' do
424
+ it 'matches the exact arity' do
425
+ expect ( validate_expectation 0 ) . to eq ( false )
426
+ expect ( validate_expectation 1 ) . to eq ( true )
427
+ expect ( validate_expectation 2 ) . to eq ( true )
428
+ end
429
+
430
+ it 'matches the exact range' do
431
+ expect ( validate_expectation 0 , 1 ) . to eq ( false )
432
+ expect ( validate_expectation 1 , 1 ) . to eq ( true )
433
+ expect ( validate_expectation 1 , 2 ) . to eq ( true )
434
+ expect ( validate_expectation 1 , 3 ) . to eq ( false )
435
+ end
436
+
437
+ it 'does not match unlimited arguments' do
438
+ expect ( validate_expectation :unlimited_args ) . to eq ( false )
439
+ end
440
+
441
+ it 'matches optional keywords with the correct arity' do
442
+ expect ( validate_expectation :z ) . to eq ( false )
443
+ expect ( validate_expectation 1 , :z ) . to eq ( true ) # Are we OK with that?
444
+ expect ( validate_expectation 1 , 2 , :z ) . to eq ( true )
445
+ expect ( validate_expectation 1 , 2 , :y ) . to eq ( false )
446
+ end
447
+
448
+ it 'does not match invalid keywords' do
449
+ expect ( validate_expectation :w ) . to eq ( false )
450
+
451
+ expect ( validate_expectation 2 , :w ) . to eq ( false )
452
+ end
453
+
454
+ it 'does not match arbitrary keywords' do
455
+ expect ( validate_expectation :arbitrary_kw_args ) . to eq ( false )
456
+ end
457
+ end
458
+ end
459
+ end
460
+
369
461
if RubyFeatures . required_kw_args_supported?
370
462
describe 'a method with required keyword arguments' do
371
463
eval <<-RUBY
0 commit comments