ruby/test/irb/command/test_show_source.rb
Stan Lo 07c774e85c [ruby/irb] Revamp help command
(https://github.com/ruby/irb/pull/877)

* Make help command display help for individual commands

Usage: `help [command]`

If the command is not specified, it will display a list of all available commands.

If the command is specified, it will display the banner OR description of the command.

If the command is not found, it will display a message saying that the command is not found.

* Rename test/irb/cmd to test/irb/command

* Add banner to edit and ls commands

* Promote help command in the help message

1. Make `show_cmds` an alias of `help` so it's not displayed in the help message
2. Update description of the help command to reflect `help <command>` syntax

* Rename banner to help_message

43a2c99f3f
2024-02-18 18:21:08 +00:00

397 lines
7.8 KiB
Ruby

# frozen_string_literal: false
require 'irb'
require_relative "../helper"
module TestIRB
class ShowSourceTest < IntegrationTestCase
def setup
super
write_rc <<~'RUBY'
IRB.conf[:USE_PAGER] = false
RUBY
end
def test_show_source
write_ruby <<~'RUBY'
binding.irb
RUBY
out = run_ruby_file do
type "show_source IRB.conf"
type "exit"
end
assert_match(%r[/irb\/init\.rb], out)
end
def test_show_source_alias
write_ruby <<~'RUBY'
binding.irb
RUBY
out = run_ruby_file do
type "$ IRB.conf"
type "exit"
end
assert_match(%r[/irb\/init\.rb], out)
end
def test_show_source_with_missing_signature
write_ruby <<~'RUBY'
binding.irb
RUBY
out = run_ruby_file do
type "show_source foo"
type "exit"
end
assert_match(%r[Couldn't locate a definition for foo], out)
end
def test_show_source_with_missing_constant
write_ruby <<~'RUBY'
binding.irb
RUBY
out = run_ruby_file do
type "show_source Foo"
type "exit"
end
assert_match(%r[Couldn't locate a definition for Foo], out)
end
def test_show_source_string
write_ruby <<~'RUBY'
binding.irb
RUBY
out = run_ruby_file do
type "show_source 'IRB.conf'"
type "exit"
end
assert_match(%r[/irb\/init\.rb], out)
end
def test_show_source_method_s
write_ruby <<~RUBY
class Baz
def foo
end
end
class Bar < Baz
def foo
super
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source Bar#foo -s"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end\r\n], out)
end
def test_show_source_method_s_with_incorrect_signature
write_ruby <<~RUBY
class Baz
def foo
end
end
class Bar < Baz
def foo
super
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source Bar#fooo -s"
type "exit"
end
assert_match(%r[Error: Couldn't locate a super definition for Bar#fooo], out)
end
def test_show_source_private_method
write_ruby <<~RUBY
class Bar
private def foo
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source Bar#foo"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:2\s+private def foo\r\n end\r\n], out)
end
def test_show_source_private_singleton_method
write_ruby <<~RUBY
class Bar
private def foo
end
end
binding.irb
RUBY
out = run_ruby_file do
type "bar = Bar.new"
type "show_source bar.foo"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:2\s+private def foo\r\n end\r\n], out)
end
def test_show_source_method_multiple_s
write_ruby <<~RUBY
class Baz
def foo
end
end
class Bar < Baz
def foo
super
end
end
class Bob < Bar
def foo
super
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source Bob#foo -ss"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end\r\n], out)
end
def test_show_source_method_no_instance_method
write_ruby <<~RUBY
class Baz
end
class Bar < Baz
def foo
super
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source Bar#foo -s"
type "exit"
end
assert_match(%r[Error: Couldn't locate a super definition for Bar#foo], out)
end
def test_show_source_method_exceeds_super_chain
write_ruby <<~RUBY
class Baz
def foo
end
end
class Bar < Baz
def foo
super
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source Bar#foo -ss"
type "exit"
end
assert_match(%r[Error: Couldn't locate a super definition for Bar#foo], out)
end
def test_show_source_method_accidental_characters
write_ruby <<~'RUBY'
class Baz
def foo
end
end
class Bar < Baz
def foo
super
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source Bar#foo -sddddd"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end], out)
end
def test_show_source_receiver_super
write_ruby <<~RUBY
class Baz
def foo
end
end
class Bar < Baz
def foo
super
end
end
binding.irb
RUBY
out = run_ruby_file do
type "bar = Bar.new"
type "show_source bar.foo -s"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end], out)
end
def test_show_source_with_double_colons
write_ruby <<~RUBY
class Foo
end
class Foo
class Bar
end
end
binding.irb
RUBY
out = run_ruby_file do
type "show_source ::Foo"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:1\s+class Foo\r\nend], out)
out = run_ruby_file do
type "show_source ::Foo::Bar"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:5\s+class Bar\r\n end], out)
end
def test_show_source_keep_script_lines
pend unless defined?(RubyVM.keep_script_lines)
write_ruby <<~RUBY
binding.irb
RUBY
out = run_ruby_file do
type "def foo; end"
type "show_source foo"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}\(irb\):1\s+def foo; end], out)
end
def test_show_source_unavailable_source
write_ruby <<~RUBY
binding.irb
RUBY
out = run_ruby_file do
type "RubyVM.keep_script_lines = false if defined?(RubyVM.keep_script_lines)"
type "def foo; end"
type "show_source foo"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}\(irb\):2\s+Source not available], out)
end
def test_show_source_shows_binary_source
write_ruby <<~RUBY
# io-console is an indirect dependency of irb
require "io/console"
binding.irb
RUBY
out = run_ruby_file do
# IO::ConsoleMode is defined in io-console gem's C extension
type "show_source IO::ConsoleMode"
type "exit"
end
# A safeguard to make sure the test subject is actually defined
refute_match(/NameError/, out)
assert_match(%r[Defined in binary file:.+io/console], out)
end
def test_show_source_with_constant_lookup
write_ruby <<~RUBY
X = 1
module M
Y = 1
Z = 2
end
class A
Z = 1
Array = 1
class B
include M
Object.new.instance_eval { binding.irb }
end
end
RUBY
out = run_ruby_file do
type "show_source X"
type "show_source Y"
type "show_source Z"
type "show_source Array"
type "exit"
end
assert_match(%r[#{@ruby_file.to_path}:1\s+X = 1], out)
assert_match(%r[#{@ruby_file.to_path}:3\s+Y = 1], out)
assert_match(%r[#{@ruby_file.to_path}:7\s+Z = 1], out)
assert_match(%r[#{@ruby_file.to_path}:8\s+Array = 1], out)
end
end
end