pry 0.10.2-i386-mswin32 → 1.0.0.pre1-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. data/.document +2 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +21 -0
  4. data/.yardopts +3 -0
  5. data/CHANGELOG +503 -0
  6. data/CONTRIBUTORS +55 -0
  7. data/Gemfile +9 -0
  8. data/Guardfile +62 -0
  9. data/LICENSE +2 -2
  10. data/{README.md → README.markdown} +31 -37
  11. data/Rakefile +144 -0
  12. data/TODO +117 -0
  13. data/lib/pry.rb +146 -33
  14. data/lib/pry/cli.rb +13 -35
  15. data/lib/pry/code.rb +63 -24
  16. data/lib/pry/code/loc.rb +2 -2
  17. data/lib/pry/code_object.rb +21 -40
  18. data/lib/pry/command.rb +6 -9
  19. data/lib/pry/command_set.rb +37 -80
  20. data/lib/pry/commands.rb +1 -1
  21. data/lib/pry/commands/amend_line.rb +1 -1
  22. data/lib/pry/commands/bang.rb +1 -1
  23. data/lib/pry/commands/cat.rb +2 -11
  24. data/lib/pry/commands/cat/abstract_formatter.rb +1 -1
  25. data/lib/pry/commands/cat/exception_formatter.rb +7 -6
  26. data/lib/pry/commands/cat/file_formatter.rb +32 -15
  27. data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
  28. data/lib/pry/commands/cd.rb +3 -14
  29. data/lib/pry/commands/code_collector.rb +4 -4
  30. data/lib/pry/commands/easter_eggs.rb +3 -3
  31. data/lib/pry/commands/edit.rb +22 -10
  32. data/lib/pry/commands/edit/exception_patcher.rb +1 -1
  33. data/lib/pry/commands/edit/file_and_line_locator.rb +2 -0
  34. data/lib/pry/{method/patcher.rb → commands/edit/method_patcher.rb} +37 -40
  35. data/lib/pry/commands/find_method.rb +22 -16
  36. data/lib/pry/commands/gem_install.rb +2 -5
  37. data/lib/pry/commands/gem_open.rb +1 -1
  38. data/lib/pry/commands/gist.rb +11 -10
  39. data/lib/pry/commands/help.rb +14 -14
  40. data/lib/pry/commands/hist.rb +5 -24
  41. data/lib/pry/commands/ls.rb +287 -56
  42. data/lib/pry/commands/play.rb +10 -44
  43. data/lib/pry/commands/pry_backtrace.rb +2 -1
  44. data/lib/pry/commands/raise_up.rb +1 -1
  45. data/lib/pry/commands/reload_code.rb +15 -31
  46. data/lib/pry/commands/ri.rb +3 -7
  47. data/lib/pry/commands/shell_command.rb +12 -17
  48. data/lib/pry/commands/shell_mode.rb +2 -2
  49. data/lib/pry/commands/show_doc.rb +0 -5
  50. data/lib/pry/commands/show_info.rb +10 -11
  51. data/lib/pry/commands/show_source.rb +3 -15
  52. data/lib/pry/commands/simple_prompt.rb +1 -1
  53. data/lib/pry/commands/toggle_color.rb +4 -8
  54. data/lib/pry/commands/whereami.rb +10 -18
  55. data/lib/pry/completion.rb +293 -0
  56. data/lib/pry/config.rb +233 -20
  57. data/lib/pry/core_extensions.rb +19 -29
  58. data/lib/pry/custom_completions.rb +6 -0
  59. data/lib/pry/editor.rb +103 -109
  60. data/lib/pry/helpers/base_helpers.rb +109 -22
  61. data/lib/pry/helpers/command_helpers.rb +8 -10
  62. data/lib/pry/helpers/documentation_helpers.rb +2 -1
  63. data/lib/pry/helpers/text.rb +5 -4
  64. data/lib/pry/history.rb +10 -21
  65. data/lib/pry/history_array.rb +0 -5
  66. data/lib/pry/hooks.rb +29 -9
  67. data/lib/pry/indent.rb +10 -5
  68. data/lib/pry/method.rb +86 -81
  69. data/lib/pry/method/weird_method_locator.rb +2 -4
  70. data/lib/pry/module_candidate.rb +14 -5
  71. data/lib/pry/pager.rb +48 -193
  72. data/lib/pry/plugins.rb +2 -2
  73. data/lib/pry/pry_class.rb +193 -104
  74. data/lib/pry/pry_instance.rb +154 -152
  75. data/lib/pry/rbx_method.rb +13 -0
  76. data/lib/pry/rbx_path.rb +1 -1
  77. data/lib/pry/repl.rb +14 -17
  78. data/lib/pry/repl_file_loader.rb +3 -8
  79. data/lib/pry/rubygem.rb +3 -3
  80. data/lib/pry/terminal.rb +3 -4
  81. data/lib/pry/test/helper.rb +11 -6
  82. data/lib/pry/version.rb +1 -1
  83. data/lib/pry/wrapped_module.rb +56 -49
  84. data/man/pry.1 +195 -0
  85. data/man/pry.1.html +204 -0
  86. data/man/pry.1.ronn +141 -0
  87. data/pry.gemspec +31 -0
  88. data/spec/Procfile +3 -0
  89. data/spec/cli_spec.rb +78 -0
  90. data/spec/code_object_spec.rb +277 -0
  91. data/spec/code_spec.rb +219 -0
  92. data/spec/command_helpers_spec.rb +29 -0
  93. data/spec/command_integration_spec.rb +562 -0
  94. data/spec/command_set_spec.rb +627 -0
  95. data/spec/command_spec.rb +821 -0
  96. data/spec/commands/amend_line_spec.rb +247 -0
  97. data/spec/commands/bang_spec.rb +18 -0
  98. data/spec/commands/cat_spec.rb +164 -0
  99. data/spec/commands/cd_spec.rb +250 -0
  100. data/spec/commands/disable_pry_spec.rb +25 -0
  101. data/spec/commands/edit_spec.rb +725 -0
  102. data/spec/commands/exit_all_spec.rb +27 -0
  103. data/spec/commands/exit_program_spec.rb +19 -0
  104. data/spec/commands/exit_spec.rb +28 -0
  105. data/spec/commands/find_method_spec.rb +70 -0
  106. data/spec/commands/gem_list_spec.rb +26 -0
  107. data/spec/commands/gist_spec.rb +79 -0
  108. data/spec/commands/help_spec.rb +56 -0
  109. data/spec/commands/hist_spec.rb +172 -0
  110. data/spec/commands/jump_to_spec.rb +15 -0
  111. data/spec/commands/ls_spec.rb +189 -0
  112. data/spec/commands/play_spec.rb +136 -0
  113. data/spec/commands/raise_up_spec.rb +56 -0
  114. data/spec/commands/save_file_spec.rb +177 -0
  115. data/spec/commands/show_doc_spec.rb +488 -0
  116. data/spec/commands/show_input_spec.rb +17 -0
  117. data/spec/commands/show_source_spec.rb +760 -0
  118. data/spec/commands/whereami_spec.rb +203 -0
  119. data/spec/completion_spec.rb +221 -0
  120. data/spec/control_d_handler_spec.rb +62 -0
  121. data/spec/documentation_helper_spec.rb +73 -0
  122. data/spec/editor_spec.rb +79 -0
  123. data/spec/exception_whitelist_spec.rb +21 -0
  124. data/spec/fixtures/candidate_helper1.rb +11 -0
  125. data/spec/fixtures/candidate_helper2.rb +8 -0
  126. data/spec/fixtures/example.erb +5 -0
  127. data/spec/fixtures/example_nesting.rb +33 -0
  128. data/spec/fixtures/show_source_doc_examples.rb +15 -0
  129. data/spec/fixtures/testlinkrc +2 -0
  130. data/spec/fixtures/testrc +2 -0
  131. data/spec/fixtures/testrcbad +2 -0
  132. data/spec/fixtures/whereami_helper.rb +6 -0
  133. data/spec/helper.rb +35 -0
  134. data/spec/helpers/bacon.rb +86 -0
  135. data/spec/helpers/mock_pry.rb +44 -0
  136. data/spec/helpers/repl_tester.rb +112 -0
  137. data/spec/helpers/table_spec.rb +105 -0
  138. data/spec/history_array_spec.rb +67 -0
  139. data/spec/hooks_spec.rb +522 -0
  140. data/spec/indent_spec.rb +301 -0
  141. data/spec/method_spec.rb +482 -0
  142. data/spec/prompt_spec.rb +61 -0
  143. data/spec/pry_defaults_spec.rb +420 -0
  144. data/spec/pry_history_spec.rb +69 -0
  145. data/spec/pry_output_spec.rb +95 -0
  146. data/spec/pry_repl_spec.rb +86 -0
  147. data/spec/pry_spec.rb +394 -0
  148. data/spec/pryrc_spec.rb +97 -0
  149. data/spec/run_command_spec.rb +25 -0
  150. data/spec/sticky_locals_spec.rb +147 -0
  151. data/spec/syntax_checking_spec.rb +81 -0
  152. data/spec/wrapped_module_spec.rb +261 -0
  153. data/wiki/Customizing-pry.md +397 -0
  154. data/wiki/Home.md +4 -0
  155. metadata +272 -61
  156. checksums.yaml +0 -7
  157. data/CHANGELOG.md +0 -714
  158. data/lib/pry/code/code_file.rb +0 -103
  159. data/lib/pry/color_printer.rb +0 -55
  160. data/lib/pry/commands/change_inspector.rb +0 -27
  161. data/lib/pry/commands/change_prompt.rb +0 -26
  162. data/lib/pry/commands/list_inspectors.rb +0 -35
  163. data/lib/pry/commands/list_prompts.rb +0 -35
  164. data/lib/pry/commands/ls/constants.rb +0 -47
  165. data/lib/pry/commands/ls/formatter.rb +0 -49
  166. data/lib/pry/commands/ls/globals.rb +0 -48
  167. data/lib/pry/commands/ls/grep.rb +0 -21
  168. data/lib/pry/commands/ls/instance_vars.rb +0 -39
  169. data/lib/pry/commands/ls/interrogatable.rb +0 -18
  170. data/lib/pry/commands/ls/jruby_hacks.rb +0 -49
  171. data/lib/pry/commands/ls/local_names.rb +0 -35
  172. data/lib/pry/commands/ls/local_vars.rb +0 -39
  173. data/lib/pry/commands/ls/ls_entity.rb +0 -70
  174. data/lib/pry/commands/ls/methods.rb +0 -57
  175. data/lib/pry/commands/ls/methods_helper.rb +0 -46
  176. data/lib/pry/commands/ls/self_methods.rb +0 -32
  177. data/lib/pry/commands/watch_expression.rb +0 -105
  178. data/lib/pry/commands/watch_expression/expression.rb +0 -38
  179. data/lib/pry/config/behavior.rb +0 -139
  180. data/lib/pry/config/convenience.rb +0 -25
  181. data/lib/pry/config/default.rb +0 -161
  182. data/lib/pry/exceptions.rb +0 -78
  183. data/lib/pry/input_completer.rb +0 -242
  184. data/lib/pry/input_lock.rb +0 -132
  185. data/lib/pry/inspector.rb +0 -27
  186. data/lib/pry/last_exception.rb +0 -61
  187. data/lib/pry/object_path.rb +0 -82
  188. data/lib/pry/output.rb +0 -50
  189. data/lib/pry/prompt.rb +0 -26
