pry 0.9.6.2-java → 0.9.7-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGELOG +19 -1
  3. data/CONTRIBUTORS +22 -16
  4. data/Rakefile +12 -6
  5. data/bin/pry +15 -12
  6. data/lib/pry.rb +39 -28
  7. data/lib/pry/command_context.rb +1 -0
  8. data/lib/pry/command_processor.rb +9 -2
  9. data/lib/pry/command_set.rb +7 -0
  10. data/lib/pry/config.rb +8 -0
  11. data/lib/pry/default_commands/basic.rb +7 -10
  12. data/lib/pry/default_commands/context.rb +36 -26
  13. data/lib/pry/default_commands/documentation.rb +31 -123
  14. data/lib/pry/default_commands/gems.rb +9 -4
  15. data/lib/pry/default_commands/input.rb +21 -11
  16. data/lib/pry/default_commands/introspection.rb +79 -88
  17. data/lib/pry/default_commands/ls.rb +165 -176
  18. data/lib/pry/default_commands/shell.rb +8 -8
  19. data/lib/pry/extended_commands/experimental.rb +1 -5
  20. data/lib/pry/extended_commands/user_command_api.rb +17 -5
  21. data/lib/pry/helpers.rb +1 -0
  22. data/lib/pry/helpers/base_helpers.rb +5 -1
  23. data/lib/pry/helpers/command_helpers.rb +22 -241
  24. data/lib/pry/helpers/options_helpers.rb +58 -0
  25. data/lib/pry/helpers/text.rb +10 -4
  26. data/lib/pry/history.rb +1 -1
  27. data/lib/pry/indent.rb +205 -0
  28. data/lib/pry/method.rb +412 -0
  29. data/lib/pry/pry_class.rb +56 -15
  30. data/lib/pry/pry_instance.rb +63 -16
  31. data/lib/pry/rbx_method.rb +20 -0
  32. data/lib/pry/rbx_path.rb +34 -0
  33. data/lib/pry/version.rb +1 -1
  34. data/pry.gemspec +16 -16
  35. data/test/helper.rb +8 -4
  36. data/test/test_command_helpers.rb +1 -69
  37. data/test/test_command_set.rb +29 -28
  38. data/test/test_default_commands/test_documentation.rb +23 -10
  39. data/test/test_default_commands/test_introspection.rb +58 -13
  40. data/test/test_default_commands/test_ls.rb +148 -0
  41. data/test/test_indent.rb +234 -0
  42. data/test/test_input_stack.rb +13 -0
  43. data/test/test_method.rb +291 -0
  44. data/test/test_pry.rb +10 -1
  45. metadata +88 -71
