pry 0.9.6.2 → 0.9.7

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 +82 -65
@@ -3,6 +3,7 @@ require 'helper'
3
3
  describe Pry::CommandSet do
4
4
  before do
5
5
  @set = Pry::CommandSet.new
6
+ @ctx = Pry::CommandContext.new
6
7
  end
7
8
 
8
9
  it 'should call the block used for the command when it is called' do
@@ -11,7 +12,7 @@ describe Pry::CommandSet do
11
12
  run = true
12
13
  end
13
14
 
14
- @set.run_command nil, 'foo'
15
+ @set.run_command @ctx, 'foo'
15
16
  run.should == true
16
17
  end
17
18
 
@@ -20,21 +21,23 @@ describe Pry::CommandSet do
20
21
  args.should == [1, 2, 3]
21
22
  end
22
23
 
23
- @set.run_command nil, 'foo', 1, 2, 3
24
+ @set.run_command @ctx, 'foo', 1, 2, 3
24
25
  end
25
26
 
26
27
  it 'should use the first argument as self' do
28
+ ctx = @ctx
29
+
27
30
  @set.command 'foo' do
28
- self.should == true
31
+ self.should == ctx
29
32
  end
30
33
 
31
- @set.run_command true, 'foo'
34
+ @set.run_command @ctx, 'foo'
32
35
  end
33
36
 
34
37
  it 'should raise an error when calling an undefined command' do
35
38
  @set.command('foo') {}
36
39
  lambda {
37
- @set.run_command nil, 'bar'
40
+ @set.run_command @ctx, 'bar'
38
41
  }.should.raise(Pry::NoCommandError)
39
42
  end
40
43
 
@@ -43,7 +46,7 @@ describe Pry::CommandSet do
43
46
  @set.delete 'foo'
44
47
 
45
48
  lambda {
46
- @set.run_command nil, 'foo'
49
+ @set.run_command @ctx, 'foo'
47
50
  }.should.raise(Pry::NoCommandError)
48
51
  end
49
52
 
@@ -57,11 +60,11 @@ describe Pry::CommandSet do
57
60
 
58
61
  @set.import_from(other_set, 'foo')
59
62
 
60
- @set.run_command nil, 'foo'
63
+ @set.run_command @ctx, 'foo'
61
64
  run.should == true
62
65
 
63
66
  lambda {
64
- @set.run_command nil, 'bar'
67
+ @set.run_command @ctx, 'bar'
65
68
  }.should.raise(Pry::NoCommandError)
66
69
  end
67
70
 
@@ -75,8 +78,8 @@ describe Pry::CommandSet do
75
78
 
76
79
  @set.import other_set
77
80
 
78
- @set.run_command nil, 'foo'
79
- @set.run_command nil, 'bar'
81
+ @set.run_command @ctx, 'foo'
82
+ @set.run_command @ctx, 'bar'
80
83
  run.should == [true, true]
81
84
  end
82
85
 
@@ -84,7 +87,7 @@ describe Pry::CommandSet do
84
87
  run = false
85
88
  @set.command('foo') { run = true }
86
89
 
87
- Pry::CommandSet.new(@set).run_command nil, 'foo'
90
+ Pry::CommandSet.new(@set).run_command @ctx, 'foo'
88
91
  run.should == true
89
92
  end
90
93
 
@@ -101,7 +104,7 @@ describe Pry::CommandSet do
101
104
  @set.commands['bar'].name.should == 'bar'
102
105
  @set.commands['bar'].description.should == ''
103
106
 
104
- @set.run_command nil, 'bar'
107
+ @set.run_command @ctx, 'bar'
105
108
  run.should == true
106
109
  end
107
110
 
@@ -114,17 +117,17 @@ describe Pry::CommandSet do
114
117
 
115
118
  it 'should return Pry::CommandContext::VOID_VALUE for commands by default' do
116
119
  @set.command('foo') { 3 }
117
- @set.run_command(nil, 'foo').should == Pry::CommandContext::VOID_VALUE
120
+ @set.run_command(@ctx, 'foo').should == Pry::CommandContext::VOID_VALUE
118
121
  end
119
122
 
120
123
  it 'should be able to keep return values' do
