From 1a60403779994ba7f73610383213ab04dbb1df85 Mon Sep 17 00:00:00 2001 From: aycabta Date: Mon, 4 Jan 2021 19:38:22 +0900 Subject: [PATCH] Stringify when a non-object is passed to PP#text If a nested object is passed to #pp, it may be sometimes passed to the #text method as an object without being stringified. This is fixed on the Ruby main repository; https://github.com/ruby/ruby/commit/433a3be86a811de0b4adbb92e054ee3a6fc6b4d8 but it was a bug of Ripper so still needs this workaround for using irb as a gem on Ruby 3.0.0 or earlier. --- lib/irb/color_printer.rb | 11 ++++++++--- test/irb/test_color.rb | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/irb/color_printer.rb b/lib/irb/color_printer.rb index 187c33718..2c815da9f 100644 --- a/lib/irb/color_printer.rb +++ b/lib/irb/color_printer.rb @@ -10,12 +10,17 @@ def self.pp(obj, out = $>, width = 79) out end - def text(str, width = str.length) + def text(str, width = nil) case str when /\A#' - super(Color.colorize(str, [:GREEN]), width) + super(Color.colorize(str, [:GREEN]), str.length) else - super(Color.colorize_code(str, ignore_error: true), width) + begin + super(Color.colorize_code(str, ignore_error: true), str.length) + rescue TypeError + str = str.inspect + super(Color.colorize(str, [:GREEN]), str.length) + end end end end diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb index c0682b1bb..9fd414fe9 100644 --- a/test/irb/test_color.rb +++ b/test/irb/test_color.rb @@ -1,6 +1,7 @@ # frozen_string_literal: false require 'test/unit' require 'irb/color' +require 'irb/color_printer' require 'rubygems' require 'stringio' @@ -152,6 +153,19 @@ def test_colorize_code_complete_false end end + def test_color_printer + unless ripper_lexer_scan_supported? + skip 'Ripper::Lexer#scan is supported in Ruby 2.7+' + end + { + 1 => "#{BLUE}#{BOLD}1#{CLEAR}", + Ripper::Lexer.new('1').scan => "[#{GREEN}##{CLEAR}]", + }.each do |object, result| + actual = with_term { IRB::ColorPrinter.pp(object, '') } + assert_equal(result, actual, "Case: IRB::ColorPrinter.pp(#{object.inspect}, '')") + end + end + def test_inspect_colorable { 1 => true, @@ -184,6 +198,10 @@ def complete_option_supported? Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0') end + def ripper_lexer_scan_supported? + Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0') + end + def with_term stdout = $stdout io = StringIO.new