pry 0.6.7-i386-mswin32

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.
@@ -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
data/test/test.rb ADDED
@@ -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