pry 0.9.8.4 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG +26 -0
  3. data/README.markdown +3 -3
  4. data/lib/pry.rb +9 -1
  5. data/lib/pry/code.rb +93 -0
  6. data/lib/pry/command.rb +35 -22
  7. data/lib/pry/command_set.rb +97 -67
  8. data/lib/pry/config.rb +63 -10
  9. data/lib/pry/core_extensions.rb +24 -18
  10. data/lib/pry/default_commands/context.rb +72 -12
  11. data/lib/pry/default_commands/easter_eggs.rb +4 -0
  12. data/lib/pry/default_commands/editing.rb +43 -15
  13. data/lib/pry/default_commands/find_method.rb +171 -0
  14. data/lib/pry/default_commands/hist.rb +10 -6
  15. data/lib/pry/default_commands/introspection.rb +183 -30
  16. data/lib/pry/default_commands/ls.rb +77 -7
  17. data/lib/pry/default_commands/misc.rb +1 -0
  18. data/lib/pry/default_commands/navigating_pry.rb +1 -8
  19. data/lib/pry/helpers/base_helpers.rb +10 -2
  20. data/lib/pry/helpers/command_helpers.rb +23 -40
  21. data/lib/pry/helpers/documentation_helpers.rb +65 -0
  22. data/lib/pry/indent.rb +17 -4
  23. data/lib/pry/method.rb +61 -45
  24. data/lib/pry/pry_class.rb +9 -3
  25. data/lib/pry/pry_instance.rb +99 -65
  26. data/lib/pry/rbx_method.rb +2 -9
  27. data/lib/pry/version.rb +1 -1
  28. data/lib/pry/wrapped_module.rb +236 -1
  29. data/pry.gemspec +5 -5
  30. data/test/helper.rb +22 -0
  31. data/test/test_command.rb +29 -0
  32. data/test/test_command_integration.rb +193 -10
  33. data/test/test_command_set.rb +82 -17
  34. data/test/test_default_commands/test_cd.rb +16 -0
  35. data/test/test_default_commands/test_context.rb +61 -0
  36. data/test/test_default_commands/test_documentation.rb +163 -43
  37. data/test/test_default_commands/test_find_method.rb +42 -0
  38. data/test/test_default_commands/test_input.rb +32 -0
  39. data/test/test_default_commands/test_introspection.rb +50 -197
  40. data/test/test_default_commands/test_ls.rb +22 -0
  41. data/test/test_default_commands/test_show_source.rb +306 -0
  42. data/test/test_pry.rb +3 -3
  43. data/test/test_pry_defaults.rb +21 -0
  44. data/test/test_sticky_locals.rb +81 -1
  45. data/test/test_syntax_checking.rb +7 -6
  46. metadata +22 -14
@@ -58,6 +58,14 @@ describe "ls" do
58
58
  it "should still work" do
59
59
  mock_pry("cd Module.new{ def foobie; end }", "ls -M").should =~ /foobie/
60
60
  end
61
+
62
+ it "should work for ivars" do
63
+ mock_pry("module StigmaT1sm; def foobie; @@gharble = 456; end; end", "Object.new.tap{ |o| o.extend(StigmaT1sm) }.foobie", "cd StigmaT1sm", "ls -i").should =~ /@@gharble/
64
+ end
65
+
66
+ it "should include instance methods by default" do
67
+ mock_pry("ls Module.new{ def shinanagarns; 4; end }").should =~ /shinanagarns/
68
+ end
61
69
  end
62
70
 
63
71
  describe "constants" do
@@ -124,4 +132,18 @@ describe "ls" do
124
132
  end
125
133
  end
126
134
  end
135
+
136
+ if Pry::Helpers::BaseHelpers.jruby?
137
+ describe 'on java objects' do
138
+ it 'should omit java-esque aliases by default' do
139
+ mock_pry('ls java.lang.Thread.current_thread').should =~ / thread_group /
140
+ mock_pry('ls java.lang.Thread.current_thread').should.not =~ / getThreadGroup /
141
+ end
142
+
143
+ it 'should include java-esque aliases if requested' do
144
+ mock_pry('ls java.lang.Thread.current_thread -J').should =~ / thread_group /
145
+ mock_pry('ls java.lang.Thread.current_thread -J').should =~ / getThreadGroup /
146
+ end
147
+ end
148
+ end
127
149
  end
