diff --git a/lib/guard/jobs/pry_wrapper.rb b/lib/guard/jobs/pry_wrapper.rb index ea48ebd61..3c3eadd8c 100644 --- a/lib/guard/jobs/pry_wrapper.rb +++ b/lib/guard/jobs/pry_wrapper.rb @@ -133,9 +133,8 @@ def _kill_pry def _setup(options) Pry.config.should_load_rc = false Pry.config.should_load_local_rc = false - history_file_path = options[:history_file] || HISTORY_FILE - Pry.config.history.file = File.expand_path(history_file_path) + _configure_history_file(options[:history_file] || HISTORY_FILE) _add_hooks(options) Commands::All.import @@ -150,6 +149,17 @@ def _setup(options) _configure_prompt end + def _configure_history_file(history_file) + history_file_path = File.expand_path(history_file) + + # Pry >= 0.13 + if Pry.config.respond_to?(:history_file=) + Pry.config.history_file = history_file_path + else + Pry.config.history.file = history_file_path + end + end + # Add Pry hooks: # # * Load `~/.guardrc` within each new Pry session. @@ -266,7 +276,15 @@ def process # rubocop:disable Lint/NestedMethodDefinition # `pry`. # def _configure_prompt - Pry.config.prompt = [_prompt(">"), _prompt("*")] + prompt_procs = [_prompt(">"), _prompt("*")] + prompt = + if Pry::Prompt.is_a?(Class) + Pry::Prompt.new("Guard", "Guard Pry prompt", prompt_procs) + else + prompt_procs + end + + Pry.config.prompt = prompt end # Returns the plugins scope, or the groups scope ready for display in the @@ -295,12 +313,11 @@ def _clip_name(target) end def _history(pry) - # https://github.com/pry/pry/blob/5bf2585d0a49a4a3666a9eae80ee31153e3ffcf4/CHANGELOG.md#v0120-november-5-2018 - if Gem::Version.new(Pry::VERSION) < Gem::Version.new("0.12.0") - return pry.input_array.size + if pry.respond_to?(:input_ring) + pry.input_ring.size + else + pry.input_array.size end - - pry.input_ring.size end end end diff --git a/spec/lib/guard/jobs/pry_wrapper_spec.rb b/spec/lib/guard/jobs/pry_wrapper_spec.rb index caf8f3f12..f103a9e72 100644 --- a/spec/lib/guard/jobs/pry_wrapper_spec.rb +++ b/spec/lib/guard/jobs/pry_wrapper_spec.rb @@ -5,10 +5,15 @@ RSpec.describe Guard::Jobs::PryWrapper do subject { described_class.new({}) } let(:listener) { instance_double("Listen::Listener") } - let(:pry_config) { double("pry_config") } + let(:pry_hooks) { double("pry_hooks", add_hook: true) } + let(:pry_config) do + double("pry_config", "history_file=" => true, command_prefix: true, "prompt=" => true, "should_load_rc=" => true, + "should_load_local_rc=" => true, hooks: pry_hooks) + end let(:pry_history) { double("pry_history") } - let(:pry_commands) { double("pry_commands") } - let(:pry_hooks) { double("pry_hooks") } + let(:pry_commands) do + double("pry_commands", alias_command: true, create_command: true, command: true, block_command: true) + end let(:terminal_settings) { instance_double("Guard::Jobs::TerminalSettings") } let(:session) { instance_double("Guard::Internals::Session") } @@ -18,22 +23,9 @@ let(:scope) { instance_double("Guard::Internals::Scope") } before do - # TODO: this are here to mock out Pry completely - allow(pry_config).to receive(:prompt=) - allow(pry_config).to receive(:should_load_rc=) - allow(pry_config).to receive(:should_load_local_rc=) - allow(pry_config).to receive(:hooks).and_return(pry_hooks) - allow(pry_config).to receive(:history).and_return(pry_history) - allow(pry_config).to receive(:commands).and_return(pry_commands) - allow(pry_history).to receive(:file=) - allow(pry_commands).to receive(:alias_command) - allow(pry_commands).to receive(:create_command) - allow(pry_commands).to receive(:command) - allow(pry_commands).to receive(:block_command) - allow(pry_hooks).to receive(:add_hook) - allow(Guard).to receive(:listener).and_return(listener) allow(Pry).to receive(:config).and_return(pry_config) + allow(Pry).to receive(:commands).and_return(pry_commands) allow(Shellany::Sheller).to receive(:run).with("hash", "stty") { false } allow(groups).to receive(:all).and_return([]) @@ -61,6 +53,30 @@ allow(terminal_settings).to receive(:restore) end + describe "#_setup" do + context "Guard is using Pry >= 0.13" do + it "calls Pry.config.history_file=" do + expect(pry_config).to receive(:history_file=) + + subject + end + end + + context "Guard is using Pry < 0.13" do + let(:pry_config) do + double("pry_config", "history" => true, command_prefix: true, "prompt=" => true, "should_load_rc=" => true, + "should_load_local_rc=" => true, hooks: pry_hooks) + end + + it "calls Pry.config.history.file=" do + expect(pry_config).to receive(:history).and_return(pry_history) + expect(pry_history).to receive(:file=) + + subject + end + end + end + describe "#foreground" do before do allow(Pry).to receive(:start) do @@ -136,60 +152,75 @@ allow(scope).to receive(:titles).and_return(["all"]) allow(listener).to receive(:paused?).and_return(false) - - expect(Pry).to receive(:view_clip).and_return("main") + allow(Pry).to receive(:view_clip).and_return("main") end - let(:pry) { instance_double(Pry, input_ring: []) } + context "Guard is using Pry >= 0.13" do + let(:pry) { double("Pry", input_ring: []) } + let(:pry_prompt) { double } - context "Guard is not paused" do - it 'displays "guard"' do - expect(prompt.call(double, 0, pry)) - .to eq "[0] guard(main)> " + it "calls Pry::Prompt.new" do + expect(Pry::Prompt).to receive(:is_a?).with(Class).and_return(true) + expect(Pry::Prompt).to receive(:new).with("Guard", "Guard Pry prompt", an_instance_of(Array)).and_return(pry_prompt) + expect(pry_config).to receive(:prompt=).with(pry_prompt) + + subject end - end - context "Guard is using a lower version of Pry" do - let(:pry) { instance_double(Pry, input_array: []) } + context "Guard is not paused" do + it "displays 'guard'" do + expect(prompt.call(double, 0, pry)) + .to eq "[0] guard(main)> " + end + end - it 'displays "guard"' do - stub_const("Pry::VERSION", "0.11.0") + context "Guard is paused" do + before do + allow(listener).to receive(:paused?).and_return(true) + end - expect(prompt.call(double, 0, pry)) - .to eq "[0] guard(main)> " + it "displays 'pause'" do + expect(prompt.call(double, 0, pry)) + .to eq "[0] pause(main)> " + end end - end - context "Guard is paused" do - before do - allow(listener).to receive(:paused?).and_return(true) - end + context "with a groups scope" do + before do + allow(scope).to receive(:titles).and_return(%w[Backend Frontend]) + end - it 'displays "pause"' do - expect(prompt.call(double, 0, pry)) - .to eq "[0] pause(main)> " + it "displays the group scope title in the prompt" do + expect(prompt.call(double, 0, pry)) + .to eq "[0] Backend,Frontend guard(main)> " + end end - end - context "with a groups scope" do - before do - allow(scope).to receive(:titles).and_return(%w[Backend Frontend]) - end + context "with a plugins scope" do + before do + allow(scope).to receive(:titles).and_return(%w[RSpec Ronn]) + end - it "displays the group scope title in the prompt" do - expect(prompt.call(double, 0, pry)) - .to eq "[0] Backend,Frontend guard(main)> " + it "displays the group scope title in the prompt" do + result = prompt.call(double, 0, pry) + expect(result).to eq "[0] RSpec,Ronn guard(main)> " + end end end - context "with a plugins scope" do - before do - allow(scope).to receive(:titles).and_return(%w[RSpec Ronn]) + context "Guard is using Pry < 0.13" do + let(:pry) { double("Pry", input_array: []) } + + it "does not call Pry::Prompt.new" do + expect(Pry::Prompt).to receive(:is_a?).with(Class).and_return(false) + expect(pry_config).to receive(:prompt=).with(an_instance_of(Array)) + + subject end - it "displays the group scope title in the prompt" do - result = prompt.call(double, 0, pry) - expect(result).to eq "[0] RSpec,Ronn guard(main)> " + it "displays 'guard'" do + expect(prompt.call(double, 0, pry)) + .to eq "[0] guard(main)> " end end end