121
124
  @set.command('foo', '', :keep_retval => true) { 3 }
122
- @set.run_command(nil, 'foo').should == 3
125
+ @set.run_command(@ctx, 'foo').should == 3
123
126
  end
124
127
 
125
128
  it 'should be able to keep return values, even if return value is nil' do
126
129
  @set.command('foo', '', :keep_retval => true) { nil }
127
- @set.run_command(nil, 'foo').should == nil
130
+ @set.run_command(@ctx, 'foo').should == nil
128
131
  end
129
132
 
130
133
  it 'should be able to have its own helpers' do
@@ -136,7 +139,7 @@ describe Pry::CommandSet do
136
139
  def my_helper; end
137
140
  end
138
141
 
139
- @set.run_command(Pry::CommandContext.new, 'foo')
142
+ @set.run_command(@ctx, 'foo')
140
143
  Pry::CommandContext.new.should.not.respond_to :my_helper
141
144
  end
142
145
 
@@ -154,7 +157,7 @@ describe Pry::CommandSet do
154
157
  def my_other_helper; end
155
158
  end
156
159
 
157
- @set.run_command(Pry::CommandContext.new, 'foo')
160
+ @set.run_command(@ctx, 'foo')
158
161
  end
159
162
 
160
163
  it 'should import helpers from imported sets' do
@@ -166,7 +169,7 @@ describe Pry::CommandSet do
166
169
 
167
170
  @set.import imported_set
168
171
  @set.command('foo') { should.respond_to :imported_helper_method }
169
- @set.run_command(Pry::CommandContext.new, 'foo')
172
+ @set.run_command(@ctx, 'foo')
170
173
  end
171
174
 
172
175
  it 'should import helpers even if only some commands are imported' do
@@ -180,7 +183,7 @@ describe Pry::CommandSet do
180
183
 
181
184
  @set.import_from imported_set, 'bar'
182
185
  @set.command('foo') { should.respond_to :imported_helper_method }
183
- @set.run_command(Pry::CommandContext.new, 'foo')
186
+ @set.run_command(@ctx, 'foo')
184
187
  end
185
188
 
186
189
  it 'should provide a :listing for a command that defaults to its name' do
@@ -194,12 +197,11 @@ describe Pry::CommandSet do
194
197
  end
195
198
 
196
199
  it "should provide a 'help' command" do
197
- context = Pry::CommandContext.new
198
- context.command_set = @set
199
- context.output = StringIO.new
200
+ @ctx.command_set = @set
201
+ @ctx.output = StringIO.new
200
202
 
201
203
  lambda {
202
- @set.run_command(context, 'help')
204
+ @set.run_command(@ctx, 'help')
203
205
  }.should.not.raise
204
206
  end
205
207
 
@@ -209,13 +211,12 @@ describe Pry::CommandSet do
209
211
  @set.command 'moo', "Mooerizes" do; end
210
212
  @set.command 'boo', "Booerizes" do; end
211
213
 
212
- context = Pry::CommandContext.new
213
- context.command_set = @set
214
- context.output = StringIO.new
214
+ @ctx.command_set = @set
215
+ @ctx.output = StringIO.new
215
216
 
216
- @set.run_command(context, 'help')
217
+ @set.run_command(@ctx, 'help')
217
218
 
218
- doc = context.output.string
219
+ doc = @ctx.output.string
219
220
 