@@ -0,0 +1,306 @@
1
+ require 'helper'
2
+
3
+ if !mri18_and_no_real_source_location?
4
+ describe "show-source" do
5
+ it 'should output a method\'s source' do
6
+ str_output = StringIO.new
7
+ redirect_pry_io(InputTester.new("show-source sample_method", "exit-all"), str_output) do
8
+ pry
9
+ end
10
+
11
+ str_output.string.should =~ /def sample/
12
+ end
13
+
14
+ it 'should output help' do
15
+ mock_pry('show-source -h').should =~ /Usage: show-source/
16
+ end
17
+
18
+ it 'should output a method\'s source with line numbers' do
19
+ str_output = StringIO.new
20
+ redirect_pry_io(InputTester.new("show-source -l sample_method", "exit-all"), str_output) do
21
+ pry
22
+ end
23
+
24
+ str_output.string.should =~ /\d+: def sample/
25
+ end
26
+
27
+ it 'should output a method\'s source with line numbers starting at 1' do
28
+ str_output = StringIO.new
29
+ redirect_pry_io(InputTester.new("show-source -b sample_method", "exit-all"), str_output) do
30
+ pry
31
+ end
32
+
33
+ str_output.string.should =~ /1: def sample/
34
+ end
35
+
36
+ it 'should output a method\'s source if inside method without needing to use method name' do
37
+ $str_output = StringIO.new
38
+
39
+ o = Object.new
40
+ def o.sample
41
+ redirect_pry_io(InputTester.new("show-source", "exit-all"), $str_output) do
42
+ binding.pry
43
+ end
44
+ end
45
+ o.sample
46
+
47
+ $str_output.string.should =~ /def o.sample/
48
+ $str_output = nil
49
+ end
50
+
51
+ it 'should output a method\'s source if inside method without needing to use method name, and using the -l switch' do
52
+ $str_output = StringIO.new
53
+
54
+ o = Object.new
55
+ def o.sample
56
+ redirect_pry_io(InputTester.new("show-source -l", "exit-all"), $str_output) do
57
+ binding.pry
58
+ end
59
+ end
60
+ o.sample
61
+
62
+ $str_output.string.should =~ /\d+: def o.sample/
63
+ $str_output = nil
64
+ end
65
+
66
+ it "should find methods even if there are spaces in the arguments" do
67
+ o = Object.new
68
+ def o.foo(*bars);
69
+ "Mr flibble"
70
+ self;
71
+ end
72
+
73
+ str_output = StringIO.new
74
+ redirect_pry_io(InputTester.new("show-source o.foo('bar', 'baz bam').foo", "exit-all"), str_output) do
75
+ binding.pry
76
+ end
77
+ str_output.string.should =~ /Mr flibble/
78
+ end
79
+
80
+ it "should find methods even if the object has an overridden method method" do
81
+ c = Class.new{
82
+ def method;
83
+ 98
84
+ end
85
+ }
86
+
87
+ mock_pry(binding, "show-source c.new.method").should =~ /98/
88
+ end
89
+
90
+ it "should find instance_methods even if the class has an override instance_method method" do
91
+ c = Class.new{
92
+ def method;
93
+ 98
94
+ end
95
+
96
+ def self.instance_method; 789; end
97
+ }
98
+
99
+ mock_pry(binding, "show-source c#method").should =~ /98/
100
+ end
101
+
102
+ it "should find instance methods with -M" do
103
+ c = Class.new{ def moo; "ve over!"; end }
104
+ mock_pry(binding, "cd c","show-source -M moo").should =~ /ve over/
105
+ end
106
+
107
+ it "should not find instance methods with -m" do
108
+ c = Class.new{ def moo; "ve over!"; end }
109
+ mock_pry(binding, "cd c", "show-source -m moo").should =~ /could not be found/
110
+ end
111
+
112
+ it "should find normal methods with -m" do
113
+ c = Class.new{ def self.moo; "ve over!"; end }
114
+ mock_pry(binding, "cd c", "show-source -m moo").should =~ /ve over/
115
+ end
116
+
117
+ it "should not find normal methods with -M" do
118
+ c = Class.new{ def self.moo; "ve over!"; end }
119
+ mock_pry(binding, "cd c", "show-source -M moo").should =~ /could not be found/
120
+ end
121
+
122
+ it "should find normal methods with no -M or -m" do
123
+ c = Class.new{ def self.moo; "ve over!"; end }
124
+ mock_pry(binding, "cd c", "show-source moo").should =~ /ve over/
125
+ end
126
+
127
+ it "should find instance methods with no -M or -m" do
128
+ c = Class.new{ def moo; "ve over!"; end }
129
+ mock_pry(binding, "cd c", "show-source moo").should =~ /ve over/
130
+ end
131
+
132
+ it "should find super methods" do
133
+ class Foo
134
+ def foo(*bars)
135
+ :super_wibble
136
+ end
137
+ end
138
+ o = Foo.new
139
+ Object.remove_const(:Foo)
140
+ def o.foo(*bars)
141
+ :wibble
142
+ end
143
+
144
+ mock_pry(binding, "show-source --super o.foo").should =~ /:super_wibble/
145
+ end
146
+
147
+ it "should not raise an exception when a non-extant super method is requested" do
148
+ o = Object.new
149
+ def o.foo(*bars); end
150
+
151
+ mock_pry(binding, "show-source --super o.foo").should =~ /'self.foo' has no super method/
152
+ end
153
+
154
+ # dynamically defined method source retrieval is only supported in
155
+ # 1.9 - where Method#source_location is native
156
+ if RUBY_VERSION =~ /1.9/
157
+ it 'should output a method\'s source for a method defined inside pry' do
158
+ str_output = StringIO.new
159
+ redirect_pry_io(InputTester.new("def dyna_method", ":testing", "end", "show-source dyna_method"), str_output) do
160
+ TOPLEVEL_BINDING.pry
161
+ end
162
+
163
+ str_output.string.should =~ /def dyna_method/
164
+ Object.remove_method :dyna_method
165
+ end
166
+
167
+ it 'should output a method\'s source for a method defined inside pry, even if exceptions raised before hand' do
168
+ str_output = StringIO.new
169
+ redirect_pry_io(InputTester.new("bad code", "123", "bad code 2", "1 + 2", "def dyna_method", ":testing", "end", "show-source dyna_method"), str_output) do
170
+ TOPLEVEL_BINDING.pry
171
+ end
172
+
173
+ str_output.string.should =~ /def dyna_method/
174
+ Object.remove_method :dyna_method
175
+ end
176
+
177
+ it 'should output an instance method\'s source for a method defined inside pry' do
178
+ str_output = StringIO.new
179
+ Object.remove_const :A if defined?(A)
180
+ redirect_pry_io(InputTester.new("class A", "def yo", "end", "end", "show-source A#yo"), str_output) do
181
+ TOPLEVEL_BINDING.pry
182
+ end
183
+
184
+ str_output.string.should =~ /def yo/
185
+ Object.remove_const :A
186
+ end
187
+
188
+ it 'should output an instance method\'s source for a method defined inside pry using define_method' do
189
+ str_output = StringIO.new
190
+ Object.remove_const :A if defined?(A)
191
+ redirect_pry_io(InputTester.new("class A", "define_method(:yup) {}", "end", "show-source A#yup"), str_output) do
192
+ TOPLEVEL_BINDING.pry
193
+ end
194
+
195
+ str_output.string.should =~ /define_method\(:yup\)/
196
+ Object.remove_const :A
197
+ end
198
+ end
199
+
200
+ describe "on modules" do
201
+ before do
202
+ class ShowSourceTestClass
203
+ def alpha
204
+ end
205
+ end
206
+
207
+ module ShowSourceTestModule
208
+ def alpha
209
+ end
210
+ end
211
+
212
+ ShowSourceTestClassWeirdSyntax = Class.new do
213
+ def beta
214
+ end
215
+ end
216
+
217
+ ShowSourceTestModuleWeirdSyntax = Module.new do
218
+ def beta
219
+ end
220
+ end
221
+ end
222
+
223
+ after do
224
+ Object.remove_const :ShowSourceTestClass
225
+ Object.remove_const :ShowSourceTestClassWeirdSyntax
226
+ Object.remove_const :ShowSourceTestModule
227
+ Object.remove_const :ShowSourceTestModuleWeirdSyntax
228
+ end
229
+
230
+ describe "basic functionality, should find top-level module definitions" do
231
+ it 'should show source for a class' do
232
+ mock_pry("show-source ShowSourceTestClass").should =~ /class ShowSourceTest.*?def alpha/m
233
+ end
234
+
235
+ it 'should show source for a module' do
236
+ mock_pry("show-source ShowSourceTestModule").should =~ /module ShowSourceTestModule/
237
+ end
238
+
239
+ it 'should show source for a class when Const = Class.new syntax is used' do
240
+ mock_pry("show-source ShowSourceTestClassWeirdSyntax").should =~ /ShowSourceTestClassWeirdSyntax = Class.new/
241
+ end
242
+
243
+ it 'should show source for a module when Const = Module.new syntax is used' do
244
+ mock_pry("show-source ShowSourceTestModuleWeirdSyntax").should =~ /ShowSourceTestModuleWeirdSyntax = Module.new/
245
+ end
246
+ end
247
+
248
+ if !Pry::Helpers::BaseHelpers.mri_18?
249
+ describe "in REPL" do
250
+ it 'should find class defined in repl' do
251
+ mock_pry("class TobinaMyDog", "def woof", "end", "end", "show-source TobinaMyDog").should =~ /class TobinaMyDog/
252
+ Object.remove_const :TobinaMyDog
253
+ end
254
+ end
255
+ end
256
+
257
+ it 'should lookup module name with respect to current context' do
258
+ constant_scope(:AlphaClass, :BetaClass) do
259
+ class BetaClass
260
+ def alpha
261
+ end
262
+ end
263
+
264
+ class AlphaClass
265
+ class BetaClass
266
+ def beta
267
+ end
268
+ end
269
+ end
270
+
271
+ redirect_pry_io(InputTester.new("show-source BetaClass", "exit-all"), out=StringIO.new) do
272
+ AlphaClass.pry
273
+ end
274
+
275
+ out.string.should =~ /def beta/
276
+ end
277
+ end
278
+
279
+ it 'should lookup nested modules' do
280
+ constant_scope(:AlphaClass) do
281
+ class AlphaClass
282
+ class BetaClass
283
+ def beta
284
+ end
285
+ end
286
+ end
287
+
288
+ mock_pry("show-source AlphaClass::BetaClass").should =~ /class BetaClass/
289
+ end
290
+ end
291
+
292
+ describe "show-source -a" do
293
+ it 'should show the source for all monkeypatches defined in different files' do
294
+ class TestClassForShowSource
295
+ def beta
296
+ end
297
+ end
298
+
299
+ result = mock_pry("show-source TestClassForShowSource -a")
300
+ result.should =~ /def alpha/
301
+ result.should =~ /def beta/
302
+ end
303
+ end
304
+ end
305
+ end
306
+ end
@@ -188,7 +188,7 @@ describe Pry do
188
188
  it "should not mutate the input!" do
