pry 0.9.9.6 → 0.9.10pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CHANGELOG +35 -0
  2. data/CONTRIBUTORS +27 -26
  3. data/README.markdown +4 -4
  4. data/Rakefile +2 -2
  5. data/lib/pry.rb +25 -19
  6. data/lib/pry/cli.rb +31 -10
  7. data/lib/pry/code.rb +41 -83
  8. data/lib/pry/command.rb +87 -76
  9. data/lib/pry/command_set.rb +13 -20
  10. data/lib/pry/completion.rb +139 -121
  11. data/lib/pry/config.rb +4 -0
  12. data/lib/pry/core_extensions.rb +87 -30
  13. data/lib/pry/default_commands/cd.rb +31 -8
  14. data/lib/pry/default_commands/context.rb +4 -58
  15. data/lib/pry/default_commands/easter_eggs.rb +1 -1
  16. data/lib/pry/default_commands/editing.rb +21 -14
  17. data/lib/pry/default_commands/find_method.rb +5 -7
  18. data/lib/pry/default_commands/gist.rb +187 -0
  19. data/lib/pry/default_commands/hist.rb +6 -6
  20. data/lib/pry/default_commands/input_and_output.rb +73 -129
  21. data/lib/pry/default_commands/introspection.rb +107 -52
  22. data/lib/pry/default_commands/ls.rb +1 -1
  23. data/lib/pry/default_commands/misc.rb +0 -5
  24. data/lib/pry/default_commands/whereami.rb +92 -0
  25. data/lib/pry/helpers/base_helpers.rb +6 -1
  26. data/lib/pry/helpers/command_helpers.rb +30 -9
  27. data/lib/pry/helpers/documentation_helpers.rb +7 -7
  28. data/lib/pry/helpers/options_helpers.rb +1 -1
  29. data/lib/pry/helpers/text.rb +7 -9
  30. data/lib/pry/history.rb +15 -2
  31. data/lib/pry/hooks.rb +1 -1
  32. data/lib/pry/indent.rb +17 -10
  33. data/lib/pry/method.rb +35 -19
  34. data/lib/pry/module_candidate.rb +130 -0
  35. data/lib/pry/pry_class.rb +54 -22
  36. data/lib/pry/pry_instance.rb +71 -14
  37. data/lib/pry/repl_file_loader.rb +80 -0
  38. data/lib/pry/version.rb +1 -1
  39. data/lib/pry/wrapped_module.rb +121 -142
  40. data/pry.gemspec +12 -12
  41. data/test/candidate_helper1.rb +11 -0
  42. data/test/candidate_helper2.rb +8 -0
  43. data/test/helper.rb +16 -0
  44. data/test/test_code.rb +1 -1
  45. data/test/test_command.rb +364 -270
  46. data/test/test_command_integration.rb +235 -267
  47. data/test/test_completion.rb +36 -0
  48. data/test/test_control_d_handler.rb +45 -0
  49. data/test/test_default_commands/example.erb +5 -0
  50. data/test/test_default_commands/test_cd.rb +316 -11
  51. data/test/test_default_commands/test_context.rb +143 -192
  52. data/test/test_default_commands/test_documentation.rb +81 -14
  53. data/test/test_default_commands/test_find_method.rb +10 -2
  54. data/test/test_default_commands/test_input.rb +102 -111
  55. data/test/test_default_commands/test_introspection.rb +17 -12
  56. data/test/test_default_commands/test_ls.rb +8 -6
  57. data/test/test_default_commands/test_shell.rb +18 -15
  58. data/test/test_default_commands/test_show_source.rb +170 -44
  59. data/test/test_exception_whitelist.rb +6 -2
  60. data/test/test_hooks.rb +32 -0
  61. data/test/test_input_stack.rb +19 -16
  62. data/test/test_method.rb +0 -4
  63. data/test/test_prompt.rb +60 -0
  64. data/test/test_pry.rb +23 -31
  65. data/test/test_pry_defaults.rb +75 -57
  66. data/test/test_syntax_checking.rb +12 -11
  67. data/test/test_wrapped_module.rb +103 -0
  68. metadata +65 -24
@@ -22,5 +22,41 @@ describe Pry::InputCompleter do
22
22
  lambda{ completer.call "a.to_s." }.should.not.raise Exception
23
23
  end
24
24
  end
