Intercept most exit calls and raise instead

This commit is contained in:
Michael Miller 2022-07-12 23:02:20 -06:00
parent 3c9c7f88be
commit 754bfd6939
No known key found for this signature in database
GPG key ID: 32B47AE8F388A1FF
4 changed files with 43 additions and 15 deletions

View file

@ -7,14 +7,9 @@ Spectator.describe "GitHub Issue #29" do
end end
end end
# mock SomeClass do
# inject_stub abstract def exit(code)
# end
describe SomeClass do describe SomeClass do
xit "captures exit", pending: "Mock redesign" do it "captures exit" do
expect(subject).to receive(:exit).with(0) expect { subject.goodbye }.to raise_error(Spectator::SystemExit)
subject.goodbye
end end
end end
@ -25,16 +20,10 @@ Spectator.describe "GitHub Issue #29" do
end end
end end
# mock Foo do
# inject_stub abstract def self.exit(code)
# end
subject { Foo } subject { Foo }
xit "must capture exit", pending: "Mock redesign" do it "must capture exit" do
expect(subject).to receive(:exit).with(0) expect { subject.test }.to raise_error(Spectator::SystemExit)
subject.test
end end
end end
end end

View file

@ -0,0 +1,13 @@
require "../spec_helper"
Spectator.describe Spectator::SystemExit do
it "is raised when an attempt is made to exit the application" do
expect { exit }.to raise_error(described_class)
end
it "has the status code passed to an exit call" do
exit 5
rescue error : Spectator::SystemExit
expect(error.status).to eq(5)
end
end

View file

@ -51,6 +51,7 @@ require "./runner_events"
require "./runner" require "./runner"
require "./spec_builder" require "./spec_builder"
require "./spec" require "./spec"
require "./system_exit"
require "./tag_node_filter" require "./tag_node_filter"
require "./test_context" require "./test_context"
require "./value" require "./value"

View file

@ -0,0 +1,25 @@
module Spectator
# Indicates a call to exit the application was performed.
class SystemExit < Exception
# Status code passed to the exit call.
getter status : Int32
# Creates the exception.
def initialize(message : String? = nil, cause : Exception? = nil, @status : Int32 = 0)
super(message, cause)
end
end
# Allow Spectator to exit normally when needed.
private def self.exit(status = 0) : NoReturn
::Crystal::System::Process.exit(status)
end
end
class Process
# Replace the typically used exit method with a method that raises.
# This allows tests to catch attempts to exit the application.
def self.exit(status = 0) : NoReturn
raise ::Spectator::SystemExit.new(status: status)
end
end