@@ -0,0 +1,234 @@
1
+ require 'helper'
2
+
3
+ # Please keep in mind that any hash signs ("#") in the heredoc strings are
4
+ # placed on purpose. Without these editors might remove the whitespace on empty
5
+ # lines.
6
+ describe Pry::Indent do
7
+ before do
8
+ @indent = Pry::Indent.new
9
+ end
10
+
11
+ it 'should indent an array' do
12
+ input = "array = [\n10,\n15\n]"
13
+ output = "array = [\n 10,\n 15\n]"
14
+
15
+ @indent.indent(input).should == output
16
+ end
17
+
18
+ it 'should indent a hash' do
19
+ input = "hash = {\n:name => 'Ruby'\n}"
20
+ output = "hash = {\n :name => 'Ruby'\n}"
21
+
22
+ @indent.indent(input).should == output
23
+ end
24
+
25
+ it 'should indent a function' do
26
+ input = "def\nreturn 10\nend"
27
+ output = "def\n return 10\nend"
28
+
29
+ @indent.indent(input).should == output
30
+ end
31
+
32
+ it 'should indent a module and class' do
33
+ input = "module Foo\n# Hello world\nend"
34
+ output = "module Foo\n # Hello world\nend"
35
+ input_class = "class Foo\n# Hello world\nend"
36
+ output_class = "class Foo\n # Hello world\nend"
37
+
38
+ @indent.indent(input).should == output
39
+ @indent.indent(input_class).should == output_class
40
+ end
41
+
42
+ it 'should indent separate lines' do
43
+ @indent.indent('def foo').should == 'def foo'
44
+ @indent.indent('return 10').should == ' return 10'
45
+ @indent.indent('end').should == 'end'
46
+ end
47
+
48
+ it 'should not indent single line statements' do
49
+ input = <<TXT.strip
50
+ def hello; end
51
+ puts "Hello"
52
+ TXT
53
+
54
+ @indent.indent(input).should == input
55
+ end
56
+
57
+ it 'should handle multiple open and closing tokens on a line' do
58
+ input = <<TXT.strip
59
+ [10, 15].each do |num|
60
+ puts num
61
+ end
62
+ TXT
63
+
64
+ output = <<TXT.strip
65
+ [10, 15].each do |num|
66
+ puts num
67
+ end
68
+ TXT
69
+
70
+ @indent.indent(input).should == output
71
+ end
72
+
73
+ it 'should properly indent nested code' do
74
+ input = <<TXT.strip
75
+ module A
76
+ module B
77
+ class C
78
+ attr_accessor :test
79
+ # keep
80
+ def number
81
+ return 10
82
+ end
83
+ end
84
+ end
85
+ end
86
+ TXT
87
+
88
+ output = <<TXT.strip
89
+ module A
90
+ module B
91
+ class C
92
+ attr_accessor :test
93
+ # keep
94
+ def number
95
+ return 10
96
+ end
97
+ end
98
+ end
99
+ end
100
+ TXT
101
+
102
+ @indent.indent(input).should == output
103
+ end
104
+
105
+ it 'should indent statements such as if, else, etc' do
106
+ input = <<TXT.strip
107
+ if a == 10
108
+ #
109
+ elsif a == 15
110
+ #
111
+ else
112
+ #
113
+ end
114
+ #
115
+ while true
116
+ #
117
+ end
118
+ #
119
+ for num in [10, 15, 20]
120
+ #
121
+ end
122
+ #
123
+ for num in [10, 15, 20] do
124
+ #
125
+ end
126
+ TXT
127
+
128
+ output = <<TXT.strip
129
+ if a == 10
130
+ #
131
+ elsif a == 15
132
+ #
133
+ else
134
+ #
135
+ end
136
+ #
137
+ while true
138
+ #
139
+ end
140
+ #
141
+ for num in [10, 15, 20]
142
+ #
143
+ end
144
+ #
145
+ for num in [10, 15, 20] do
146
+ #
147
+ end
148
+ TXT
149
+
150
+ @indent.indent(input).should == output
151
+ end
152
+
153
+ it "should ident case statements" do
154
+ input = <<TXT.strip
155
+ case foo
156
+ when 1
157
+ 2
158
+ when 2
159
+ if 3
160
+ 4
161
+ end
162
+ when 5
163
+ #
164
+ else
165
+ #
166
+ end
167
+ TXT
168
+
169
+ output = <<TXT.strip
170
+ case foo
171
+ when 1
172
+ 2
173
+ when 2
174
+ if 3
175
+ 4
176
+ end
177
+ when 5
178
+ #
179
+ else
180
+ #
181
+ end
182
+ TXT
183
+
184
+ @indent.indent(input).should == output
185
+ end
186
+
187
+ it "should indent correctly with nesting" do
188
+ @indent.indent("[[\n[]]\n]").should == "[[\n []]\n]"
189
+ @indent.reset.indent("[[\n[]]\n]").should == "[[\n []]\n]"
190
+ @indent.reset.indent("[[{\n[] =>\n[]}]\n]").should == "[[{\n [] =>\n []}]\n]"
191
+ end
192
+
193
+ it "should not indent single-line ifs" do
194
+ @indent.indent("foo if bar\n#").should == "foo if bar\n#"
195
+ @indent.reset.indent("foo() if bar\n#").should == "foo() if bar\n#"
196
+ @indent.reset.indent("foo 'hi' if bar\n#").should == "foo 'hi' if bar\n#"
197
+ @indent.reset.indent("foo 1 while bar\n#").should == "foo 1 while bar\n#"
198
+ end
199
+
200
+ it "should indent cunningly disguised ifs" do
201
+ @indent.indent("{1 => if bar\n#").should == "{1 => if bar\n #"
202
+ @indent.reset.indent("foo(if bar\n#").should == "foo(if bar\n #"
203
+ @indent.reset.indent("bar(baz, if bar\n#").should == "bar(baz, if bar\n #"
204
+ @indent.reset.indent("[if bar\n#").should == "[if bar\n #"
205
+ @indent.reset.indent("true; while bar\n#").should == "true; while bar\n #"
206
+ end
207
+
208
+ it "should differentiate single/multi-line unless" do
209
+ @indent.indent("foo unless bar\nunless foo\nbar\nend").should == "foo unless bar\nunless foo\n bar\nend"
210
+ end
211
+
212
+ it "should not indent single/multi-line until" do
213
+ @indent.indent("%w{baz} until bar\nuntil foo\nbar\nend").should == "%w{baz} until bar\nuntil foo\n bar\nend"
214
+ end
215
+
216
+ it "should indent begin rescue end" do
217
+ input = <<INPUT.strip
218
+ begin
219
+ doo :something => :wrong
220
+ rescue => e
221
+ doit :right
222
+ end
223
+ INPUT
224
+ output = <<OUTPUT.strip
225
+ begin
226
+ doo :something => :wrong
227
+ rescue => e
228
+ doit :right
229
+ end
230
+ OUTPUT
231
+
232
+ @indent.indent(input).should == output
233
+ end
234
+ end
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'helper'
2
3
 