25
+
26
+ it 'should take parenthesis and other characters into account for symbols' do
27
+ b = Pry.binding_for(Object.new)
28
+ completer = Pry::InputCompleter.build_completion_proc(b)
29
+
30
+ lambda { completer.call(":class)") }.should.not.raise(RegexpError)
31
+ end
32
+
33
+ it 'should complete instance variables' do
34
+ object = Object.new
35
+
36
+ object.instance_variable_set(:'@name', 'Pry')
37
+ object.class.send(:class_variable_set, :'@@number', 10)
38
+
39
+ object.instance_variables.map { |v| v.to_sym } \
40
+ .include?(:'@name').should == true
41
+
42
+ object.class.class_variables.map { |v| v.to_sym } \
43
+ .include?(:'@@number').should == true
44
+
45
+ completer = Pry::InputCompleter.build_completion_proc(
46
+ Pry.binding_for(object)
47
+ )
48
+
49
+ # Complete instance variables.
50
+ completer.call('@na').include?('@name').should == true
51
+ completer.call('@name.down').include?('@name.downcase').should == true
52
+
53
+ # Complete class variables.
54
+ completer = Pry::InputCompleter.build_completion_proc(
55
+ Pry.binding_for(object.class)
56
+ )
57
+
58
+ completer.call('@@nu').include?('@@number').should == true
59
+ completer.call('@@number.cl').include?('@@number.class').should == true
60
+ end
25
61
  end
26
62
 
@@ -0,0 +1,45 @@
1
+ require 'helper'
2
+
3
+ describe Pry::DEFAULT_CONTROL_D_HANDLER do
4
+ describe 'control-d press' do
5
+ before do
6
+ @control_d = "Pry::DEFAULT_CONTROL_D_HANDLER.call('', _pry_)"
7
+ @binding_stack = "self.binding_stack = _pry_.binding_stack.dup"
8
+ end
9
+
10
+ describe 'in an expression' do
11
+ it 'should clear out passed string' do
12
+ str = "hello world"
13
+ Pry::DEFAULT_CONTROL_D_HANDLER.call(str, nil)
14
+ str.should == ""
15
+ end
16
+ end
17
+
18
+ describe 'at top-level session' do
19
+ it 'should break out of a REPL loop' do
20
+ instance = nil
21
+ redirect_pry_io(InputTester.new(@control_d)) do
22
+ instance = Pry.new
23
+ instance.repl
24
+ end
25
+
26
+ instance.binding_stack.should.be.empty
27
+ end
28
+ end
29
+
30
+ describe 'in a nested session' do
31
+ it 'should pop last binding from the binding stack' do
32
+ base = OpenStruct.new
33
+ base.obj = OpenStruct.new
34
+
35
+ redirect_pry_io(InputTester.new("cd obj", "self.stack_size = _pry_.binding_stack.size",
36
+ @control_d, "self.stack_size = _pry_.binding_stack.size", "exit-all")) do
37
+ Pry.start(base)
38
+ end
39
+
40
+ base.obj.stack_size.should == 2
41
+ base.stack_size.should == 1
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ <html>
2
+
3
+ Look at me, testing my erb!
4
+
5
+ </html>
@@ -1,16 +1,321 @@
1
1
  require 'helper'
2
2
 
