pry 0.9.7.4-i386-mswin32 → 0.9.8-i386-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/.gitignore +2 -3
  2. data/CHANGELOG +43 -0
  3. data/README.markdown +3 -1
  4. data/Rakefile +51 -32
  5. data/bin/pry +2 -80
  6. data/lib/pry.rb +33 -26
  7. data/lib/pry/cli.rb +152 -0
  8. data/lib/pry/code.rb +351 -0
  9. data/lib/pry/command.rb +422 -0
  10. data/lib/pry/command_set.rb +259 -129
  11. data/lib/pry/commands.rb +0 -1
  12. data/lib/pry/config.rb +43 -9
  13. data/lib/pry/default_commands/context.rb +109 -92
  14. data/lib/pry/default_commands/documentation.rb +174 -63
  15. data/lib/pry/default_commands/easter_eggs.rb +26 -2
  16. data/lib/pry/default_commands/gems.rb +65 -37
  17. data/lib/pry/default_commands/input.rb +175 -243
  18. data/lib/pry/default_commands/introspection.rb +173 -112
  19. data/lib/pry/default_commands/ls.rb +96 -114
  20. data/lib/pry/default_commands/shell.rb +175 -70
  21. data/lib/pry/helpers/base_helpers.rb +7 -2
  22. data/lib/pry/helpers/command_helpers.rb +71 -77
  23. data/lib/pry/helpers/options_helpers.rb +10 -41
  24. data/lib/pry/helpers/text.rb +24 -4
  25. data/lib/pry/history.rb +55 -17
  26. data/lib/pry/history_array.rb +2 -0
  27. data/lib/pry/hooks.rb +252 -0
  28. data/lib/pry/indent.rb +9 -5
  29. data/lib/pry/method.rb +149 -50
  30. data/lib/pry/plugins.rb +12 -4
  31. data/lib/pry/pry_class.rb +69 -26
  32. data/lib/pry/pry_instance.rb +187 -115
  33. data/lib/pry/version.rb +1 -1
  34. data/lib/pry/wrapped_module.rb +73 -0
  35. data/man/pry.1 +195 -0
  36. data/man/pry.1.html +204 -0
  37. data/man/pry.1.ronn +141 -0
  38. data/pry.gemspec +29 -32
  39. data/test/helper.rb +32 -36
  40. data/test/test_cli.rb +78 -0
  41. data/test/test_code.rb +201 -0
  42. data/test/test_command.rb +327 -0
  43. data/test/test_command_integration.rb +512 -0
  44. data/test/test_command_set.rb +338 -12
  45. data/test/test_completion.rb +1 -1
  46. data/test/test_default_commands.rb +1 -2
  47. data/test/test_default_commands/test_context.rb +27 -5
  48. data/test/test_default_commands/test_documentation.rb +20 -8
  49. data/test/test_default_commands/test_input.rb +84 -45
  50. data/test/test_default_commands/test_introspection.rb +74 -17
  51. data/test/test_default_commands/test_ls.rb +9 -36
  52. data/test/test_default_commands/test_shell.rb +240 -13
  53. data/test/test_hooks.rb +490 -0
  54. data/test/test_indent.rb +2 -0
  55. data/test/test_method.rb +60 -0
  56. data/test/test_pry.rb +29 -904
  57. data/test/test_pry_defaults.rb +380 -0
  58. data/test/test_pry_history.rb +24 -24
  59. data/test/test_syntax_checking.rb +63 -0
  60. data/test/test_wrapped_module.rb +71 -0
  61. metadata +50 -39
  62. data/lib/pry/command_context.rb +0 -53
  63. data/lib/pry/command_processor.rb +0 -181
  64. data/lib/pry/extended_commands/user_command_api.rb +0 -65
  65. data/test/test_command_processor.rb +0 -176
@@ -3,7 +3,10 @@ require 'helper'
3
3
  describe Pry::CommandSet do