@@ -0,0 +1,25 @@
1
+ require 'helper'
2
+
3
+ describe "disable-pry" do
4
+ before do
5
+ @t = pry_tester
6
+ end
7
+
8
+ after do
9
+ ENV.delete 'DISABLE_PRY'
10
+ end
11
+
12
+ it 'should quit the current session' do
13
+ lambda{
14
+ @t.process_command 'disable-pry'
15
+ }.should.throw(:breakout)
16
+ end
17
+
18
+ it "should set DISABLE_PRY" do
19
+ ENV['DISABLE_PRY'].should == nil
20
+ lambda{
21
+ @t.process_command 'disable-pry'
22
+ }.should.throw(:breakout)
23
+ ENV['DISABLE_PRY'].should == 'true'
24
+ end
25
+ end
@@ -0,0 +1,725 @@
1
+ require 'pathname'
2
+ require 'helper'
3
+
4
+ describe "edit" do
5
+ before do
6
+ @old_editor = Pry.config.editor
7
+ @file = @line = @contents = nil
8
+ Pry.config.editor = lambda do |file, line|
9
+ @file = file; @line = line; @contents = File.read(@file)
10
+ nil
11
+ end
12
+ end
13
+
14
+ after do
15
+ Pry.config.editor = @old_editor
16
+ end
17
+
18
+ describe "with FILE" do
19
+
20
+ before do
21
+ # OS-specific tempdir name. For GNU/Linux it's "tmp", for Windows it's
22
+ # something "Temp".
23
+ @tf_dir =
24
+ if Pry::Helpers::BaseHelpers.mri_19?
25
+ Pathname.new(Dir::Tmpname.tmpdir)
26
+ else
27
+ Pathname.new(Dir.tmpdir)
28
+ end
29
+
30
+ @tf_path = File.expand_path(File.join(@tf_dir.to_s, 'bar.rb'))
31
+ FileUtils.touch(@tf_path)
32
+ end
33
+
34
+ after do
35
+ FileUtils.rm(@tf_path) if File.exists?(@tf_path)
36
+ end
37
+
38
+ it "should invoke Pry.config.editor with absolutified filenames" do
39
+ pry_eval 'edit lib/pry.rb'
40
+ @file.should == File.expand_path('lib/pry.rb')
41
+
42
+ pry_eval "edit #@tf_path"
43
+ @file.should == @tf_path
44
+ end
45
+
46
+ it "should guess the line number from a colon" do
47
+ pry_eval 'edit lib/pry.rb:10'
48
+ @line.should == 10
49
+ end
50
+
51
+ it "should use the line number from -l" do
52
+ pry_eval 'edit -l 10 lib/pry.rb'
53
+ @line.should == 10
54
+ end
55
+
56
+ it "should not delete the file!" do
57
+ pry_eval 'edit Rakefile'
58
+ File.exist?(@file).should == true
59
+ end
60
+
61
+ it "works with files that contain blanks in their names" do
62
+ tf_path = File.join(File.dirname(@tf_path), 'swoop and doop.rb')
63
+ FileUtils.touch(tf_path)
64
+ pry_eval "edit #{ tf_path }"
65
+ @file.should == tf_path
66
+ FileUtils.rm(tf_path)
67
+ end
68
+
69
+ describe do
70
+ before do
71
+ Pad.counter = 0
72
+ Pry.config.editor = lambda { |file, line|
73
+ File.open(file, 'w') { |f| f << "Pad.counter = Pad.counter + 1" }
74
+ nil
75
+ }
76
+ end
77
+
78
+ it "should reload the file if it is a ruby file" do
79
+ temp_file do |tf|
80
+ counter = Pad.counter
81
+ path = tf.path
82
+
83
+ pry_eval "edit #{path}"
84
+
85
+ Pad.counter.should == counter + 1
86
+ end
87
+ end
88
+
89
+ it "should not reload the file if it is not a ruby file" do
90
+ temp_file('.py') do |tf|
91
+ counter = Pad.counter
92
+ path = tf.path
93
+
94
+ pry_eval "edit #{path}"
95
+
96
+ Pad.counter.should == counter
97
+ end
98
+ end
99
+
100
+ it "should not reload a ruby file if -n is given" do
101
+ temp_file do |tf|
102
+ counter = Pad.counter
103
+ path = tf.path
104
+
105
+ Pad.counter.should == counter
106
+ end
107
+ end
108
+
109
+ it "should reload a non-ruby file if -r is given" do
110
+ temp_file('.pryrc') do |tf|
111
+ counter = Pad.counter
112
+ path = tf.path
113
+
114
+ pry_eval "edit -r #{path}"
115
+
116
+ Pad.counter.should == counter + 1
117
+ end
118
+ end
119
+ end
120
+
121
+ describe do
122
+ before do
123
+ @reloading = nil
124
+ Pry.config.editor = lambda do |file, line, reloading|
125
+ @file = file; @line = line; @reloading = reloading
126
+ nil
127
+ end
128
+ end
129
+
130
+ it "should pass the editor a reloading arg" do
131
+ pry_eval 'edit lib/pry.rb'
132
+ @reloading.should == true
133
+ pry_eval 'edit -n lib/pry.rb'
134
+ @reloading.should == false
135
+ end
136
+ end
137
+ end
138
+
139
+ describe "with --ex" do
140
+ before do
141
+ @t = pry_tester do
142
+ def last_exception=(exception)
143
+ @pry.last_exception = exception
144
+ end
145
+ def last_exception; @pry.last_exception; end
146
+ end
147
+ end
148
+
149
+ describe "with a real file" do
150
+ before do
151
+ @tf = Tempfile.new(["pry", ".rb"])
152
+ @path = @tf.path
153
+ @tf << "1\n2\nraise RuntimeError"
154
+ @tf.flush
155
+
156
+ begin
157
+ load @path
158
+ rescue RuntimeError => e
159
+ @t.last_exception = e
160
+ end
161
+ end
162
+
163
+ after do
164
+ @tf.close(true)
165
+ File.unlink("#{@path}c") if File.exists?("#{@path}c") #rbx
166
+ end
167
+
168
+ it "should reload the file" do
169
+ Pry.config.editor = lambda {|file, line|
170
+ File.open(file, 'w'){|f| f << "FOO = 'BAR'" }
171
+ nil
172
+ }
173
+
174
+ defined?(FOO).should.be.nil
175
+
176
+ @t.eval 'edit --ex'
177
+
178
+ FOO.should == 'BAR'
179
+ end
180
+
181
+ # regression test (this used to edit the current method instead
182
+ # of the exception)
183
+ it 'edits the exception even when in a patched method context' do
184
+ source_location = nil
185
+ Pry.config.editor = lambda {|file, line|
186
+ source_location = [file, line]
187
+ nil
188
+ }
189
+
190
+ Pad.le = @t.last_exception
191
+ redirect_pry_io(InputTester.new("def broken_method", "binding.pry", "end",
192
+ "broken_method",
193
+ "_pry_.last_exception = Pad.le",
194
+ "edit --ex -n", "exit-all", "exit-all")) do
195
+ Object.new.pry
196
+ end
197
+
198
+ source_location.should == [@path, 3]
199
+ Pad.clear
200
+ end
201
+
202
+ it "should not reload the file if -n is passed" do
203
+ Pry.config.editor = lambda {|file, line|
204
+ File.open(file, 'w'){|f| f << "FOO2 = 'BAZ'" }
205
+ nil
206
+ }
207
+
208
+ defined?(FOO2).should.be.nil
209
+
210
+ @t.eval 'edit -n --ex'
211
+
212
+ defined?(FOO2).should.be.nil
213
+ end
214
+
215
+ describe "with --patch" do
216
+ # Original source code must be untouched.
217
+ it "should apply changes only in memory (monkey patching)" do
218
+ Pry.config.editor = lambda {|file, line|
219
+ File.open(file, 'w'){|f| f << "FOO3 = 'PIYO'" }
220
+ @patched_def = File.open(file, 'r').read
221
+ nil
222
+ }
223
+
224
+ defined?(FOO3).should.be.nil
225
+
226
+ @t.eval 'edit --ex --patch'
227
+
228
+ FOO3.should == 'PIYO'
229
+
230
+ @tf.rewind
231
+ @tf.read.should == "1\n2\nraise RuntimeError"
232
+ @patched_def.should == "FOO3 = 'PIYO'"
233
+ end
234
+ end
235
+ end
236
+
237
+ describe "with --ex NUM" do
238
+ before do
239
+ Pry.config.editor = proc do |file, line|
240
+ @__ex_file__ = file
241
+ @__ex_line__ = line
242
+ nil
243
+ end
244
+
245
+ @t.last_exception = mock_exception('a:1', 'b:2', 'c:3')
246
+ end
247
+
248
+ it 'should start on first level of backtrace with just --ex' do
249
+ @t.eval 'edit -n --ex'
250
+ @__ex_file__.should == "a"
251
+ @__ex_line__.should == 1
252
+ end
253
+
254
+ it 'should start editor on first level of backtrace with --ex 0' do
255
+ @t.eval 'edit -n --ex 0'
256
+ @__ex_file__.should == "a"
257
+ @__ex_line__.should == 1
258
+ end
259
+
260
+ it 'should start editor on second level of backtrace with --ex 1' do
261
+ @t.eval 'edit -n --ex 1'
262
+ @__ex_file__.should == "b"
263
+ @__ex_line__.should == 2
264
+ end
265
+
266
+ it 'should start editor on third level of backtrace with --ex 2' do
267
+ @t.eval 'edit -n --ex 2'
268
+ @__ex_file__.should == "c"
269
+ @__ex_line__.should == 3
270
+ end
271
+
272
+ it 'should display error message when backtrace level is invalid' do
273
+ proc {
274
+ @t.eval 'edit -n --ex 4'
275
+ }.should.raise(Pry::CommandError)
276
+ end
277
+ end
278
+ end
279
+
280
+ describe "without FILE" do
281
+ before do
282
+ @t = pry_tester
283
+ end
284
+
285
+ it "should edit the current expression if it's incomplete" do
286
+ @t.push 'def a'
287
+ @t.process_command 'edit'
288
+ @contents.should == "def a\n"
289
+ end
290
+
291
+ it "should edit the previous expression if the current is empty" do
292
+ @t.eval 'def a; 2; end', 'edit'
293
+ @contents.should == "def a; 2; end\n"
294
+ end
295
+
296
+ it "should use a blank file if -t is specified" do
297
+ @t.eval 'def a; 5; end', 'edit -t'
298
+ @contents.should == "\n"
299
+ end
300
+
301
+ it "should use a blank file if -t given, even during an expression" do
302
+ @t.push 'def a;'
303
+ @t.process_command 'edit -t'
304
+ @contents.should == "\n"
305
+ end
306
+
307
+ it "should position the cursor at the end of the expression" do
308
+ @t.eval "def a; 2;\nend"
309
+ @t.process_command 'edit'
310
+ @line.should == 2
311
+ end
312
+
313
+ it "should evaluate the expression" do
314
+ Pry.config.editor = lambda {|file, line|
315
+ File.open(file, 'w'){|f| f << "'FOO'\n" }
316
+ nil
317
+ }
318
+ @t.process_command 'edit'
319
+ @t.eval_string.should == "'FOO'\n"
320
+ end
321
+
322
+ it "should not evaluate the expression with -n" do
323
+ Pry.config.editor = lambda {|file, line|
324
+ File.open(file, 'w'){|f| f << "'FOO'\n" }
325
+ nil
326
+ }
327
+ @t.process_command 'edit -n'
328
+ @t.eval_string.should == ''
329
+ end
330
+ end
331
+
332
+ describe "with --in" do
333
+ it "should edit the nth line of _in_" do
334
+ pry_eval '10', '11', 'edit --in -2'
335
+ @contents.should == "10\n"
336
+ end
337
+
338
+ it "should edit the last line if no argument is given" do
339
+ pry_eval '10', '11', 'edit --in'
340
+ @contents.should == "11\n"
341
+ end
342
+
343
+ it "should edit a range of lines if a range is given" do
344
+ pry_eval "10", "11", "edit -i 1,2"
345
+ @contents.should == "10\n11\n"
346
+ end
347
+
348
+ it "should edit a multi-line expression as it occupies one line of _in_" do
349
+ pry_eval "class Fixnum\n def invert; -self; end\nend", "edit -i 1"
350
+ @contents.should == "class Fixnum\n def invert; -self; end\nend\n"
351
+ end
352
+
353
+ it "should not work with a filename" do
354
+ proc {
355
+ pry_eval 'edit ruby.rb -i'
356
+ }.should.raise(Pry::CommandError).
357
+ message.should =~ /Only one of --ex, --temp, --in, --method and FILE/
358
+ end
359
+
360
+ it "should not work with nonsense" do
361
+ proc {
362
+ pry_eval 'edit --in three'
363
+ }.should.raise(Pry::CommandError).
364
+ message.should =~ /Not a valid range: three/
365
+ end
366
+ end
367
+
368
+ describe "old edit-method tests now migrated to edit" do
369
+ describe "on a method defined in a file" do
370
+ before do
371
+ @tempfile = (Tempfile.new(['pry', '.rb']))
372
+ @tempfile.puts <<-EOS
373
+ module A
374
+ def a
375
+ :yup
376
+ end
377
+
378
+ def b
379
+ :kinda
380
+ end
381
+ end
382
+
383
+ class X
384
+ include A
385
+
386
+ def self.x
387
+ :double_yup
388
+ end
389
+
390
+ def x
391
+ :nope
392
+ end
393
+
394
+ def b
395
+ super
396
+ end
397
+ alias c b
398
+
399
+ def y?
400
+ :because
401
+ end
402
+
403
+ class B
404
+ G = :nawt
405
+
406
+ def foo
407
+ :possibly
408
+ G
409
+ end
410
+ end
411
+ end
412
+ EOS
413
+ @tempfile.flush
414
+ load @tempfile.path
415
+
416
+ @tempfile_path = @tempfile.path
417
+ end
418
+
419
+ after do
420
+ @tempfile.close(true)
421
+ end
422
+
423
+ describe 'without -p' do
424
+ before do
425
+ @file = @line = @contents = nil
426
+ Pry.config.editor = lambda do |file, line|
427
+ @file = file; @line = line
428
+ nil
429
+ end
430
+ end
431
+
432
+ it "should correctly find a class method" do
433
+ pry_eval 'edit X.x'
434
+
435
+ @file.should == @tempfile_path
436
+ @line.should == 14
437
+
438
+ end
439
+
440
+ it "should correctly find an instance method" do
441
+ pry_eval 'edit X#x'
442
+ @file.should == @tempfile_path
443
+ @line.should == 18
444
+ end
445
+
446
+ it "should correctly find a method on an instance" do
447
+ pry_eval 'x = X.new', 'edit x.x'
448
+ @file.should == @tempfile_path
449
+ @line.should == 18
450
+ end
451
+
452
+ it "should correctly find a method from a module" do
453
+ pry_eval 'edit X#a'
454
+ @file.should == @tempfile_path
455
+ @line.should == 2
456
+ end
457
+
458
+ it "should correctly find an aliased method" do
459
+ pry_eval 'edit X#c'
460
+ @file.should == @tempfile_path
461
+ @line.should == 22
462
+ end
463
+ end
464
+
465
+ describe 'with -p' do
466
+ before do
467
+ Pry.config.editor = lambda do |file, line|
468
+ lines = File.read(file).lines.to_a
469
+ lines[1] = ":maybe\n"
470
+ File.open(file, 'w') do |f|
471
+ f.write(lines.join)
472
+ end
473
+ @patched_def = String(lines[1]).chomp
474
+ nil
475
+ end
476
+ end
477
+
478
+ it "should successfully replace a class method" do
479
+ pry_eval 'edit -p X.x'
480
+
481
+ class << X
482
+ X.method(:x).owner.should == self
483
+ end
484
+ X.method(:x).receiver.should == X
485
+ X.x.should == :maybe
486
+ end
487
+
488
+ it "should successfully replace an instance method" do
489
+ pry_eval 'edit -p X#x'
490
+
491
+ X.instance_method(:x).owner.should == X
492
+ X.new.x.should == :maybe
493
+ end
494
+
495
+ it "should successfully replace a method on an instance" do
496
+ pry_eval 'instance = X.new', 'edit -p instance.x'
497
+
498
+ instance = X.new
499
+ instance.method(:x).owner.should == X
500
+ instance.x.should == :maybe
501
+ end
502
+
503
+ it "should successfully replace a method from a module" do
504
+ pry_eval 'edit -p X#a'
505
+
506
+ X.instance_method(:a).owner.should == A
507
+ X.new.a.should == :maybe
508
+ end
509
+
510
+ it "should successfully replace a method with a question mark" do
511
+ pry_eval 'edit -p X#y?'
512
+
513
+ X.instance_method(:y?).owner.should == X
514
+ X.new.y?.should == :maybe
515
+ end
516
+
517
+ it "should preserve module nesting" do
518
+ pry_eval 'edit -p X::B#foo'
519
+
520
+ X::B.instance_method(:foo).owner.should == X::B
521
+ X::B.new.foo.should == :nawt
522
+ end
523
+
524
+ describe "monkey-patching" do
525
+ before do
526
+ @edit = 'edit --patch ' # A shortcut.
527
+ end
528
+
529
+ # @param [Integer] lineno
530
+ # @return [String] the stripped line from the tempfile at +lineno+
531
+ def stripped_line_at(lineno)
532
+ @tempfile.rewind
533
+ @tempfile.lines.to_a[lineno].strip
534
+ end
535
+
536
+ # Applies the monkey patch for +method+ with help of evaluation of
537
+ # +eval_strs+. The idea is to capture the initial line number (before
538
+ # the monkey patch), because it gets overwritten by the line number from
539
+ # the monkey patch. And our goal is to check that the original
540
+ # definition hasn't changed.
541
+ # @param [UnboundMethod] method
542
+ # @param [Array<String>] eval_strs
543
+ # @return [Array<String] the lines with definitions of the same line
544
+ # before monkey patching and after (normally, they should be equal)
545
+ def apply_monkey_patch(method, *eval_strs)
546
+ _, lineno = method.source_location
547
+ definition_before = stripped_line_at(lineno)
548
+
549
+ pry_eval(*eval_strs)
550
+
551
+ definition_after = stripped_line_at(lineno)
552
+
553
+ [definition_before, definition_after]
554
+ end
555
+
556
+ it "should work for a class method" do
557
+ def_before, def_after =
558
+ apply_monkey_patch(X.method(:x), "#@edit X.x")
559
+
560
+ def_before.should == ':double_yup'
561
+ def_after.should == ':double_yup'
562
+ @patched_def.should == ':maybe'
563
+ end
564
+
565
+ it "should work for an instance method" do
566
+ def_before, def_after =
567
+ apply_monkey_patch(X.instance_method(:x), "#@edit X#x")
568
+
569
+ def_before.should == ':nope'
570
+ def_after.should == ':nope'
571
+ @patched_def.should == ':maybe'
572
+ end
573
+
574
+ it "should work for a method on an instance" do
575
+ def_before, def_after =
576
+ apply_monkey_patch(X.instance_method(:x), 'instance = X.new', "#@edit instance.x")
577
+
578
+ def_before.should == ':nope'
579
+ def_after.should == ':nope'
580
+ @patched_def.should == ':maybe'
581
+ end
582
+
583
+ it "should work for a method from a module" do
584
+ def_before, def_after =
585
+ apply_monkey_patch(X.instance_method(:a), "#@edit X#a")
586
+
587
+ def_before.should == ':yup'
588
+ def_after.should == ':yup'
589
+ @patched_def.should == ':maybe'
590
+ end
591
+
592
+ it "should work for a method with a question mark" do
593
+ def_before, def_after =
594
+ apply_monkey_patch(X.instance_method(:y?), "#@edit X#y?")
595
+
596
+ def_before.should == ':because'
597
+ def_after.should == ':because'
598
+ @patched_def.should == ':maybe'
599
+ end
600
+
601
+ it "should work with nesting" do
602
+ def_before, def_after =
603
+ apply_monkey_patch(X::B.instance_method(:foo), "#@edit X::B#foo")
604
+
605
+ def_before.should == ':possibly'
606
+ def_after.should == ':possibly'
607
+ @patched_def.should == ':maybe'
608
+ end
609
+ end
610
+ end
611
+
612
+ describe 'on an aliased method' do
613
+ before do
614
+ Pry.config.editor = lambda do |file, line|
615
+ lines = File.read(file).lines.to_a
616
+ lines[1] = '"#{super}aa".to_sym' + "\n"
617
+ File.open(file, 'w') do |f|
618
+ f.write(lines.join)
619
+ end
620
+ nil
621
+ end
622
+ end
623
+
624
+ it "should change the alias, but not the original, without breaking super" do
625
+
626
+ $x = :bebe
627
+ pry_eval 'edit -p X#c'
628
+
629
+
630
+ Pry::Method.from_str("X#c").alias?.should == true
631
+
632
+ X.new.b.should == :kinda
633
+ X.new.c.should == :kindaaa
634
+ $x = nil
635
+ end
636
+ end
637
+
638
+ describe 'with three-arg editor' do
639
+ before do
640
+ @file = @line = @reloading = nil
641
+ Pry.config.editor = lambda do |file, line, reloading|
642
+ @file = file; @line = line; @reloading = reloading
643
+ nil
644
+ end
645
+ end
646
+
647
+ it "should pass the editor a reloading arg" do
648
+ pry_eval 'edit X.x'
649
+ @reloading.should == true
650
+ pry_eval 'edit -n X.x'
651
+ @reloading.should == false
652
+ end
653
+ end
654
+ end
655
+ end
656
+
657
+ describe "--method flag" do
658
+ before do
659
+ @t = pry_tester
660
+ class BinkyWink
661
+ eval %{
662
+ def tits_macgee
663
+ binding
664
+ end
665
+ }
666
+
667
+ def tots_macgee
668
+ :jeremy_jones
669
+ binding
670
+ end
671
+ end
672
+ end
673
+
674
+ after do
675
+ Object.remove_const(:BinkyWink)
676
+ end
677
+
678
+ it 'should edit method context' do
679
+ Pry.editor = lambda do |file, line|
680
+ [file, line].should == BinkyWink.instance_method(:tots_macgee).source_location
681
+ nil
682
+ end
683
+
684
+ t = pry_tester(BinkyWink.new.tots_macgee)
685
+ t.process_command "edit -m -n"
686
+ end
687
+
688
+ it 'errors when cannot find method context' do
689
+ Pry.editor = lambda do |file, line|
690
+ [file, line].should == BinkyWink.instance_method(:tits_macgee).source_location
691
+ nil
692
+ end
693
+
694
+ t = pry_tester(BinkyWink.new.tits_macgee)
695
+ lambda { t.process_command "edit -m -n" }.should.
696
+ raise(Pry::CommandError).message.should.match(/Cannot find a file for/)
697
+ end
698
+
699
+ it 'errors when a filename arg is passed with --method' do
700
+ lambda { @t.process_command "edit -m Pry#repl" }.should.
701
+ raise(Pry::CommandError).message.should.match(/Only one of/)
702
+ end
703
+ end
704
+
705
+ describe "pretty error messages" do
706
+ before do
707
+ @t = pry_tester
708
+ class TrinkyDink
709
+ eval %{
710
+ def claudia_linklater
711
+ end
712
+ }
713
+ end
714
+ end
715
+
716
+ after do
717
+ Object.remove_const(:TrinkyDink)
718
+ end
719
+
720
+ it 'should display a nice error message when cannot open a file' do
721
+ lambda { @t.process_command "edit TrinkyDink#claudia_linklater" }.should.
722
+ raise(Pry::CommandError).message.should.match(/Cannot find a file for/)
723
+ end
724
+ end
725
+ end