[ruby/irb] Polish the exit! command and its tests
(https://github.com/ruby/irb/pull/867) * Remove IRB.irb_exit! method It's not necessary to introduce a new method just for the exit! command at this moment. * Rename ExitForcedAction to ForceExit * Move force exit tests to a dedicated file * Fix nested history saving with exit! command Because we switched to use `Kernel#exit` instead of `exit!`, the outer session's ensure block in `Irb#run` will be run, which will save the history. This means the separate check to save history when force exiting is no longer necessary. * execute_lines helper should also capture IRB setup's output This prevents setup warnings from being printed to test output while allowing those output to be tested. * Update readme https://github.com/ruby/irb/commit/899d10ade1
This commit is contained in:
parent
429eeb09f2
commit
5c4657f883
13
lib/irb.rb
13
lib/irb.rb
@ -889,10 +889,6 @@ module IRB
|
||||
throw :IRB_EXIT, false
|
||||
end
|
||||
|
||||
def IRB.irb_exit!(*)
|
||||
throw :IRB_EXIT, true
|
||||
end
|
||||
|
||||
# Aborts then interrupts irb.
|
||||
#
|
||||
# Will raise an Abort exception, or the given +exception+.
|
||||
@ -972,8 +968,7 @@ module IRB
|
||||
conf[:IRB_RC].call(context) if conf[:IRB_RC]
|
||||
conf[:MAIN_CONTEXT] = context
|
||||
|
||||
supports_history_saving = conf[:SAVE_HISTORY] && context.io.support_history_saving?
|
||||
save_history = !in_nested_session && supports_history_saving
|
||||
save_history = !in_nested_session && conf[:SAVE_HISTORY] && context.io.support_history_saving?
|
||||
|
||||
if save_history
|
||||
context.io.load_history
|
||||
@ -993,12 +988,8 @@ module IRB
|
||||
trap("SIGINT", prev_trap)
|
||||
conf[:AT_EXIT].each{|hook| hook.call}
|
||||
|
||||
if forced_exit
|
||||
context.io.save_history if supports_history_saving
|
||||
Kernel.exit(0)
|
||||
else
|
||||
context.io.save_history if save_history
|
||||
end
|
||||
Kernel.exit(0) if forced_exit
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -6,12 +6,12 @@ module IRB
|
||||
# :stopdoc:
|
||||
|
||||
module ExtendCommand
|
||||
class ExitForcedAction < Nop
|
||||
class ForceExit < Nop
|
||||
category "IRB"
|
||||
description "Exit the current process."
|
||||
|
||||
def execute(*)
|
||||
IRB.irb_exit!
|
||||
throw :IRB_EXIT, true
|
||||
rescue UncaughtThrowError
|
||||
Kernel.exit(0)
|
||||
end
|
@ -37,7 +37,7 @@ module IRB # :nodoc:
|
||||
[:irb_quit, OVERRIDE_PRIVATE_ONLY],
|
||||
],
|
||||
[
|
||||
:irb_exit!, :ExitForcedAction, "cmd/exit_forced_action",
|
||||
:irb_exit!, :ForceExit, "cmd/force_exit",
|
||||
[:exit!, OVERRIDE_PRIVATE_ONLY],
|
||||
],
|
||||
|
||||
|
51
test/irb/cmd/test_force_exit.rb
Normal file
51
test/irb/cmd/test_force_exit.rb
Normal file
@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: false
|
||||
require 'irb'
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
module TestIRB
|
||||
class ForceExitTest < IntegrationTestCase
|
||||
def test_forced_exit_finishes_process_immediately
|
||||
write_ruby <<~'ruby'
|
||||
puts "First line"
|
||||
puts "Second line"
|
||||
binding.irb
|
||||
puts "Third line"
|
||||
binding.irb
|
||||
puts "Fourth line"
|
||||
ruby
|
||||
|
||||
output = run_ruby_file do
|
||||
type "123"
|
||||
type "456"
|
||||
type "exit!"
|
||||
end
|
||||
|
||||
assert_match(/First line\r\n/, output)
|
||||
assert_match(/Second line\r\n/, output)
|
||||
assert_match(/irb\(main\):001> 123/, output)
|
||||
assert_match(/irb\(main\):002> 456/, output)
|
||||
refute_match(/Third line\r\n/, output)
|
||||
refute_match(/Fourth line\r\n/, output)
|
||||
end
|
||||
|
||||
def test_forced_exit_in_nested_sessions
|
||||
write_ruby <<~'ruby'
|
||||
def foo
|
||||
binding.irb
|
||||
end
|
||||
|
||||
binding.irb
|
||||
binding.irb
|
||||
ruby
|
||||
|
||||
output = run_ruby_file do
|
||||
type "123"
|
||||
type "foo"
|
||||
type "exit!"
|
||||
end
|
||||
|
||||
assert_match(/irb\(main\):001> 123/, output)
|
||||
end
|
||||
end
|
||||
end
|
@ -34,6 +34,7 @@ module TestIRB
|
||||
end
|
||||
|
||||
def execute_lines(*lines, conf: {}, main: self, irb_path: nil)
|
||||
capture_output do
|
||||
IRB.init_config(nil)
|
||||
IRB.conf[:VERBOSE] = false
|
||||
IRB.conf[:PROMPT_MODE] = :SIMPLE
|
||||
@ -44,7 +45,6 @@ module TestIRB
|
||||
irb.context.return_format = "=> %s\n"
|
||||
irb.context.irb_path = irb_path if irb_path
|
||||
IRB.conf[:MAIN_CONTEXT] = irb.context
|
||||
capture_output do
|
||||
irb.eval_input
|
||||
end
|
||||
end
|
||||
@ -58,7 +58,9 @@ module TestIRB
|
||||
"irb_info",
|
||||
main: main
|
||||
)
|
||||
assert_empty err
|
||||
# Because the main object is frozen, IRB would wrap a delegator around it
|
||||
# Which's exit! method can't be overridden and would raise a warning
|
||||
assert_match(/delegator does not forward private method #exit\!/, err)
|
||||
assert_match(/RUBY_PLATFORM/, out)
|
||||
end
|
||||
end
|
||||
|
@ -255,47 +255,6 @@ module TestIRB
|
||||
assert_match(/irb\(main\):001> next/, output)
|
||||
end
|
||||
|
||||
def test_forced_exit_finishes_process_when_nested_sessions
|
||||
write_ruby <<~'ruby'
|
||||
puts "First line"
|
||||
puts "Second line"
|
||||
binding.irb
|
||||
puts "Third line"
|
||||
binding.irb
|
||||
puts "Fourth line"
|
||||
ruby
|
||||
|
||||
output = run_ruby_file do
|
||||
type "123"
|
||||
type "456"
|
||||
type "exit!"
|
||||
end
|
||||
|
||||
assert_match(/First line\r\n/, output)
|
||||
assert_match(/Second line\r\n/, output)
|
||||
assert_match(/irb\(main\):001> 123/, output)
|
||||
assert_match(/irb\(main\):002> 456/, output)
|
||||
refute_match(/Third line\r\n/, output)
|
||||
refute_match(/Fourth line\r\n/, output)
|
||||
end
|
||||
|
||||
def test_forced_exit
|
||||
write_ruby <<~'ruby'
|
||||
puts "Hello"
|
||||
binding.irb
|
||||
ruby
|
||||
|
||||
output = run_ruby_file do
|
||||
type "123"
|
||||
type "456"
|
||||
type "exit!"
|
||||
end
|
||||
|
||||
assert_match(/Hello\r\n/, output)
|
||||
assert_match(/irb\(main\):001> 123/, output)
|
||||
assert_match(/irb\(main\):002> 456/, output)
|
||||
end
|
||||
|
||||
def test_quit
|
||||
write_ruby <<~'RUBY'
|
||||
binding.irb
|
||||
|
@ -379,20 +379,58 @@ module TestIRB
|
||||
HISTORY
|
||||
end
|
||||
|
||||
def test_history_saving_with_exit!
|
||||
def test_nested_history_saving_from_inner_session_with_exit!
|
||||
write_history ""
|
||||
|
||||
write_ruby <<~'RUBY'
|
||||
def foo
|
||||
binding.irb
|
||||
end
|
||||
|
||||
binding.irb
|
||||
RUBY
|
||||
|
||||
run_ruby_file do
|
||||
type "'starting session'"
|
||||
type "'outer session'"
|
||||
type "foo"
|
||||
type "'inner session'"
|
||||
type "exit!"
|
||||
end
|
||||
|
||||
assert_equal <<~HISTORY, @history_file.open.read
|
||||
'starting session'
|
||||
'outer session'
|
||||
foo
|
||||
'inner session'
|
||||
exit!
|
||||
HISTORY
|
||||
end
|
||||
|
||||
def test_nested_history_saving_from_outer_session_with_exit!
|
||||
write_history ""
|
||||
|
||||
write_ruby <<~'RUBY'
|
||||
def foo
|
||||
binding.irb
|
||||
end
|
||||
|
||||
binding.irb
|
||||
RUBY
|
||||
|
||||
run_ruby_file do
|
||||
type "'outer session'"
|
||||
type "foo"
|
||||
type "'inner session'"
|
||||
type "exit"
|
||||
type "'outer session again'"
|
||||
type "exit!"
|
||||
end
|
||||
|
||||
assert_equal <<~HISTORY, @history_file.open.read
|
||||
'outer session'
|
||||
foo
|
||||
'inner session'
|
||||
exit
|
||||
'outer session again'
|
||||
exit!
|
||||
HISTORY
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user