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