pry 0.6.7-i386-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,316 @@
1
+ class Pry
2
+
3
+ # The list of configuration options.
4
+ CONFIG_OPTIONS = [:input, :output, :commands, :print,
5
+ :prompt, :hooks]
6
+
7
+ attr_accessor *CONFIG_OPTIONS
8
+
9
+ # Create a new `Pry` object.
10
+ # @param [Hash] options The optional configuration parameters.
11
+ # @option options [#readline] :input The object to use for input.
12
+ # @option options [#puts] :output The object to use for output.
13
+ # @option options [Pry::CommandBase] :commands The object to use for
14
+ # commands. (see commands.rb)
15
+ # @option options [Hash] :hooks The defined hook Procs (see hooks.rb)
16
+ # @option options [Array<Proc>] :default_prompt The array of Procs
17
+ # to use for the prompts. (see prompts.rb)
18
+ # @option options [Proc] :print The Proc to use for the 'print'
19
+ # component of the REPL. (see print.rb)
20
+ def initialize(options={})
21
+
22
+ default_options = {}
23
+ CONFIG_OPTIONS.each { |v| default_options[v] = Pry.send(v) }
24
+ default_options.merge!(options)
25
+
26
+ CONFIG_OPTIONS.each do |key|
27
+ instance_variable_set("@#{key}", default_options[key])
28
+ end
29
+ end
30
+
31
+ # Get nesting data.
32
+ # This method should not need to be accessed directly.
33
+ # @return [Array] The unparsed nesting information.
34
+ def nesting
35
+ self.class.nesting
36
+ end
37
+
38
+ # Set nesting data.
39
+ # This method should not need to be accessed directly.
40
+ # @param v nesting data.
41
+ def nesting=(v)
42
+ self.class.nesting = v
43
+ end
44
+
45
+ # Return parent of current Pry session.
46
+ # @return [Pry] The parent of the current Pry session.
47
+ def parent
48
+ idx = Pry.sessions.index(self)
49
+
50
+ if idx > 0
51
+ Pry.sessions[idx - 1]
52
+ else
53
+ nil
54
+ end
55
+ end
56
+
57
+ # Execute the hook `hook_name`, if it is defined.
58
+ # @param [Symbol] hook_name The hook to execute
59
+ # @param [Array] args The arguments to pass to the hook.
60
+ def exec_hook(hook_name, *args, &block)
61
+ hooks[hook_name].call(*args, &block) if hooks[hook_name]
62
+ end
63
+
64
+ # Start a read-eval-print-loop.
65
+ # If no parameter is given, default to top-level (main).
66
+ # @param [Object, Binding] target The receiver of the Pry session
67
+ # @return [Object] The target of the Pry session or an explictly given
68
+ # return value. If given return value is `nil` or no return value
69
+ # is specified then `target` will be returned.
70
+ # @example
71
+ # Pry.new.repl(Object.new)
72
+ def repl(target=TOPLEVEL_BINDING)
73
+ target = Pry.binding_for(target)
74
+ target_self = target.eval('self')
75
+
76
+ exec_hook :before_session, output, target_self
77
+
78
+ # cannot rely on nesting.level as
79
+ # nesting.level changes with new sessions
80
+ nesting_level = nesting.size
81
+
82
+ Pry.active_instance = self
83
+
84
+ # Make sure special locals exist
85
+ target.eval("_pry_ = Pry.active_instance")
86
+ target.eval("_ = Pry.last_result")
87
+
88
+ break_data = catch(:breakout) do
89
+ nesting.push [nesting.size, target_self, self]
90
+ loop do
91
+ rep(target)
92
+ end
93
+ end
94
+
95
+ nesting.pop
96
+
97
+ exec_hook :after_session, output, target_self
98
+
99
+ # If break_data is an array, then the last element is the return value
100
+ break_level, return_value = Array(break_data)
101
+
102
+ # keep throwing until we reach the desired nesting level
103
+ if nesting_level != break_level
104
+ throw :breakout, break_data
105
+ end
106
+
107
+ # if one was provided, return the return value
108
+ return return_value if return_value
109
+
110
+ # otherwise return the target_self
111
+ target_self
112
+ end
113
+
114
+ # Perform a read-eval-print.
115
+ # If no parameter is given, default to top-level (main).
116
+ # @param [Object, Binding] target The receiver of the read-eval-print
117
+ # @example
118
+ # Pry.new.rep(Object.new)
119
+ def rep(target=TOPLEVEL_BINDING)
120
+ target = Pry.binding_for(target)
121
+ print.call output, re(target)
122
+ end
123
+
124
+ # Perform a read-eval
125
+ # If no parameter is given, default to top-level (main).
126
+ # @param [Object, Binding] target The receiver of the read-eval-print
127
+ # @return [Object] The result of the eval or an `Exception` object in case of error.
128
+ # @example
129
+ # Pry.new.re(Object.new)
130
+ def re(target=TOPLEVEL_BINDING)
131
+ target = Pry.binding_for(target)
132
+
133
+ if input == Readline
134
+ # Readline tab completion
135
+ Readline.completion_proc = Pry::InputCompleter.build_completion_proc(target, commands.commands.keys)
136
+ end
137
+
138
+ # eval the expression and save to last_result
139
+ Pry.last_result = target.eval r(target)
140
+
141
+ # save the pry instance to active_instance
142
+ Pry.active_instance = self
143
+
144
+ # define locals _pry_ and _ (active instance and last expression)
145
+ target.eval("_pry_ = Pry.active_instance")
146
+ target.eval("_ = Pry.last_result")
147
+ rescue SystemExit => e
148
+ exit
149
+ rescue Exception => e
150
+ e
151
+ end
152
+
153
+ # Perform a read.
154
+ # If no parameter is given, default to top-level (main).
155
+ # This is a multi-line read; so the read continues until a valid
156
+ # Ruby expression is received.
157
+ # Pry commands are also accepted here and operate on the target.
158
+ # @param [Object, Binding] target The receiver of the read.
159
+ # @return [String] The Ruby expression.
160
+ # @example
161
+ # Pry.new.r(Object.new)
162
+ def r(target=TOPLEVEL_BINDING)
163
+ target = Pry.binding_for(target)
164
+ eval_string = ""
165
+
166
+ loop do
167
+ current_prompt = select_prompt(eval_string.empty?, target.eval('self'))
168
+
169
+ val = readline(current_prompt)
170
+
171
+ # exit pry if we receive EOF character
172
+ if !val
173
+ output.puts
174
+ throw(:breakout, nesting.level)
175
+ end
176
+
177
+ val.chomp!
178
+
179
+ Pry.cmd_ret_value = process_commands(val, eval_string, target)
180
+
181
+ if Pry.cmd_ret_value
182
+ eval_string << "Pry.cmd_ret_value\n"
183
+ else
184
+ eval_string << "#{val}\n"
185
+ end
186
+
187
+ break eval_string if valid_expression?(eval_string)
188
+ end
189
+ end
190
+
191
+ # Process Pry commands. Pry commands are not Ruby methods and are evaluated
192
+ # prior to Ruby expressions.
193
+ # Commands can be modified/configured by the user: see `Pry::Commands`
194
+ # This method should not need to be invoked directly - it is called
195
+ # by `Pry#r`.
196
+ # @param [String] val The current line of input.
197
+ # @param [String] eval_string The cumulative lines of input for
198
+ # multi-line input.
199
+ # @param [Binding] target The receiver of the commands.
200
+ def process_commands(val, eval_string, target)
201
+ def val.clear() replace("") end
202
+ def eval_string.clear() replace("") end
203
+
204
+ pattern, cmd_data = commands.commands.find do |name, cmd_data|
205
+ /^#{name}(?!\S)(?:\s+(.+))?/ =~ val
206
+ end
207
+
208
+ # no command was matched, so return to caller
209
+ return if !pattern
210
+
211
+ args_string = $1
212
+ args = args_string ? Shellwords.shellwords(args_string) : []
213
+ action = cmd_data[:action]
214
+ keep_retval = cmd_data[:keep_retval]
215
+
216
+ options = {
217
+ :val => val,
218
+ :eval_string => eval_string,
219
+ :nesting => nesting,
220
+ :commands => commands.commands
221
+ }
222
+
223
+ # set some useful methods to be used by the action blocks
224
+ commands.opts = options
225
+ commands.target = target
226
+ commands.output = output
227
+
228
+ case action.arity <=> 0
229
+ when -1
230
+
231
+ # Use instance_exec() to make the `opts` method, etc available
232
+ ret_value = commands.instance_exec(*args, &action)
233
+ when 1, 0
234
+
235
+ # ensure that we get the right number of parameters
236
+ # since 1.8.7 complains about incorrect arity (1.9.2
237
+ # doesn't care)
238
+ args_with_corrected_arity = args.values_at *0..(action.arity - 1)
239
+ ret_value = commands.instance_exec(*args_with_corrected_arity, &action)
240
+ end
241
+
242
+ # a command was processed so we can now clear the input string
243
+ val.clear
244
+
245
+ # return value of block only if :keep_retval is true
246
+ ret_value if keep_retval
247
+ end
248
+
249
+ # Returns the next line of input to be used by the pry instance.
250
+ # This method should not need to be invoked directly.
251
+ # @param [String] current_prompt The prompt to use for input.
252
+ # @return [String] The next line of input.
253
+ def readline(current_prompt="> ")
254
+
255
+ if input == Readline
256
+
257
+ # Readline must be treated differently
258
+ # as it has a second parameter.
259
+ input.readline(current_prompt, true)
260
+ else
261
+ if input.method(:readline).arity == 1
262
+ input.readline(current_prompt)
263
+ else
264
+ input.readline
265
+ end
266
+ end
267
+ end
268
+
269
+ # Returns the appropriate prompt to use.
270
+ # This method should not need to be invoked directly.
271
+ # @param [Boolean] first_line Whether this is the first line of input
272
+ # (and not multi-line input).
273
+ # @param [Object] target_self The receiver of the Pry session.
274
+ # @return [String] The prompt.
275
+ def select_prompt(first_line, target_self)
276
+
277
+ if first_line
278
+ Array(prompt).first.call(target_self, nesting.level)
279
+ else
280
+ Array(prompt).last.call(target_self, nesting.level)
281
+ end
282
+ end
283
+
284
+ if RUBY_VERSION =~ /1.9/
285
+ require 'ripper'
286
+
287
+ # Determine if a string of code is a valid Ruby expression.
288
+ # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
289
+ # @param [String] code The code to validate.
290
+ # @return [Boolean] Whether or not the code is a valid Ruby expression.
291
+ # @example
292
+ # valid_expression?("class Hello") #=> false
293
+ # valid_expression?("class Hello; end") #=> true
294
+ def valid_expression?(code)
295
+ !!Ripper::SexpBuilder.new(code).parse
296
+ end
297
+
298
+ else
299
+ require 'ruby_parser'
300
+
301
+ # Determine if a string of code is a valid Ruby expression.
302
+ # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
303
+ # @param [String] code The code to validate.
304
+ # @return [Boolean] Whether or not the code is a valid Ruby expression.
305
+ # @example
306
+ # valid_expression?("class Hello") #=> false
307
+ # valid_expression?("class Hello; end") #=> true
308
+ def valid_expression?(code)
309
+ RubyParser.new.parse(code)
310
+ rescue Racc::ParseError, SyntaxError
311
+ false
312
+ else
313
+ true
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,3 @@
1
+ class Pry
2
+ VERSION = "0.6.7"
3
+ end
@@ -0,0 +1,681 @@
1
+ direc = File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'bacon'
5
+ require "#{direc}/../lib/pry"
6
+ require "#{direc}/test_helper"
7
+
8
+ puts "Ruby Version #{RUBY_VERSION}"
9
+ puts "Testing Pry #{Pry::VERSION}"
10
+ puts "With method_source version #{MethodSource::VERSION}"
11
+ puts "--"
12
+
13
+ describe Pry do
14
+ describe "open a Pry session on an object" do
15
+ describe "rep" do
16
+
17
+ before do
18
+ class Hello
19
+ end
20
+ end
21
+
22
+ after do
23
+ Object.send(:remove_const, :Hello)
24
+ end
25
+
26
+ it 'should set an ivar on an object' do
27
+ input_string = "@x = 10"
28
+ input = InputTester.new(input_string)
29
+ o = Object.new
30
+
31
+ pry_tester = Pry.new(:input => input, :output => Pry::NullOutput)
32
+ pry_tester.rep(o)
33
+ o.instance_variable_get(:@x).should == 10
34
+ end
35
+
36
+ it 'should make self evaluate to the receiver of the rep session' do
37
+ o = Object.new
38
+ str_output = StringIO.new
39
+
40
+ pry_tester = Pry.new(:input => InputTester.new("self"), :output => str_output)
41
+ pry_tester.rep(o)
42
+ str_output.string.should =~ /#{o.to_s}/
43
+ end
44
+
45
+ it 'should work with multi-line input' do
46
+ o = Object.new
47
+ str_output = StringIO.new
48
+
49
+ pry_tester = Pry.new(:input => InputTester.new("x = ", "1 + 4"), :output => str_output)
50
+ pry_tester.rep(o)
51
+ str_output.string.should =~ /5/
52
+ end
53
+
54
+ it 'should define a nested class under Hello and not on top-level or Pry' do
55
+ pry_tester = Pry.new(:input => InputTester.new("class Nested", "end"), :output => Pry::NullOutput)
56
+ pry_tester.rep(Hello)
57
+ Hello.const_defined?(:Nested).should == true
58
+ end
59
+ end
60
+
61
+ describe "repl" do
62
+ describe "basic functionality" do
63
+ it 'should set an ivar on an object and exit the repl' do
64
+ input_strings = ["@x = 10", "exit"]
65
+ input = InputTester.new(*input_strings)
66
+
67
+ o = Object.new
68
+
69
+ pry_tester = Pry.start(o, :input => input, :output => Pry::NullOutput)
70
+
71
+ o.instance_variable_get(:@x).should == 10
72
+ end
73
+
74
+ it 'should execute start session and end session hooks' do
75
+ input = InputTester.new("exit")
76
+ str_output = StringIO.new
77
+ o = Object.new
78
+
79
+ pry_tester = Pry.start(o, :input => input, :output => str_output)
80
+ str_output.string.should =~ /Beginning.*#{o}/
81
+ str_output.string.should =~ /Ending.*#{o}/
82
+ end
83
+ end
84
+
85
+ describe "nesting" do
86
+ after do
87
+ Pry.reset_defaults
88
+ end
89
+
90
+ it 'should nest properly' do
91
+ Pry.input = InputTester.new("pry", "pry", "pry", "\"nest:\#\{Pry.nesting.level\}\"", "exit_all")
92
+
93
+ str_output = StringIO.new
94
+ Pry.output = str_output
95
+
96
+ o = Object.new
97
+
98
+ pry_tester = o.pry
99
+ str_output.string.should =~ /nest:3/
100
+ end
101
+ end
102
+
103
+ describe "defining methods" do
104
+ it 'should define a method on the singleton class of an object when performing "def meth;end" inside the object' do
105
+ [Object.new, {}, []].each do |val|
106
+ str_input = StringIO.new("def hello;end")
107
+ Pry.new(:input => str_input, :output => StringIO.new).rep(val)
108
+
109
+ val.methods(false).map(&:to_sym).include?(:hello).should == true
110
+ end
111
+ end
112
+
113
+ it 'should define an instance method on the module when performing "def meth;end" inside the module' do
114
+ str_input = StringIO.new("def hello;end")
115
+ hello = Module.new
116
+ Pry.new(:input => str_input, :output => StringIO.new).rep(hello)
117
+ hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true
118
+ end
119
+
120
+ it 'should define an instance method on the class when performing "def meth;end" inside the class' do
121
+ str_input = StringIO.new("def hello;end")
122
+ hello = Class.new
123
+ Pry.new(:input => str_input, :output => StringIO.new).rep(hello)
124
+ hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true
125
+ end
126
+
127
+ it 'should define a method on the class of an object when performing "def meth;end" inside an immediate value or Numeric' do
128
+ # should include float in here, but test fails for some reason
129
+ # on 1.8.7, no idea why!
130
+ [:test, 0, true, false, nil].each do |val|
131
+ str_input = StringIO.new("def hello;end")
132
+ Pry.new(:input => str_input, :output => StringIO.new).rep(val)
133
+ val.class.instance_methods(false).map(&:to_sym).include?(:hello).should == true
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+
140
+ describe "commands" do
141
+ it 'should run a command with no parameter' do
142
+ pry_tester = Pry.new
143
+ pry_tester.commands = CommandTester
144
+ pry_tester.input = InputTester.new("command1", "exit_all")
145
+ pry_tester.commands = CommandTester
146
+
147
+ str_output = StringIO.new
148
+ pry_tester.output = str_output
149
+
150
+ pry_tester.rep
151
+
152
+ str_output.string.should =~ /command1/
153
+ end
154
+
155
+ it 'should run a command with one parameter' do
156
+ pry_tester = Pry.new
157
+ pry_tester.commands = CommandTester
158
+ pry_tester.input = InputTester.new("command2 horsey", "exit_all")
159
+ pry_tester.commands = CommandTester
160
+
161
+ str_output = StringIO.new
162
+ pry_tester.output = str_output
163
+
164
+ pry_tester.rep
165
+
166
+ str_output.string.should =~ /horsey/
167
+ end
168
+ end
169
+
170
+ describe "Object#pry" do
171
+
172
+ after do
173
+ Pry.reset_defaults
174
+ end
175
+
176
+ it "should start a pry session on the receiver (first form)" do
177
+ Pry.input = InputTester.new("self", "exit")
178
+
179
+ str_output = StringIO.new
180
+ Pry.output = str_output
181
+
182
+ 20.pry
183
+
184
+ str_output.string.should =~ /20/
185
+ end
186
+
187
+ it "should start a pry session on the receiver (second form)" do
188
+ Pry.input = InputTester.new("self", "exit")
189
+
190
+ str_output = StringIO.new
191
+ Pry.output = str_output
192
+
193
+ pry 20
194
+
195
+ str_output.string.should =~ /20/
196
+ end
197
+
198
+ it "should error if more than one argument is passed to Object#pry" do
199
+ lambda { pry(20, :input => Readline) }.should.raise ArgumentError
200
+ end
201
+ end
202
+
203
+ describe "Pry.binding_for" do
204
+ it 'should return TOPLEVEL_BINDING if parameter self is main' do
205
+ _main_ = lambda { TOPLEVEL_BINDING.eval('self') }
206
+ Pry.binding_for(_main_.call).is_a?(Binding).should == true
207
+ Pry.binding_for(_main_.call).should == TOPLEVEL_BINDING
208
+ Pry.binding_for(_main_.call).should == Pry.binding_for(_main_.call)
209
+ end
210
+ end
211
+
212
+
213
+ describe "test Pry defaults" do
214
+
215
+ after do
216
+ Pry.reset_defaults
217
+ end
218
+
219
+ describe "input" do
220
+
221
+ after do
222
+ Pry.reset_defaults
223
+ end
224
+
225
+ it 'should set the input default, and the default should be overridable' do
226
+ Pry.input = InputTester.new("5")
227
+
228
+ str_output = StringIO.new
229
+ Pry.output = str_output
230
+ Pry.new.rep
231
+ str_output.string.should =~ /5/
232
+
233
+ Pry.new(:input => InputTester.new("6")).rep
234
+ str_output.string.should =~ /6/
235
+ end
236
+
237
+ it 'should pass in the prompt if readline arity is 1' do
238
+ Pry.prompt = proc { "A" }
239
+
240
+ arity_one_input = Class.new do
241
+ attr_accessor :prompt
242
+ def readline(prompt)
243
+ @prompt = prompt
244
+ "exit"
245
+ end
246
+ end.new
247
+
248
+ Pry.start(self, :input => arity_one_input, :output => Pry::NullOutput)
249
+ arity_one_input.prompt.should == Pry.prompt.call
250
+ end
251
+
252
+ it 'should not pass in the prompt if the arity is 0' do
253
+ Pry.prompt = proc { "A" }
254
+
255
+ arity_zero_input = Class.new do
256
+ def readline
257
+ "exit"
258
+ end
259
+ end.new
260
+
261
+ lambda { Pry.start(self, :input => arity_zero_input, :output => Pry::NullOutput) }.should.not.raise Exception
262
+ end
263
+
264
+ it 'should not pass in the prompt if the arity is -1' do
265
+ Pry.prompt = proc { "A" }
266
+
267
+ arity_multi_input = Class.new do
268
+ attr_accessor :prompt
269
+
270
+ def readline(*args)
271
+ @prompt = args.first
272
+ "exit"
273
+ end
274
+ end.new
275
+
276
+ Pry.start(self, :input => arity_multi_input, :output => Pry::NullOutput)
277
+ arity_multi_input.prompt.should == nil
278
+ end
279
+
280
+ end
281
+
282
+ it 'should set the output default, and the default should be overridable' do
283
+ Pry.input = InputTester.new("5", "6", "7")
284
+
285
+ str_output = StringIO.new
286
+ Pry.output = str_output
287
+
288
+ Pry.new.rep
289
+ str_output.string.should =~ /5/
290
+
291
+ Pry.new.rep
292
+ str_output.string.should =~ /5\n.*6/
293
+
294
+ str_output2 = StringIO.new
295
+ Pry.new(:output => str_output2).rep
296
+ str_output2.string.should.not =~ /5\n.*6/
297
+ str_output2.string.should =~ /7/
298
+ end
299
+
300
+ describe "Pry.run_command" do
301
+ before do
302
+ class RCTest
303
+ def a() end
304
+ B = 20
305
+ @x = 10
306
+ end
307
+ end
308
+
309
+ after do
310
+ Object.remove_const(:RCTest)
311
+ end
312
+
313
+ it "should execute command in the appropriate object context" do
314
+ result = Pry.run_command "ls", :context => RCTest
315
+ result.map(&:to_sym).should == [:@x]
316
+ end
317
+
318
+ it "should execute command with parameters in the appropriate object context" do
319
+ result = Pry.run_command "ls -M", :context => RCTest
320
+ result.map(&:to_sym).should == [:a]
321
+ end
322
+
323
+ it "should execute command and show output with :show_output => true flag" do
324
+ str = StringIO.new
325
+ Pry.output = str
326
+ result = Pry.run_command "ls -av", :context => RCTest, :show_output => true
327
+ str.string.should =~ /global variables/
328
+ Pry.output = $stdout
329
+ end
330
+
331
+ it "should execute command with multiple parameters" do
332
+ result = Pry.run_command "ls -c -M RCTest"
333
+ result.map(&:to_sym).should == [:a, :B]
334
+ end
335
+ end
336
+
337
+ describe "commands" do
338
+ it 'should define a command that keeps its return value' do
339
+ class Command68 < Pry::CommandBase
340
+ command "hello", "", :keep_retval => true do
341
+ :kept_hello
342
+ end
343
+ end
344
+ str_output = StringIO.new
345
+ Pry.new(:input => StringIO.new("hello"), :output => str_output, :commands => Command68).rep
346
+ str_output.string.should =~ /:kept_hello/
347
+
348
+ Object.remove_const(:Command68)
349
+ end
350
+
351
+ it 'should define a command that does NOT keep its return value' do
352
+ class Command68 < Pry::CommandBase
353
+ command "hello", "", :keep_retval => false do
354
+ :kept_hello
355
+ end
356
+ end
357
+ str_output = StringIO.new
358
+ Pry.new(:input => StringIO.new("hello"), :output => str_output, :commands => Command68).rep
359
+ (str_output.string =~ /:kept_hello/).should == nil
360
+
361
+ Object.remove_const(:Command68)
362
+ end
363
+
364
+
365
+ it 'should set the commands default, and the default should be overridable' do
366
+ class Command0 < Pry::CommandBase
367
+ command "hello" do
368
+ output.puts "hello world"
369
+ end
370
+ end
371
+
372
+ Pry.commands = Command0
373
+
374
+ str_output = StringIO.new
375
+ Pry.new(:input => InputTester.new("hello"), :output => str_output).rep
376
+ str_output.string.should =~ /hello world/
377
+
378
+ class Command1 < Pry::CommandBase
379
+ command "goodbye", "" do
380
+ output.puts "goodbye world"
381
+ end
382
+ end
383
+
384
+ str_output = StringIO.new
385
+
386
+ Pry.new(:input => InputTester.new("goodbye"), :output => str_output, :commands => Command1).rep
387
+ str_output.string.should =~ /goodbye world/
388
+
389
+ Object.remove_const(:Command0)
390
+ Object.remove_const(:Command1)
391
+ end
392
+
393
+ it 'should inherit "help" command from Pry::CommandBase' do
394
+ class Command2 < Pry::CommandBase
395
+ command "h", "h command" do
396
+ end
397
+ end
398
+
399
+ Command2.commands.keys.size.should == 2
400
+ Command2.commands.keys.include?("help").should == true
401
+ Command2.commands.keys.include?("h").should == true
402
+
403
+ Object.remove_const(:Command2)
404
+ end
405
+
406
+ it 'should inherit commands from Pry::Commands' do
407
+ class Command3 < Pry::Commands
408
+ command "v" do
409
+ end
410
+ end
411
+
412
+ Command3.commands.include?("nesting").should == true
413
+ Command3.commands.include?("jump-to").should == true
414
+ Command3.commands.include?("cd").should == true
415
+ Command3.commands.include?("v").should == true
416
+
417
+ Object.remove_const(:Command3)
418
+ end
419
+
420
+ it 'should alias a command with another command' do
421
+ class Command6 < Pry::CommandBase
422
+ alias_command "help2", "help"
423
+ end
424
+
425
+ Command6.commands["help2"].should == Command6.commands["help"]
426
+ # str_output = StringIO.new
427
+ # Pry.new(:input => InputTester.new("run_v"), :output => str_output, :commands => Command3).rep
428
+ # str_output.string.should =~ /v command/
429
+
430
+ Object.remove_const(:Command6)
431
+ end
432
+
433
+ it 'should change description of a command using desc' do
434
+
435
+ class Command7 < Pry::Commands
436
+ end
437
+
438
+ orig = Command7.commands["help"][:description]
439
+
440
+ class Command7
441
+ desc "help", "blah"
442
+ end
443
+
444
+ Command7.commands["help"][:description].should.not == orig
445
+ Command7.commands["help"][:description].should == "blah"
446
+
447
+ Object.remove_const(:Command7)
448
+ end
449
+
450
+ it 'should run a command from within a command' do
451
+ class Command01 < Pry::Commands
452
+ command "v" do
453
+ output.puts "v command"
454
+ end
455
+
456
+ command "run_v" do
457
+ run "v"
458
+ end
459
+ end
460
+
461
+ str_output = StringIO.new
462
+ Pry.new(:input => InputTester.new("run_v"), :output => str_output, :commands => Command01).rep
463
+ str_output.string.should =~ /v command/
464
+
465
+ Object.remove_const(:Command01)
466
+ end
467
+
468
+ it 'should enable an inherited method to access opts and output and target, due to instance_exec' do
469
+ class Command3 < Pry::Commands
470
+ command "v" do
471
+ output.puts "#{target.eval('self')}"
472
+ end
473
+ end
474
+
475
+ class Command4 < Command3
476
+ end
477
+
478
+ str_output = StringIO.new
479
+ Pry.new(:print => proc {}, :input => InputTester.new("v"),
480
+ :output => str_output, :commands => Command4).rep("john")
481
+ str_output.string.chomp.should == "john"
482
+
483
+ Object.remove_const(:Command3)
484
+ Object.remove_const(:Command4)
485
+ end
486
+
487
+ it 'should import commands from another command object' do
488
+ class Command3 < Pry::CommandBase
489
+ import_from Pry::Commands, "status", "jump-to"
490
+ end
491
+
492
+ str_output = StringIO.new
493
+ Pry.new(:print => proc {}, :input => InputTester.new("status"),
494
+ :output => str_output, :commands => Command3).rep("john")
495
+ str_output.string.should =~ /Status:/
496
+
497
+ Object.remove_const(:Command3)
498
+ end
499
+
500
+ it 'should delete some inherited commands when using delete method' do
501
+ class Command3 < Pry::Commands
502
+ command "v" do
503
+ end
504
+
505
+ delete "show_doc", "show_method"
506
+ delete "ls"
507
+ end
508
+
509
+ Command3.commands.include?("nesting").should == true
510
+ Command3.commands.include?("jump-to").should == true
511
+ Command3.commands.include?("cd").should == true
512
+ Command3.commands.include?("v").should == true
513
+ Command3.commands.include?("show_doc").should == false
514
+ Command3.commands.include?("show_method").should == false
515
+ Command3.commands.include?("ls").should == false
516
+
517
+ Object.remove_const(:Command3)
518
+ end
519
+
520
+ it 'should override some inherited commands' do
521
+ class Command3 < Pry::Commands
522
+ command "jump-to" do
523
+ output.puts "jump-to the music"
524
+ end
525
+
526
+ command "help" do
527
+ output.puts "help to the music"
528
+ end
529
+ end
530
+
531
+ # suppress evaluation output
532
+ Pry.print = proc {}
533
+
534
+ str_output = StringIO.new
535
+ Pry.new(:input => InputTester.new("jump-to"), :output => str_output, :commands => Command3).rep
536
+ str_output.string.chomp.should == "jump-to the music"
537
+
538
+ str_output = StringIO.new
539
+ Pry.new(:input => InputTester.new("help"), :output => str_output, :commands => Command3).rep
540
+ str_output.string.chomp.should == "help to the music"
541
+
542
+ Object.remove_const(:Command3)
543
+
544
+ Pry.reset_defaults
545
+ end
546
+ end
547
+
548
+ it "should set the print default, and the default should be overridable" do
549
+ new_print = proc { |out, value| out.puts value }
550
+ Pry.print = new_print
551
+
552
+ Pry.new.print.should == Pry.print
553
+ str_output = StringIO.new
554
+ Pry.new(:input => InputTester.new("\"test\""), :output => str_output).rep
555
+ str_output.string.should == "test\n"
556
+
557
+ str_output = StringIO.new
558
+ Pry.new(:input => InputTester.new("\"test\""), :output => str_output,
559
+ :print => proc { |out, value| out.puts value.reverse }).rep
560
+ str_output.string.should == "tset\n"
561
+
562
+ Pry.new.print.should == Pry.print
563
+ str_output = StringIO.new
564
+ Pry.new(:input => InputTester.new("\"test\""), :output => str_output).rep
565
+ str_output.string.should == "test\n"
566
+ end
567
+
568
+ describe "pry return values" do
569
+ it 'should return the target object' do
570
+ Pry.start(self, :input => StringIO.new("exit"), :output => Pry::NullOutput).should == self
571
+ end
572
+
573
+ it 'should return the parameter given to exit' do
574
+ Pry.start(self, :input => StringIO.new("exit 10"), :output => Pry::NullOutput).should == 10
575
+ end
576
+
577
+ it 'should return the parameter (multi word string) given to exit' do
578
+ Pry.start(self, :input => StringIO.new("exit \"john mair\""), :output => Pry::NullOutput).should == "john mair"
579
+ end
580
+
581
+ it 'should return the parameter (function call) given to exit' do
582
+ Pry.start(self, :input => StringIO.new("exit 'abc'.reverse"), :output => Pry::NullOutput).should == 'cba'
583
+ end
584
+
585
+ it 'should return the parameter (self) given to exit' do
586
+ Pry.start("carl", :input => StringIO.new("exit self"), :output => Pry::NullOutput).should == "carl"
587
+ end
588
+ end
589
+
590
+ describe "prompts" do
591
+ it 'should set the prompt default, and the default should be overridable (single prompt)' do
592
+ new_prompt = proc { "test prompt> " }
593
+ Pry.prompt = new_prompt
594
+
595
+ Pry.new.prompt.should == Pry.prompt
596
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
597
+ Pry.new.select_prompt(false, 0).should == "test prompt> "
598
+
599
+ new_prompt = proc { "A" }
600
+ pry_tester = Pry.new(:prompt => new_prompt)
601
+ pry_tester.prompt.should == new_prompt
602
+ pry_tester.select_prompt(true, 0).should == "A"
603
+ pry_tester.select_prompt(false, 0).should == "A"
604
+
605
+ Pry.new.prompt.should == Pry.prompt
606
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
607
+ Pry.new.select_prompt(false, 0).should == "test prompt> "
608
+ end
609
+
610
+ it 'should set the prompt default, and the default should be overridable (multi prompt)' do
611
+ new_prompt = [proc { "test prompt> " }, proc { "test prompt* " }]
612
+ Pry.prompt = new_prompt
613
+
614
+ Pry.new.prompt.should == Pry.prompt
615
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
616
+ Pry.new.select_prompt(false, 0).should == "test prompt* "
617
+
618
+ new_prompt = [proc { "A" }, proc { "B" }]
619
+ pry_tester = Pry.new(:prompt => new_prompt)
620
+ pry_tester.prompt.should == new_prompt
621
+ pry_tester.select_prompt(true, 0).should == "A"
622
+ pry_tester.select_prompt(false, 0).should == "B"
623
+
624
+ Pry.new.prompt.should == Pry.prompt
625
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
626
+ Pry.new.select_prompt(false, 0).should == "test prompt* "
627
+ end
628
+ end
629
+
630
+ it 'should set the hooks default, and the default should be overridable' do
631
+ Pry.input = InputTester.new("exit")
632
+ Pry.hooks = {
633
+ :before_session => proc { |out,_| out.puts "HELLO" },
634
+ :after_session => proc { |out,_| out.puts "BYE" }
635
+ }
636
+
637
+ str_output = StringIO.new
638
+ Pry.new(:output => str_output).repl
639
+ str_output.string.should =~ /HELLO/
640
+ str_output.string.should =~ /BYE/
641
+
642
+ Pry.input.rewind
643
+
644
+ str_output = StringIO.new
645
+ Pry.new(:output => str_output,
646
+ :hooks => {
647
+ :before_session => proc { |out,_| out.puts "MORNING" },
648
+ :after_session => proc { |out,_| out.puts "EVENING" }
649
+ }
650
+ ).repl
651
+
652
+ str_output.string.should =~ /MORNING/
653
+ str_output.string.should =~ /EVENING/
654
+
655
+ # try below with just defining one hook
656
+ Pry.input.rewind
657
+ str_output = StringIO.new
658
+ Pry.new(:output => str_output,
659
+ :hooks => {
660
+ :before_session => proc { |out,_| out.puts "OPEN" }
661
+ }
662
+ ).repl
663
+
664
+ str_output.string.should =~ /OPEN/
665
+
666
+ Pry.input.rewind
667
+ str_output = StringIO.new
668
+ Pry.new(:output => str_output,
669
+ :hooks => {
670
+ :after_session => proc { |out,_| out.puts "CLOSE" }
671
+ }
672
+ ).repl
673
+
674
+ str_output.string.should =~ /CLOSE/
675
+
676
+ Pry.reset_defaults
677
+ end
678
+ end
679
+ end
680
+ end
681
+ end