mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
cli_spec: improve test coverage and refactor
57.14% is covered. We don't cover `on` switches because it's hard to test them. We also replace `exit` with `Kernel.exit` because this way we can mock this method. Not sure why plain `exit` cannot be mocked.
This commit is contained in:
parent
5b6ac7997b
commit
77295853bf
2 changed files with 221 additions and 70 deletions
|
@ -80,7 +80,7 @@ class Pry
|
|||
rescue Pry::Slop::InvalidOptionError
|
||||
# Display help message on unknown switches and exit.
|
||||
puts Pry::Slop.new(&options)
|
||||
exit
|
||||
Kernel.exit
|
||||
end
|
||||
|
||||
Pry.initial_session_setup
|
||||
|
@ -93,7 +93,7 @@ class Pry
|
|||
end
|
||||
|
||||
def start(opts)
|
||||
exit if opts.help?
|
||||
Kernel.exit if opts.help?
|
||||
|
||||
# invoked via cli
|
||||
Pry.cli = true
|
||||
|
@ -110,7 +110,7 @@ class Pry
|
|||
if !@pass_argv && Pry::CLI.input_args.any? && Pry::CLI.input_args != ["pry"]
|
||||
full_name = File.expand_path(Pry::CLI.input_args.first)
|
||||
Pry.load_file_through_repl(full_name)
|
||||
exit
|
||||
Kernel.exit
|
||||
end
|
||||
|
||||
# Start the session (running any code passed with -e, if there is any)
|
||||
|
@ -182,7 +182,7 @@ Pry::CLI.add_options do
|
|||
Pry.locate_plugins.each do |plugin|
|
||||
puts plugin.name.to_s.ljust(18) << plugin.spec.summary
|
||||
end
|
||||
exit
|
||||
Kernel.exit
|
||||
end
|
||||
|
||||
on "simple-prompt", "Enable simple prompt mode" do
|
||||
|
@ -214,7 +214,7 @@ Pry::CLI.add_options do
|
|||
|
||||
on :v, :version, "Display the Pry version" do
|
||||
puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}"
|
||||
exit
|
||||
Kernel.exit
|
||||
end
|
||||
|
||||
on :c, :context=,
|
||||
|
|
281
spec/cli_spec.rb
281
spec/cli_spec.rb
|
@ -1,85 +1,236 @@
|
|||
RSpec.describe Pry::CLI do
|
||||
before do
|
||||
Pry::CLI.reset
|
||||
end
|
||||
before { described_class.reset }
|
||||
|
||||
describe "parsing options" do
|
||||
it 'should raise if no options defined' do
|
||||
expect { Pry::CLI.parse_options(["--nothing"]) }
|
||||
.to raise_error Pry::CLI::NoOptionsError
|
||||
describe ".add_options" do
|
||||
it "returns self" do
|
||||
expect(described_class.add_options).to eq(described_class)
|
||||
end
|
||||
|
||||
it "should remove args from ARGV by default" do
|
||||
argv = ['filename', '-v']
|
||||
Pry::CLI.add_options do
|
||||
on :v, "Display the Pry version" do
|
||||
# irrelevant
|
||||
end
|
||||
end.parse_options(argv)
|
||||
expect(argv.include?('-v')).to eq false
|
||||
context "when options is nil and a block is provided" do
|
||||
before { described_class.options = nil }
|
||||
|
||||
it "sets the block as options" do
|
||||
block = proc {}
|
||||
described_class.add_options(&block)
|
||||
expect(described_class.options).to eql(block)
|
||||
end
|
||||
end
|
||||
|
||||
context "when options were previously set" do
|
||||
it "overwrites the options proc that executes the provided block" do
|
||||
described_class.options = proc {}
|
||||
|
||||
executed = false
|
||||
described_class.add_options { executed = true }
|
||||
|
||||
described_class.options.call
|
||||
expect(executed).to be_truthy
|
||||
end
|
||||
|
||||
it "overwrites the options proc that executes original options" do
|
||||
original_executed = false
|
||||
described_class.options = proc { original_executed = true }
|
||||
|
||||
described_class.add_options {}
|
||||
described_class.options.call
|
||||
|
||||
expect(original_executed).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "adding options" do
|
||||
it "should be able to add an option" do
|
||||
run = false
|
||||
|
||||
Pry::CLI.add_options do
|
||||
on :optiontest, "A test option" do
|
||||
run = true
|
||||
end
|
||||
end.parse_options(["--optiontest"])
|
||||
|
||||
expect(run).to eq true
|
||||
describe ".add_plugin_options" do
|
||||
it "returns self" do
|
||||
expect(described_class.add_plugin_options).to eq(described_class)
|
||||
end
|
||||
|
||||
it "should be able to add multiple options" do
|
||||
run = false
|
||||
run2 = false
|
||||
it "loads cli options of plugins" do
|
||||
plugin_mock = double
|
||||
expect(plugin_mock).to receive(:load_cli_options)
|
||||
plugins = { 'pry-testplugin' => plugin_mock }
|
||||
expect(Pry).to receive(:plugins).and_return(plugins)
|
||||
|
||||
Pry::CLI.add_options do
|
||||
on :optiontest, "A test option" do
|
||||
run = true
|
||||
end
|
||||
end.add_options do
|
||||
on :optiontest2, "Another test option" do
|
||||
run2 = true
|
||||
end
|
||||
end.parse_options(["--optiontest", "--optiontest2"])
|
||||
|
||||
expect(run).to equal true
|
||||
expect(run2).to equal true
|
||||
described_class.add_plugin_options
|
||||
end
|
||||
end
|
||||
|
||||
describe "processing options" do
|
||||
it "should be able to process an option" do
|
||||
run = false
|
||||
|
||||
Pry::CLI.add_options do
|
||||
on :optiontest, "A test option"
|
||||
end.add_option_processor do |opts|
|
||||
run = true if opts.present?(:optiontest)
|
||||
end.parse_options(["--optiontest"])
|
||||
|
||||
expect(run).to eq true
|
||||
describe ".add_option_processor" do
|
||||
it "returns self" do
|
||||
expect(described_class.add_option_processor {}).to eq(described_class)
|
||||
end
|
||||
|
||||
it "should be able to process multiple options" do
|
||||
run = false
|
||||
run2 = false
|
||||
it "adds an option processor" do
|
||||
option_processor = proc {}
|
||||
described_class.add_option_processor(&option_processor)
|
||||
expect(described_class.option_processors).to eql([option_processor])
|
||||
end
|
||||
end
|
||||
|
||||
Pry::CLI.add_options do
|
||||
on :optiontest, "A test option"
|
||||
on :optiontest2, "Another test option"
|
||||
end.add_option_processor do |opts|
|
||||
run = true if opts.present?(:optiontest)
|
||||
end.add_option_processor do |opts|
|
||||
run2 = true if opts.present?(:optiontest2)
|
||||
end.parse_options(["--optiontest", "--optiontest2"])
|
||||
describe ".parse_options" do
|
||||
context "when option exists" do
|
||||
before { described_class.options = proc { on(:v, 'test') } }
|
||||
|
||||
expect(run).to eq true
|
||||
expect(run2).to eq true
|
||||
it "removes the existing option from ARGV" do
|
||||
argv = %w[filename -v]
|
||||
described_class.parse_options(argv)
|
||||
expect(argv).not_to include('-v')
|
||||
end
|
||||
|
||||
it "initializes session setup" do
|
||||
expect(Pry).to receive(:initial_session_setup)
|
||||
described_class.parse_options(%w[-v])
|
||||
end
|
||||
|
||||
it "finalizes session setup" do
|
||||
expect(Pry).to receive(:final_session_setup)
|
||||
described_class.parse_options(%w[-v])
|
||||
end
|
||||
end
|
||||
|
||||
context "when multiple options exist" do
|
||||
it "processes only called options" do
|
||||
processor_a_called = false
|
||||
processor_b_called = false
|
||||
processor_c_called = false
|
||||
described_class.options = proc do
|
||||
on('option-a', 'test a') { processor_a_called = true }
|
||||
on('option-b', 'test b') { processor_b_called = true }
|
||||
on('option-c', 'test c') { processor_c_called = true }
|
||||
end
|
||||
|
||||
described_class.parse_options(%w[--option-a --option-b])
|
||||
|
||||
expect(processor_a_called).to be_truthy
|
||||
expect(processor_b_called).to be_truthy
|
||||
expect(processor_c_called).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context "when option doesn't exist" do
|
||||
it "raises error" do
|
||||
expect { described_class.parse_options(['--nothing']) }
|
||||
.to raise_error(Pry::CLI::NoOptionsError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when argv is passed with a dash (-)" do
|
||||
before { described_class.options = proc {} }
|
||||
|
||||
it "sets everything after the dash as input args" do
|
||||
argv = %w[filename - foo bar]
|
||||
described_class.parse_options(argv)
|
||||
expect(described_class.input_args).to eq(%w[foo bar])
|
||||
end
|
||||
end
|
||||
|
||||
context "when argv is passed with a double dash (--)" do
|
||||
before { described_class.options = proc {} }
|
||||
|
||||
it "sets everything after the double dash as input args" do
|
||||
argv = %w[filename -- foo bar]
|
||||
described_class.parse_options(argv)
|
||||
expect(described_class.input_args).to eq(%w[foo bar])
|
||||
end
|
||||
end
|
||||
|
||||
context "when invalid option is provided" do
|
||||
before { described_class.options = proc { on(:valid, 'valid') } }
|
||||
|
||||
it "exits program" do
|
||||
expect(Kernel).to receive(:exit)
|
||||
expect(STDOUT).to receive(:puts)
|
||||
|
||||
described_class.parse_options(%w[--invalid])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".start" do
|
||||
before do
|
||||
# Don't start Pry session in the middle of tests.
|
||||
allow(Pry).to receive(:start)
|
||||
|
||||
described_class.options = proc {}
|
||||
end
|
||||
|
||||
it "sets Pry.cli to true" do
|
||||
opts = described_class.parse_options(%w[])
|
||||
described_class.start(opts)
|
||||
expect(Pry.cli).to be_truthy
|
||||
end
|
||||
|
||||
context "when the help option is provided" do
|
||||
before { described_class.options = proc { on(:help, 'help') } }
|
||||
|
||||
it "exits" do
|
||||
expect(Kernel).to receive(:exit)
|
||||
|
||||
opts = described_class.parse_options(%w[--help])
|
||||
described_class.start(opts)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the context option is provided" do
|
||||
before { described_class.options = proc { on(:context=, 'context') } }
|
||||
|
||||
it "initializes session setup" do
|
||||
expect(Pry).to receive(:initial_session_setup).twice
|
||||
opts = described_class.parse_options(%w[--context=Object])
|
||||
described_class.start(opts)
|
||||
end
|
||||
|
||||
it "finalizes session setup" do
|
||||
expect(Pry).to receive(:final_session_setup).twice
|
||||
opts = described_class.parse_options(%w[--context=Object])
|
||||
described_class.start(opts)
|
||||
end
|
||||
|
||||
it "starts Pry in the provided context" do
|
||||
expect(Pry).to receive(:start).with(
|
||||
instance_of(Binding), input: instance_of(StringIO)
|
||||
) do |binding, _opts|
|
||||
expect(binding.eval('self')).to be_an(Object)
|
||||
end
|
||||
opts = described_class.parse_options(%w[--context=Object])
|
||||
described_class.start(opts)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the context option is not provided" do
|
||||
before { described_class.options = proc {} }
|
||||
|
||||
it "starts Pry in the top level" do
|
||||
expect(Pry).to receive(:start).with(
|
||||
instance_of(Binding), input: instance_of(StringIO)
|
||||
) do |binding, _opts|
|
||||
expect(binding.eval('self')).to eq(Pry.main)
|
||||
end
|
||||
opts = described_class.parse_options(%w[])
|
||||
described_class.start(opts)
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are some input args" do
|
||||
before { described_class.options = proc {} }
|
||||
|
||||
it "loads files through repl and exits" do
|
||||
expect(Pry).to receive(:load_file_through_repl).with(match(%r{pry/foo}))
|
||||
expect(Kernel).to receive(:exit)
|
||||
|
||||
opts = described_class.parse_options(%w[foo])
|
||||
described_class.start(opts)
|
||||
end
|
||||
end
|
||||
|
||||
context "when 'pry' is passed as an input arg" do
|
||||
before { described_class.options = proc {} }
|
||||
|
||||
it "does not load files through repl" do
|
||||
expect(Pry).not_to receive(:load_file_through_repl)
|
||||
|
||||
opts = described_class.parse_options(%w[pry])
|
||||
described_class.start(opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue