pry 0.9.7.4-i386-mingw32 → 0.9.8-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -3
- data/CHANGELOG +43 -0
- data/README.markdown +3 -1
- data/Rakefile +51 -32
- data/bin/pry +2 -80
- data/lib/pry.rb +33 -26
- data/lib/pry/cli.rb +152 -0
- data/lib/pry/code.rb +351 -0
- data/lib/pry/command.rb +422 -0
- data/lib/pry/command_set.rb +259 -129
- data/lib/pry/commands.rb +0 -1
- data/lib/pry/config.rb +43 -9
- data/lib/pry/default_commands/context.rb +109 -92
- data/lib/pry/default_commands/documentation.rb +174 -63
- data/lib/pry/default_commands/easter_eggs.rb +26 -2
- data/lib/pry/default_commands/gems.rb +65 -37
- data/lib/pry/default_commands/input.rb +175 -243
- data/lib/pry/default_commands/introspection.rb +173 -112
- data/lib/pry/default_commands/ls.rb +96 -114
- data/lib/pry/default_commands/shell.rb +175 -70
- data/lib/pry/helpers/base_helpers.rb +7 -2
- data/lib/pry/helpers/command_helpers.rb +71 -77
- data/lib/pry/helpers/options_helpers.rb +10 -41
- data/lib/pry/helpers/text.rb +24 -4
- data/lib/pry/history.rb +55 -17
- data/lib/pry/history_array.rb +2 -0
- data/lib/pry/hooks.rb +252 -0
- data/lib/pry/indent.rb +9 -5
- data/lib/pry/method.rb +149 -50
- data/lib/pry/plugins.rb +12 -4
- data/lib/pry/pry_class.rb +69 -26
- data/lib/pry/pry_instance.rb +187 -115
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +73 -0
- data/man/pry.1 +195 -0
- data/man/pry.1.html +204 -0
- data/man/pry.1.ronn +141 -0
- data/pry.gemspec +29 -32
- data/test/helper.rb +32 -36
- data/test/test_cli.rb +78 -0
- data/test/test_code.rb +201 -0
- data/test/test_command.rb +327 -0
- data/test/test_command_integration.rb +512 -0
- data/test/test_command_set.rb +338 -12
- data/test/test_completion.rb +1 -1
- data/test/test_default_commands.rb +1 -2
- data/test/test_default_commands/test_context.rb +27 -5
- data/test/test_default_commands/test_documentation.rb +20 -8
- data/test/test_default_commands/test_input.rb +84 -45
- data/test/test_default_commands/test_introspection.rb +74 -17
- data/test/test_default_commands/test_ls.rb +9 -36
- data/test/test_default_commands/test_shell.rb +240 -13
- data/test/test_hooks.rb +490 -0
- data/test/test_indent.rb +2 -0
- data/test/test_method.rb +60 -0
- data/test/test_pry.rb +29 -904
- data/test/test_pry_defaults.rb +380 -0
- data/test/test_pry_history.rb +24 -24
- data/test/test_syntax_checking.rb +63 -0
- data/test/test_wrapped_module.rb +71 -0
- metadata +50 -39
- data/lib/pry/command_context.rb +0 -53
- data/lib/pry/command_processor.rb +0 -181
- data/lib/pry/extended_commands/user_command_api.rb +0 -65
- data/test/test_command_processor.rb +0 -176
@@ -0,0 +1,327 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Pry::Command" do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@set = Pry::CommandSet.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'call_safely' do
|
10
|
+
|
11
|
+
it 'should display a message if gems are missing' do
|
12
|
+
cmd = @set.create_command "ford-prefect", "From a planet near Beetlegeuse", :requires_gem => %w(ghijkl) do
|
13
|
+
#
|
14
|
+
end
|
15
|
+
|
16
|
+
mock_command(cmd, %w(hello world)).output.should =~ /install-command ford-prefect/
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should abort early if arguments are required' do
|
20
|
+
cmd = @set.create_command 'arthur-dent', "Doesn't understand Thursdays", :argument_required => true do
|
21
|
+
#
|
22
|
+
end
|
23
|
+
|
24
|
+
lambda {
|
25
|
+
mock_command(cmd, %w())
|
26
|
+
}.should.raise(Pry::CommandError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return VOID without keep_retval' do
|
30
|
+
cmd = @set.create_command 'zaphod-beeblebrox', "Likes pan-Galactic Gargle Blasters" do
|
31
|
+
def process
|
32
|
+
3
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
mock_command(cmd).return.should == Pry::Command::VOID_VALUE
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should return the return value with keep_retval' do
|
40
|
+
cmd = @set.create_command 'tricia-mcmillian', "a.k.a Trillian", :keep_retval => true do
|
41
|
+
def process
|
42
|
+
5
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
mock_command(cmd).return.should == 5
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should call hooks in the right order' do
|
50
|
+
cmd = @set.create_command 'marvin', "Pained by the diodes in his left side" do
|
51
|
+
def process
|
52
|
+
output.puts 3 + args[0].to_i
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
@set.before_command 'marvin' do |i|
|
57
|
+
output.puts 2 + i.to_i
|
58
|
+
end
|
59
|
+
@set.before_command 'marvin' do |i|
|
60
|
+
output.puts 1 + i.to_i
|
61
|
+
end
|
62
|
+
|
63
|
+
@set.after_command 'marvin' do |i|
|
64
|
+
output.puts 4 + i.to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
@set.after_command 'marvin' do |i|
|
68
|
+
output.puts 5 + i.to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
mock_command(cmd, %w(2)).output.should == "3\n4\n5\n6\n7\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
# TODO: This strikes me as rather silly...
|
75
|
+
it 'should return the value from the last hook with keep_retval' do
|
76
|
+
cmd = @set.create_command 'slartibartfast', "Designs Fjords", :keep_retval => true do
|
77
|
+
def process
|
78
|
+
22
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
@set.after_command 'slartibartfast' do
|
83
|
+
10
|
84
|
+
end
|
85
|
+
|
86
|
+
mock_command(cmd).return.should == 10
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'help' do
|
91
|
+
it 'should default to the description for blocky commands' do
|
92
|
+
@set.command 'oolon-colluphid', "Raving Atheist" do
|
93
|
+
#
|
94
|
+
end
|
95
|
+
|
96
|
+
mock_command(@set.commands['help'], %w(oolon-colluphid), :command_set => @set).output.should =~ /Raving Atheist/
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should use slop to generate the help for classy commands' do
|
100
|
+
@set.create_command 'eddie', "The ship-board computer" do
|
101
|
+
def options(opt)
|
102
|
+
opt.banner "Over-cheerful, and makes a ticking noise."
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
mock_command(@set.commands['help'], %w(eddie), :command_set => @set).output.should =~ /Over-cheerful/
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should provide --help for classy commands' do
|
110
|
+
cmd = @set.create_command 'agrajag', "Killed many times by Arthur" do
|
111
|
+
def options(opt)
|
112
|
+
opt.on :r, :retaliate, "Try to get Arthur back"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
mock_command(cmd, %w(--help)).output.should =~ /--retaliate/
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should provide a -h for classy commands' do
|
120
|
+
cmd = @set.create_command 'zarniwoop', "On an intergalactic cruise, in his office." do
|
121
|
+
def options(opt)
|
122
|
+
opt.on :e, :escape, "Help zaphod escape the Total Perspective Vortex"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
mock_command(cmd, %w(--help)).output.should =~ /Total Perspective Vortex/
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should use the banner provided' do
|
130
|
+
cmd = @set.create_command 'deep-thought', "The second-best computer ever" do
|
131
|
+
banner <<-BANNER
|
132
|
+
Who's merest operational parameters, I am not worthy to compute.
|
133
|
+
BANNER
|
134
|
+
end
|
135
|
+
|
136
|
+
mock_command(cmd, %w(--help)).output.should =~ /Who\'s merest/
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
describe 'context' do
|
142
|
+
context = {
|
143
|
+
:target => binding,
|
144
|
+
:output => StringIO.new,
|
145
|
+
:eval_string => "eval-string",
|
146
|
+
:command_set => @set,
|
147
|
+
:pry_instance => Object.new
|
148
|
+
}
|
149
|
+
|
150
|
+
it 'should capture lots of stuff from the hash passed to new before setup' do
|
151
|
+
cmd = @set.create_command 'fenchurch', "Floats slightly off the ground" do
|
152
|
+
define_method(:setup) do
|
153
|
+
self.context.should == context
|
154
|
+
target.should == context[:target]
|
155
|
+
target_self.should == context[:target].eval('self')
|
156
|
+
output.should == context[:output]
|
157
|
+
end
|
158
|
+
|
159
|
+
define_method(:process) do
|
160
|
+
eval_string.should == "eval-string"
|
161
|
+
command_set.should == @set
|
162
|
+
_pry_.should == context[:pry_instance]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
cmd.new(context).call
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe 'classy api' do
|
171
|
+
|
172
|
+
it 'should call setup, then options, then process' do
|
173
|
+
cmd = @set.create_command 'rooster', "Has a tasty towel" do
|
174
|
+
def setup
|
175
|
+
output.puts "setup"
|
176
|
+
end
|
177
|
+
|
178
|
+
def options(opt)
|
179
|
+
output.puts "options"
|
180
|
+
end
|
181
|
+
|
182
|
+
def process
|
183
|
+
output.puts "process"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
mock_command(cmd).output.should == "setup\noptions\nprocess\n"
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should raise a command error if process is not overridden' do
|
191
|
+
cmd = @set.create_command 'jeltz', "Commander of a Vogon constructor fleet" do
|
192
|
+
def proccces
|
193
|
+
#
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
lambda {
|
198
|
+
mock_command(cmd)
|
199
|
+
}.should.raise(Pry::CommandError)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'should work if neither options, nor setup is overridden' do
|
203
|
+
cmd = @set.create_command 'wowbagger', "Immortal, insulting.", :keep_retval => true do
|
204
|
+
def process
|
205
|
+
5
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
mock_command(cmd).return.should == 5
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should provide opts and args as provided by slop' do
|
213
|
+
cmd = @set.create_command 'lintilla', "One of 800,000,000 clones" do
|
214
|
+
def options(opt)
|
215
|
+
opt.on :f, :four, "A numeric four", :as => Integer, :optional => true
|
216
|
+
end
|
217
|
+
|
218
|
+
def process
|
219
|
+
args.should == ['four']
|
220
|
+
opts[:f].should == 4
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
mock_command(cmd, %w(--four 4 four))
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should allow overriding options after definition' do
|
228
|
+
cmd = @set.create_command /number-(one|two)/, "Lieutenants of the Golgafrinchan Captain", :shellwords => false do
|
229
|
+
|
230
|
+
command_options :listing => 'number-one'
|
231
|
+
end
|
232
|
+
|
233
|
+
cmd.command_options[:shellwords].should == false
|
234
|
+
cmd.command_options[:listing].should == 'number-one'
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe 'tokenize' do
|
239
|
+
it 'should interpolate string with #{} in them' do
|
240
|
+
cmd = @set.command 'random-dent' do |*args|
|
241
|
+
args.should == ["3", "8"]
|
242
|
+
end
|
243
|
+
|
244
|
+
foo = 5
|
245
|
+
|
246
|
+
cmd.new(:target => binding).process_line 'random-dent #{1 + 2} #{3 + foo}'
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should not fail if interpolation is not needed and target is not set' do
|
250
|
+
cmd = @set.command 'the-book' do |*args|
|
251
|
+
args.should == ['--help']
|
252
|
+
end
|
253
|
+
|
254
|
+
cmd.new.process_line 'the-book --help'
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'should not interpolate commands with :interpolate => false' do
|
258
|
+
cmd = @set.command 'thor', 'norse god', :interpolate => false do |*args|
|
259
|
+
args.should == ['%(#{foo})']
|
260
|
+
end
|
261
|
+
|
262
|
+
cmd.new.process_line 'thor %(#{foo})'
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'should use shell-words to split strings' do
|
266
|
+
cmd = @set.command 'eccentrica' do |*args|
|
267
|
+
args.should == ['gallumbits', 'eroticon', '6']
|
268
|
+
end
|
269
|
+
|
270
|
+
cmd.new.process_line %(eccentrica "gallumbits" 'erot''icon' 6)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should split on spaces if shellwords is not used' do
|
274
|
+
cmd = @set.command 'bugblatter-beast', 'would eat its grandmother', :shellwords => false do |*args|
|
275
|
+
args.should == ['"of', 'traal"']
|
276
|
+
end
|
277
|
+
|
278
|
+
cmd.new.process_line %(bugblatter-beast "of traal")
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'should add captures to arguments for regex commands' do
|
282
|
+
cmd = @set.command /perfectly (normal)( beast)?/i do |*args|
|
283
|
+
args.should == ['Normal', ' Beast', '(honest!)']
|
284
|
+
end
|
285
|
+
|
286
|
+
cmd.new.process_line %(Perfectly Normal Beast (honest!))
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe 'process_line' do
|
291
|
+
it 'should check for command name collisions if configured' do
|
292
|
+
old = Pry.config.collision_warning
|
293
|
+
Pry.config.collision_warning = true
|
294
|
+
|
295
|
+
cmd = @set.command 'frankie' do
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
frankie = 'boyle'
|
300
|
+
output = StringIO.new
|
301
|
+
cmd.new(:target => binding, :output => output).process_line %(frankie mouse)
|
302
|
+
|
303
|
+
output.string.should =~ /Command name collision/
|
304
|
+
|
305
|
+
Pry.config.collision_warning = old
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should set the commands' arg_string and captures" do
|
309
|
+
|
310
|
+
cmd = @set.command /benj(ie|ei)/ do |*args|
|
311
|
+
self.arg_string.should == "mouse"
|
312
|
+
self.captures.should == ['ie']
|
313
|
+
args.should == ['ie', 'mouse']
|
314
|
+
end
|
315
|
+
|
316
|
+
cmd.new.process_line %(benjie mouse)
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should raise an error if the line doesn't match the command" do
|
320
|
+
cmd = @set.command 'grunthos', 'the flatulent'
|
321
|
+
|
322
|
+
lambda {
|
323
|
+
cmd.new.process_line %(grumpos)
|
324
|
+
}.should.raise(Pry::CommandError)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
@@ -0,0 +1,512 @@
|
|
1
|
+
require 'helper'
|
2
|
+
describe "commands" do
|
3
|
+
it 'should interpolate ruby code into commands' do
|
4
|
+
klass = Pry::CommandSet.new do
|
5
|
+
command "hello", "", :keep_retval => true do |arg|
|
6
|
+
arg
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
$test_interpolation = "bing"
|
11
|
+
str_output = StringIO.new
|
12
|
+
Pry.new(:input => StringIO.new('hello #{$test_interpolation}'), :output => str_output, :commands => klass).rep
|
13
|
+
str_output.string.should =~ /bing/
|
14
|
+
$test_interpolation = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# bug fix for https://github.com/pry/pry/issues/170
|
18
|
+
it 'should not choke on complex string interpolation when checking if ruby code is a command' do
|
19
|
+
redirect_pry_io(InputTester.new('/#{Regexp.escape(File.expand_path("."))}/'), str_output = StringIO.new) do
|
20
|
+
pry
|
21
|
+
end
|
22
|
+
|
23
|
+
str_output.string.should.not =~ /SyntaxError/
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should NOT interpolate ruby code into commands if :interpolate => false' do
|
27
|
+
klass = Pry::CommandSet.new do
|
28
|
+
command "hello", "", :keep_retval => true, :interpolate => false do |arg|
|
29
|
+
arg
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
$test_interpolation = "bing"
|
34
|
+
str_output = StringIO.new
|
35
|
+
Pry.new(:input => StringIO.new('hello #{$test_interpolation}'), :output => str_output, :commands => klass).rep
|
36
|
+
str_output.string.should =~ /test_interpolation/
|
37
|
+
$test_interpolation = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should NOT try to interpolate pure ruby code (no commands) ' do
|
41
|
+
str_output = StringIO.new
|
42
|
+
Pry.new(:input => StringIO.new('format \'#{aggy}\''), :output => str_output).rep
|
43
|
+
str_output.string.should.not =~ /NameError/
|
44
|
+
|
45
|
+
Pry.new(:input => StringIO.new('format #{aggy}'), :output => str_output).rep
|
46
|
+
str_output.string.should.not =~ /NameError/
|
47
|
+
|
48
|
+
$test_interpolation = "blah"
|
49
|
+
Pry.new(:input => StringIO.new('format \'#{$test_interpolation}\''), :output => str_output).rep
|
50
|
+
|
51
|
+
str_output.string.should.not =~ /blah/
|
52
|
+
$test_interpolation = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should create a command with a space in its name' do
|
56
|
+
set = Pry::CommandSet.new do
|
57
|
+
command "hello baby", "" do
|
58
|
+
output.puts "hello baby command"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
str_output = StringIO.new
|
63
|
+
redirect_pry_io(InputTester.new("hello baby", "exit-all"), str_output) do
|
64
|
+
Pry.new(:commands => set).rep
|
65
|
+
end
|
66
|
+
|
67
|
+
str_output.string.should =~ /hello baby command/
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should create a command with a space in its name and pass an argument' do
|
71
|
+
set = Pry::CommandSet.new do
|
72
|
+
command "hello baby", "" do |arg|
|
73
|
+
output.puts "hello baby command #{arg}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
str_output = StringIO.new
|
78
|
+
redirect_pry_io(InputTester.new("hello baby john"), str_output) do
|
79
|
+
Pry.new(:commands => set).rep
|
80
|
+
end
|
81
|
+
|
82
|
+
str_output.string.should =~ /hello baby command john/
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should create a regex command and be able to invoke it' do
|
86
|
+
set = Pry::CommandSet.new do
|
87
|
+
command /hello(.)/, "" do
|
88
|
+
c = captures.first
|
89
|
+
output.puts "hello#{c}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
str_output = StringIO.new
|
94
|
+
redirect_pry_io(InputTester.new("hello1"), str_output) do
|
95
|
+
Pry.new(:commands => set).rep
|
96
|
+
end
|
97
|
+
|
98
|
+
str_output.string.should =~ /hello1/
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should create a regex command and pass captures into the args list before regular arguments' do
|
102
|
+
set = Pry::CommandSet.new do
|
103
|
+
command /hello(.)/, "" do |c1, a1|
|
104
|
+
output.puts "hello #{c1} #{a1}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
str_output = StringIO.new
|
109
|
+
redirect_pry_io(InputTester.new("hello1 baby"), str_output) do
|
110
|
+
Pry.new(:commands => set).rep
|
111
|
+
end
|
112
|
+
|
113
|
+
str_output.string.should =~ /hello 1 baby/
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should create a regex command and interpolate the captures' do
|
117
|
+
set = Pry::CommandSet.new do
|
118
|
+
command /hello (.*)/, "" do |c1|
|
119
|
+
output.puts "hello #{c1}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
str_output = StringIO.new
|
124
|
+
$obj = "bing"
|
125
|
+
redirect_pry_io(InputTester.new('hello #{$obj}'), str_output) do
|
126
|
+
Pry.new(:commands => set).rep
|
127
|
+
end
|
128
|
+
|
129
|
+
str_output.string.should =~ /hello bing/
|
130
|
+
$obj = nil
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should create a regex command and arg_string should be interpolated' do
|
134
|
+
set = Pry::CommandSet.new do
|
135
|
+
command /hello(\w+)/, "" do |c1, a1, a2, a3|
|
136
|
+
output.puts "hello #{c1} #{a1} #{a2} #{a3}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
str_output = StringIO.new
|
141
|
+
$a1 = "bing"
|
142
|
+
$a2 = "bong"
|
143
|
+
$a3 = "bang"
|
144
|
+
redirect_pry_io(InputTester.new('hellojohn #{$a1} #{$a2} #{$a3}'), str_output) do
|
145
|
+
Pry.new(:commands => set).rep
|
146
|
+
end
|
147
|
+
|
148
|
+
str_output.string.should =~ /hello john bing bong bang/
|
149
|
+
|
150
|
+
$a1 = nil
|
151
|
+
$a2 = nil
|
152
|
+
$a3 = nil
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
it 'if a regex capture is missing it should be nil' do
|
157
|
+
set = Pry::CommandSet.new do
|
158
|
+
command /hello(.)?/, "" do |c1, a1|
|
159
|
+
output.puts "hello #{c1.inspect} #{a1}"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
str_output = StringIO.new
|
164
|
+
redirect_pry_io(InputTester.new("hello baby"), str_output) do
|
165
|
+
Pry.new(:commands => set).rep
|
166
|
+
end
|
167
|
+
|
168
|
+
str_output.string.should =~ /hello nil baby/
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should create a command in a nested context and that command should be accessible from the parent' do
|
172
|
+
str_output = StringIO.new
|
173
|
+
x = "@x=nil\ncd 7\n_pry_.commands.instance_eval {\ncommand('bing') { |arg| run arg }\n}\ncd ..\nbing ls\nexit-all"
|
174
|
+
redirect_pry_io(StringIO.new("@x=nil\ncd 7\n_pry_.commands.instance_eval {\ncommand('bing') { |arg| run arg }\n}\ncd ..\nbing ls\nexit-all"), str_output) do
|
175
|
+
Pry.new.repl(0)
|
176
|
+
end
|
177
|
+
|
178
|
+
str_output.string.should =~ /@x/
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should define a command that keeps its return value' do
|
182
|
+
klass = Pry::CommandSet.new do
|
183
|
+
command "hello", "", :keep_retval => true do
|
184
|
+
:kept_hello
|
185
|
+
end
|
186
|
+
end
|
187
|
+
str_output = StringIO.new
|
188
|
+
Pry.new(:input => StringIO.new("hello\n"), :output => str_output, :commands => klass).rep
|
189
|
+
str_output.string.should =~ /:kept_hello/
|
190
|
+
str_output.string.should =~ /=>/
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should define a command that does NOT keep its return value' do
|
194
|
+
klass = Pry::CommandSet.new do
|
195
|
+
command "hello", "", :keep_retval => false do
|
196
|
+
:kept_hello
|
197
|
+
end
|
198
|
+
end
|
199
|
+
str_output = StringIO.new
|
200
|
+
Pry.new(:input => StringIO.new("hello\n"), :output => str_output, :commands => klass).rep
|
201
|
+
(str_output.string =~ /:kept_hello/).should == nil
|
202
|
+
str_output.string !~ /=>/
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should define a command that keeps its return value even when nil' do
|
206
|
+
klass = Pry::CommandSet.new do
|
207
|
+
command "hello", "", :keep_retval => true do
|
208
|
+
nil
|
209
|
+
end
|
210
|
+
end
|
211
|
+
str_output = StringIO.new
|
212
|
+
Pry.new(:input => StringIO.new("hello\n"), :output => str_output, :commands => klass).rep
|
213
|
+
str_output.string.should =~ /nil/
|
214
|
+
str_output.string.should =~ /=>/
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should define a command that keeps its return value but does not return when value is void' do
|
218
|
+
klass = Pry::CommandSet.new do
|
219
|
+
command "hello", "", :keep_retval => true do
|
220
|
+
void
|
221
|
+
end
|
222
|
+
end
|
223
|
+
str_output = StringIO.new
|
224
|
+
Pry.new(:input => StringIO.new("hello\n"), :output => str_output, :commands => klass).rep
|
225
|
+
str_output.string.empty?.should == true
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'a command (with :keep_retval => false) that replaces eval_string with a valid expression should not have the expression value suppressed' do
|
229
|
+
klass = Pry::CommandSet.new do
|
230
|
+
command "hello", "" do
|
231
|
+
eval_string.replace("6")
|
232
|
+
end
|
233
|
+
end
|
234
|
+
str_output = StringIO.new
|
235
|
+
Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => str_output, :commands => klass).rep
|
236
|
+
str_output.string.should =~ /6/
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
it 'a command (with :keep_retval => true) that replaces eval_string with a valid expression should overwrite the eval_string with the return value' do
|
241
|
+
klass = Pry::CommandSet.new do
|
242
|
+
command "hello", "", :keep_retval => true do
|
243
|
+
eval_string.replace("6")
|
244
|
+
7
|
245
|
+
end
|
246
|
+
end
|
247
|
+
str_output = StringIO.new
|
248
|
+
Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => str_output, :commands => klass).rep
|
249
|
+
str_output.string.should =~ /7/
|
250
|
+
str_output.string.should.not =~ /6/
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'a command that return a value in a multi-line expression should clear the expression and return the value' do
|
254
|
+
klass = Pry::CommandSet.new do
|
255
|
+
command "hello", "", :keep_retval => true do
|
256
|
+
5
|
257
|
+
end
|
258
|
+
end
|
259
|
+
str_output = StringIO.new
|
260
|
+
Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => str_output, :commands => klass).rep
|
261
|
+
str_output.string.should =~ /5/
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
it 'should set the commands default, and the default should be overridable' do
|
266
|
+
klass = Pry::CommandSet.new do
|
267
|
+
command "hello" do
|
268
|
+
output.puts "hello world"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
Pry.commands = klass
|
273
|
+
|
274
|
+
str_output = StringIO.new
|
275
|
+
Pry.new(:input => InputTester.new("hello"), :output => str_output).rep
|
276
|
+
str_output.string.should =~ /hello world/
|
277
|
+
|
278
|
+
other_klass = Pry::CommandSet.new do
|
279
|
+
command "goodbye", "" do
|
280
|
+
output.puts "goodbye world"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
str_output = StringIO.new
|
285
|
+
|
286
|
+
Pry.new(:input => InputTester.new("goodbye"), :output => str_output, :commands => other_klass).rep
|
287
|
+
str_output.string.should =~ /goodbye world/
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'should inherit "help" command from Pry::CommandBase' do
|
291
|
+
klass = Pry::CommandSet.new do
|
292
|
+
command "h", "h command" do
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
klass.commands.keys.size.should == 3
|
297
|
+
klass.commands.keys.include?("help").should == true
|
298
|
+
klass.commands.keys.include?("install-command").should == true
|
299
|
+
klass.commands.keys.include?("h").should == true
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'should inherit commands from Pry::Commands' do
|
303
|
+
klass = Pry::CommandSet.new Pry::Commands do
|
304
|
+
command "v" do
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
klass.commands.include?("nesting").should == true
|
309
|
+
klass.commands.include?("jump-to").should == true
|
310
|
+
klass.commands.include?("cd").should == true
|
311
|
+
klass.commands.include?("v").should == true
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'should alias a command with another command' do
|
315
|
+
klass = Pry::CommandSet.new do
|
316
|
+
alias_command "help2", "help"
|
317
|
+
end
|
318
|
+
klass.commands["help2"].block.should == klass.commands["help"].block
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'should change description of a command using desc' do
|
322
|
+
klass = Pry::CommandSet.new do; end
|
323
|
+
orig = klass.commands["help"].description
|
324
|
+
klass.instance_eval do
|
325
|
+
desc "help", "blah"
|
326
|
+
end
|
327
|
+
klass.commands["help"].description.should.not == orig
|
328
|
+
klass.commands["help"].description.should == "blah"
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'should run a command from within a command' do
|
332
|
+
klass = Pry::CommandSet.new do
|
333
|
+
command "v" do
|
334
|
+
output.puts "v command"
|
335
|
+
end
|
336
|
+
|
337
|
+
command "run_v" do
|
338
|
+
run "v"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
str_output = StringIO.new
|
343
|
+
Pry.new(:input => InputTester.new("run_v"), :output => str_output, :commands => klass).rep
|
344
|
+
str_output.string.should =~ /v command/
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'should run a regex command from within a command' do
|
348
|
+
klass = Pry::CommandSet.new do
|
349
|
+
command /v(.*)?/ do |arg|
|
350
|
+
output.puts "v #{arg}"
|
351
|
+
end
|
352
|
+
|
353
|
+
command "run_v" do
|
354
|
+
run "vbaby"
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
str_output = StringIO.new
|
359
|
+
redirect_pry_io(InputTester.new("run_v"), str_output) do
|
360
|
+
Pry.new(:commands => klass).rep
|
361
|
+
end
|
362
|
+
|
363
|
+
str_output.string.should =~ /v baby/
|
364
|
+
end
|
365
|
+
|
366
|
+
it 'should run a command from within a command with arguments' do
|
367
|
+
klass = Pry::CommandSet.new do
|
368
|
+
command /v(\w+)/ do |arg1, arg2|
|
369
|
+
output.puts "v #{arg1} #{arg2}"
|
370
|
+
end
|
371
|
+
|
372
|
+
command "run_v_explicit_parameter" do
|
373
|
+
run "vbaby", "param"
|
374
|
+
end
|
375
|
+
|
376
|
+
command "run_v_embedded_parameter" do
|
377
|
+
run "vbaby param"
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
["run_v_explicit_parameter", "run_v_embedded_parameter"].each do |cmd|
|
382
|
+
str_output = StringIO.new
|
383
|
+
redirect_pry_io(InputTester.new(cmd), str_output) do
|
384
|
+
Pry.new(:commands => klass).rep
|
385
|
+
end
|
386
|
+
str_output.string.should =~ /v baby param/
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'should enable an inherited method to access opts and output and target, due to instance_exec' do
|
391
|
+
klass = Pry::CommandSet.new do
|
392
|
+
command "v" do
|
393
|
+
output.puts "#{target.eval('self')}"
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
child_klass = Pry::CommandSet.new klass do
|
398
|
+
end
|
399
|
+
|
400
|
+
str_output = StringIO.new
|
401
|
+
Pry.new(:print => proc {}, :input => InputTester.new("v"),
|
402
|
+
:output => str_output, :commands => child_klass).rep("john")
|
403
|
+
|
404
|
+
str_output.string.rstrip.should == "john"
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'should import commands from another command object' do
|
408
|
+
klass = Pry::CommandSet.new do
|
409
|
+
import_from Pry::Commands, "ls", "jump-to"
|
410
|
+
end
|
411
|
+
|
412
|
+
klass.commands.include?("ls").should == true
|
413
|
+
klass.commands.include?("jump-to").should == true
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'should delete some inherited commands when using delete method' do
|
417
|
+
klass = Pry::CommandSet.new Pry::Commands do
|
418
|
+
command "v" do
|
419
|
+
end
|
420
|
+
|
421
|
+
delete "show-doc", "show-method"
|
422
|
+
delete "ls"
|
423
|
+
end
|
424
|
+
|
425
|
+
klass.commands.include?("nesting").should == true
|
426
|
+
klass.commands.include?("jump-to").should == true
|
427
|
+
klass.commands.include?("cd").should == true
|
428
|
+
klass.commands.include?("v").should == true
|
429
|
+
klass.commands.include?("show-doc").should == false
|
430
|
+
klass.commands.include?("show-method").should == false
|
431
|
+
klass.commands.include?("ls").should == false
|
432
|
+
end
|
433
|
+
|
434
|
+
it 'should override some inherited commands' do
|
435
|
+
klass = Pry::CommandSet.new Pry::Commands do
|
436
|
+
command "jump-to" do
|
437
|
+
output.puts "jump-to the music"
|
438
|
+
end
|
439
|
+
|
440
|
+
command "help" do
|
441
|
+
output.puts "help to the music"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
# suppress evaluation output
|
446
|
+
Pry.print = proc {}
|
447
|
+
|
448
|
+
str_output = StringIO.new
|
449
|
+
Pry.new(:input => InputTester.new("jump-to"), :output => str_output, :commands => klass).rep
|
450
|
+
str_output.string.rstrip.should == "jump-to the music"
|
451
|
+
|
452
|
+
str_output = StringIO.new
|
453
|
+
Pry.new(:input => InputTester.new("help"), :output => str_output, :commands => klass).rep
|
454
|
+
str_output.string.should == "help to the music\n"
|
455
|
+
|
456
|
+
|
457
|
+
Pry.reset_defaults
|
458
|
+
Pry.color = false
|
459
|
+
end
|
460
|
+
|
461
|
+
it 'should run a command with no parameter' do
|
462
|
+
pry_tester = Pry.new
|
463
|
+
pry_tester.commands = CommandTester
|
464
|
+
pry_tester.input = InputTester.new("command1", "exit-all")
|
465
|
+
pry_tester.commands = CommandTester
|
466
|
+
|
467
|
+
str_output = StringIO.new
|
468
|
+
pry_tester.output = str_output
|
469
|
+
|
470
|
+
pry_tester.rep
|
471
|
+
|
472
|
+
str_output.string.should =~ /command1/
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'should run a command with one parameter' do
|
476
|
+
pry_tester = Pry.new
|
477
|
+
pry_tester.commands = CommandTester
|
478
|
+
pry_tester.input = InputTester.new("command2 horsey", "exit-all")
|
479
|
+
pry_tester.commands = CommandTester
|
480
|
+
|
481
|
+
str_output = StringIO.new
|
482
|
+
pry_tester.output = str_output
|
483
|
+
|
484
|
+
pry_tester.rep
|
485
|
+
|
486
|
+
str_output.string.should =~ /horsey/
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
describe "Pry#run_command" do
|
491
|
+
it 'should run a command in a specified context' do
|
492
|
+
b = Pry.binding_for(7)
|
493
|
+
p = Pry.new(:output => StringIO.new)
|
494
|
+
p.run_command("ls -m", "", b)
|
495
|
+
p.output.string.should =~ /divmod/
|
496
|
+
end
|
497
|
+
|
498
|
+
it 'should run a command that modifies the passed in eval_string' do
|
499
|
+
b = Pry.binding_for(7)
|
500
|
+
p = Pry.new(:output => StringIO.new)
|
501
|
+
eval_string = "def hello\npeter pan\n"
|
502
|
+
p.run_command("amend-line !", eval_string, b)
|
503
|
+
eval_string.should =~ /def hello/
|
504
|
+
eval_string.should.not =~ /peter pan/
|
505
|
+
end
|
506
|
+
|
507
|
+
it 'should run a command in the context of a session' do
|
508
|
+
mock_pry("@session_ivar = 10", "_pry_.run_command('ls')").should =~ /@session_ivar/
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
|