189
189
  clean = "puts <<-FOO\nhi\nFOO\n"
190
190
  a = clean.dup
191
- Pry.new.complete_expression?(a)
191
+ Pry::Code.complete_expression?(a)
192
192
  a.should == clean
193
193
  end
194
194
  end
@@ -444,8 +444,8 @@ describe Pry do
444
444
  str_output.string.should =~ /20/
445
445
  end
446
446
 
447
- it "should error if more than one argument is passed to Object#pry" do
448
- lambda { pry(20, :input => Readline) }.should.raise ArgumentError
447
+ it "should raise if more than two arguments are passed to Object#pry" do
448
+ lambda { pry(20, :quiet, :input => Readline) }.should.raise ArgumentError
449
449
  end
450
450
  end
451
451
 
@@ -377,4 +377,25 @@ describe "test Pry defaults" do
377
377
  Pry.reset_defaults
378
378
  Pry.color = false
379
379
  end
380
+
381
+ describe 'quiet' do
382
+ it 'should show whereami by default' do
383
+ output = StringIO.new
384
+ Pry.start(binding, :input => InputTester.new("1", "exit-all"),
385
+ :output => output,
386
+ :hooks => Pry::DEFAULT_HOOKS)
387
+
388
+ output.string.should =~ /[w]hereami by default/
389
+ end
390
+
391
+ it 'should hide whereami if quiet is set' do
392
+ output = StringIO.new
393
+ Pry.new(:input => InputTester.new("exit-all"),
394
+ :output => output,
395
+ :quiet => true,
396
+ :hooks => Pry::DEFAULT_HOOKS)
397
+
398
+ output.string.should == ""
399
+ end
400
+ end
380
401
  end