4
4
  before do
5
5
  @set = Pry::CommandSet.new
6
- @ctx = Pry::CommandContext.new
6
+ @ctx = {
7
+ :target => binding,
8
+ :command_set => @set
9
+ }
7
10
  end
8
11
 
9
12
  it 'should call the block used for the command when it is called' do
@@ -24,11 +27,11 @@ describe Pry::CommandSet do
24
27
  @set.run_command @ctx, 'foo', 1, 2, 3
25
28
  end
26
29
 
27
- it 'should use the first argument as self' do
30
+ it 'should use the first argument as context' do
28
31
  ctx = @ctx
29
32
 
30
33
  @set.command 'foo' do
31
- self.should == ctx
34
+ self.context.should == ctx
32
35
  end
33
36
 
34
37
  @set.run_command @ctx, 'foo'
@@ -50,6 +53,15 @@ describe Pry::CommandSet do
50
53
  }.should.raise(Pry::NoCommandError)
51
54
  end
52
55
 
56
+ it 'should be able to remove its own commands, by listing name' do
57
+ @set.command(/^foo1/, 'desc', :listing => 'foo') {}
58
+ @set.delete 'foo'
59
+
60
+ lambda {
61
+ @set.run_command @ctx, /^foo1/
62
+ }.should.raise(Pry::NoCommandError)
63
+ end
64
+
53
65
  it 'should be able to import some commands from other sets' do
54
66
  run = false
55
67
 
@@ -68,6 +80,19 @@ describe Pry::CommandSet do
68
80
  }.should.raise(Pry::NoCommandError)
69
81
  end
70
82
 
83
+ it 'should be able to import some commands from other sets using listing name' do
84
+ run = false
85
+
86
+ other_set = Pry::CommandSet.new do
87
+ command(/^foo1/, 'desc', :listing => 'foo') { run = true }
88
+ end
89
+
90
+ @set.import_from(other_set, 'foo')
91
+
92
+ @set.run_command @ctx, /^foo1/
93
+ run.should == true
94
+ end
95
+
71
96
  it 'should be able to import a whole set' do
72
97
  run = []
73
98
 
@@ -108,16 +133,38 @@ describe Pry::CommandSet do
108
133
  run.should == true
109
134
  end
110
135
 
111
- it 'should be able to change the descritpions of methods' do
136
+ it "should be able to alias a method by the command's listing name" do
137
+ run = false
138
+ @set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
139
+
140
+ @set.alias_command 'bar', 'foo'
141
+ @set.commands['bar'].name.should == 'bar'
142
+ @set.commands['bar'].description.should == ''
143
+
144
+ @set.run_command @ctx, 'bar'
145
+ run.should == true
146
+ end
147
+
148
+ it 'should be able to change the descriptions of commands' do
112
149
  @set.command('foo', 'bar') {}
113
150
  @set.desc 'foo', 'baz'
114
151
 
115
152
  @set.commands['foo'].description.should == 'baz'
116
153
  end
117
154
 
118
- it 'should return Pry::CommandContext::VOID_VALUE for commands by default' do
155
+ it 'should get the descriptions of commands' do
156
+ @set.command('foo', 'bar') {}
157
+ @set.desc('foo').should == 'bar'
158
+ end
159
+
160
+ it 'should get the descriptions of commands, by listing' do
161
+ @set.command(/^foo1/, 'bar', :listing => 'foo') {}
162
+ @set.desc('foo').should == 'bar'
163
+ end
164
+
165
+ it 'should return Pry::Command::VOID_VALUE for commands by default' do
119
166
  @set.command('foo') { 3 }
120
- @set.run_command(@ctx, 'foo').should == Pry::CommandContext::VOID_VALUE
167
+ @set.run_command(@ctx, 'foo').should == Pry::Command::VOID_VALUE
121
168
  end
122
169
 
123
170
  it 'should be able to keep return values' do