220
221
  order = [doc.index("boo"),
221
222
  doc.index("foo"),
@@ -10,16 +10,6 @@ describe "Pry::DefaultCommands::Documentation" do
10
10
 
11
11
  str_output.string.should =~ /sample doc/
12
12
  end
13
-
14
- it 'should output multiple methods\' documentation' do
15
- str_output = StringIO.new
16
- redirect_pry_io(InputTester.new("show-doc sample_method another_sample_method", "exit-all"), str_output) do
17
- pry
18
- end
19
-
20
- str_output.string.should =~ /sample doc/
21
- str_output.string.should =~ /another sample doc/
22
- end
23
13
 
24
14
  it 'should output a method\'s documentation if inside method without needing to use method name' do
25
15
  $str_output = StringIO.new
@@ -37,5 +27,28 @@ describe "Pry::DefaultCommands::Documentation" do
37
27
  $str_output.string.should =~ /sample comment/
38
28
  $str_output = nil
39
29
  end
30
+
31
+ it "should be able to find super methods" do
32
+
33
+ c = Class.new{
34
+ # classy initialize!
35
+ def initialize(*args); end
36
+ }
37
+
38
+ d = Class.new(c){
39
+ # grungy initialize??
40
+ def initialize(*args, &block); end
41
+ }
42
+
43
+ o = d.new
44
+
45
+ # instancey initialize!
46
+ def o.initialize; end
47
+
48
+ mock_pry(binding, "show-doc o.initialize").should =~ /instancey initialize/
49
+ mock_pry(binding, "show-doc --super o.initialize").should =~ /grungy initialize/
50
+ mock_pry(binding, "show-doc o.initialize -ss").should =~ /classy initialize/
51
+ mock_pry(binding, "show-doc --super o.initialize -ss").should == mock_pry("show-doc Object#initialize")
52
+ end
40
53
  end
41
54
  end
@@ -254,16 +254,6 @@ describe "Pry::DefaultCommands::Introspection" do
254
254
  str_output.string.should =~ /def sample/
255
255
  end
256
256
 
257
- it 'should output multiple methods\' sources' do
258
- str_output = StringIO.new
259
- redirect_pry_io(InputTester.new("show-method sample_method another_sample_method", "exit-all"), str_output) do
260
- pry
261
- end
262
-
263
- str_output.string.should =~ /def sample/
264
- str_output.string.should =~ /def another_sample/
265
- end
266
-
267
257
  it 'should output a method\'s source with line numbers' do
268
258
  str_output = StringIO.new
269
259
  redirect_pry_io(InputTester.new("show-method -l sample_method", "exit-all"), str_output) do
@@ -312,6 +302,20 @@ describe "Pry::DefaultCommands::Introspection" do
312
302
  $str_output = nil
313
303
  end
314
304
 
305
+ it "should find methods even if there are spaces in the arguments" do
306
+ o = Object.new
307
+ def o.foo(*bars);
308
+ "Mr flibble"
309
+ self;
310
+ end
311
+
312
+ str_output = StringIO.new
313
+ redirect_pry_io(InputTester.new("show-method o.foo('bar', 'baz bam').foo", "exit-all"), str_output) do
314
+ binding.pry
315
+ end
316
+ str_output.string.should =~ /Mr flibble/
317
+ end
318
+
315
319
  # dynamically defined method source retrieval is only supported in
316
320
  # 1.9 - where Method#source_location is native
317
321
  if RUBY_VERSION =~ /1.9/
@@ -366,6 +370,10 @@ describe "Pry::DefaultCommands::Introspection" do
366
370
  def a
367
371
  :yup
368
372
  end
373
+
374
+ def b
375
+ :kinda
376
+ end
369
377
  end
370
378
 
371
379
  class X
@@ -378,6 +386,11 @@ describe "Pry::DefaultCommands::Introspection" do
378
386
  def x
379
387
  :nope
380
388
  end
389
+
390
+ def b
391
+ super
392
+ end
393
+ alias c b
381
394
  end
382
395
  EOS
383
396
  @tempfile.flush
@@ -404,19 +417,19 @@ describe "Pry::DefaultCommands::Introspection" do
404
417
  it "should correctly find a class method" do
405
418
  mock_pry("edit-method X.x")
406
419
  @file.should == @tempfile.path
407
- @line.should == 10
420
+ @line.should == 14
408
421
  end
409
422
 
410
423
  it "should correctly find an instance method" do
411
424
  mock_pry("edit-method X#x")
412
425
  @file.should == @tempfile.path
413
- @line.should == 14
426
+ @line.should == 18
414
427
  end
415
428
 
416
429
  it "should correctly find a method on an instance" do
417
430
  mock_pry("x = X.new", "edit-method x.x")
418
431
  @file.should == @tempfile.path
419
- @line.should == 14
432
+ @line.should == 18
420
433
  end
421
434
 
422
435
  it "should correctly find a method from a module" do
@@ -424,6 +437,12 @@ describe "Pry::DefaultCommands::Introspection" do
424
437
  @file.should == @tempfile.path
425
438
  @line.should == 2
426
439
  end
440
+
441
+ it "should correctly find an aliased method" do
442
+ mock_pry("edit-method X#c")
443
+ @file.should == @tempfile.path
444
+ @line.should == 22
445
+ end
427
446
  end
428
447
 
429
448
  describe 'with -p' do
@@ -474,6 +493,32 @@ describe "Pry::DefaultCommands::Introspection" do
474
493
  X.new.a.should == :maybe
475
494
  end
476
495
  end
496
+
497
+ describe 'on an aliased method' do
498
+ before do
499
+ @old_editor = Pry.config.editor
500
+ Pry.config.editor = lambda do |file, line|
501
+ lines = File.read(file).lines.to_a
502
+ lines[1] = '"#{super}aa".to_sym' + "\n"
503
+ File.open(file, 'w') do |f|
504
+ f.write(lines.join)
505
+ end
506
+ nil
507
+ end
508
+ end
509
+ after do
510
+ Pry.config.editor = @old_editor
511
+ end
512
+
513
+ it "should change the alias, but not the original, without breaking super" do
514
+ mock_pry("edit-method -p X#c")
515
+
516
+ Pry::Method.from_str("X#c").alias?.should == true
517
+
518
+ X.new.b.should == :kinda
519
+ X.new.c.should == :kindaaa
520
+ end
521
+ end
477
522
  end
478
523
  end
479
524
 
@@ -0,0 +1,148 @@
1
+ require 'helper'
2
+ describe "ls" do
3
+ describe "class_name" do
4
+ extend Pry::DefaultCommands::Ls.helper_module
5
+ it "should use the name of the class if it exists" do
6
+ class_name(Object).should == "Object"
7
+ end
8
+
9
+ it "should use the name of the module if it exists" do
10
+ class_name(Kernel).should == "Kernel"
11
+ end
12
+
13
+ it "should use Foo.self for singleton classes of classes" do
14
+ class_name(class << Object; self; end).should == "Object.self"
15
+ end
16
+
17
+ it "should use Foo.self for singleton methods of modules" do
18
+ class_name(class << Kernel; self; end).should == "Kernel.self"
19
+ end
20
+
21
+ it "should default to the .to_s if that's not possible" do
22
+ cls = Class.new
23
+ class_name(cls).should == cls.to_s
24
+ end
25
+
26
+ it "should default to .to_s.self" do
27
+ cls = Class.new
28
+ class_name(class << cls; self; end).should == "#{cls.to_s}.self"
29
+ end
30
+
31
+ it "should just be self for singleton classes of normal objects" do
32
+ class_name(class << "hi"; self; end).should == "self"
33
+ end
34
+ end
35
+
36
+ describe "below ceiling" do
37
+ it "should stop before Object by default" do
38
+ mock_pry("cd Class.new{ def goo; end }.new", "ls").should.not =~ /Object/
39
+ mock_pry("cd Class.new{ def goo; end }", "ls -M").should.not =~ /Object/
40
+ end
41
+
42
+ it "should include object if -v is given" do
43
+ mock_pry("cd Class.new{ def goo; end }.new", "ls -m -v").should =~ /Object/
44
+ mock_pry("cd Class.new{ def goo; end }", "ls -vM").should =~ /Object/
45
+ end
46
+
47
+ it "should include super-classes by default" do
48
+ mock_pry("cd Class.new(Class.new{ def goo; end }).new", "ls").should =~ /goo/
49
+ mock_pry("cd Class.new(Class.new{ def goo; end })", "ls -M").should =~ /goo/
50
+ end
51
+
52
+ it "should not include super-classes when -q is given" do
53
+ mock_pry("cd Class.new(Class.new{ def goo; end }).new", "ls -q").should.not =~ /goo/
54
+ mock_pry("cd Class.new(Class.new{ def goo; end })", "ls -M -q").should.not =~ /goo/
55
+ end
56
+ end
57
+
58
+ describe "methods" do
59
+ it "should show public methods by default" do
60
+ mock_pry("ls Class.new{ def goo; end }.new").should =~ /goo/
61
+ end
62
+
63
+ it "should not show protected/private by default" do
64
+ mock_pry("ls -M Class.new{ def goo; end; private :goo }").should.not =~ /goo/
65
+ mock_pry("ls Class.new{ def goo; end; protected :goo }.new").should.not =~ /goo/
66
+ end
67
+
68
+ it "should show public methods with -p" do
69
+ mock_pry("ls -p Class.new{ def goo; end }.new").should =~ /goo/
70
+ end
71
+
72
+ it "should show protected/private methods with -p" do
73
+ mock_pry("ls -pM Class.new{ def goo; end; protected :goo }").should =~ /goo/
74
+ mock_pry("ls -p Class.new{ def goo; end; private :goo }.new").should =~ /goo/
75
+ end
76
+
77
+ it "should work for objects with an overridden method method" do
78
+ require 'net/http'
79
+ # This doesn't actually touch the network, promise!
80
+ mock_pry("ls Net::HTTP::Get.new('localhost')").should =~ /Net::HTTPGenericRequest methods/
81
+ end
82
+ end
83
+
84
+ describe "constants" do
85
+ it "should show constants defined on the current module" do
86
+ mock_pry("class TempFoo1; BARGHL = 1; end", "ls TempFoo1").should =~ /BARGHL/
87
+ end
88
+
89
+ it "should not show constants defined on parent modules by default" do
90
+ mock_pry("class TempFoo2; LHGRAB = 1; end; class TempFoo3 < TempFoo2; BARGHL = 1; end", "ls TempFoo3").should.not =~ /LHGRAB/
91
+ end
92
+
93
+ it "should show constants defined on ancestors with -v" do
94
+ mock_pry("class TempFoo4; LHGRAB = 1; end; class TempFoo5 < TempFoo4; BARGHL = 1; end", "ls -v TempFoo5").should =~ /LHGRAB/
95
+ end
96
+
97
+ it "should not autoload constants!" do
98
+ autoload :McflurgleTheThird, "/tmp/this-file-d000esnat-exist.rb"
99
+ lambda{ mock_pry("ls -c") }.should.not.raise
100
+ end
101
+ end
102
+
103
+ describe "grep" do
104
+ it "should reduce the number of outputted things" do
105
+ mock_pry("ls -c").should =~ /ArgumentError/
106
+ mock_pry("ls -c --grep Run").should.not =~ /ArgumentError/
107
+ end
108
+ it "should still output matching things" do
109
+ mock_pry("ls -c --grep Run").should =~ /RuntimeError/
110
+ end
111
+ end
112
+
113
+ describe "when no arguments given" do
114
+ describe "when at the top-level" do
115
+ # rubinius has a bug that means local_variables of "main" aren't reported inside eval()
116
+ unless defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /rbx/
117
+ it "should show local variables" do
118
+ mock_pry("ls").should =~ /_pry_/
119
+ mock_pry("arbitrar = 1", "ls").should =~ /arbitrar/
120
+ end
121
+ end
122
+ end
123
+
124
+ describe "when in a class" do
125
+ it "should show constants" do
126
+ mock_pry("class GeFromulate1; FOOTIFICATE=1.3; end", "cd GeFromulate1", "ls").should =~ /FOOTIFICATE/
127
+ end
128
+
129
+ it "should show class variables" do
130
+ mock_pry("class GeFromulate2; @@flurb=1.3; end", "cd GeFromulate2", "ls").should =~ /@@flurb/
131
+ end
132
+
133
+ it "should show methods" do
134
+ mock_pry("class GeFromulate3; def self.mooflight; end ; end", "cd GeFromulate3", "ls").should =~ /mooflight/
135
+ end
136
+ end
137
+
138
+ describe "when in an object" do
139
+ it "should show methods" do
140
+ mock_pry("cd Class.new{ def self.fooerise; end; self }", "ls").should =~ /fooerise/
141
+ end
142
+
143
+ it "should show instance variables" do
144
+ mock_pry("cd Class.new", "@alphooent = 1", "ls").should =~ /@alphooent/
145
+ end
146
+ end
147
+ end
148
+ end