pry 0.6.8-java

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
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
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), __FILE__, __LINE__
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.8"
3
+ end
@@ -0,0 +1,725 @@
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
+ # Ensure we do not execute any rc files
14
+ Pry::RC_FILES.clear
15
+ Pry.color = false
16
+ Pry.should_load_rc = false
17
+
18
+ describe Pry do
19
+ describe "open a Pry session on an object" do
20
+ describe "rep" do
21
+
22
+ before do
23
+ class Hello
24
+ end
25
+ end
26
+
27
+ after do
28
+ Object.send(:remove_const, :Hello)
29
+ end
30
+
31
+ it 'should set an ivar on an object' do
32
+ input_string = "@x = 10"
33
+ input = InputTester.new(input_string)
34
+ o = Object.new
35
+
36
+ pry_tester = Pry.new(:input => input, :output => Pry::NullOutput)
37
+ pry_tester.rep(o)
38
+ o.instance_variable_get(:@x).should == 10
39
+ end
40
+
41
+ it 'should make self evaluate to the receiver of the rep session' do
42
+ o = Object.new
43
+ str_output = StringIO.new
44
+
45
+ pry_tester = Pry.new(:input => InputTester.new("self"), :output => str_output)
46
+ pry_tester.rep(o)
47
+ str_output.string.should =~ /#{o.to_s}/
48
+ end
49
+
50
+ it 'should work with multi-line input' do
51
+ o = Object.new
52
+ str_output = StringIO.new
53
+
54
+ pry_tester = Pry.new(:input => InputTester.new("x = ", "1 + 4"), :output => str_output)
55
+ pry_tester.rep(o)
56
+ str_output.string.should =~ /5/
57
+ end
58
+
59
+ it 'should define a nested class under Hello and not on top-level or Pry' do
60
+ pry_tester = Pry.new(:input => InputTester.new("class Nested", "end"), :output => Pry::NullOutput)
61
+ pry_tester.rep(Hello)
62
+ Hello.const_defined?(:Nested).should == true
63
+ end
64
+ end
65
+
66
+ describe "repl" do
67
+ describe "basic functionality" do
68
+ it 'should set an ivar on an object and exit the repl' do
69
+ input_strings = ["@x = 10", "exit"]
70
+ input = InputTester.new(*input_strings)
71
+
72
+ o = Object.new
73
+
74
+ pry_tester = Pry.start(o, :input => input, :output => Pry::NullOutput)
75
+
76
+ o.instance_variable_get(:@x).should == 10
77
+ end
78
+
79
+ it 'should execute start session and end session hooks' do
80
+ input = InputTester.new("exit")
81
+ str_output = StringIO.new
82
+ o = Object.new
83
+
84
+ pry_tester = Pry.start(o, :input => input, :output => str_output)
85
+ str_output.string.should =~ /Beginning.*#{o}/
86
+ str_output.string.should =~ /Ending.*#{o}/
87
+ end
88
+ end
89
+
90
+ describe "test loading rc files" do
91
+ after do
92
+ Pry::RC_FILES.clear
93
+ Pry.should_load_rc = false
94
+ end
95
+
96
+ it "should run the rc file only once" do
97
+ Pry.should_load_rc = true
98
+ Pry::RC_FILES << "#{direc}/testrc"
99
+
100
+ Pry.start(self, :input => StringIO.new("exit\n"), :output => Pry::NullOutput)
101
+ TEST_RC.should == [0]
102
+
103
+ Pry.start(self, :input => StringIO.new("exit\n"), :output => Pry::NullOutput)
104
+ TEST_RC.should == [0]
105
+
106
+ Object.remove_const(:TEST_RC)
107
+ end
108
+
109
+ it "should not run the rc file at all if Pry.should_load_rc is false" do
110
+ Pry.should_load_rc = false
111
+ Pry.start(self, :input => StringIO.new("exit\n"), :output => Pry::NullOutput)
112
+ Object.const_defined?(:TEST_RC).should == false
113
+ end
114
+
115
+ it "should not load the rc file if #repl method invoked" do
116
+ Pry.should_load_rc = true
117
+ Pry.new(:input => StringIO.new("exit\n"), :output => Pry::NullOutput).repl(self)
118
+ Object.const_defined?(:TEST_RC).should == false
119
+ Pry.should_load_rc = false
120
+ end
121
+ end
122
+
123
+ describe "nesting" do
124
+ after do
125
+ Pry.reset_defaults
126
+ Pry.color = false
127
+ end
128
+
129
+ it 'should nest properly' do
130
+ Pry.input = InputTester.new("pry", "pry", "pry", "\"nest:\#\{Pry.nesting.level\}\"", "exit_all")
131
+
132
+ str_output = StringIO.new
133
+ Pry.output = str_output
134
+
135
+ o = Object.new
136
+
137
+ pry_tester = o.pry
138
+ str_output.string.should =~ /nest:3/
139
+ end
140
+ end
141
+
142
+ describe "defining methods" do
143
+ it 'should define a method on the singleton class of an object when performing "def meth;end" inside the object' do
144
+ [Object.new, {}, []].each do |val|
145
+ str_input = StringIO.new("def hello;end")
146
+ Pry.new(:input => str_input, :output => StringIO.new).rep(val)
147
+
148
+ val.methods(false).map(&:to_sym).include?(:hello).should == true
149
+ end
150
+ end
151
+
152
+ it 'should define an instance method on the module when performing "def meth;end" inside the module' do
153
+ str_input = StringIO.new("def hello;end")
154
+ hello = Module.new
155
+ Pry.new(:input => str_input, :output => StringIO.new).rep(hello)
156
+ hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true
157
+ end
158
+
159
+ it 'should define an instance method on the class when performing "def meth;end" inside the class' do
160
+ str_input = StringIO.new("def hello;end")
161
+ hello = Class.new
162
+ Pry.new(:input => str_input, :output => StringIO.new).rep(hello)
163
+ hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true
164
+ end
165
+
166
+ it 'should define a method on the class of an object when performing "def meth;end" inside an immediate value or Numeric' do
167
+ # should include float in here, but test fails for some reason
168
+ # on 1.8.7, no idea why!
169
+ [:test, 0, true, false, nil].each do |val|
170
+ str_input = StringIO.new("def hello;end")
171
+ Pry.new(:input => str_input, :output => StringIO.new).rep(val)
172
+ val.class.instance_methods(false).map(&:to_sym).include?(:hello).should == true
173
+ end
174
+ end
175
+
176
+ end
177
+
178
+
179
+ describe "commands" do
180
+ it 'should run a command with no parameter' do
181
+ pry_tester = Pry.new
182
+ pry_tester.commands = CommandTester
183
+ pry_tester.input = InputTester.new("command1", "exit_all")
184
+ pry_tester.commands = CommandTester
185
+
186
+ str_output = StringIO.new
187
+ pry_tester.output = str_output
188
+
189
+ pry_tester.rep
190
+
191
+ str_output.string.should =~ /command1/
192
+ end
193
+
194
+ it 'should run a command with one parameter' do
195
+ pry_tester = Pry.new
196
+ pry_tester.commands = CommandTester
197
+ pry_tester.input = InputTester.new("command2 horsey", "exit_all")
198
+ pry_tester.commands = CommandTester
199
+
200
+ str_output = StringIO.new
201
+ pry_tester.output = str_output
202
+
203
+ pry_tester.rep
204
+
205
+ str_output.string.should =~ /horsey/
206
+ end
207
+ end
208
+
209
+ describe "Object#pry" do
210
+
211
+ after do
212
+ Pry.reset_defaults
213
+ Pry.color = false
214
+ end
215
+
216
+ it "should start a pry session on the receiver (first form)" do
217
+ Pry.input = InputTester.new("self", "exit")
218
+
219
+ str_output = StringIO.new
220
+ Pry.output = str_output
221
+
222
+ 20.pry
223
+
224
+ str_output.string.should =~ /20/
225
+ end
226
+
227
+ it "should start a pry session on the receiver (second form)" do
228
+ Pry.input = InputTester.new("self", "exit")
229
+
230
+ str_output = StringIO.new
231
+ Pry.output = str_output
232
+
233
+ pry 20
234
+
235
+ str_output.string.should =~ /20/
236
+ end
237
+
238
+ it "should error if more than one argument is passed to Object#pry" do
239
+ lambda { pry(20, :input => Readline) }.should.raise ArgumentError
240
+ end
241
+ end
242
+
243
+ describe "Pry.binding_for" do
244
+ it 'should return TOPLEVEL_BINDING if parameter self is main' do
245
+ _main_ = lambda { TOPLEVEL_BINDING.eval('self') }
246
+ Pry.binding_for(_main_.call).is_a?(Binding).should == true
247
+ Pry.binding_for(_main_.call).should == TOPLEVEL_BINDING
248
+ Pry.binding_for(_main_.call).should == Pry.binding_for(_main_.call)
249
+ end
250
+ end
251
+
252
+
253
+ describe "test Pry defaults" do
254
+
255
+ after do
256
+ Pry.reset_defaults
257
+ Pry.color = false
258
+ end
259
+
260
+ describe "input" do
261
+
262
+ after do
263
+ Pry.reset_defaults
264
+ Pry.color = false
265
+ end
266
+
267
+ it 'should set the input default, and the default should be overridable' do
268
+ Pry.input = InputTester.new("5")
269
+
270
+ str_output = StringIO.new
271
+ Pry.output = str_output
272
+ Pry.new.rep
273
+ str_output.string.should =~ /5/
274
+
275
+ Pry.new(:input => InputTester.new("6")).rep
276
+ str_output.string.should =~ /6/
277
+ end
278
+
279
+ it 'should pass in the prompt if readline arity is 1' do
280
+ Pry.prompt = proc { "A" }
281
+
282
+ arity_one_input = Class.new do
283
+ attr_accessor :prompt
284
+ def readline(prompt)
285
+ @prompt = prompt
286
+ "exit"
287
+ end
288
+ end.new
289
+
290
+ Pry.start(self, :input => arity_one_input, :output => Pry::NullOutput)
291
+ arity_one_input.prompt.should == Pry.prompt.call
292
+ end
293
+
294
+ it 'should not pass in the prompt if the arity is 0' do
295
+ Pry.prompt = proc { "A" }
296
+
297
+ arity_zero_input = Class.new do
298
+ def readline
299
+ "exit"
300
+ end
301
+ end.new
302
+
303
+ lambda { Pry.start(self, :input => arity_zero_input, :output => Pry::NullOutput) }.should.not.raise Exception
304
+ end
305
+
306
+ it 'should not pass in the prompt if the arity is -1' do
307
+ Pry.prompt = proc { "A" }
308
+
309
+ arity_multi_input = Class.new do
310
+ attr_accessor :prompt
311
+
312
+ def readline(*args)
313
+ @prompt = args.first
314
+ "exit"
315
+ end
316
+ end.new
317
+
318
+ Pry.start(self, :input => arity_multi_input, :output => Pry::NullOutput)
319
+ arity_multi_input.prompt.should == nil
320
+ end
321
+
322
+ end
323
+
324
+ it 'should set the output default, and the default should be overridable' do
325
+ Pry.input = InputTester.new("5", "6", "7")
326
+
327
+ str_output = StringIO.new
328
+ Pry.output = str_output
329
+
330
+ Pry.new.rep
331
+ str_output.string.should =~ /5/
332
+
333
+ Pry.new.rep
334
+ str_output.string.should =~ /5\n.*6/
335
+
336
+ str_output2 = StringIO.new
337
+ Pry.new(:output => str_output2).rep
338
+ str_output2.string.should.not =~ /5\n.*6/
339
+ str_output2.string.should =~ /7/
340
+ end
341
+
342
+ describe "Pry.run_command" do
343
+ before do
344
+ class RCTest
345
+ def a() end
346
+ B = 20
347
+ @x = 10
348
+ end
349
+ end
350
+
351
+ after do
352
+ Object.remove_const(:RCTest)
353
+ end
354
+
355
+ it "should execute command in the appropriate object context" do
356
+ result = Pry.run_command "ls", :context => RCTest
357
+ result.map(&:to_sym).should == [:@x]
358
+ end
359
+
360
+ it "should execute command with parameters in the appropriate object context" do
361
+ result = Pry.run_command "ls -M", :context => RCTest
362
+ result.map(&:to_sym).should == [:a]
363
+ end
364
+
365
+ it "should execute command and show output with :show_output => true flag" do
366
+ str = StringIO.new
367
+ Pry.output = str
368
+ result = Pry.run_command "ls -av", :context => RCTest, :show_output => true
369
+ str.string.should =~ /global variables/
370
+ Pry.output = $stdout
371
+ end
372
+
373
+ it "should execute command with multiple parameters" do
374
+ result = Pry.run_command "ls -c -M RCTest"
375
+ result.map(&:to_sym).should == [:a, :B]
376
+ end
377
+ end
378
+
379
+ describe "commands" do
380
+ it 'should define a command that keeps its return value' do
381
+ class Command68 < Pry::CommandBase
382
+ command "hello", "", :keep_retval => true do
383
+ :kept_hello
384
+ end
385
+ end
386
+ str_output = StringIO.new
387
+ Pry.new(:input => StringIO.new("hello"), :output => str_output, :commands => Command68).rep
388
+ str_output.string.should =~ /:kept_hello/
389
+
390
+ Object.remove_const(:Command68)
391
+ end
392
+
393
+ it 'should define a command that does NOT keep its return value' do
394
+ class Command68 < Pry::CommandBase
395
+ command "hello", "", :keep_retval => false do
396
+ :kept_hello
397
+ end
398
+ end
399
+ str_output = StringIO.new
400
+ Pry.new(:input => StringIO.new("hello"), :output => str_output, :commands => Command68).rep
401
+ (str_output.string =~ /:kept_hello/).should == nil
402
+
403
+ Object.remove_const(:Command68)
404
+ end
405
+
406
+
407
+ it 'should set the commands default, and the default should be overridable' do
408
+ class Command0 < Pry::CommandBase
409
+ command "hello" do
410
+ output.puts "hello world"
411
+ end
412
+ end
413
+
414
+ Pry.commands = Command0
415
+
416
+ str_output = StringIO.new
417
+ Pry.new(:input => InputTester.new("hello"), :output => str_output).rep
418
+ str_output.string.should =~ /hello world/
419
+
420
+ class Command1 < Pry::CommandBase
421
+ command "goodbye", "" do
422
+ output.puts "goodbye world"
423
+ end
424
+ end
425
+
426
+ str_output = StringIO.new
427
+
428
+ Pry.new(:input => InputTester.new("goodbye"), :output => str_output, :commands => Command1).rep
429
+ str_output.string.should =~ /goodbye world/
430
+
431
+ Object.remove_const(:Command0)
432
+ Object.remove_const(:Command1)
433
+ end
434
+
435
+ it 'should inherit "help" command from Pry::CommandBase' do
436
+ class Command2 < Pry::CommandBase
437
+ command "h", "h command" do
438
+ end
439
+ end
440
+
441
+ Command2.commands.keys.size.should == 2
442
+ Command2.commands.keys.include?("help").should == true
443
+ Command2.commands.keys.include?("h").should == true
444
+
445
+ Object.remove_const(:Command2)
446
+ end
447
+
448
+ it 'should inherit commands from Pry::Commands' do
449
+ class Command3 < Pry::Commands
450
+ command "v" do
451
+ end
452
+ end
453
+
454
+ Command3.commands.include?("nesting").should == true
455
+ Command3.commands.include?("jump-to").should == true
456
+ Command3.commands.include?("cd").should == true
457
+ Command3.commands.include?("v").should == true
458
+
459
+ Object.remove_const(:Command3)
460
+ end
461
+
462
+ it 'should alias a command with another command' do
463
+ class Command6 < Pry::CommandBase
464
+ alias_command "help2", "help"
465
+ end
466
+
467
+ Command6.commands["help2"].should == Command6.commands["help"]
468
+ # str_output = StringIO.new
469
+ # Pry.new(:input => InputTester.new("run_v"), :output => str_output, :commands => Command3).rep
470
+ # str_output.string.should =~ /v command/
471
+
472
+ Object.remove_const(:Command6)
473
+ end
474
+
475
+ it 'should change description of a command using desc' do
476
+
477
+ class Command7 < Pry::Commands
478
+ end
479
+
480
+ orig = Command7.commands["help"][:description]
481
+
482
+ class Command7
483
+ desc "help", "blah"
484
+ end
485
+
486
+ Command7.commands["help"][:description].should.not == orig
487
+ Command7.commands["help"][:description].should == "blah"
488
+
489
+ Object.remove_const(:Command7)
490
+ end
491
+
492
+ it 'should run a command from within a command' do
493
+ class Command01 < Pry::Commands
494
+ command "v" do
495
+ output.puts "v command"
496
+ end
497
+
498
+ command "run_v" do
499
+ run "v"
500
+ end
501
+ end
502
+
503
+ str_output = StringIO.new
504
+ Pry.new(:input => InputTester.new("run_v"), :output => str_output, :commands => Command01).rep
505
+ str_output.string.should =~ /v command/
506
+
507
+ Object.remove_const(:Command01)
508
+ end
509
+
510
+ it 'should enable an inherited method to access opts and output and target, due to instance_exec' do
511
+ class Command3 < Pry::Commands
512
+ command "v" do
513
+ output.puts "#{target.eval('self')}"
514
+ end
515
+ end
516
+
517
+ class Command4 < Command3
518
+ end
519
+
520
+ str_output = StringIO.new
521
+ Pry.new(:print => proc {}, :input => InputTester.new("v"),
522
+ :output => str_output, :commands => Command4).rep("john")
523
+ str_output.string.chomp.should == "john"
524
+
525
+ Object.remove_const(:Command3)
526
+ Object.remove_const(:Command4)
527
+ end
528
+
529
+ it 'should import commands from another command object' do
530
+ class Command3 < Pry::CommandBase
531
+ import_from Pry::Commands, "status", "jump-to"
532
+ end
533
+
534
+ str_output = StringIO.new
535
+ Pry.new(:print => proc {}, :input => InputTester.new("status"),
536
+ :output => str_output, :commands => Command3).rep("john")
537
+ str_output.string.should =~ /Status:/
538
+
539
+ Object.remove_const(:Command3)
540
+ end
541
+
542
+ it 'should delete some inherited commands when using delete method' do
543
+ class Command3 < Pry::Commands
544
+ command "v" do
545
+ end
546
+
547
+ delete "show_doc", "show_method"
548
+ delete "ls"
549
+ end
550
+
551
+ Command3.commands.include?("nesting").should == true
552
+ Command3.commands.include?("jump-to").should == true
553
+ Command3.commands.include?("cd").should == true
554
+ Command3.commands.include?("v").should == true
555
+ Command3.commands.include?("show_doc").should == false
556
+ Command3.commands.include?("show_method").should == false
557
+ Command3.commands.include?("ls").should == false
558
+
559
+ Object.remove_const(:Command3)
560
+ end
561
+
562
+ it 'should override some inherited commands' do
563
+ class Command3 < Pry::Commands
564
+ command "jump-to" do
565
+ output.puts "jump-to the music"
566
+ end
567
+
568
+ command "help" do
569
+ output.puts "help to the music"
570
+ end
571
+ end
572
+
573
+ # suppress evaluation output
574
+ Pry.print = proc {}
575
+
576
+ str_output = StringIO.new
577
+ Pry.new(:input => InputTester.new("jump-to"), :output => str_output, :commands => Command3).rep
578
+ str_output.string.chomp.should == "jump-to the music"
579
+
580
+ str_output = StringIO.new
581
+ Pry.new(:input => InputTester.new("help"), :output => str_output, :commands => Command3).rep
582
+ str_output.string.chomp.should == "help to the music"
583
+
584
+ Object.remove_const(:Command3)
585
+
586
+ Pry.reset_defaults
587
+ Pry.color = false
588
+ end
589
+ end
590
+
591
+ it "should set the print default, and the default should be overridable" do
592
+ new_print = proc { |out, value| out.puts value }
593
+ Pry.print = new_print
594
+
595
+ Pry.new.print.should == Pry.print
596
+ str_output = StringIO.new
597
+ Pry.new(:input => InputTester.new("\"test\""), :output => str_output).rep
598
+ str_output.string.should == "test\n"
599
+
600
+ str_output = StringIO.new
601
+ Pry.new(:input => InputTester.new("\"test\""), :output => str_output,
602
+ :print => proc { |out, value| out.puts value.reverse }).rep
603
+ str_output.string.should == "tset\n"
604
+
605
+ Pry.new.print.should == Pry.print
606
+ str_output = StringIO.new
607
+ Pry.new(:input => InputTester.new("\"test\""), :output => str_output).rep
608
+ str_output.string.should == "test\n"
609
+ end
610
+
611
+ describe "pry return values" do
612
+ it 'should return the target object' do
613
+ Pry.start(self, :input => StringIO.new("exit"), :output => Pry::NullOutput).should == self
614
+ end
615
+
616
+ it 'should return the parameter given to exit' do
617
+ Pry.start(self, :input => StringIO.new("exit 10"), :output => Pry::NullOutput).should == 10
618
+ end
619
+
620
+ it 'should return the parameter (multi word string) given to exit' do
621
+ Pry.start(self, :input => StringIO.new("exit \"john mair\""), :output => Pry::NullOutput).should == "john mair"
622
+ end
623
+
624
+ it 'should return the parameter (function call) given to exit' do
625
+ Pry.start(self, :input => StringIO.new("exit 'abc'.reverse"), :output => Pry::NullOutput).should == 'cba'
626
+ end
627
+
628
+ it 'should return the parameter (self) given to exit' do
629
+ Pry.start("carl", :input => StringIO.new("exit self"), :output => Pry::NullOutput).should == "carl"
630
+ end
631
+ end
632
+
633
+ describe "prompts" do
634
+ it 'should set the prompt default, and the default should be overridable (single prompt)' do
635
+ new_prompt = proc { "test prompt> " }
636
+ Pry.prompt = new_prompt
637
+
638
+ Pry.new.prompt.should == Pry.prompt
639
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
640
+ Pry.new.select_prompt(false, 0).should == "test prompt> "
641
+
642
+ new_prompt = proc { "A" }
643
+ pry_tester = Pry.new(:prompt => new_prompt)
644
+ pry_tester.prompt.should == new_prompt
645
+ pry_tester.select_prompt(true, 0).should == "A"
646
+ pry_tester.select_prompt(false, 0).should == "A"
647
+
648
+ Pry.new.prompt.should == Pry.prompt
649
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
650
+ Pry.new.select_prompt(false, 0).should == "test prompt> "
651
+ end
652
+
653
+ it 'should set the prompt default, and the default should be overridable (multi prompt)' do
654
+ new_prompt = [proc { "test prompt> " }, proc { "test prompt* " }]
655
+ Pry.prompt = new_prompt
656
+
657
+ Pry.new.prompt.should == Pry.prompt
658
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
659
+ Pry.new.select_prompt(false, 0).should == "test prompt* "
660
+
661
+ new_prompt = [proc { "A" }, proc { "B" }]
662
+ pry_tester = Pry.new(:prompt => new_prompt)
663
+ pry_tester.prompt.should == new_prompt
664
+ pry_tester.select_prompt(true, 0).should == "A"
665
+ pry_tester.select_prompt(false, 0).should == "B"
666
+
667
+ Pry.new.prompt.should == Pry.prompt
668
+ Pry.new.select_prompt(true, 0).should == "test prompt> "
669
+ Pry.new.select_prompt(false, 0).should == "test prompt* "
670
+ end
671
+ end
672
+
673
+ it 'should set the hooks default, and the default should be overridable' do
674
+ Pry.input = InputTester.new("exit")
675
+ Pry.hooks = {
676
+ :before_session => proc { |out,_| out.puts "HELLO" },
677
+ :after_session => proc { |out,_| out.puts "BYE" }
678
+ }
679
+
680
+ str_output = StringIO.new
681
+ Pry.new(:output => str_output).repl
682
+ str_output.string.should =~ /HELLO/
683
+ str_output.string.should =~ /BYE/
684
+
685
+ Pry.input.rewind
686
+
687
+ str_output = StringIO.new
688
+ Pry.new(:output => str_output,
689
+ :hooks => {
690
+ :before_session => proc { |out,_| out.puts "MORNING" },
691
+ :after_session => proc { |out,_| out.puts "EVENING" }
692
+ }
693
+ ).repl
694
+
695
+ str_output.string.should =~ /MORNING/
696
+ str_output.string.should =~ /EVENING/
697
+
698
+ # try below with just defining one hook
699
+ Pry.input.rewind
700
+ str_output = StringIO.new
701
+ Pry.new(:output => str_output,
702
+ :hooks => {
703
+ :before_session => proc { |out,_| out.puts "OPEN" }
704
+ }
705
+ ).repl
706
+
707
+ str_output.string.should =~ /OPEN/
708
+
709
+ Pry.input.rewind
710
+ str_output = StringIO.new
711
+ Pry.new(:output => str_output,
712
+ :hooks => {
713
+ :after_session => proc { |out,_| out.puts "CLOSE" }
714
+ }
715
+ ).repl
716
+
717
+ str_output.string.should =~ /CLOSE/
718
+
719
+ Pry.reset_defaults
720
+ Pry.color = false
721
+ end
722
+ end
723
+ end
724
+ end
725
+ end