@@ -140,7 +187,7 @@ describe Pry::CommandSet do
140
187
  end
141
188
 
142
189
  @set.run_command(@ctx, 'foo')
143
- Pry::CommandContext.new.should.not.respond_to :my_helper
190
+ Pry::Command.subclass('foo', '', {}, Module.new).new({:target => binding}).should.not.respond_to :my_helper
144
191
  end
145
192
 
146
193
  it 'should not recreate a new helper module when helpers is called' do
@@ -197,8 +244,8 @@ describe Pry::CommandSet do
197
244
  end
198
245
 
199
246
  it "should provide a 'help' command" do
200
- @ctx.command_set = @set
201
- @ctx.output = StringIO.new
247
+ @ctx[:command_set] = @set
248
+ @ctx[:output] = StringIO.new
202
249
 
203
250
  lambda {
204
251
  @set.run_command(@ctx, 'help')
@@ -211,12 +258,12 @@ describe Pry::CommandSet do
211
258
  @set.command 'moo', "Mooerizes" do; end
212
259
  @set.command 'boo', "Booerizes" do; end
213
260
 
214
- @ctx.command_set = @set
215
- @ctx.output = StringIO.new
261
+ @ctx[:command_set] = @set
262
+ @ctx[:output] = StringIO.new
216
263
 
217
264
  @set.run_command(@ctx, 'help')
218
265
 
219
- doc = @ctx.output.string
266
+ doc = @ctx[:output].string
220
267
 
221
268
  order = [doc.index("boo"),
222
269
  doc.index("foo"),
@@ -226,4 +273,283 @@ describe Pry::CommandSet do
226
273
 
227
274
  order.should == order.sort
228
275
  end
276
+
277
+ describe "renaming a command" do
278
+ it 'should be able to rename and run a command' do
279
+ run = false
280
+ @set.command('foo') { run = true }
281
+ @set.rename_command('bar', 'foo')
282
+ @set.run_command(@ctx, 'bar')
283
+ run.should == true
284
+ end
285
+
286
+ it 'should accept listing name when renaming a command' do
287
+ run = false
288
+ @set.command('foo', "", :listing => 'love') { run = true }
289
+ @set.rename_command('bar', 'love')
290
+ @set.run_command(@ctx, 'bar')
291
+ run.should == true
292
+ end
293
+
294
+ it 'should raise exception trying to rename non-existent command' do
295
+ lambda { @set.rename_command('bar', 'foo') }.should.raise ArgumentError
296
+ end
297
+
298
+ it 'should make old command name inaccessible' do
299
+ @set.command('foo') { }
300
+ @set.rename_command('bar', 'foo')
301
+ lambda { @set.run_command(@ctx, 'foo') }.should.raise Pry::NoCommandError
302
+ end
303
+
304
+
305
+ it 'should be able to pass in options when renaming command' do
306
+ desc = "hello"
307
+ listing = "bing"
308
+ @set.command('foo') { }
309
+ @set.rename_command('bar', 'foo', :description => desc, :listing => listing, :keep_retval => true)
310
+ @set.commands['bar'].description.should == desc
311
+ @set.commands['bar'].options[:listing].should == listing
312
+ @set.commands['bar'].options[:keep_retval].should == true
313
+ end
314
+ end
315
+
316
+ describe "command decorators - before_command and after_command" do
317
+ describe "before_command" do
318
+ it 'should be called before the original command' do
319
+ foo = []
320
+ @set.command('foo') { foo << 1 }
321
+ @set.before_command('foo') { foo << 2 }
322
+ @set.run_command(@ctx, 'foo')
323
+
324
+ foo.should == [2, 1]
325
+ end
326
+
327
+ it 'should be called before the original command, using listing name' do
328
+ foo = []
329
+ @set.command(/^foo1/, '', :listing => 'foo') { foo << 1 }
330
+ @set.before_command('foo') { foo << 2 }
331
+ @set.run_command(@ctx, /^foo1/)
332
+
333
+ foo.should == [2, 1]
334
+ end
335
+
336
+ it 'should share the context with the original command' do
337
+ @ctx[:target] = "test target string".__binding__
338
+ before_val = nil
339
+ orig_val = nil
340
+ @set.command('foo') { orig_val = target }
341
+ @set.before_command('foo') { before_val = target }
342
+ @set.run_command(@ctx, 'foo')
343
+
344
+ before_val.should == @ctx[:target]
345
+ orig_val.should == @ctx[:target]
346
+ end
347
+
348
+ it 'should work when applied multiple times' do
349
+ foo = []
350
+ @set.command('foo') { foo << 1 }
351
+ @set.before_command('foo') { foo << 2 }
352
+ @set.before_command('foo') { foo << 3 }
353
+ @set.before_command('foo') { foo << 4 }
354
+ @set.run_command(@ctx, 'foo')
355
+
356
+ foo.should == [4, 3, 2, 1]
357
+ end
358
+
359
+ end
360
+
361
+ describe "after_command" do
362
+ it 'should be called after the original command' do
363
+ foo = []
364
+ @set.command('foo') { foo << 1 }
365
+ @set.after_command('foo') { foo << 2 }
366
+ @set.run_command(@ctx, 'foo')
367
+
368
+ foo.should == [1, 2]
369
+ end
370
+
371
+ it 'should be called after the original command, using listing name' do
372
+ foo = []
373
+ @set.command(/^foo1/, '', :listing => 'foo') { foo << 1 }
374
+ @set.after_command('foo') { foo << 2 }
375
+ @set.run_command(@ctx, /^foo1/)
376
+
377
+ foo.should == [1, 2]
378
+ end
379
+
380
+ it 'should share the context with the original command' do
381
+ @ctx[:target] = "test target string".__binding__
382
+ after_val = nil
383
+ orig_val = nil
384
+ @set.command('foo') { orig_val = target }
385
+ @set.after_command('foo') { after_val = target }
386
+ @set.run_command(@ctx, 'foo')
387
+
388
+ after_val.should == @ctx[:target]
389
+ orig_val.should == @ctx[:target]
390
+ end
391
+
392
+ it 'should determine the return value for the command' do
393
+ @set.command('foo', 'bar', :keep_retval => true) { 1 }
394
+ @set.after_command('foo') { 2 }
395
+ @set.run_command(@ctx, 'foo').should == 2
396
+ end
397
+
398
+ it 'should work when applied multiple times' do
399
+ foo = []
400
+ @set.command('foo') { foo << 1 }
401
+ @set.after_command('foo') { foo << 2 }
402
+ @set.after_command('foo') { foo << 3 }
403
+ @set.after_command('foo') { foo << 4 }
404
+ @set.run_command(@ctx, 'foo')
405
+
406
+ foo.should == [1, 2, 3, 4]
407
+ end
408
+ end
409
+
410
+ describe "before_command and after_command" do
411
+ it 'should work when combining both before_command and after_command' do
412
+ foo = []
413
+ @set.command('foo') { foo << 1 }
414
+ @set.after_command('foo') { foo << 2 }
415
+ @set.before_command('foo') { foo << 3 }
416
+ @set.run_command(@ctx, 'foo')
417
+
418
+ foo.should == [3, 1, 2]
419
+ end
420
+
421
+ end
422
+
423
+ end
424
+
425
+ describe 'find_command' do
426
+ it 'should find commands with the right string' do
427
+ cmd = @set.command('rincewind'){ }
428
+ @set.find_command('rincewind').should == cmd
429
+ end
430
+
431
+ it 'should not find commands with spaces before' do
432
+ cmd = @set.command('luggage'){ }
433
+ @set.find_command(' luggage').should == nil
434
+ end
435
+
436
+ it 'should find commands with arguments after' do
437
+ cmd = @set.command('vetinari'){ }
438
+ @set.find_command('vetinari --knock 3').should == cmd
439
+ end
440
+
441
+ it 'should find commands with names containing spaces' do
442
+ cmd = @set.command('nobby nobbs'){ }
443
+ @set.find_command('nobby nobbs --steal petty-cash').should == cmd
444
+ end
445
+
446
+ it 'should find command defined by regex' do
447
+ cmd = @set.command(/(capt|captain) vimes/i){ }
448
+ @set.find_command('Capt Vimes').should == cmd
449
+ end
450
+
451
+ it 'should find commands defined by regex with arguments' do
452
+ cmd = @set.command(/(cpl|corporal) Carrot/i){ }
453
+ @set.find_command('cpl carrot --write-home').should == cmd
454
+ end
455
+
456
+ it 'should not find commands by listing' do
457
+ cmd = @set.command(/werewol(f|ve)s?/, 'only once a month', :listing => "angua"){ }
458
+ @set.find_command('angua').should == nil
459
+ end
460
+
461
+ it 'should not find commands without command_prefix' do
462
+ Pry.config.command_prefix = '%'
463
+ cmd = @set.command('detritus'){ }
464
+ @set.find_command('detritus').should == nil
465
+ Pry.config.command_prefix = ''
466
+ end
467
+
468
+ it "should find commands that don't use the prefix" do
469
+ Pry.config.command_prefix = '%'
470
+ cmd = @set.command('colon', 'Sergeant Fred', :use_prefix => false){ }
471
+ @set.find_command('colon').should == cmd
472
+ Pry.config.command_prefix = ''
473
+ end
474
+ end
475
+
476
+ describe '.valid_command?' do
477
+ it 'should be true for commands that can be found' do
478
+ cmd = @set.command('archchancellor')
479
+ @set.valid_command?('archchancellor of_the?(:University)').should == true
480
+ end
481
+
482
+ it 'should be false for commands that can\'' do
483
+ @set.valid_command?('def monkey(ape)').should == false
484
+ end
485
+
486
+ it 'should not cause argument interpolation' do
487
+ cmd = @set.command('hello')
488
+ lambda {
489
+ @set.valid_command?('hello #{raise "futz"}')
490
+ }.should.not.raise
491
+ end
492
+ end
493
+
494
+ describe '.process_line' do
495
+
496
+ it 'should return Result.new(false) if there is no matching command' do
497
+ result = @set.process_line('1 + 42')
498
+ result.command?.should == false
499
+ result.void_command?.should == false
500
+ result.retval.should == nil
501
+ end
502
+
503
+ it 'should return Result.new(true, VOID) if the command is not keep_retval' do
504
+ @set.create_command('mrs-cake') do
505
+ def process; 42; end
506
+ end
507
+
508
+ result = @set.process_line('mrs-cake')
509
+ result.command?.should == true
510
+ result.void_command?.should == true
511
+ result.retval.should == Pry::Command::VOID_VALUE
512
+ end
513
+
514
+ it 'should return Result.new(true, retval) if the command is keep_retval' do
515
+ @set.create_command('magrat', 'the maiden', :keep_retval => true) do
516
+ def process; 42; end
517
+ end
518
+
519
+ result = @set.process_line('magrat')
520
+ result.command?.should == true
521
+ result.void_command?.should == false
522
+ result.retval.should == 42
523
+ end
524
+
525
+ it 'should pass through context' do
526
+ ctx = {
527
+ :eval_string => "bloomers",
528
+ :pry_instance => Object.new,
529
+ :output => StringIO.new,
530
+ :target => binding
531
+ }
532
+ @set.create_command('agnes') do
533
+ define_method(:process) do
534
+ eval_string.should == ctx[:eval_string]
535
+ output.should == ctx[:output]
536
+ target.should == ctx[:target]
537
+ _pry_.should == ctx[:pry_instance]
538
+ end
539
+ end
540
+
541
+ @set.process_line('agnes', ctx)
542
+ end
543
+
544
+ it 'should add command_set to context' do
545
+ set = @set
546
+ @set.create_command(/nann+y ogg+/) do
547
+ define_method(:process) do
548
+ command_set.should == set
549
+ end
550
+ end
551
+
552
+ @set.process_line('nannnnnny oggggg')
553
+ end
554
+ end
229
555
  end
@@ -16,7 +16,7 @@ describe Pry::InputCompleter do
16
16
  end
17
17
 
18
18
  # another jruby hack :((
19
- if !jruby?
19
+ if !Pry::Helpers::BaseHelpers.jruby?
20
20
  it "should not crash if there's a Module that has a symbolic name." do
21
21
  completer = Pry::InputCompleter.build_completion_proc(Pry.binding_for(Object.new))
22
22
  lambda{ completer.call "a.to_s." }.should.not.raise Exception
@@ -7,8 +7,7 @@ describe "Pry::Commands" do
7
7
  redirect_pry_io(InputTester.new("help ls", "exit-all"), str_output) do
8
8
  pry
9
9
  end
10
- str_output.string.each_line.count.should == 1
11
- str_output.string.should =~ /ls --help/
10
+ str_output.string.should =~ /Usage: ls/
12
11
  end
13
12
 
14
13
  it 'should display help for a regex command with a "listing"' do
@@ -2,9 +2,9 @@ require 'helper'
2
2
 
3
3
  describe "Pry::DefaultCommands::Context" do
4
4
  describe "exit-all" do
5
- it 'should break out of the repl loop of Pry instance (returning target of session)' do
5
+ it 'should break out of the repl loop of Pry instance and return nil' do
6
6
  redirect_pry_io(InputTester.new("exit-all"), StringIO.new) do
7
- Pry.new.repl(0).should == 0
7
+ Pry.new.repl(0).should == nil
8
8
  end
9
9
  end
10
10
 
@@ -31,6 +31,21 @@ describe "Pry::DefaultCommands::Context" do
31
31
  end
32
32
  end
33
33
 
34
+ describe "whereami" do
35
+ it 'should work with methods that have been undefined' do
36
+ class Cor
37
+ def blimey!
38
+ Cor.send :undef_method, :blimey!
39
+ # using [.] so the regex doesn't match itself
40
+ mock_pry(binding, 'whereami').should =~ /self[.]blimey!/
41
+ end
42
+ end
43
+
44
+ Cor.new.blimey!
45
+ Object.remove_const(:Cor)
46
+ end
47
+ end
48
+
34
49
  describe "exit" do
35
50
  it 'should pop a binding with exit' do
36
51
  b = Pry.binding_for(:outer)
@@ -44,7 +59,7 @@ describe "Pry::DefaultCommands::Context" do
44
59
  end
45
60
 
46
61
  it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit' do
47
- Pry.start(0, :input => StringIO.new("exit")).should == 0
62
+ Pry.start(0, :input => StringIO.new("exit")).should == nil
48
63
  end
49
64
 
50
65
  it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit, and return user-given value' do
@@ -126,8 +141,15 @@ describe "Pry::DefaultCommands::Context" do
126
141
  $outer.should == :outer
127
142
  end
128
143
 
129
- it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with cd ..' do
130
- Pry.start(0, :input => StringIO.new("cd ..")).should == 0
144
+ it "should not leave the REPL session when given 'cd ..'" do
145
+ b = Pry.binding_for(Object.new)
146
+ input = InputTester.new "cd ..", "$obj = self", "exit-all"
147
+
148
+ redirect_pry_io(input, StringIO.new) do
149
+ b.pry
150
+ end
151
+
152
+ $obj.should == b.eval("self")
131
153
  end
132
154
 
133
155
  it 'should break out to outer-most session with cd /' do