summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Silin <silin@kyrylo.org>2019-04-04 02:46:45 +0300
committerKyrylo Silin <silin@kyrylo.org>2019-04-04 02:46:45 +0300
commitc0716319c2bc82c5393ef25aad4cdd9a9ca900da (patch)
tree9a372765425dc511e28ba49655e7906977cd4817
parentbe0acf0a6744f9a9a79b0fce4875ee1d56743752 (diff)
downloadpry-c0716319c2bc82c5393ef25aad4cdd9a9ca900da.tar.gz
command_set: refactor specs
In this change we: * Used modern RSpec API * Deleted unused methods
-rw-r--r--lib/pry/command_set.rb45
-rw-r--r--spec/command_set_spec.rb782
2 files changed, 288 insertions, 539 deletions
diff --git a/lib/pry/command_set.rb b/lib/pry/command_set.rb
index 737a5cf7..57d7884e 100644
--- a/lib/pry/command_set.rb
+++ b/lib/pry/command_set.rb
@@ -171,7 +171,7 @@ class Pry
def find_command_by_match_or_listing(match_or_listing)
cmd = (@commands[match_or_listing] ||
Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands))
- cmd || raise(ArgumentError, "Cannot find a command: '#{match_or_listing}'!")
+ cmd || raise(ArgumentError, "cannot find a command: '#{match_or_listing}'")
end
# Aliases a command
@@ -186,7 +186,7 @@ class Pry
# @example Pass explicit description (overriding default).
# Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie"
def alias_command(match, action, options = {})
- (cmd = find_command(action)) || raise("Command: `#{action}` not found")
+ (cmd = find_command(action)) || raise("command: '#{action}' not found")
original_options = cmd.options.dup
options = original_options.merge!(
@@ -201,6 +201,7 @@ class Pry
run action, *args
end
+ # TODO: untested. What's this about?
c.class_eval do
define_method(:complete) do |input|
cmd.new(context).complete(input)
@@ -254,22 +255,6 @@ class Pry
cmd.description = description
end
- # Defines helpers methods for this command sets.
- # Those helpers are only defined in this command set.
- #
- # @yield A block defining helper methods
- # @example
- # helpers do
- # def hello
- # puts "Hello!"
- # end
- #
- # include OtherModule
- # end
- def helpers(&block)
- helper_module.class_eval(&block)
- end
-
# @return [Array]
# The list of commands provided by the command set.
def list_commands
@@ -371,12 +356,6 @@ class Pry
end
end
- # @private (used for testing)
- def run_command(context, match, *args)
- (command = @commands[match]) || raise(NoCommandError.new(match, self))
- command.new(context).call_safely(*args)
- end
-
# Generate completions for the user's search.
# @param [String] search The line to search for
# @param [Hash] context The context to create the command with
@@ -391,6 +370,24 @@ class Pry
keys.map { |key| key + " " }
end
end
+
+ private
+
+ # Defines helpers methods for this command sets.
+ # Those helpers are only defined in this command set.
+ #
+ # @yield A block defining helper methods
+ # @example
+ # helpers do
+ # def hello
+ # puts "Hello!"
+ # end
+ #
+ # include OtherModule
+ # end
+ def helpers(&block)
+ helper_module.class_eval(&block)
+ end
end
# Wraps the return result of process_commands, indicates if the
diff --git a/spec/command_set_spec.rb b/spec/command_set_spec.rb
index 9899c060..de2b1307 100644
--- a/spec/command_set_spec.rb
+++ b/spec/command_set_spec.rb
@@ -1,669 +1,421 @@
-describe Pry::CommandSet do
- before do
- @set = Pry::CommandSet.new do
- import Pry::Commands
- end
+RSpec.describe Pry::CommandSet do
+ let(:set) do
+ Pry::CommandSet.new { import(Pry::Commands) }
+ end
- @ctx = {
+ let(:ctx) do
+ {
target: binding,
- command_set: @set,
+ command_set: set,
pry_instance: Pry.new(output: StringIO.new)
}
end
- describe "[]=" do
- it "removes a command from the command set" do
- expect(@set["help"]).not_to eq nil
- @set["help"] = nil
- expect(@set["help"]).to eq nil
- expect { @set.run_command(TOPLEVEL_BINDING, "help") }
- .to raise_error Pry::NoCommandError
+ describe "#new" do
+ it "merges other set with itself" do
+ other_set = described_class.new
+ other_set.command('test') {}
+ expect(described_class.new(other_set).count).to eq(1)
end
- it "replaces a command" do
- old_help = @set["help"]
- @set["help"] = @set["pry-version"]
- expect(@set["help"]).not_to eq old_help
+ context "when block given" do
+ it "instance evals the block" do
+ other = described_class.new do
+ command('test') {}
+ end
+ expect(described_class.new(other).count).to eq(1)
+ end
end
+ end
- it "rebinds the command with key" do
- @set["help-1"] = @set["help"]
- expect(@set["help-1"].match).to eq "help-1"
+ describe "#block_command" do
+ it "defines a new command" do
+ subject.block_command('test')
+ expect(subject.count).to eq(1)
end
- it "raises a TypeError when command is not a subclass of Pry::Command" do
- expect { @set["help"] = "hello" }.to raise_error TypeError
+ it "assings default description" do
+ command = subject.block_command('test')
+ expect(command.description).to eq('No description.')
end
- end
- it 'should call the block used for the command when it is called' do
- run = false
- @set.command 'foo' do
- run = true
+ it "can overwrite default description" do
+ command = subject.block_command('test', 'test description')
+ expect(command.description).to eq('test description')
end
- @set.run_command @ctx, 'foo'
- expect(run).to eq true
- end
-
- it 'should pass arguments of the command to the block' do
- expect do |probe|
- @set.command('foo', &probe)
- @set.run_command(@ctx, 'foo', 1, 2, 3)
- end.to yield_with_args(1, 2, 3)
- end
-
- it 'should use the first argument as context' do
- inside = inner_scope do |probe|
- @set.command('foo', &probe)
-
- @set.run_command @ctx, 'foo'
+ it "configures command options" do
+ command = subject.block_command(
+ 'test', 'test description', some_option: 'some value'
+ )
+ expect(command.options).to include(some_option: 'some value')
end
- expect(inside.context).to eq(@ctx)
- end
-
- it 'should raise an error when calling an undefined command' do
- @set.command('foo') {}
- expect { @set.run_command @ctx, 'bar' }.to raise_error Pry::NoCommandError
- end
-
- it 'should be able to remove its own commands' do
- @set.command('foo') {}
- @set.delete 'foo'
-
- expect { @set.run_command @ctx, 'foo' }.to raise_error Pry::NoCommandError
- end
-
- it 'should be able to remove its own commands, by listing name' do
- @set.command(/^foo1/, 'desc', listing: 'foo') {}
- @set.delete 'foo'
-
- expect { @set.run_command @ctx, /^foo1/ }.to raise_error Pry::NoCommandError
- end
-
- it 'should be able to import some commands from other sets' do
- run = false
-
- other_set = Pry::CommandSet.new do
- command('foo') { run = true }
- command('bar') {}
+ context "when description is a hash" do
+ it "treats description as options" do
+ command = subject.block_command('test', some_option: 'some value')
+ expect(command.options).to include(some_option: 'some value')
+ end
end
-
- @set.import_from(other_set, 'foo')
-
- @set.run_command @ctx, 'foo'
- expect(run).to eq true
-
- expect { @set.run_command @ctx, 'bar' }.to raise_error Pry::NoCommandError
end
- it 'should return command set after import' do
- run = false
-
- other_set = Pry::CommandSet.new do
- command('foo') { run = true }
- command('bar') {}
+ describe "#create_command" do
+ it "defines a new class command" do
+ subject.create_command('test') {}
+ expect(subject.count).to eq(1)
end
- expect(@set.import(other_set)).to eq @set
- end
-
- it 'should return command set after import_from' do
- run = false
-
- other_set = Pry::CommandSet.new do
- command('foo') { run = true }
- command('bar') {}
+ it "assings default description" do
+ command = subject.create_command('test') {}
+ expect(command.description).to eq('No description.')
end
- expect(@set.import_from(other_set, 'foo')).to eq @set
- end
-
- it 'should be able to import some commands from other sets using listing name' do
- run = false
-
- other_set = Pry::CommandSet.new do
- command(/^foo1/, 'desc', listing: 'foo') { run = true }
+ it "can overwrite default description" do
+ command = subject.create_command('test', 'test description') {}
+ expect(command.description).to eq('test description')
end
- @set.import_from(other_set, 'foo')
-
- @set.run_command @ctx, /^foo1/
- expect(run).to eq true
- end
-
- it 'should be able to import a whole set' do
- run = []
-
- other_set = Pry::CommandSet.new do
- command('foo') { run << true }
- command('bar') { run << true }
+ it "configures command options" do
+ command = subject.create_command(
+ 'test', 'test description', some_option: 'some value'
+ ) {}
+ expect(command.options).to include(some_option: 'some value')
end
- @set.import other_set
-
- @set.run_command @ctx, 'foo'
- @set.run_command @ctx, 'bar'
- expect(run).to eq [true, true]
- end
-
- it 'should be able to import sets at creation' do
- run = false
- @set.command('foo') { run = true }
-
- Pry::CommandSet.new(@set).run_command @ctx, 'foo'
- expect(run).to eq true
- end
-
- it 'should set the descriptions of commands' do
- @set.command('foo', 'some stuff') {}
- expect(@set['foo'].description).to eq 'some stuff'
- end
-
- describe "aliases" do
- it 'should be able to alias command' do
- run = false
- @set.command('foo', 'stuff') { run = true }
-
- @set.alias_command 'bar', 'foo'
- expect(@set['bar'].match).to eq 'bar'
- expect(@set['bar'].description).to eq 'Alias for `foo`'
-
- @set.run_command @ctx, 'bar'
- expect(run).to eq true
+ it "class_evals the given block in the command context" do
+ command = subject.create_command('test') do
+ description('class eval description')
+ end
+ expect(command.description).to eq('class eval description')
end
- it "should be able to alias command with command_prefix" do
- run = false
-
- begin
- @set.command('owl', 'stuff') { run = true }
- @set.alias_command 'owlet', 'owl'
-
- Pry.config.command_prefix = '%'
- expect(@set['%owlet'].match).to eq 'owlet'
- expect(@set['%owlet'].description).to eq 'Alias for `owl`'
-
- @set.run_command @ctx, 'owlet'
- expect(run).to eq true
- ensure
- Pry.config.command_prefix = ''
+ context "when description is a hash" do
+ it "treats description as options" do
+ command = subject.create_command('test', some_option: 'some value') {}
+ expect(command.options).to include(some_option: 'some value')
end
end
+ end
- it 'should inherit options from original command' do
- run = false
- @set.command('foo', 'stuff', shellwords: true, interpolate: false) { run = true }
-
- @set.alias_command 'bar', 'foo'
- expect(@set['bar'].options[:shellwords]).to eq @set['foo'].options[:shellwords]
- expect(@set['bar'].options[:interpolate]).to eq @set['foo'].options[:interpolate]
-
- # however some options should not be inherited
- expect(@set['bar'].options[:listing]).not_to eq @set['foo'].options[:listing]
- expect(@set['bar'].options[:listing]).to eq "bar"
+ describe "#each" do
+ it "iterates over commands" do
+ subject.command('test')
+ expect(subject.each.first.first).to eq('test')
end
+ end
- it 'should be able to specify alias\'s description when aliasing' do
- run = false
- @set.command('foo', 'stuff') { run = true }
+ describe "#delete" do
+ it "deletes given commands" do
+ subject.command('peach')
+ subject.command('kiwi')
+ subject.command('apple')
- @set.alias_command 'bar', 'foo', desc: "tobina"
- expect(@set['bar'].match).to eq 'bar'
- expect(@set['bar'].description).to eq "tobina"
+ subject.delete('kiwi', 'apple')
- @set.run_command @ctx, 'bar'
- expect(run).to eq true
+ expect(subject.count).to eq(1)
end
+ end
- it "should be able to alias a command by its invocation line" do
- run = false
- @set.command(/^foo1/, 'stuff', listing: 'foo') { run = true }
-
- @set.alias_command 'bar', 'foo1'
- expect(@set['bar'].match).to eq 'bar'
- expect(@set['bar'].description).to eq 'Alias for `foo1`'
+ describe "#import" do
+ let(:first_set) { described_class.new.tap { |set| set.command('first') } }
+ let(:second_set) { described_class.new.tap { |set| set.command('second') } }
- @set.run_command @ctx, 'bar'
- expect(run).to eq true
+ it "imports commands from given sets" do
+ subject.import(first_set, second_set)
+ expect(subject.count).to eq(2)
end
- it "should be able to specify options when creating alias" do
- run = false
- @set.command(/^foo1/, 'stuff', listing: 'foo') { run = true }
-
- @set.alias_command(/^b.r/, 'foo1', listing: "bar")
- expect(@set.to_hash[/^b.r/].options[:listing]).to eq "bar"
+ it "returns self" do
+ expect(subject.import(first_set)).to eql(subject)
end
- it "should set description to default if description parameter is nil" do
- run = false
- @set.command(/^foo1/, 'stuff', listing: 'foo') { run = true }
-
- @set.alias_command "bar", 'foo1'
- expect(@set["bar"].description).to eq "Alias for `foo1`"
+ it "includes given sets' helper modules" do
+ subject.import(first_set, second_set)
+ expect(subject.helper_module.ancestors.size).to eq(3)
end
end
- it 'should be able to change the descriptions of commands' do
- @set.command('foo', 'bar') {}
- @set.desc 'foo', 'baz'
-
- expect(@set['foo'].description).to eq 'baz'
- end
-
- it 'should get the descriptions of commands' do
- @set.command('foo', 'bar') {}
- expect(@set.desc('foo')).to eq 'bar'
- end
-
- it 'should get the descriptions of commands, by listing' do
- @set.command(/^foo1/, 'bar', listing: 'foo') {}
- expect(@set.desc('foo')).to eq 'bar'
- end
-
- it 'should return Pry::Command::VOID_VALUE for commands by default' do
- @set.command('foo') { 3 }
- expect(@set.run_command(@ctx, 'foo')).to eq Pry::Command::VOID_VALUE
- end
-
- it 'should be able to keep return values' do
- @set.command('foo', '', keep_retval: true) { 3 }
- expect(@set.run_command(@ctx, 'foo')).to eq 3
- end
-
- it 'should be able to keep return values, even if return value is nil' do
- @set.command('foo', '', keep_retval: true) { nil }
- expect(@set.run_command(@ctx, 'foo')).to eq nil
- end
-
- it 'should be able to have its own helpers' do
- @set.command('foo') { my_helper }
- @set.helpers { def my_helper; end }
-
- @set.run_command(@ctx, 'foo')
- expect(
- Pry::Command.subclass('foo', '', {}, Module.new).new(target: binding)
- ).not_to(respond_to :my_helper)
- end
-
- it 'should not recreate a new helper module when helpers is called' do
- @set.command('foo') do
- my_helper
- my_other_helper
+ describe "#import_from" do
+ let(:other_set) do
+ set = described_class.new
+ set.command('kiwi')
+ set.command('peach')
+ set.command('plum')
+ set
end
- @set.helpers do
- def my_helper; end
+ it "imports matching command from a set" do
+ subject.import_from(other_set, 'kiwi', 'peach')
+ expect(subject.count).to eq(2)
end
- @set.helpers do
- def my_other_helper; end
+ it "returns self" do
+ expect(subject.import_from(other_set)).to eql(subject)
end
- @set.run_command(@ctx, 'foo')
- end
-
- it 'should import helpers from imported sets' do
- imported_set = Pry::CommandSet.new do
- helpers do
- def imported_helper_method; end
- end
+ it "includes other set's helper module" do
+ subject.import_from(other_set)
+ expect(subject.helper_module.ancestors.size).to eq(2)
end
-
- @set.import imported_set
- @set.command('foo') { imported_helper_method }
- @set.run_command(@ctx, 'foo')
end
- it 'should import helpers even if only some commands are imported' do
- imported_set = Pry::CommandSet.new do
- helpers do
- def imported_helper_method; end
- end
-
- command('bar') {}
+ describe "#find_command_by_match_or_listing" do
+ it "returns a matching by name command" do
+ subject.command('test')
+ command = subject.find_command_by_match_or_listing('test')
+ expect(command.command_name).to eq('test')
end
- @set.import_from imported_set, 'bar'
- @set.command('foo') { imported_helper_method }
- @set.run_command(@ctx, 'foo')
- end
-
- it 'should provide a :listing for a command that defaults to its name' do
- @set.command('foo', '') {}
- expect(@set['foo'].options[:listing]).to eq 'foo'
- end
+ it "returns a matching by listing command" do
+ subject.command('test', listing: 'wtf')
+ command = subject.find_command_by_match_or_listing('wtf')
+ expect(command.command_name).to eq('wtf')
+ end
- it 'should provide a :listing for a command that differs from its name' do
- @set.command('foo', '', listing: 'bar') {}
- expect(@set['foo'].options[:listing]).to eq 'bar'
+ it "raises ArgumentError on non-matching command" do
+ expect { subject.find_command_by_match_or_listing('test') }
+ .to raise_error(ArgumentError, "cannot find a command: 'test'")
+ end
end
- it "should provide a 'help' command" do
- @ctx[:command_set] = @set
- @ctx[:output] = StringIO.new
+ describe "#alias_command" do
+ before { subject.command('test') }
- expect { @set.run_command(@ctx, 'help') }.to_not raise_error
- end
-
- describe "renaming a command" do
- it 'should be able to rename and run a command' do
- run = false
- @set.command('foo') { run = true }
- @set.rename_command('bar', 'foo')
- @set.run_command(@ctx, 'bar')
- expect(run).to eq true
+ it "returns the aliased command" do
+ new_command = subject.alias_command('new-test', 'test')
+ expect(new_command.command_name).to eq('new-test')
end
- it 'should accept listing name when renaming a command' do
- run = false
- @set.command('foo', "", listing: 'love') { run = true }
- @set.rename_command('bar', 'love')
- @set.run_command(@ctx, 'bar')
- expect(run).to eq true
+ it "sets description for the aliased command automatically" do
+ new_command = subject.alias_command('new-test', 'test')
+ expect(new_command.description).to eq('Alias for `test`')
end
- it 'should raise exception trying to rename non-existent command' do
- expect { @set.rename_command('bar', 'foo') }.to raise_error ArgumentError
+ it "sets aliased command's listing" do
+ new_command = subject.alias_command('new-test', 'test')
+ expect(new_command.options).to include(listing: 'new-test')
end
- it 'should make old command name inaccessible' do
- @set.command('foo') {}
- @set.rename_command('bar', 'foo')
- expect { @set.run_command(@ctx, 'foo') }.to raise_error Pry::NoCommandError
+ it "sets group for the aliased command automatically" do
+ new_command = subject.alias_command('new-test', 'test')
+ expect(new_command.group).to eq('Aliases')
end
- it 'should be able to pass in options when renaming command' do
- desc = "hello"
- listing = "bing"
- @set.command('foo') {}
- @set.rename_command(
- 'bar', 'foo', description: desc, listing: listing, keep_retval: true
- )
- expect(@set['bar'].description).to eq desc
- expect(@set['bar'].options[:listing]).to eq listing
- expect(@set['bar'].options[:keep_retval]).to eq true
+ context "when string description is provided" do
+ it "uses the given description for the aliased command" do
+ new_command = subject.alias_command('new-test', 'test', desc: 'description')
+ expect(new_command.description).to eq('description')
+ end
end
- end
- describe "before_* hook" do
- it 'should be called before the original command' do
- foo = []
- @set.command('foo') { foo << 1 }
- @set['foo'].hooks.add_hook('before_foo', 'name') { foo << 2 }
- @set.run_command(@ctx, 'foo')
-
- expect(foo).to eq [2, 1]
+ context "when non-string description is provided" do
+ it "uses the string representation of the given object" do
+ new_command = subject.alias_command('new-test', 'test', desc: Object.new)
+ expect(new_command.description).to match(/#<Object.+/)
+ end
end
- it 'should be called before the original command, using listing name' do
- foo = []
- @set.command(/^foo1/, '', listing: 'foo') { foo << 1 }
- cmd = @set.find_command_by_match_or_listing('foo')
- cmd.hooks.add_hook('before_foo', 'name') { foo << 2 }
- @set.run_command(@ctx, /^foo1/)
-
- expect(foo).to eq [2, 1]
+ context "when command doesn't match" do
+ it "raises RuntimeError" do
+ expect { subject.alias_command('nonexisting-command', 'action') }
+ .to raise_error(RuntimeError, "command: 'action' not found")
+ end
end
+ end
- it 'should share the context with the original command' do
- @ctx[:target] = "test target string".__binding__
- before_val = nil
- orig_val = nil
- @set.command('foo') { orig_val = target }
- @set['foo'].hooks.add_hook('before_foo', 'name') { before_val = target }
- @set.run_command(@ctx, 'foo')
+ describe "#rename_command" do
+ before { subject.command('test') }
- expect(before_val).to eq @ctx[:target]
- expect(orig_val).to eq @ctx[:target]
+ it "renames a comamnd" do
+ subject.rename_command('new-name', 'test')
+ expect(subject['test']).to be_nil
+ expect(subject['new-name']).not_to be_nil
end
- it 'should work when applied multiple times' do
- foo = []
- @set.command('foo') { foo << 1 }
- @set['foo'].hooks.add_hook('before_foo', 'name1') { foo << 2 }
- @set['foo'].hooks.add_hook('before_foo', 'name2') { foo << 3 }
- @set['foo'].hooks.add_hook('before_foo', 'name3') { foo << 4 }
- @set.run_command(@ctx, 'foo')
-
- expect(foo).to eq [2, 3, 4, 1]
+ it "can optionally set custom description" do
+ subject.rename_command('new-name', 'test', description: 'new description')
+ expect(subject['new-name'].description).to eq('new description')
end
- end
-
- describe "after_* hooks" do
- it 'should be called after the original command' do
- foo = []
- @set.command('foo') { foo << 1 }
- @set['foo'].hooks.add_hook('after_foo', 'name') { foo << 2 }
- @set.run_command(@ctx, 'foo')
- expect(foo).to eq [1, 2]
+ context "when provided command is not registered" do
+ it "raises ArgumentError" do
+ expect { subject.rename_command('new-name', 'unknown') }
+ .to raise_error(ArgumentError)
+ end
end
+ end
- it 'should be called after the original command, using listing name' do
- foo = []
- @set.command(/^foo1/, '', listing: 'foo') { foo << 1 }
- cmd = @set.find_command_by_match_or_listing('foo')
- cmd.hooks.add_hook('after_foo', 'name') { foo << 2 }
- @set.run_command(@ctx, /^foo1/)
+ describe "#desc" do
+ before { subject.command('test') }
- expect(foo).to eq [1, 2]
+ it "sets command description" do
+ subject.desc('test', 'test description')
+ expect(subject['test'].description).to eq('test description')
end
- it 'should share the context with the original command' do
- @ctx[:target] = "test target string".__binding__
- after_val = nil
- orig_val = nil
- @set.command('foo') { orig_val = target }
- @set['foo'].hooks.add_hook('after_foo', 'name') { after_val = target }
- @set.run_command(@ctx, 'foo')
-
- expect(after_val).to eq @ctx[:target]
- expect(orig_val).to eq @ctx[:target]
+ it "gets command description" do
+ expect(subject.desc('test')).to eq('No description.')
end
+ end
- it 'should determine the return value for the command' do
- @set.command('foo', 'bar', keep_retval: true) { 1 }
- @set['foo'].hooks.add_hook('after_foo', 'name') { 2 }
- expect(@set.run_command(@ctx, 'foo')).to eq 2
+ describe "#list_commands" do
+ before do
+ subject.command('test-one')
+ subject.command('test-two')
end
- it 'should work when applied multiple times' do
- foo = []
- @set.command('foo') { foo << 1 }
- @set['foo'].hooks.add_hook('after_foo', 'name1') { foo << 2 }
- @set['foo'].hooks.add_hook('after_foo', 'name2') { foo << 3 }
- @set['foo'].hooks.add_hook('after_foo', 'name3') { foo << 4 }
- @set.run_command(@ctx, 'foo')
-
- expect(foo).to eq [1, 2, 3, 4]
+ it "returns the list of commands" do
+ expect(subject.list_commands).to eq(%w[test-one test-two])
end
end
- describe "before_command and after_command" do
- it 'should work when combining both before_command and after_command' do
- foo = []
- @set.command('foo') { foo << 1 }
- @set['foo'].hooks.add_hook('after_foo', 'name') { foo << 2 }
- @set['foo'].hooks.add_hook('before_foo', 'name') { foo << 3 }
- @set.run_command(@ctx, 'foo')
+ describe "#to_hash" do
+ before { subject.command('test') }
- expect(foo).to eq [3, 1, 2]
+ it "converts commands to hash" do
+ expect(subject.to_hash).to include('test' => respond_to(:command_name))
end
- end
- describe 'find_command' do
- it 'should find commands with the right string' do
- cmd = @set.command('rincewind') {}
- expect(@set.find_command('rincewind')).to eq cmd
+ it "doesn't mutate original commands" do
+ hash = subject.to_hash
+ hash['foo'] = 'bar'
+ expect(subject.to_hash).not_to include('foo')
end
+ end
- it 'should not find commands with spaces before' do
- @set.command('luggage') {}
- expect(@set.find_command(' luggage')).to eq nil
- end
+ describe "#[]" do
+ context "when there's an unambiguous command" do
+ before { subject.command('test') }
- it 'should find commands with arguments after' do
- cmd = @set.command('vetinari') {}
- expect(@set.find_command('vetinari --knock 3')).to eq cmd
+ it "selects the command according to the given pattern" do
+ expect(subject['test']).to respond_to(:command_name)
+ end
end
- it 'should find commands with names containing spaces' do
- cmd = @set.command('nobby nobbs') {}
- expect(@set.find_command('nobby nobbs --steal petty-cash')).to eq cmd
- end
+ context "when there's an ambiguous command" do
+ before do
+ subject.command(/\.(.*)/)
+ subject.command(/\.*(.*)/)
+ end
- it 'should find command defined by regex' do
- cmd = @set.command(/(capt|captain) vimes/i) {}
- expect(@set.find_command('Capt Vimes')).to eq cmd
+ it "prefers a command with a higher score" do
+ expect(subject['.foo'].command_name).to eq("/\\.(.*)/")
+ expect(subject['..foo'].command_name).to eq("/\\.*(.*)/")
+ end
end
+ end
- it 'should find commands defined by regex with arguments' do
- cmd = @set.command(/(cpl|corporal) Carrot/i) {}
- expect(@set.find_command('cpl carrot --write-home')).to eq cmd
- end
+ describe "#[]=" do
+ before { subject.command('test') }
- it 'should not find commands by listing' do
- @set.command(/werewol(f|ve)s?/, 'only once a month', listing: "angua") {}
- expect(@set.find_command('angua')).to eq nil
+ it "rebinds the command with key" do
+ subject['test-1'] = subject['test']
+ expect(subject['test-1'].match).to eq('test-1')
end
- it 'should not find commands without command_prefix' do
- begin
- Pry.config.command_prefix = '%'
- @set.command('detritus') {}
- expect(@set.find_command('detritus')).to eq nil
- ensure
- Pry.config.command_prefix = ''
+ context "when given command is nil" do
+ it "deletes the command matching the pattern" do
+ subject['test'] = nil
+ expect(subject.count).to be_zero
end
end
- it "should find commands that don't use the prefix" do
- begin
- Pry.config.command_prefix = '%'
- cmd = @set.command('colon', 'Sergeant Fred', use_prefix: false) {}
- expect(@set.find_command('colon')).to eq cmd
- ensure
- Pry.config.command_prefix = ''
+ context "when given command is not a subclass of Pry::Command" do
+ it "raises TypeError" do
+ expect { subject['test'] = 1 }
+ .to raise_error(TypeError, 'command is not a subclass of Pry::Command')
end
end
+ end
- it "should find the command that has the longest match" do
- @set.command(/\.(.*)/) {}
- cmd2 = @set.command(/\.\|\|(.*)/) {}
- expect(@set.find_command('.||')).to eq cmd2
- end
-
- it "should find the command that has the longest name" do
- @set.command(/\.(.*)/) {}
- cmd2 = @set.command('.||') {}
- expect(@set.find_command('.||')).to eq cmd2
+ describe "#add_command" do
+ it "adds a command" do
+ subject.add_command(Class.new(Pry::Command))
+ expect(subject.count).to eq(1)
end
end
- describe '.valid_command?' do
- it 'should be true for commands that can be found' do
- @set.command('archchancellor')
- expect(@set.valid_command?('archchancellor of_the?(:University)')).to eq true
- end
+ describe "#find_command_for_help" do
+ before { subject.command('test') }
- it 'should be false for commands that can\'' do
- expect(@set.valid_command?('def monkey(ape)')).to eq false
+ context "when the command can be found" do
+ it "returns the command" do
+ expect(subject.find_command_for_help('test')).to respond_to(:command_name)
+ end
end
- it 'should not cause argument interpolation' do
- @set.command('hello')
- # rubocop:disable Lint/InterpolationCheck
- expect { @set.valid_command?('hello #{raise "futz"}') }.to_not raise_error
- # rubocop:enable Lint/InterpolationCheck
+ context "when the command cannot be found" do
+ it "returns nil" do
+ expect(subject.find_command_for_help('foo')).to be_nil
+ end
end
end
- describe '.process_line' do
- it 'should return Result.new(false) if there is no matching command' do
- result = @set.process_line('1 + 42')
- expect(result.command?).to eq false
- expect(result.void_command?).to eq false
- expect(result.retval).to eq nil
- end
+ describe "#valid_command?" do
+ before { subject.command('test') }
- it 'should return Result.new(true, VOID) if the command is not keep_retval' do
- @set.create_command('mrs-cake') do
- def process
- 42
- end
+ context "when command can be found" do
+ it "returns true" do
+ expect(subject.valid_command?('test')).to be_truthy
end
-
- result = @set.process_line('mrs-cake')
- expect(result.command?).to eq true
- expect(result.void_command?).to eq true
- expect(result.retval).to eq Pry::Command::VOID_VALUE
end
- it 'should return Result.new(true, retval) if the command is keep_retval' do
- @set.create_command('magrat', 'the maiden', keep_retval: true) do
- def process
- 42
- end
+ context "when command cannot be found" do
+ it "returns false" do
+ expect(subject.valid_command?('foo')).to be_falsey
end
-
- result = @set.process_line('magrat')
- expect(result.command?).to eq true
- expect(result.void_command?).to eq false
- expect(result.retval).to eq 42
end
+ end
- it 'should pass through context' do
- ctx = {
- eval_string: "bloomers",
- pry_instance: Object.new,
- output: StringIO.new,
- target: binding
- }
+ describe "#process_line" do
+ before { subject.command('test') {} }
- inside = inner_scope do |probe|
- @set.create_command('agnes') do
- define_method(:process, &probe)
- end
+ context "when the given line is a command" do
+ it "returns a command" do
+ expect(subject.process_line('test')).to be_command
+ end
- @set.process_line('agnes', ctx)
+ it "returns a non-void command" do
+ expect(subject.process_line('test')).to be_void_command
end
- expect(inside.eval_string).to eq(ctx[:eval_string])
- expect(inside.output).to eq(ctx[:output])
- expect(inside.target).to eq(ctx[:target])
- expect(inside.pry_instance).to eq(ctx[:pry_instance])
- end
+ context "and context is provided" do
+ before { subject.command('test') { output.puts('kiwi') } }
- it 'should add command_set to context' do
- inside = inner_scope do |probe|
- @set.create_command(/nann+y ogg+/) do
- define_method(:process, &probe)
+ it "passes the context to the command" do
+ output = StringIO.new
+ subject.process_line('test', output: output)
+ expect(output.string).to eq("kiwi\n")
end
+ end
+ end
- @set.process_line('nannnnnny oggggg')
+ context "when the given line is not a command" do
+ it "returns not a command" do
+ expect(subject.process_line('abcdefg')).not_to be_command
end
- expect(inside.command_set).to eq(@set)
+ it "returns a void result" do
+ expect(subject.process_line('test')).to be_void_command
+ end
end
end
+ # TODO: rewrite this block.
if defined?(Bond)
- describe '.complete' do
+ describe "#complete" do
it "should list all command names" do
- @set.create_command('susan') {}
- expect(@set.complete('sus')).to.include 'susan '
+ set.create_command('susan') {}
+ expect(set.complete('sus')).to.include 'susan '
end
it "should delegate to commands" do
- @set.create_command('susan') do
+ set.create_command('susan') do
def complete(_search)
['--foo']
end
end
- expect(@set.complete('susan ')).to eq ['--foo']
+ expect(set.complete('susan ')).to eq ['--foo']
end
end
end