From 39de8fbd838551f2178cd3a54de6e3a19b848396 Mon Sep 17 00:00:00 2001 From: Brian Hawley Date: Fri, 24 Jan 2020 11:39:23 -0800 Subject: [PATCH] Don't raise exception on JRuby 9k < 9.2.1.0 JRuby 9k 9.2.0.0 and lower will has a bug in Ripper.sexp that raises a NoMethodError when analyzing code that even references a method with keyword arguments. This makes failure formatting raise that exception. Best to just not use Ripper on JRuby 9k < 9.2.1.0. [Fixes #399] --- lib/rspec/support/ruby_features.rb | 3 ++- spec/rspec/support/ruby_features_spec.rb | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/rspec/support/ruby_features.rb b/lib/rspec/support/ruby_features.rb index ea4033df6..3fdcbb563 100644 --- a/lib/rspec/support/ruby_features.rb +++ b/lib/rspec/support/ruby_features.rb @@ -111,7 +111,8 @@ def supports_taint? ripper_requirements.push(Ruby.jruby_version >= '1.7.5') # Ripper on JRuby 9.0.0.0.rc1 - 9.1.8.0 reports wrong line number # or cannot parse source including `:if`. - ripper_requirements.push(!Ruby.jruby_version.between?('9.0.0.0.rc1', '9.1.8.0')) + # Ripper on JRuby 9.x.x.x < 9.2.1.0 can't handle keyword arguments. + ripper_requirements.push(!Ruby.jruby_version.between?('9.0.0.0.rc1', '9.2.0.0')) end if ripper_requirements.all? diff --git a/spec/rspec/support/ruby_features_spec.rb b/spec/rspec/support/ruby_features_spec.rb index fd53035ab..0f368cbcf 100644 --- a/spec/rspec/support/ruby_features_spec.rb +++ b/spec/rspec/support/ruby_features_spec.rb @@ -120,7 +120,8 @@ def ripper_is_implemented? def ripper_works_correctly? ripper_reports_correct_line_number? && - ripper_can_parse_source_including_keywordish_symbol? + ripper_can_parse_source_including_keywordish_symbol? && + ripper_can_parse_source_referencing_keyword_arguments? end # https://github.com/jruby/jruby/issues/3386 @@ -144,6 +145,25 @@ def ripper_can_parse_source_including_keywordish_symbol? end end + # https://github.com/jruby/jruby/issues/5209 + def ripper_can_parse_source_referencing_keyword_arguments? + in_sub_process_if_possible do + require 'ripper' + # It doesn't matter if keyword arguments don't exist. + if Ruby.mri? || Ruby.jruby? + if RUBY_VERSION < '2.0' + true + else + begin + !::Ripper.sexp('def a(**kw_args); end').nil? + rescue NoMethodError + false + end + end + end + end + end + it 'returns whether Ripper is correctly implemented in the current environment' do expect(RubyFeatures.ripper_supported?).to eq(ripper_is_implemented? && ripper_works_correctly?) end