pry 0.9.5-i386-mingw32 → 0.9.6-i386-mingw32
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.
- 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
|