pry 0.9.5-i386-mingw32 → 0.9.6-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +21 -0
- data/Gemfile +2 -0
- data/README.markdown +15 -17
- data/Rakefile +1 -1
- data/bin/pry +8 -6
- data/examples/example_command_override.rb +1 -1
- data/lib/pry.rb +19 -4
- data/lib/pry/command_context.rb +1 -0
- data/lib/pry/command_processor.rb +1 -0
- data/lib/pry/command_set.rb +2 -2
- data/lib/pry/config.rb +15 -0
- data/lib/pry/default_commands/context.rb +8 -4
- data/lib/pry/default_commands/documentation.rb +18 -12
- data/lib/pry/default_commands/input.rb +120 -67
- data/lib/pry/default_commands/introspection.rb +112 -67
- data/lib/pry/default_commands/shell.rb +28 -17
- data/lib/pry/helpers/command_helpers.rb +73 -40
- data/lib/pry/history_array.rb +4 -0
- data/lib/pry/pry_class.rb +10 -6
- data/lib/pry/pry_instance.rb +57 -25
- data/lib/pry/version.rb +1 -1
- data/pry.gemspec +8 -8
- data/test/helper.rb +35 -1
- data/test/test_command_set.rb +1 -1
- data/test/test_default_commands/test_input.rb +30 -17
- data/test/test_default_commands/test_introspection.rb +334 -1
- data/test/test_default_commands/test_shell.rb +100 -5
- data/test/test_exception_whitelist.rb +17 -0
- data/test/test_input_stack.rb +70 -0
- data/test/test_pry.rb +26 -22
- data/test/test_pry_output.rb +2 -6
- metadata +73 -74
@@ -1,6 +1,219 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
describe "Pry::DefaultCommands::Introspection" do
|
4
|
+
|
5
|
+
describe "edit" do
|
6
|
+
before do
|
7
|
+
@old_editor = Pry.config.editor
|
8
|
+
@file = nil; @line = nil; @contents = nil
|
9
|
+
Pry.config.editor = lambda do |file, line|
|
10
|
+
@file = file; @line = line; @contents = File.read(@file)
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
after do
|
15
|
+
Pry.config.editor = @old_editor
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "with FILE" do
|
19
|
+
it "should invoke Pry.config.editor with absolutified filenames" do
|
20
|
+
mock_pry("edit foo.rb")
|
21
|
+
@file.should == File.expand_path("foo.rb")
|
22
|
+
mock_pry("edit /tmp/bar.rb")
|
23
|
+
@file.should == "/tmp/bar.rb"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should guess the line number from a colon" do
|
27
|
+
mock_pry("edit /tmp/foo.rb:10")
|
28
|
+
@line.should == 10
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should use the line number from -l" do
|
32
|
+
mock_pry("edit -l 10 /tmp/foo.rb")
|
33
|
+
@line.should == 10
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not delete the file!" do
|
37
|
+
mock_pry("edit Rakefile")
|
38
|
+
File.exist?(@file).should == true
|
39
|
+
end
|
40
|
+
|
41
|
+
describe do
|
42
|
+
before do
|
43
|
+
@rand = rand
|
44
|
+
Pry.config.editor = lambda { |file, line|
|
45
|
+
File.open(file, 'w') { |f| f << "$rand = #{@rand.inspect}" }
|
46
|
+
nil
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should reload the file if it is a ruby file" do
|
51
|
+
tf = Tempfile.new(["tmp", ".rb"])
|
52
|
+
path = tf.path
|
53
|
+
|
54
|
+
mock_pry("edit #{path}", "$rand").should =~ /#{@rand}/
|
55
|
+
|
56
|
+
tf.close
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not reload the file if it is not a ruby file" do
|
60
|
+
tf = Tempfile.new(["tmp", ".py"])
|
61
|
+
path = tf.path
|
62
|
+
|
63
|
+
mock_pry("edit #{path}", "$rand").should.not =~ /#{@rand}/
|
64
|
+
|
65
|
+
tf.close
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should not reload a ruby file if -n is given" do
|
69
|
+
tf = Tempfile.new(["tmp", ".rb"])
|
70
|
+
path = tf.path
|
71
|
+
|
72
|
+
mock_pry("edit -n #{path}", "$rand").should.not =~ /#{@rand}/
|
73
|
+
|
74
|
+
tf.close
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should reload a non-ruby file if -r is given" do
|
78
|
+
tf = Tempfile.new(["tmp", ".pryrc"])
|
79
|
+
path = tf.path
|
80
|
+
|
81
|
+
mock_pry("edit -r #{path}", "$rand").should =~ /#{@rand}/
|
82
|
+
|
83
|
+
tf.close
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "with --ex" do
|
89
|
+
before do
|
90
|
+
@tf = Tempfile.new(["tmp", ".rb"])
|
91
|
+
@path = @tf.path
|
92
|
+
@tf << "1\n2\nraise RuntimeError"
|
93
|
+
@tf.flush
|
94
|
+
end
|
95
|
+
after do
|
96
|
+
@tf.close
|
97
|
+
File.unlink("#{@path}c") if File.exists?("#{@path}c") #rbx
|
98
|
+
end
|
99
|
+
it "should open the correct file" do
|
100
|
+
mock_pry("require #{@path.inspect}", "edit --ex")
|
101
|
+
|
102
|
+
@file.should == @path
|
103
|
+
@line.should == 3
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should reload the file" do
|
107
|
+
Pry.config.editor = lambda {|file, line|
|
108
|
+
File.open(file, 'w'){|f| f << "FOO = 'BAR'" }
|
109
|
+
nil
|
110
|
+
}
|
111
|
+
|
112
|
+
mock_pry("require #{@path.inspect}", "edit --ex", "FOO").should =~ /BAR/
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should not reload the file if -n is passed" do
|
116
|
+
Pry.config.editor = lambda {|file, line|
|
117
|
+
File.open(file, 'w'){|f| f << "FOO2 = 'BAZ'" }
|
118
|
+
nil
|
119
|
+
}
|
120
|
+
|
121
|
+
mock_pry("require #{@path.inspect}", "edit -n --ex", "FOO2").should.not =~ /BAZ/
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "with --ex NUM" do
|
126
|
+
before do
|
127
|
+
Pry.config.editor = proc do |file, line|
|
128
|
+
@__ex_file__ = file
|
129
|
+
@__ex_line__ = line
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should start editor on first level of backtrace when --ex used with no argument ' do
|
135
|
+
pry_instance = Pry.new(:input => StringIO.new("edit -n --ex"), :output => StringIO.new)
|
136
|
+
pry_instance.last_exception = MockPryException.new("a:1", "b:2", "c:3")
|
137
|
+
pry_instance.rep(self)
|
138
|
+
@__ex_file__.should == "a"
|
139
|
+
@__ex_line__.should == 1
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should start editor on first level of backtrace when --ex 0 used ' do
|
143
|
+
pry_instance = Pry.new(:input => StringIO.new("edit -n --ex 0"), :output => StringIO.new)
|
144
|
+
pry_instance.last_exception = MockPryException.new("a:1", "b:2", "c:3")
|
145
|
+
pry_instance.rep(self)
|
146
|
+
@__ex_file__.should == "a"
|
147
|
+
@__ex_line__.should == 1
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should start editor on second level of backtrace when --ex 1 used' do
|
151
|
+
pry_instance = Pry.new(:input => StringIO.new("edit -n --ex 1"), :output => StringIO.new)
|
152
|
+
pry_instance.last_exception = MockPryException.new("a:1", "b:2", "c:3")
|
153
|
+
pry_instance.rep(self)
|
154
|
+
@__ex_file__.should == "b"
|
155
|
+
@__ex_line__.should == 2
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should start editor on third level of backtrace when --ex 2 used' do
|
159
|
+
pry_instance = Pry.new(:input => StringIO.new("edit -n --ex 2"), :output => StringIO.new)
|
160
|
+
pry_instance.last_exception = MockPryException.new("a:1", "b:2", "c:3")
|
161
|
+
pry_instance.rep(self)
|
162
|
+
@__ex_file__.should == "c"
|
163
|
+
@__ex_line__.should == 3
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should display error message when backtrace level is out of bounds (using --ex 4)' do
|
167
|
+
pry_instance = Pry.new(:input => StringIO.new("edit -n --ex 4"), :output => str_output = StringIO.new)
|
168
|
+
pry_instance.last_exception = MockPryException.new("a:1", "b:2", "c:3")
|
169
|
+
pry_instance.rep(self)
|
170
|
+
str_output.string.should =~ /Exception has no associated file/
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "without FILE" do
|
175
|
+
it "should edit the current expression if it's incomplete" do
|
176
|
+
mock_pry("def a", "edit")
|
177
|
+
@contents.should == "def a\n"
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should edit the previous expression if the current is empty" do
|
181
|
+
mock_pry("def a; 2; end", "edit")
|
182
|
+
@contents.should == "def a; 2; end\n"
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should use a blank file if -t is specified" do
|
186
|
+
mock_pry("def a; 5; end", "edit -t")
|
187
|
+
@contents.should == "\n"
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should use a blank file if -t is specified even half-way through an expression" do
|
191
|
+
mock_pry("def a;", "edit -t")
|
192
|
+
@contents.should == "\n"
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should position the cursor at the end of the expression" do
|
196
|
+
mock_pry("def a; 2;"," end", "edit")
|
197
|
+
@line.should == 2
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should evaluate the expression" do
|
201
|
+
Pry.config.editor = lambda {|file, line|
|
202
|
+
File.open(file, 'w'){|f| f << "'FOO'\n" }
|
203
|
+
nil
|
204
|
+
}
|
205
|
+
mock_pry("edit").should =~ /FOO/
|
206
|
+
end
|
207
|
+
it "should not evaluate the expression with -n" do
|
208
|
+
Pry.config.editor = lambda {|file, line|
|
209
|
+
File.open(file, 'w'){|f| f << "'FOO'\n" }
|
210
|
+
nil
|
211
|
+
}
|
212
|
+
mock_pry("edit -n").should.not =~ /FOO/
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
4
217
|
describe "show-method" do
|
5
218
|
it 'should output a method\'s source' do
|
6
219
|
str_output = StringIO.new
|
@@ -10,7 +223,7 @@ describe "Pry::DefaultCommands::Introspection" do
|
|
10
223
|
|
11
224
|
str_output.string.should =~ /def sample/
|
12
225
|
end
|
13
|
-
|
226
|
+
|
14
227
|
it 'should output multiple methods\' sources' do
|
15
228
|
str_output = StringIO.new
|
16
229
|
redirect_pry_io(InputTester.new("show-method sample_method another_sample_method", "exit-all"), str_output) do
|
@@ -114,6 +327,126 @@ describe "Pry::DefaultCommands::Introspection" do
|
|
114
327
|
end
|
115
328
|
end
|
116
329
|
|
330
|
+
describe "edit-method" do
|
331
|
+
describe "on a method defined in a file" do
|
332
|
+
before do
|
333
|
+
@tempfile = Tempfile.new(['tmp', '*.rb'])
|
334
|
+
@tempfile.puts <<-EOS
|
335
|
+
module A
|
336
|
+
def a
|
337
|
+
:yup
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
class X
|
342
|
+
include A
|
343
|
+
|
344
|
+
def self.x
|
345
|
+
:double_yup
|
346
|
+
end
|
347
|
+
|
348
|
+
def x
|
349
|
+
:nope
|
350
|
+
end
|
351
|
+
end
|
352
|
+
EOS
|
353
|
+
@tempfile.flush
|
354
|
+
load @tempfile.path
|
355
|
+
end
|
356
|
+
|
357
|
+
after do
|
358
|
+
@tempfile.close
|
359
|
+
end
|
360
|
+
|
361
|
+
describe 'without -p' do
|
362
|
+
before do
|
363
|
+
@old_editor = Pry.config.editor
|
364
|
+
@file, @line, @contents = nil, nil, nil
|
365
|
+
Pry.config.editor = lambda do |file, line|
|
366
|
+
@file = file; @line = line
|
367
|
+
nil
|
368
|
+
end
|
369
|
+
end
|
370
|
+
after do
|
371
|
+
Pry.config.editor = @old_editor
|
372
|
+
end
|
373
|
+
|
374
|
+
it "should correctly find a class method" do
|
375
|
+
mock_pry("edit-method X.x")
|
376
|
+
@file.should == @tempfile.path
|
377
|
+
@line.should == 10
|
378
|
+
end
|
379
|
+
|
380
|
+
it "should correctly find an instance method" do
|
381
|
+
mock_pry("edit-method X#x")
|
382
|
+
@file.should == @tempfile.path
|
383
|
+
@line.should == 14
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should correctly find a method on an instance" do
|
387
|
+
mock_pry("x = X.new", "edit-method x.x")
|
388
|
+
@file.should == @tempfile.path
|
389
|
+
@line.should == 14
|
390
|
+
end
|
391
|
+
|
392
|
+
it "should correctly find a method from a module" do
|
393
|
+
mock_pry("edit-method X#a")
|
394
|
+
@file.should == @tempfile.path
|
395
|
+
@line.should == 2
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
describe 'with -p' do
|
400
|
+
before do
|
401
|
+
@old_editor = Pry.config.editor
|
402
|
+
Pry.config.editor = lambda do |file, line|
|
403
|
+
lines = File.read(file).lines.to_a
|
404
|
+
lines[1] = ":maybe\n"
|
405
|
+
File.open(file, 'w') do |f|
|
406
|
+
f.write(lines.join)
|
407
|
+
end
|
408
|
+
nil
|
409
|
+
end
|
410
|
+
end
|
411
|
+
after do
|
412
|
+
Pry.config.editor = @old_editor
|
413
|
+
end
|
414
|
+
|
415
|
+
it "should successfully replace a class method" do
|
416
|
+
mock_pry("edit-method -p X.x")
|
417
|
+
|
418
|
+
class << X
|
419
|
+
X.method(:x).owner.should == self
|
420
|
+
end
|
421
|
+
X.method(:x).receiver.should == X
|
422
|
+
X.x.should == :maybe
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should successfully replace an instance method" do
|
426
|
+
mock_pry("edit-method -p X#x")
|
427
|
+
|
428
|
+
X.instance_method(:x).owner.should == X
|
429
|
+
X.new.x.should == :maybe
|
430
|
+
end
|
431
|
+
|
432
|
+
it "should successfully replace a method on an instance" do
|
433
|
+
mock_pry("instance = X.new", "edit-method -p instance.x")
|
434
|
+
|
435
|
+
instance = X.new
|
436
|
+
instance.method(:x).owner.should == X
|
437
|
+
instance.x.should == :maybe
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should successfully replace a method from a module" do
|
441
|
+
mock_pry("edit-method -p X#a")
|
442
|
+
|
443
|
+
X.instance_method(:a).owner.should == A
|
444
|
+
X.new.a.should == :maybe
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
117
450
|
# show-command only works in implementations that support Proc#source_location
|
118
451
|
if Proc.method_defined?(:source_location)
|
119
452
|
describe "show-command" do
|
@@ -3,16 +3,111 @@ require 'helper'
|
|
3
3
|
describe "Pry::DefaultCommands::Shell" do
|
4
4
|
describe "cat" do
|
5
5
|
|
6
|
+
describe "on receiving a file that does not exist" do
|
7
|
+
it 'should display an error message' do
|
8
|
+
mock_pry("cat supercalifragilicious66").should =~ /Could not find file/
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
6
12
|
# this doesnt work so well on rbx due to differences in backtrace
|
7
13
|
# so we currently skip rbx until we figure out a workaround
|
8
|
-
|
9
|
-
|
10
|
-
|
14
|
+
describe "with --ex" do
|
15
|
+
if !rbx?
|
16
|
+
it 'cat --ex should correctly display code that generated exception even if raised in repl' do
|
17
|
+
mock_pry("this raises error", "cat --ex").should =~ /\d+:(\s*) this raises error/
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'cat --ex should correctly display code that generated exception' do
|
21
|
+
mock_pry("broken_method", "cat --ex").should =~ /this method is broken/
|
22
|
+
end
|
11
23
|
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "with --ex N" do
|
27
|
+
it 'should cat first level of backtrace when --ex used with no argument ' do
|
28
|
+
pry_instance = Pry.new(:input => StringIO.new("cat --ex"), :output => str_output = StringIO.new)
|
29
|
+
|
30
|
+
temp_file do |f|
|
31
|
+
f << "bt number 1"
|
32
|
+
f.flush
|
33
|
+
pry_instance.last_exception = MockPryException.new("#{f.path}:1", "x", "x")
|
34
|
+
pry_instance.rep(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
str_output.string.should =~ /bt number 1/
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should cat first level of backtrace when --ex 0 used ' do
|
41
|
+
pry_instance = Pry.new(:input => StringIO.new("cat --ex 0"), :output => str_output = StringIO.new)
|
42
|
+
|
43
|
+
temp_file do |f|
|
44
|
+
f << "bt number 1"
|
45
|
+
f.flush
|
46
|
+
pry_instance.last_exception = MockPryException.new("#{f.path}:1", "x", "x")
|
47
|
+
pry_instance.rep(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
str_output.string.should =~ /bt number 1/
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should cat second level of backtrace when --ex 1 used ' do
|
54
|
+
pry_instance = Pry.new(:input => StringIO.new("cat --ex 1"), :output => str_output = StringIO.new)
|
55
|
+
|
56
|
+
temp_file do |f|
|
57
|
+
f << "bt number 2"
|
58
|
+
f.flush
|
59
|
+
pry_instance.last_exception = MockPryException.new("x", "#{f.path}:1", "x")
|
60
|
+
pry_instance.rep(self)
|
61
|
+
end
|
12
62
|
|
13
|
-
|
14
|
-
mock_pry("broken_method", "cat --ex").should =~ /this method is broken/
|
63
|
+
str_output.string.should =~ /bt number 2/
|
15
64
|
end
|
65
|
+
|
66
|
+
it 'should cat third level of backtrace when --ex 2 used ' do
|
67
|
+
pry_instance = Pry.new(:input => StringIO.new("cat --ex 2"), :output => str_output = StringIO.new)
|
68
|
+
|
69
|
+
temp_file do |f|
|
70
|
+
f << "bt number 3"
|
71
|
+
f.flush
|
72
|
+
pry_instance.last_exception = MockPryException.new("x", "x", "#{f.path}:1")
|
73
|
+
pry_instance.rep(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
str_output.string.should =~ /bt number 3/
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should show error when backtrace level out of bounds ' do
|
80
|
+
pry_instance = Pry.new(:input => StringIO.new("cat --ex 3"), :output => str_output = StringIO.new)
|
81
|
+
pry_instance.last_exception = MockPryException.new("x", "x", "x")
|
82
|
+
pry_instance.rep(self)
|
83
|
+
str_output.string.should =~ /No Exception or Exception has no associated file/
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'each successive cat --ex should show the next level of backtrace, and going past the final level should return to the first' do
|
87
|
+
temp_files = []
|
88
|
+
3.times do |i|
|
89
|
+
temp_files << Tempfile.new(['tmp', '*.rb'])
|
90
|
+
temp_files.last << "bt number #{i}"
|
91
|
+
temp_files.last.flush
|
92
|
+
end
|
93
|
+
|
94
|
+
pry_instance = Pry.new(:input => StringIO.new("cat --ex\n" * 4),
|
95
|
+
:output => (str_output = StringIO.new))
|
96
|
+
|
97
|
+
pry_instance.last_exception = MockPryException.new(*temp_files.map { |f| "#{f.path}:1" })
|
98
|
+
|
99
|
+
3.times do |i|
|
100
|
+
pry_instance.rep(self)
|
101
|
+
str_output.string.should =~ /bt number #{i}/
|
102
|
+
end
|
103
|
+
|
104
|
+
str_output.reopen
|
105
|
+
pry_instance.rep(self)
|
106
|
+
str_output.string.should =~ /bt number 0/
|
107
|
+
|
108
|
+
temp_files.each(&:close)
|
109
|
+
end
|
110
|
+
|
16
111
|
end
|
17
112
|
end
|
18
113
|
end
|