3
- describe 'Pry::DefaultCommands::CD' do
4
- describe 'cd' do
5
- # Regression test for ticket #516.
6
- #it 'should be able to cd into the Object BasicObject.' do
7
- # mock_pry('cd BasicObject.new').should.not =~ /\Aundefined method `__binding__'/
8
- #end
9
-
10
- # Regression test for ticket #516
11
- # Possibly move higher up.
12
- it 'should not fail with undefined BasicObject#is_a?' do
13
- mock_pry('cd BasicObject.new').should.not =~ /undefined method `is_a\?'/
3
+ describe 'Pry::DefaultCommands::Cd' do
4
+ before do
5
+ @o, @obj = Object.new, Object.new
6
+ @obj.instance_variable_set(:@x, 66)
7
+ @obj.instance_variable_set(:@y, 79)
8
+ @o.instance_variable_set(:@obj, @obj)
9
+
10
+ # Shortcuts. They save a lot of typing.
11
+ @bs1 = "Pad.bs1 = _pry_.binding_stack.dup"
12
+ @bs2 = "Pad.bs2 = _pry_.binding_stack.dup"
13
+ @bs3 = "Pad.bs3 = _pry_.binding_stack.dup"
14
+
15
+ @os1 = "Pad.os1 = _pry_.command_state['cd'].old_stack.dup"
16
+ @os2 = "Pad.os2 = _pry_.command_state['cd'].old_stack.dup"
17
+
18
+ @self = "Pad.self = self"
19
+ @inner = "Pad.inner = self"
20
+ @outer = "Pad.outer = self"
21
+ end
22
+
23
+ after do
24
+ Pad.clear
25
+ end
26
+
27
+ describe 'state' do
28
+ it 'should not to be set up in fresh instance' do
29
+ redirect_pry_io(InputTester.new(@os1, "exit-all")) do
30
+ Pry.start(@o)
31
+ end
32
+
33
+ Pad.os1.should == nil
14
34
  end
15
35
  end
36
+
37
+ describe 'old stack toggling with `cd -`' do
38
+ describe 'in fresh pry instance' do
39
+ it 'should not toggle when there is no old stack' do
40
+ redirect_pry_io(InputTester.new("cd -", @bs1, "cd -",
41
+ @bs2, "exit-all")) do
42
+ Pry.start(@o)
43
+ end
44
+
45
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o]
46
+ Pad.bs2.map { |v| v.eval("self") }.should == [@o]
47
+ end
48
+ end
49
+
50
+ describe 'when an error was raised' do
51
+ it 'should ensure cd @ raises SyntaxError' do
52
+ mock_pry("cd @").should =~ /SyntaxError/
53
+ end
54
+
55
+ it 'should not toggle and should keep correct old stack' do
56
+ redirect_pry_io(InputTester.new("cd @", @os1, "cd -", @os2, "exit-all")) do
57
+ Pry.start(@o)
58
+ end
59
+
60
+ Pad.os1.should == []
61
+ Pad.os2.should == []
62
+ end
63
+
64
+ it 'should not toggle and should keep correct current binding stack' do
65
+ redirect_pry_io(InputTester.new("cd @", @bs1, "cd -", @bs2, "exit-all")) do
66
+ Pry.start(@o)
67
+ end
68
+
69
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o]
70
+ Pad.bs2.map { |v| v.eval("self") }.should == [@o]
71
+ end
72
+ end
73
+
74
+ describe 'when using simple cd syntax' do
75
+ it 'should toggle' do
76
+ redirect_pry_io(InputTester.new("cd :mon_dogg", "cd -", @bs1,
77
+ "cd -", @bs2, "exit-all")) do
78
+ Pry.start(@o)
79
+ end
80
+
81
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o]
82
+ Pad.bs2.map { |v| v.eval("self") }.should == [@o, :mon_dogg]
83
+ end
84
+ end
85
+
86
+ describe "when using complex cd syntax" do
87
+ it 'should toggle with a complex path (simple case)' do
88
+ redirect_pry_io(InputTester.new("cd 1/2/3", "cd -", @bs1,
89
+ "cd -", @bs2, "exit-all")) do
90
+ Pry.start(@o)
91
+ end
92
+
93
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o]
94
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, 1, 2, 3]
95
+ end
96
+
97
+ it 'should toggle with a complex path (more complex case)' do
98
+ redirect_pry_io(InputTester.new("cd 1/2/3", "cd ../4", "cd -",
99
+ @bs1, "cd -", @bs2, "exit-all")) do
100
+ Pry.start(@o)
101
+ end
102
+
103
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o, 1, 2, 3]
104
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, 1, 2, 4]
105
+ end
106
+ end
107
+
108
+ describe 'series of cd calls' do
109
+ it 'should toggle with fuzzy `cd -` calls' do
110
+ redirect_pry_io(InputTester.new("cd :mon_dogg", "cd -", "cd 42", "cd -",
111
+ @bs1, "cd -", @bs2, "exit-all")) do
112
+ Pry.start(@o)
113
+ end
114
+
115
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o]
116
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, 42]
117
+ end
118
+ end
119
+
120
+ describe 'when using cd ..' do
121
+ it 'should toggle with a simple path' do
122
+ redirect_pry_io(InputTester.new("cd :john_dogg", "cd ..", @bs1,
123
+ "cd -", @bs2, "exit-all")) do
124
+ Pry.start(@o)
125
+ end
126
+
127
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o]
128
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, :john_dogg]
129
+ end
130
+
131
+ it 'should toggle with a complex path' do
132
+ redirect_pry_io(InputTester.new("cd 1/2/3/../4", "cd -", @bs1,
133
+ "cd -", @bs2, "exit-all")) do
134
+ Pry.start(@o)
135
+ end
136
+
137
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o]
138
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, 1, 2, 4]
139
+ end
140
+ end
141
+
142
+ describe 'when using cd ::' do
143
+ it 'should toggle' do
144
+ redirect_pry_io(InputTester.new("cd ::", "cd -", @bs1,
145
+ "cd -", @bs2, "exit-all")) do
146
+ Pry.start(@o)
147
+ end
148
+
149
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o]
150
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, TOPLEVEL_BINDING.eval("self")]
151
+ end
152
+ end
153
+
154
+ describe 'when using cd /' do
155
+ it 'should toggle' do
156
+ redirect_pry_io(InputTester.new("cd /", "cd -", @bs1, "cd :john_dogg",
157
+ "cd /", "cd -", @bs2, "exit-all")) do
158
+ Pry.start(@o)
159
+ end
160
+
161
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o]
162
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, :john_dogg]
163
+ end
164
+ end
165
+
166
+ describe 'when using ^D (Control-D) key press' do
167
+ before do
168
+ @control_d = "Pry::DEFAULT_CONTROL_D_HANDLER.call('', _pry_)"
169
+ end
170
+
171
+ it 'should keep correct old binding' do
172
+ redirect_pry_io(InputTester.new("cd :john_dogg", "cd :mon_dogg",
173
+ "cd :kyr_dogg", @control_d, @bs1,
174
+ "cd -", @bs2, "cd -", @bs3, "exit-all")) do
175
+ Pry.start(@o)
176
+ end
177
+
178
+ Pad.bs1.map { |v| v.eval('self') }.should == [@o, :john_dogg, :mon_dogg]
179
+ Pad.bs2.map { |v| v.eval('self') }.should == [@o, :john_dogg, :mon_dogg, :kyr_dogg]
180
+ Pad.bs3.map { |v| v.eval('self') }.should == [@o, :john_dogg, :mon_dogg]
181
+ end
182
+ end
183
+ end
184
+
185
+ it 'should cd into simple input' do
186
+ redirect_pry_io(InputTester.new("cd :mon_ouie", @inner, "exit-all")) do
187
+ Pry.start(@o)
188
+ end
189
+
190
+ Pad.inner.should == :mon_ouie
191
+ end
192
+
193
+ it 'should break out of session with cd ..' do
194
+ redirect_pry_io(InputTester.new("cd :inner", @inner, "cd ..", @outer, "exit-all")) do
195
+ Pry.start(:outer)
196
+ end
197
+
198
+ Pad.inner.should == :inner
199
+ Pad.outer.should == :outer
200
+ end
201
+
202
+ it "should not leave the REPL session when given 'cd ..'" do
203
+ redirect_pry_io(InputTester.new("cd ..", @self, "exit-all")) do
204
+ Pry.start(@o)
205
+ end
206
+
207
+ Pad.self.should == @o
208
+ end
209
+
210
+ it 'should break out to outer-most session with cd /' do
211
+ redirect_pry_io(InputTester.new("cd :inner", @inner, "cd 5", "Pad.five = self",
212
+ "cd /", @outer, "exit-all")) do
213
+ Pry.start(:outer)
214
+ end
215
+
216
+ Pad.inner.should == :inner
217
+ Pad.five.should == 5
218
+ Pad.outer.should == :outer
219
+ end
220
+
221
+ it 'should break out to outer-most session with just cd (no args)' do
222
+ redirect_pry_io(InputTester.new("cd :inner", @inner, "cd 5", "Pad.five = self",
223
+ "cd", @outer, "exit-all")) do
224
+ Pry.start(:outer)
225
+ end
226
+
227
+ Pad.inner.should == :inner
228
+ Pad.five.should == 5
229
+ Pad.outer.should == :outer
230
+ end
231
+
232
+ it 'should cd into an object and its ivar using cd obj/@ivar syntax' do
233
+ redirect_pry_io(InputTester.new("cd @obj/@x", @bs1, "exit-all")) do
234
+ Pry.start(@o)
235
+ end
236
+
237
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o, @obj, 66]
238
+ end
239
+
240
+ it 'should cd into an object and its ivar using cd obj/@ivar/ syntax (note following /)' do
241
+ redirect_pry_io(InputTester.new("cd @obj/@x/", @bs1, "exit-all")) do
242
+ Pry.start(@o)
243
+ end
244
+
245
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o, @obj, 66]
246
+ end
247
+
248
+ it 'should cd into previous object and its local using cd ../local syntax' do
249
+ redirect_pry_io(InputTester.new("cd @obj", "local = :local", "cd @x",
250
+ "cd ../local", @bs1, "exit-all")) do
251
+ Pry.start(@o)
252
+ end
253
+
254
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o, @obj, :local]
255
+ end
256
+
257
+ it 'should cd into an object and its ivar and back again using cd obj/@ivar/.. syntax' do
258
+ redirect_pry_io(InputTester.new("cd @obj/@x/..", @bs1, "exit-all")) do
259
+ Pry.start(@o)
260
+ end
261
+
262
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o, @obj]
263
+ end
264
+
265
+ it 'should cd into an object and its ivar and back and then into another ivar using cd obj/@ivar/../@y syntax' do
266
+ redirect_pry_io(InputTester.new("cd @obj/@x/../@y", @bs1, "exit-all")) do
267
+ Pry.start(@o)
268
+ end
269
+
270
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o, @obj, 79]
271
+ end
272
+
273
+ it 'should cd back to top-level and then into another ivar using cd /@ivar/ syntax' do
274
+ redirect_pry_io(InputTester.new("@z = 20", "cd @obj/@x/", "cd /@z",
275
+ @bs1, "exit-all")) do
276
+ Pry.start(@o)
277
+ end
278
+
279
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o, 20]
280
+ end
281
+
282
+ it 'should start a session on TOPLEVEL_BINDING with cd ::' do
283
+ redirect_pry_io(InputTester.new("cd ::", @self, "exit-all")) do
284
+ Pry.start(@o)
285
+ end
286
+
287
+ Pad.self.should == TOPLEVEL_BINDING.eval("self")
288
+ end
289
+
290
+ it 'should cd into complex input (with spaces)' do
291
+ def @o.hello(x, y, z)
292
+ :mon_ouie
293
+ end
294
+
295
+ redirect_pry_io(InputTester.new("cd hello 1, 2, 3", @self, "exit-all")) do
296
+ Pry.start(@o)
297
+ end
298
+
299
+ Pad.self.should == :mon_ouie
300
+ end
301
+
302
+ it 'should not cd into complex input when it encounters an exception' do
303
+ redirect_pry_io(InputTester.new("cd 1/2/swoop_a_doop/3",
304
+ @bs1, "exit-all")) do
305
+ Pry.start(@o)
306
+ end
307
+
308
+ Pad.bs1.map { |v| v.eval("self") }.should == [@o]
309
+ end
310
+
311
+ # Regression test for ticket #516.
312
+ #it 'should be able to cd into the Object BasicObject.' do
313
+ # mock_pry('cd BasicObject.new').should.not =~ /\Aundefined method `__binding__'/
314
+ #end
315
+
316
+ # Regression test for ticket #516
317
+ # Possibly move higher up.
318
+ it 'should not fail with undefined BasicObject#is_a?' do
319
+ mock_pry('cd BasicObject.new').should.not =~ /undefined method `is_a\?'/
320
+ end
16
321
  end
@@ -1,29 +1,40 @@
1
1
  require 'helper'
2
2
 
3
3
  describe "Pry::DefaultCommands::Context" do
4
+
5
+ before do
6
+ @self = "Pad.self = self"
7
+ @inner = "Pad.inner = self"
8
+ @outer = "Pad.outer = self"
9
+ end
10
+
11
+ after do
12
+ Pad.clear
13
+ end
14
+
4
15
  describe "exit-all" do
5
16
  it 'should break out of the repl loop of Pry instance and return nil' do
6
- redirect_pry_io(InputTester.new("exit-all"), StringIO.new) do
17
+ redirect_pry_io(InputTester.new("exit-all")) do
7
18
  Pry.new.repl(0).should == nil
8
19
  end
9
20
  end
10
21
 
11
22
  it 'should break out of the repl loop of Pry instance wth a user specified value' do
12
- redirect_pry_io(InputTester.new("exit-all 'message'"), StringIO.new) do
23
+ redirect_pry_io(InputTester.new("exit-all 'message'")) do
13
24
  Pry.new.repl(0).should == 'message'
14
25
  end
15
26
  end
16
27
 
17
28
  it 'should break of the repl loop even if multiple bindings still on stack' do
18
29
  ins = nil
19
- redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all 'message'"), StringIO.new) do
30
+ redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all 'message'")) do
20
31
  ins = Pry.new.tap { |v| v.repl(0).should == 'message' }
21
32
  end
22
33
  end
23
34
 
24
35
  it 'binding_stack should be empty after breaking out of the repl loop' do
25
36
  ins = nil
26
- redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all"), StringIO.new) do
37
+ redirect_pry_io(InputTester.new("cd 1", "cd 2", "exit-all")) do
27
38
  ins = Pry.new.tap { |v| v.repl(0) }
28
39
  end
29
40
 
@@ -56,259 +67,199 @@ describe "Pry::DefaultCommands::Context" do
56
67
  Cor.new.blimey!
57
68
  Object.remove_const(:Cor)
58
69
  end
59
- end
60
-
61
- describe "exit" do
62
- it 'should pop a binding with exit' do
63
- b = Pry.binding_for(:outer)
64
- b.eval("x = :inner")
65
70
 
66
- redirect_pry_io(InputTester.new("cd x", "$inner = self;", "exit", "$outer = self", "exit-all"), StringIO.new) do
67
- b.pry
71
+ it 'should properly set _file_, _line_ and _dir_' do
72
+ class Cor
73
+ def blimey!
74
+ mock_pry(binding, 'whereami', '_file_') \
75
+ .should =~ /#{File.expand_path(__FILE__)}/
76
+ end
68
77
  end
69
- $inner.should == :inner
70
- $outer.should == :outer
71
- end
72
-
73
- it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit' do
74
- Pry.start(0, :input => StringIO.new("exit")).should == nil
75
- end
76
78
 
77
- 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
78
- Pry.start(0, :input => StringIO.new("exit :john")).should == :john
79
+ Cor.new.blimey!
80
+ Object.remove_const(:Cor)
79
81
  end
80
82
 
81
- it 'should break out the repl loop of Pry instance even after an exception in user-given value' do
82
- redirect_pry_io(InputTester.new("exit = 42", "exit"), StringIO.new) do
83
- ins = Pry.new.tap { |v| v.repl(0).should == nil }
83
+ it 'should show description and correct code when __LINE__ and __FILE__ are outside @method.source_location' do
84
+ class Cor
85
+ def blimey!
86
+ eval <<-END, binding, "test/test_default_commands/example.erb", 1
87
+ mock_pry(binding, 'whereami')
88
+ END
89
+ end
84
90
  end
85
- end
86
- end
87
91
 
88
- describe "jump-to" do
89
- it 'should jump to the proper binding index in the stack' do
90
- outp = StringIO.new
91
- redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 1", "$blah = self", "exit-all"), outp) do
92
- Pry.start(0)
93
- end
92
+ Cor.instance_method(:blimey!).source.should =~ /mock_pry/
94
93
 
95
- $blah.should == 1
94
+ Cor.new.blimey!.should =~ /Cor#blimey!.*Look at me/m
95
+ Object.remove_const(:Cor)
96
96
  end
97
97
 
98
- it 'should print error when trying to jump to a non-existent binding index' do
99
- outp = StringIO.new
100
- redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 100", "exit-all"), outp) do
101
- Pry.start(0)
98
+ it 'should show description and correct code when @method.source_location would raise an error' do
99
+ class Cor
100
+ eval <<-END, binding, "test/test_default_commands/example.erb", 1
101
+ def blimey!
102
+ mock_pry(binding, 'whereami')
103
+ end
104
+ END
102
105
  end
103
106
 
104
- outp.string.should =~ /Invalid nest level/
105
- end
107
+ lambda{
108
+ Cor.instance_method(:blimey!).source
109
+ }.should.raise(MethodSource::SourceNotFoundError)
106
110
 
107
- it 'should print error when trying to jump to the same binding index' do
108
- outp = StringIO.new
109
- redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 2", "exit-all"), outp) do
110
- Pry.new.repl(0)
111
- end
111
+ Cor.new.blimey!.should =~ /Cor#blimey!.*Look at me/m
112
+ Object.remove_const(:Cor)
112
113
 
113
- outp.string.should =~ /Already/
114
114
  end
115
- end
116
115
 
117
- describe "exit-program" do
118
- it 'should raise SystemExit' do
119
- redirect_pry_io(InputTester.new("exit-program"), StringIO.new) do
120
- lambda { Pry.new.repl(0).should == 0 }.should.raise SystemExit
116
+ it 'should display a description and and error if reading the file goes wrong' do
117
+ class Cor
118
+ def blimey!
119
+ eval <<-END, binding, "not.found.file.erb", 7
120
+ mock_pry(binding, 'whereami')
121
+ END
122
+ end
121
123
  end
124
+
125
+ Cor.new.blimey!.should =~ /From: not.found.file.erb @ line 7 Cor#blimey!:\n\nError: Cannot open "not.found.file.erb" for reading./m
126
+ Object.remove_const(:Cor)
122
127
  end
123
128
 
124
- it 'should exit the program with the provided value' do
125
- redirect_pry_io(InputTester.new("exit-program 66"), StringIO.new) do
126
- begin
127
- Pry.new.repl(0)
128
- rescue SystemExit => e
129
- e.status.should == 66
129
+ it 'should show code window (not just method source) if parameter passed to whereami' do
130
+ class Cor
131
+ def blimey!
132
+ mock_pry(binding, 'whereami 3').should =~ /class Cor/
130
133
  end
131
134
  end
135
+ Cor.new.blimey!
136
+ Object.remove_const(:Cor)
132
137
  end
133
- end
134
138
 
135
- describe "cd" do
136
- after do
137
- $obj = nil
138
- end
139
+ it 'should use Pry.config.default_window_size for window size when outside a method context' do
140
+ old_size, Pry.config.default_window_size = Pry.config.default_window_size, 1
141
+ :litella
142
+ :pig
143
+ out = mock_pry(binding, 'whereami')
144
+ :punk
145
+ :sanders
139
146
 
140
- it 'should cd into simple input' do
141
- b = Pry.binding_for(Object.new)
142
- b.eval("x = :mon_ouie")
147
+ out.should.not =~ /:litella/
148
+ out.should =~ /:pig/
149
+ out.should =~ /:punk/
150
+ out.should.not =~ /:sanders/
143
151
 
144
- redirect_pry_io(InputTester.new("cd x", "$obj = self", "exit-all"), StringIO.new) do
145
- b.pry
146
- end
152
+ Pry.config.default_window_size = old_size
153
+ end
147
154
 
148
- $obj.should == :mon_ouie
155
+ it "should work at the top level" do
156
+ mock_pry(Pry.toplevel_binding, 'whereami').should =~ /At the top level/
149
157
  end
150
158
 
151
- it 'should break out of session with cd ..' do
152
- b = Pry.binding_for(:outer)
153
- b.eval("x = :inner")
159
+ it "should work inside a class" do
160
+ mock_pry(Pry.binding_for(Pry), 'whereami').should =~ /Inside Pry/
161
+ end
154
162
 
155
- redirect_pry_io(InputTester.new("cd x", "$inner = self;", "cd ..", "$outer = self", "exit-all"), StringIO.new) do
156
- b.pry
157
- end
158
- $inner.should == :inner
159
- $outer.should == :outer
163
+ it "should work inside an object" do
164
+ mock_pry(Pry.binding_for(Object.new), 'whereami').should =~ /Inside #<Object/
160
165
  end
166
+ end
161
167
 
162
- it "should not leave the REPL session when given 'cd ..'" do
163
- b = Pry.binding_for(Object.new)
164
- input = InputTester.new "cd ..", "$obj = self", "exit-all"
165
-
166
- redirect_pry_io(input, StringIO.new) do
167
- b.pry
168
+ describe "exit" do
169
+ it 'should pop a binding with exit' do
170
+ redirect_pry_io(InputTester.new("cd :inner", @inner, "exit",
171
+ @outer, "exit-all")) do
172
+ Pry.start(:outer)
168
173
  end
169
174
 
170
- $obj.should == b.eval("self")
175
+ Pad.inner.should == :inner
176
+ Pad.outer.should == :outer
171
177
  end
172
178
 
173
- it 'should break out to outer-most session with cd /' do
174
- b = Pry.binding_for(:outer)
175
- b.eval("x = :inner")
176
-
177
- redirect_pry_io(InputTester.new("cd x", "$inner = self;", "cd 5", "$five = self", "cd /", "$outer = self", "exit-all"), StringIO.new) do
178
- b.pry
179
- end
180
- $inner.should == :inner
181
- $five.should == 5
182
- $outer.should == :outer
179
+ it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit' do
180
+ Pry.start(0, :input => StringIO.new("exit")).should == nil
183
181
  end
184
182
 
185
- it 'should break out to outer-most session with just cd (no args)' do
186
- b = Pry.binding_for(:outer)
187
- b.eval("x = :inner")
188
-
189
- redirect_pry_io(InputTester.new("cd x", "$inner = self;", "cd 5", "$five = self", "cd", "$outer = self", "exit-all"), StringIO.new) do
190
- b.pry
191
- end
192
- $inner.should == :inner
193
- $five.should == 5
194
- $outer.should == :outer
183
+ 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
184
+ Pry.start(0, :input => StringIO.new("exit :john")).should == :john
195
185
  end
196
186
 
197
- it 'should cd into an object and its ivar using cd obj/@ivar syntax' do
198
- $obj = Object.new
199
- $obj.instance_variable_set(:@x, 66)
200
-
201
- redirect_pry_io(InputTester.new("cd $obj/@x", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
202
- Pry.start
187
+ it 'should break out the repl loop of Pry instance even after an exception in user-given value' do
188
+ redirect_pry_io(InputTester.new("exit = 42", "exit")) do
189
+ ins = Pry.new.tap { |v| v.repl(0).should == nil }
203
190
  end
204
- $result.size.should == 3
205
- $result[1].eval('self').should == $obj
206
- $result[2].eval('self').should == 66
207
191
  end
192
+ end
208
193
 
209
- it 'should cd into an object and its ivar using cd obj/@ivar/ syntax (note following /)' do
210
- $obj = Object.new
211
- $obj.instance_variable_set(:@x, 66)
212
-
213
- redirect_pry_io(InputTester.new("cd $obj/@x/", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
214
- Pry.start
215
- end
216
- $result.size.should == 3
217
- $result[1].eval('self').should == $obj
218
- $result[2].eval('self').should == 66
194
+ describe "jump-to" do
195
+ before do
196
+ @str_output = StringIO.new
219
197
  end
220
198
 
221
- it 'should cd into previous object and its local using cd ../local syntax' do
222
- $obj = Object.new
223
- $obj.instance_variable_set(:@x, 66)
224
-
225
- redirect_pry_io(InputTester.new("cd $obj", "local = :local", "cd @x", "cd ../local", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
226
- Pry.start
199
+ it 'should jump to the proper binding index in the stack' do
200
+ redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 1", @self, "exit-all")) do
201
+ Pry.start(0)
227
202
  end
228
- $result.size.should == 3
229
- $result[1].eval('self').should == $obj
230
- $result[2].eval('self').should == :local
231
- end
232
-
233
- it 'should cd into an object and its ivar and back again using cd obj/@ivar/.. syntax' do
234
- $obj = Object.new
235
- $obj.instance_variable_set(:@x, 66)
236
203
 
237
- redirect_pry_io(InputTester.new("cd $obj/@x/..", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
238
- Pry.start
239
- end
240
- $result.size.should == 2
241
- $result[1].eval('self').should == $obj
204
+ Pad.self.should == 1
242
205
  end
243
206
 
244
- it 'should cd into an object and its ivar and back and then into another ivar using cd obj/@ivar/../@y syntax' do
245
- $obj = Object.new
246
- $obj.instance_variable_set(:@x, 66)
247
- $obj.instance_variable_set(:@y, 79)
248
-
249
- redirect_pry_io(InputTester.new("cd $obj/@x/../@y", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
250
- Pry.start
207
+ it 'should print error when trying to jump to a non-existent binding index' do
208
+ redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 100", "exit-all"), @str_output) do
209
+ Pry.start(0)
251
210
  end
252
- $result.size.should == 3
253
- $result[1].eval('self').should == $obj
254
- $result[2].eval('self').should == 79
255
- end
256
211
 
257
- it 'should cd back to top-level and then into another ivar using cd /@ivar/ syntax' do
258
- $obj = Object.new
259
- $obj.instance_variable_set(:@x, 66)
260
- TOPLEVEL_BINDING.eval('@z = 20')
261
-
262
- redirect_pry_io(InputTester.new("cd $obj/@x/", "cd /@z", "$result = _pry_.binding_stack.dup", "exit-all"), StringIO.new) do
263
- Pry.start
264
- end
265
- $result.size.should == 2
266
- $result[1].eval('self').should == 20
212
+ @str_output.string.should =~ /Invalid nest level/
267
213
  end
268
214
 
269
- it 'should start a session on TOPLEVEL_BINDING with cd ::' do
270
- redirect_pry_io(InputTester.new("cd ::", "$obj = self", "exit-all"), StringIO.new) do
271
- 5.pry
215
+ it 'should print error when trying to jump to the same binding index' do
216
+ redirect_pry_io(InputTester.new("cd 1", "cd 2", "jump-to 2", "exit-all"), @str_output) do
217
+ Pry.new.repl(0)
272
218
  end
273
- $obj.should == TOPLEVEL_BINDING.eval('self')
219
+
220
+ @str_output.string.should =~ /Already/
274
221
  end
222
+ end
275
223
 
276
- it 'should cd into complex input (with spaces)' do
277
- o = Object.new
278
- def o.hello(x, y, z)
279
- :mon_ouie
224
+ describe "exit-program" do
225
+ it 'should raise SystemExit' do
226
+ redirect_pry_io(InputTester.new("exit-program")) do
227
+ lambda { Pry.new.repl(0).should == 0 }.should.raise SystemExit
280
228
  end
229
+ end
281
230
 
282
- redirect_pry_io(InputTester.new("cd hello 1, 2, 3", "$obj = self", "exit-all"), StringIO.new) do
283
- o.pry
231
+ it 'should exit the program with the provided value' do
232
+ redirect_pry_io(InputTester.new("exit-program 66")) do
233
+ begin
234
+ Pry.new.repl(0)
235
+ rescue SystemExit => e
236
+ e.status.should == 66
237
+ end
284
238
  end
285
- $obj.should == :mon_ouie
286
239
  end
287
240
  end
288
241
 
289
242
  describe "raise-up" do
290
243
  it "should raise the exception with raise-up" do
291
- redirect_pry_io(InputTester.new("raise NoMethodError", "raise-up NoMethodError"),StringIO.new) do
244
+ redirect_pry_io(InputTester.new("raise NoMethodError", "raise-up NoMethodError")) do
292
245
  lambda { Pry.new.repl(0) }.should.raise NoMethodError
293
246
  end
294
247
  end
295
248
 
296
249
  it "should raise an unamed exception with raise-up" do
297
- redirect_pry_io(InputTester.new("raise 'stop'","raise-up 'noreally'"),StringIO.new) do
250
+ redirect_pry_io(InputTester.new("raise 'stop'","raise-up 'noreally'")) do
298
251
  lambda { Pry.new.repl(0) }.should.raise RuntimeError, "noreally"
299
252
  end
300
253
  end
301
254
 
302
255
  it "should eat the exception at the last new pry instance on raise-up" do
303
- b = Pry.binding_for(:outer)
304
- b.eval("x = :inner")
305
-
306
- redirect_pry_io(InputTester.new("x.pry", "raise NoMethodError",
307
- "$inner = self", "raise-up NoMethodError", "$outer = self", "exit-all"),StringIO.new) do
308
- b.pry
256
+ redirect_pry_io(InputTester.new(":inner.pry", "raise NoMethodError", @inner,
257
+ "raise-up NoMethodError", @outer, "exit-all")) do
258
+ Pry.start(:outer)
309
259
  end
310
- $inner.should == :inner
311
- $outer.should == :outer
260
+
261
+ Pad.inner.should == :inner
262
+ Pad.outer.should == :outer
312
263
  end
313
264
 
314
265
  it "should raise the most recently raised exception" do
@@ -316,16 +267,16 @@ describe "Pry::DefaultCommands::Context" do
316
267
  end
317
268
 
318
269
  it "should allow you to cd up and (eventually) out" do
319
- $deep = $inner = $outer = nil
320
- b = Pry.binding_for(:outer)
321
- b.eval("x = :inner")
322
- redirect_pry_io(InputTester.new("cd x", "raise NoMethodError","$inner = self",
323
- "deep = :deep", "cd deep","$deep = self","raise-up NoMethodError", "raise-up", "$outer = self", "raise-up", "exit-all"),StringIO.new) do
324
- lambda { b.pry }.should.raise NoMethodError
270
+ redirect_pry_io(InputTester.new("cd :inner", "raise NoMethodError", @inner,
271
+ "deep = :deep", "cd deep","Pad.deep = self",
272
+ "raise-up NoMethodError", "raise-up", @outer,
273
+ "raise-up", "exit-all")) do
274
+ lambda { Pry.start(:outer) }.should.raise NoMethodError
325
275
  end
326
- $deep.should == :deep
327
- $inner.should == :inner
328
- $outer.should == :outer
276
+
277
+ Pad.deep.should == :deep
278
+ Pad.inner.should == :inner
279
+ Pad.outer.should == :outer
329
280
  end
330
281
  end
331
282