pry 0.10.2-i386-mingw32 → 1.0.0.pre1-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.
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