3
4
  describe "Pry#input_stack" do
@@ -67,4 +68,16 @@ describe "Pry#input_stack" do
67
68
  str_output.string.should =~ /Error: Pry ran out of things to read/
68
69
  end
69
70
 
71
+ if "".respond_to?(:encoding)
72
+ it "should pass strings to Pry in the right encoding" do
73
+ input1 = "'f。。'.encoding.name" # utf-8, see coding declaration
74
+ input2 = input1.encode('Shift_JIS')
75
+
76
+ mock_pry(input1, input2).should == %{=> "UTF-8"\n=> "Shift_JIS"\n\n}
77
+ end
78
+
79
+ it "should be able to use unicode regexes on a UTF-8 terminal" do
80
+ mock_pry('":-Þ" =~ /\p{Upper}/').should == %{=> 2\n\n}
81
+ end
82
+ end
70
83
  end
@@ -0,0 +1,291 @@
1
+ require 'helper'
2
+
3
+ describe Pry::Method do
4
+ it "should use String names for compatibility" do
5
+ klass = Class.new { def hello; end }
6
+ Pry::Method.new(klass.instance_method(:hello)).name.should == "hello"
7
+ end
8
+
9
+ describe ".from_str" do
10
+ it 'should look up instance methods if no methods available and no options provided' do
11
+ klass = Class.new { def hello; end }
12
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
13
+ meth.should == klass.instance_method(:hello)
14
+ end
15
+
16
+ it 'should look up methods if no instance methods available and no options provided' do
17
+ klass = Class.new { def self.hello; end }
18
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
19
+ meth.should == klass.method(:hello)
20
+ end
21
+
22
+ it 'should look up instance methods first even if methods available and no options provided' do
23
+ klass = Class.new { def hello; end; def self.hello; end }
24
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
25
+ meth.should == klass.instance_method(:hello)
26
+ end
27
+
28
+ it 'should look up instance methods if "instance-methods" option provided' do
29
+ klass = Class.new { def hello; end; def self.hello; end }
30
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {"instance-methods" => true})
31
+ meth.should == klass.instance_method(:hello)
32
+ end
33
+
34
+ it 'should look up methods if :methods option provided' do
35
+ klass = Class.new { def hello; end; def self.hello; end }
36
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {:methods => true})
37
+ meth.should == klass.method(:hello)
38
+ end
39
+
40
+ it 'should look up instance methods using the Class#method syntax' do
41
+ klass = Class.new { def hello; end; def self.hello; end }
42
+ meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding))
43
+ meth.should == klass.instance_method(:hello)
44
+ end
45
+
46
+ it 'should look up methods using the object.method syntax' do
47
+ klass = Class.new { def hello; end; def self.hello; end }
48
+ meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding))
49
+ meth.should == klass.method(:hello)
50
+ end
51
+
52
+ it 'should NOT look up instance methods using the Class#method syntax if no instance methods defined' do
53
+ klass = Class.new { def self.hello; end }
54
+ meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding))
55
+ meth.should == nil
56
+ end
57
+
58
+ it 'should NOT look up methods using the object.method syntax if no methods defined' do
59
+ klass = Class.new { def hello; end }
60
+ meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding))
61
+ meth.should == nil
62
+ end
63
+
64
+ it 'should look up methods using klass.new.method syntax' do
65
+ klass = Class.new { def hello; :hello; end }
66
+ meth = Pry::Method.from_str("klass.new.hello", Pry.binding_for(binding))
67
+ meth.name.should == "hello"
68
+ end
69
+
70
+ it 'should look up instance methods using klass.meth#method syntax' do
71
+ klass = Class.new { def self.meth; Class.new; end }
72
+ meth = Pry::Method.from_str("klass.meth#initialize", Pry.binding_for(binding))
73
+ meth.name.should == "initialize"
74
+ end
75
+ end
76
+
77
+ describe 'all_from_class' do
78
+ def should_find_method(name)
79
+ Pry::Method.all_from_class(@class).map(&:name).should.include(name)
80
+ end
81
+
82
+ it 'should be able to find public instance methods defined in a class' do
83
+ @class = Class.new{ def meth; 1; end }
84
+ should_find_method('meth')
85
+ end
86
+
87
+ it 'should be able to find private and protected instance methods defined in a class' do
88
+ @class = Class.new { protected; def prot; 1; end; private; def priv; 1; end }
89
+ should_find_method('priv')
90
+ should_find_method('prot')
91
+ end
92
+
93
+ it 'should find methods all the way up to Kernel' do
94
+ @class = Class.new
95
+ should_find_method('exit!')
96
+ end
97
+
98
+ it 'should be able to find instance methods defined in a super-class' do
99
+ @class = Class.new(Class.new{ def meth; 1; end }) {}
100
+ should_find_method('meth')
101
+ end
102
+
103
+ it 'should be able to find instance methods defined in modules included into this class' do
104
+ @class = Class.new{ include Module.new{ def meth; 1; end; } }
105
+ should_find_method('meth')
106
+ end
107
+
108
+ it 'should be able to find instance methods defined in modules included into super-classes' do
109
+ @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } })
110
+ should_find_method('meth')
111
+ end
112
+
113
+ it 'should attribute overridden methods to the sub-class' do
114
+ @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } }) { def meth; 2; end }
115
+ Pry::Method.all_from_class(@class).detect{ |x| x.name == 'meth' }.owner.should == @class
116
+ end
117
+
118
+ it 'should be able to find methods defined on a singleton class' do
119
+ @class = (class << Object.new; def meth; 1; end; self; end)
120
+ should_find_method('meth')
121
+ end
122
+
123
+ it 'should be able to find methods on super-classes when given a singleton class' do
124
+ @class = (class << Class.new{ def meth; 1; end}.new; self; end)
125
+ should_find_method('meth')
126
+ end
127
+ end
128
+
129
+ describe 'all_from_obj' do
130
+ describe 'on normal objects' do
131
+ def should_find_method(name)
132
+ Pry::Method.all_from_obj(@obj).map(&:name).should.include(name)
133
+ end
134
+
135
+ it "should find methods defined in the object's class" do
136
+ @obj = Class.new{ def meth; 1; end }.new
137
+ should_find_method('meth')
138
+ end
139
+
140
+ it "should find methods defined in modules included into the object's class" do
141
+ @obj = Class.new{ include Module.new{ def meth; 1; end } }.new
142
+ should_find_method('meth')
143
+ end
144
+
145
+ it "should find methods defined in the object's singleton class" do
146
+ @obj = Object.new
147
+ class << @obj; def meth; 1; end; end
148
+ should_find_method('meth')
149
+ end
150
+
151
+ it "should find methods in modules included into the object's singleton class" do
152
+ @obj = Object.new
153
+ @obj.extend Module.new{ def meth; 1; end }
154
+ should_find_method('meth')
155
+ end
156
+
157
+ it "should find methods all the way up to Kernel" do
158
+ @obj = Object.new
159
+ should_find_method('exit!')
160
+ end
161
+
162
+ it "should not find methods defined on the classes singleton class" do
163
+ @obj = Class.new{ class << self; def meth; 1; end; end }.new
164
+ Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth')
165
+ end
166
+
167
+ it "should work in the face of an overridden send" do
168
+ @obj = Class.new{ def meth; 1; end; def send; raise EOFError; end }.new
169
+ should_find_method('meth')
170
+ end
171
+ end
172
+
173
+ describe 'on classes' do
174
+ def should_find_method(name)
175
+ Pry::Method.all_from_obj(@class).map(&:name).should.include(name)
176
+ end
177
+
178
+ it "should find methods defined in the class' singleton class" do
179
+ @class = Class.new{ class << self; def meth; 1; end; end }
180
+ should_find_method('meth')
181
+ end
182
+
183
+ it "should find methods defined on modules extended into the class" do
184
+ @class = Class.new{ extend Module.new{ def meth; 1; end; } }
185
+ should_find_method('meth')
186
+ end
187
+
188
+ it "should find methods defined on the singleton class of super-classes" do
189
+ @class = Class.new(Class.new{ class << self; def meth; 1; end; end })
190
+ should_find_method('meth')
191
+ end
192
+
193
+ it "should not find methods defined within the class" do
194
+ @class = Class.new{ def meth; 1; end }
195
+ Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth')
196
+ end
197
+
198
+ it "should find methods defined on Class" do
199
+ @class = Class.new
200
+ should_find_method('allocate')
201
+ end
202
+
203
+ it "should find methods defined on Kernel" do
204
+ @class = Class.new
205
+ should_find_method('exit!')
206
+ end
207
+
208
+ it "should attribute overridden methods to the sub-class' singleton class" do
209
+ @class = Class.new(Class.new{ class << self; def meth; 1; end; end }) { class << self; def meth; 1; end; end }
210
+ Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end)
211
+ end
212
+
213
+ it "should attrbute overridden methods to the class not the module" do
214
+ @class = Class.new { class << self; def meth; 1; end; end; extend Module.new{ def meth; 1; end; } }
215
+ Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end)
216
+ end
217
+
218
+ it "should attribute overridden methods to the relevant singleton class in preference to Class" do
219
+ @class = Class.new { class << self; def allocate; 1; end; end }
220
+ Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'allocate' }.owner.should == (class << @class; self; end)
221
+ end
222
+ end
223
+
224
+ describe 'method resolution order' do
225
+ module LS
226
+ class Top; end
227
+
228
+ class Next < Top; end
229
+
230
+ module M; end
231
+ module N; include M; end
232
+ module O; include M; end
233
+ module P; end
234
+
235
+ class Low < Next; include N; include P; end
236
+ class Lower < Low; extend N; end
237
+ class Bottom < Lower; extend O; end
238
+ end
239
+
240
+ def singleton_class(obj); class << obj; self; end; end
241
+
242
+ it "should look at a class and then its superclass" do
243
+ Pry::Method.instance_resolution_order(LS::Next).should == [LS::Next] + Pry::Method.instance_resolution_order(LS::Top)
244
+ end
245
+
246
+ it "should include the included modules between a class and its superclass" do
247
+ Pry::Method.instance_resolution_order(LS::Low).should == [LS::Low, LS::P, LS::N, LS::M] + Pry::Method.instance_resolution_order(LS::Next)
248
+ end
249
+
250
+ it "should not include modules extended into the class" do
251
+ Pry::Method.instance_resolution_order(LS::Bottom).should == [LS::Bottom] + Pry::Method.instance_resolution_order(LS::Lower)
252
+ end
253
+
254
+ it "should include included modules for Modules" do
255
+ Pry::Method.instance_resolution_order(LS::O).should == [LS::O, LS::M]
256
+ end
257
+
258
+ it "should include the singleton class of objects" do
259
+ obj = LS::Low.new
260
+ Pry::Method.resolution_order(obj).should == [singleton_class(obj)] + Pry::Method.instance_resolution_order(LS::Low)
261
+ end
262
+
263
+ it "should not include singleton classes of numbers" do
264
+ Pry::Method.resolution_order(4).should == Pry::Method.instance_resolution_order(Fixnum)
265
+ end
266
+
267
+ it "should include singleton classes for classes" do
268
+ Pry::Method.resolution_order(LS::Low).should == [singleton_class(LS::Low)] + Pry::Method.resolution_order(LS::Next)
269
+ end
270
+
271
+ it "should include modules included into singleton classes" do
272
+ Pry::Method.resolution_order(LS::Lower).should == [singleton_class(LS::Lower), LS::N, LS::M] + Pry::Method.resolution_order(LS::Low)
273
+ end
274
+
275
+ it "should include modules at most once" do
276
+ Pry::Method.resolution_order(LS::Bottom).count(LS::M).should == 1
277
+ end
278
+
279
+ it "should include modules at the point which they would be reached" do
280
+ Pry::Method.resolution_order(LS::Bottom).should == [singleton_class(LS::Bottom), LS::O] + (Pry::Method.resolution_order(LS::Lower))
281
+ end
282
+
283
+ it "should include the Pry::Method.instance_resolution_order of Class after the singleton classes" do
284
+ Pry::Method.resolution_order(LS::Top).should ==
285
+ [singleton_class(LS::Top), singleton_class(Object), (defined? BasicObject) && singleton_class(BasicObject)].compact +
286
+ Pry::Method.instance_resolution_order(Class)
287
+ end
288
+ end
289
+ end
290
+ end
291
+