2014-03-14 05:31:24 +01:00
|
|
|
require_relative 'helper'
|
2014-03-31 03:14:59 +02:00
|
|
|
require "readline" unless defined?(Readline)
|
|
|
|
require "pry/input_completer"
|
2011-08-16 21:53:20 -07:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
def completer_test(bind, pry=nil, assert_flag=true)
|
2012-12-28 15:19:21 -08:00
|
|
|
test = proc {|symbol|
|
2018-10-13 03:09:29 +08:00
|
|
|
expect(Pry::InputCompleter.new(pry || Readline, pry).call(symbol[0..-2], target: Pry.binding_for(bind)).include?(symbol)).to eq(assert_flag)}
|
2012-08-12 00:38:32 -04:00
|
|
|
return proc {|*symbols| symbols.each(&test) }
|
|
|
|
end
|
2014-03-31 03:14:59 +02:00
|
|
|
|
2011-08-16 21:53:20 -07:00
|
|
|
describe Pry::InputCompleter do
|
|
|
|
before do
|
|
|
|
# The AMQP gem has some classes like this:
|
|
|
|
# pry(main)> AMQP::Protocol::Test::ContentOk.name
|
|
|
|
# => :content_ok
|
|
|
|
module SymbolyName
|
|
|
|
def self.name; :symboly_name; end
|
|
|
|
end
|
2012-08-18 22:49:20 +00:00
|
|
|
|
2014-04-01 05:55:21 +02:00
|
|
|
@before_completer = Pry.config.completer
|
2012-08-18 22:49:20 +00:00
|
|
|
Pry.config.completer = Pry::InputCompleter
|
2011-08-16 21:53:20 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
2014-04-01 05:55:21 +02:00
|
|
|
Pry.config.completer = @before_completer
|
2011-08-16 21:53:20 -07:00
|
|
|
Object.remove_const :SymbolyName
|
|
|
|
end
|
|
|
|
|
2018-11-02 00:16:35 +08:00
|
|
|
it "should not crash if there's a Module that has a symbolic name." do
|
|
|
|
skip unless Pry::Helpers::Platform.jruby?
|
|
|
|
expect { Pry::InputCompleter.new(Readline).call "a.to_s.", target: Pry.binding_for(Object.new) }.not_to raise_error
|
2011-08-16 21:53:20 -07:00
|
|
|
end
|
2012-06-19 12:32:03 +02:00
|
|
|
|
2012-06-19 11:40:58 +02:00
|
|
|
it 'should take parenthesis and other characters into account for symbols' do
|
2018-10-13 03:09:29 +08:00
|
|
|
expect { Pry::InputCompleter.new(Readline).call ":class)", target: Pry.binding_for(Object.new) }.not_to raise_error
|
2012-06-19 11:40:58 +02:00
|
|
|
end
|
2012-06-19 15:47:52 +02:00
|
|
|
|
2012-06-19 12:32:03 +02:00
|
|
|
it 'should complete instance variables' do
|
2012-09-05 22:56:45 -07:00
|
|
|
object = Class.new.new
|
2012-06-19 12:32:03 +02:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
# set variables in appropriate scope
|
2012-06-19 12:32:03 +02:00
|
|
|
object.instance_variable_set(:'@name', 'Pry')
|
2012-06-19 13:09:55 +02:00
|
|
|
object.class.send(:class_variable_set, :'@@number', 10)
|
2012-06-19 12:32:03 +02:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
# check to see if variables are in scope
|
2015-03-10 22:49:29 +02:00
|
|
|
expect(object.instance_variables.
|
2012-08-12 00:38:32 -04:00
|
|
|
map { |v| v.to_sym }.
|
2015-03-10 22:49:29 +02:00
|
|
|
include?(:'@name')).to eq true
|
2012-08-09 19:32:23 -07:00
|
|
|
|
2015-03-10 22:49:29 +02:00
|
|
|
expect(object.class.class_variables.
|
2012-08-12 00:38:32 -04:00
|
|
|
map { |v| v.to_sym }.
|
2015-03-10 22:49:29 +02:00
|
|
|
include?(:'@@number')).to eq true
|
2012-06-19 12:32:03 +02:00
|
|
|
|
|
|
|
# Complete instance variables.
|
2012-08-12 00:38:32 -04:00
|
|
|
b = Pry.binding_for(object)
|
|
|
|
completer_test(b).call('@name', '@name.downcase')
|
2012-06-19 12:32:03 +02:00
|
|
|
|
|
|
|
# Complete class variables.
|
2012-08-12 00:38:32 -04:00
|
|
|
b = Pry.binding_for(object.class)
|
|
|
|
completer_test(b).call('@@number', '@@number.class')
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should complete for stdlib symbols' do
|
|
|
|
|
|
|
|
o = Object.new
|
|
|
|
# Regexp
|
|
|
|
completer_test(o).call('/foo/.extend')
|
|
|
|
|
|
|
|
# Array
|
|
|
|
completer_test(o).call('[1].push')
|
2013-01-14 13:36:57 +01:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
# Hash
|
|
|
|
completer_test(o).call('{"a" => "b"}.keys')
|
2013-01-14 13:36:57 +01:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
# Proc
|
|
|
|
completer_test(o).call('{2}.call')
|
|
|
|
|
|
|
|
# Symbol
|
|
|
|
completer_test(o).call(':symbol.to_s')
|
|
|
|
|
|
|
|
# Absolute Constant
|
|
|
|
completer_test(o).call('::IndexError')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should complete for target symbols' do
|
|
|
|
o = Object.new
|
|
|
|
|
|
|
|
# Constant
|
|
|
|
module Mod
|
2015-01-22 22:52:20 +01:00
|
|
|
remove_const :Con if defined? Con
|
2012-08-12 00:38:32 -04:00
|
|
|
Con = 'Constant'
|
|
|
|
module Mod2
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
completer_test(Mod).call('Con')
|
|
|
|
|
|
|
|
# Constants or Class Methods
|
|
|
|
completer_test(o).call('Mod::Con')
|
|
|
|
|
|
|
|
# Symbol
|
2015-01-22 22:52:20 +01:00
|
|
|
_foo = :symbol
|
2012-08-12 00:38:32 -04:00
|
|
|
completer_test(o).call(':symbol')
|
2012-06-19 12:32:03 +02:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
# Variables
|
|
|
|
class << o
|
|
|
|
attr_accessor :foo
|
|
|
|
end
|
|
|
|
o.foo = 'bar'
|
|
|
|
completer_test(binding).call('o.foo')
|
|
|
|
|
|
|
|
# trailing slash
|
2018-10-13 03:09:29 +08:00
|
|
|
expect(Pry::InputCompleter.new(Readline).call('Mod2/', target: Pry.binding_for(Mod)).include?('Mod2/')).to eq(true)
|
2012-06-19 12:32:03 +02:00
|
|
|
end
|
2012-08-12 00:38:32 -04:00
|
|
|
|
|
|
|
it 'should complete for arbitrary scopes' do
|
|
|
|
module Bar
|
|
|
|
@barvar = :bar
|
|
|
|
end
|
|
|
|
|
|
|
|
module Baz
|
2015-01-22 22:52:20 +01:00
|
|
|
remove_const :Con if defined? Con
|
2012-08-12 00:38:32 -04:00
|
|
|
@bar = Bar
|
|
|
|
@bazvar = :baz
|
|
|
|
Con = :constant
|
|
|
|
end
|
|
|
|
|
2018-10-13 03:09:29 +08:00
|
|
|
pry = Pry.new(target: Baz)
|
2012-12-18 00:10:00 -08:00
|
|
|
pry.push_binding(Bar)
|
2012-08-12 00:38:32 -04:00
|
|
|
|
|
|
|
b = Pry.binding_for(Bar)
|
|
|
|
completer_test(b, pry).call("../@bazvar")
|
|
|
|
completer_test(b, pry).call('/Con')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should complete for stdlib symbols' do
|
|
|
|
|
|
|
|
o = Object.new
|
|
|
|
# Regexp
|
|
|
|
completer_test(o).call('/foo/.extend')
|
|
|
|
|
|
|
|
# Array
|
|
|
|
completer_test(o).call('[1].push')
|
2013-01-14 13:36:57 +01:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
# Hash
|
|
|
|
completer_test(o).call('{"a" => "b"}.keys')
|
2013-01-14 13:36:57 +01:00
|
|
|
|
2012-08-12 00:38:32 -04:00
|
|
|
# Proc
|
|
|
|
completer_test(o).call('{2}.call')
|
|
|
|
|
|
|
|
# Symbol
|
|
|
|
completer_test(o).call(':symbol.to_s')
|
|
|
|
|
|
|
|
# Absolute Constant
|
|
|
|
completer_test(o).call('::IndexError')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should complete for target symbols' do
|
|
|
|
o = Object.new
|
|
|
|
|
|
|
|
# Constant
|
|
|
|
module Mod
|
2015-01-22 22:52:20 +01:00
|
|
|
remove_const :Con if defined? Con
|
2012-08-12 00:38:32 -04:00
|
|
|
Con = 'Constant'
|
|
|
|
module Mod2
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
completer_test(Mod).call('Con')
|
|
|
|
|
|
|
|
# Constants or Class Methods
|
|
|
|
completer_test(o).call('Mod::Con')
|
|
|
|
|
|
|
|
# Symbol
|
2015-01-22 22:52:20 +01:00
|
|
|
_foo = :symbol
|
2012-08-12 00:38:32 -04:00
|
|
|
completer_test(o).call(':symbol')
|
|
|
|
|
|
|
|
# Variables
|
|
|
|
class << o
|
|
|
|
attr_accessor :foo
|
|
|
|
end
|
|
|
|
o.foo = 'bar'
|
|
|
|
completer_test(binding).call('o.foo')
|
|
|
|
|
|
|
|
# trailing slash
|
2018-10-13 03:09:29 +08:00
|
|
|
expect(Pry::InputCompleter.new(Readline).call('Mod2/', target: Pry.binding_for(Mod)).include?('Mod2/')).to eq(true)
|
2012-08-12 00:38:32 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'should complete for arbitrary scopes' do
|
|
|
|
module Bar
|
|
|
|
@barvar = :bar
|
|
|
|
end
|
|
|
|
|
|
|
|
module Baz
|
2015-01-22 22:52:20 +01:00
|
|
|
remove_const :Con if defined? Con
|
2012-08-12 00:38:32 -04:00
|
|
|
@bar = Bar
|
|
|
|
@bazvar = :baz
|
|
|
|
Con = :constant
|
|
|
|
end
|
|
|
|
|
2018-10-13 03:09:29 +08:00
|
|
|
pry = Pry.new(target: Baz)
|
2012-12-18 00:10:00 -08:00
|
|
|
pry.push_binding(Bar)
|
2012-08-12 00:38:32 -04:00
|
|
|
|
|
|
|
b = Pry.binding_for(Bar)
|
|
|
|
completer_test(b, pry).call("../@bazvar")
|
|
|
|
completer_test(b, pry).call('/Con')
|
|
|
|
end
|
|
|
|
|
2013-01-14 13:36:57 +01:00
|
|
|
it 'should not return nil in its output' do
|
|
|
|
pry = Pry.new
|
2018-10-13 03:09:29 +08:00
|
|
|
expect(Pry::InputCompleter.new(Readline, pry).call("pry.", target: binding)).not_to include nil
|
2013-01-14 13:36:57 +01:00
|
|
|
end
|
2016-12-12 02:02:48 +02:00
|
|
|
|
|
|
|
it 'completes expressions with all available methods' do
|
|
|
|
completer_test(self).call("[].size.chars")
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not offer methods from blacklisted modules' do
|
|
|
|
require 'irb'
|
2016-12-12 03:53:06 +02:00
|
|
|
completer_test(self, nil, false).call("[].size.parse_printf_format")
|
2016-12-12 02:02:48 +02:00
|
|
|
end
|
2016-12-12 13:54:55 +02:00
|
|
|
|
2018-11-02 00:16:35 +08:00
|
|
|
unless Pry::Helpers::Platform.jruby?
|
2016-12-13 23:46:28 +02:00
|
|
|
# Classes that override .hash are still hashable in JRuby, for some reason.
|
|
|
|
it 'ignores methods from modules that override Object#hash incompatibly' do
|
2018-11-02 00:16:35 +08:00
|
|
|
# skip unless Pry::Helpers::Platform.jruby?
|
|
|
|
|
|
|
|
m = Module.new do
|
2016-12-13 23:46:28 +02:00
|
|
|
def self.hash(a, b)
|
|
|
|
end
|
|
|
|
|
|
|
|
def aaaa
|
|
|
|
end
|
2016-12-12 13:54:55 +02:00
|
|
|
end
|
|
|
|
|
2018-11-02 00:16:35 +08:00
|
|
|
completer_test(m, nil, false).call("[].size.aaaa")
|
2016-12-12 13:54:55 +02:00
|
|
|
end
|
|
|
|
end
|
2011-08-16 21:53:20 -07:00
|
|
|
end
|