@@ -32,7 +32,87 @@ describe "Sticky locals (_file_ and friends)" do
32
32
  Pry.commands.delete "file-and-dir-test"
33
33
  end
34
34
 
35
- describe "User defined sticky locals, Pry#add_sticky_local()" do
35
+ describe "User defined sticky locals" do
36
+ describe "setting as Pry.config option" do
37
+ it 'should define a new sticky local for the session (normal value)' do
38
+ Pry.config.extra_sticky_locals[:test_local] = :john
39
+
40
+ o = Object.new
41
+ redirect_pry_io(InputTester.new("@value = test_local",
42
+ "exit-all")) do
43
+ Pry.start(o)
44
+ end
45
+
46
+ o.instance_variable_get(:@value).should == :john
47
+ Pry.config.extra_sticky_locals = {}
48
+ end
49
+
50
+ it 'should define a new sticky local for the session (proc)' do
51
+ Pry.config.extra_sticky_locals[:test_local] = proc { :john }
52
+
53
+ o = Object.new
54
+ redirect_pry_io(InputTester.new("@value = test_local",
55
+ "exit-all")) do
56
+ Pry.start(o)
57
+ end
58
+
59
+ o.instance_variable_get(:@value).should == :john
60
+ Pry.config.extra_sticky_locals = {}
61
+ end
62
+
63
+ end
64
+
65
+ describe "passing in as hash option when creating pry instance" do
66
+ it 'should define a new sticky local for the session (normal value)' do
67
+ o = Object.new
68
+ redirect_pry_io(InputTester.new("@value = test_local",
69
+ "exit-all")) do
70
+ Pry.start(o, :extra_sticky_locals => { :test_local => :john } )
71
+ end
72
+
73
+ o.instance_variable_get(:@value).should == :john
74
+ end
75
+
76
+ it 'should define multiple sticky locals' do
77
+ o = Object.new
78
+ redirect_pry_io(InputTester.new("@value1 = test_local1",
79
+ "@value2 = test_local2",
80
+ "exit-all")) do
81
+ Pry.start(o, :extra_sticky_locals => { :test_local1 => :john ,
82
+ :test_local2 => :carl} )
83
+ end
84
+
85
+ o.instance_variable_get(:@value1).should == :john
86
+ o.instance_variable_get(:@value2).should == :carl
87
+ end
88
+
89
+
90
+ it 'should define a new sticky local for the session (as Proc)' do
91
+ o = Object.new
92
+ redirect_pry_io(InputTester.new("@value = test_local",
93
+ "exit-all")) do
94
+ Pry.start(o, :extra_sticky_locals => { :test_local => proc { :john }} )
95
+ end
96
+
97
+ o.instance_variable_get(:@value).should == :john
98
+ end
99
+ end
100
+
101
+ describe "hash option value should override config value" do
102
+ it 'should define a new sticky local for the session (normal value)' do
103
+ Pry.config.extra_sticky_locals[:test_local] = :john
104
+
105
+ o = Object.new
106
+ redirect_pry_io(InputTester.new("@value = test_local",
107
+ "exit-all")) do
108
+ Pry.start(o, :extra_sticky_locals => { :test_local => :carl })
109
+ end
110
+
111
+ o.instance_variable_get(:@value).should == :carl
112
+ Pry.config.extra_sticky_locals = {}
113
+ end
114
+ end
115
+
36
116
  it 'should create a new sticky local' do
37
117
  o = Object.new
38
118
  pi = Pry.new