pry 0.9.6.2-i386-mswin32 → 0.9.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.
Files changed (45) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGELOG +19 -1
  3. data/CONTRIBUTORS +22 -16
  4. data/Rakefile +12 -6
  5. data/bin/pry +15 -12
  6. data/lib/pry.rb +39 -28
  7. data/lib/pry/command_context.rb +1 -0
  8. data/lib/pry/command_processor.rb +9 -2
  9. data/lib/pry/command_set.rb +7 -0
  10. data/lib/pry/config.rb +8 -0
  11. data/lib/pry/default_commands/basic.rb +7 -10
  12. data/lib/pry/default_commands/context.rb +36 -26
  13. data/lib/pry/default_commands/documentation.rb +31 -123
  14. data/lib/pry/default_commands/gems.rb +9 -4
  15. data/lib/pry/default_commands/input.rb +21 -11
  16. data/lib/pry/default_commands/introspection.rb +79 -88
  17. data/lib/pry/default_commands/ls.rb +165 -176
  18. data/lib/pry/default_commands/shell.rb +8 -8
  19. data/lib/pry/extended_commands/experimental.rb +1 -5
  20. data/lib/pry/extended_commands/user_command_api.rb +17 -5
  21. data/lib/pry/helpers.rb +1 -0
  22. data/lib/pry/helpers/base_helpers.rb +5 -1
  23. data/lib/pry/helpers/command_helpers.rb +22 -241
  24. data/lib/pry/helpers/options_helpers.rb +58 -0
  25. data/lib/pry/helpers/text.rb +10 -4
  26. data/lib/pry/history.rb +1 -1
  27. data/lib/pry/indent.rb +205 -0
  28. data/lib/pry/method.rb +412 -0
  29. data/lib/pry/pry_class.rb +56 -15
  30. data/lib/pry/pry_instance.rb +63 -16
  31. data/lib/pry/rbx_method.rb +20 -0
  32. data/lib/pry/rbx_path.rb +34 -0
  33. data/lib/pry/version.rb +1 -1
  34. data/pry.gemspec +16 -16
  35. data/test/helper.rb +8 -4
  36. data/test/test_command_helpers.rb +1 -69
  37. data/test/test_command_set.rb +29 -28
  38. data/test/test_default_commands/test_documentation.rb +23 -10
  39. data/test/test_default_commands/test_introspection.rb +58 -13
  40. data/test/test_default_commands/test_ls.rb +148 -0
  41. data/test/test_indent.rb +234 -0
  42. data/test/test_input_stack.rb +13 -0
  43. data/test/test_method.rb +291 -0
  44. data/test/test_pry.rb +10 -1
  45. metadata +88 -71
@@ -0,0 +1,234 @@
1
+ require 'helper'
2
+
3
+ # Please keep in mind that any hash signs ("#") in the heredoc strings are
4
+ # placed on purpose. Without these editors might remove the whitespace on empty
5
+ # lines.
6
+ describe Pry::Indent do
7
+ before do
8
+ @indent = Pry::Indent.new
9
+ end
10
+
11
+ it 'should indent an array' do
12
+ input = "array = [\n10,\n15\n]"
13
+ output = "array = [\n 10,\n 15\n]"
14
+
15
+ @indent.indent(input).should == output
16
+ end
17
+
18
+ it 'should indent a hash' do
19
+ input = "hash = {\n:name => 'Ruby'\n}"
20
+ output = "hash = {\n :name => 'Ruby'\n}"
21
+
22
+ @indent.indent(input).should == output
23
+ end
24
+
25
+ it 'should indent a function' do
26
+ input = "def\nreturn 10\nend"
27
+ output = "def\n return 10\nend"
28
+
29
+ @indent.indent(input).should == output
30
+ end
31
+
32
+ it 'should indent a module and class' do
33
+ input = "module Foo\n# Hello world\nend"
34
+ output = "module Foo\n # Hello world\nend"
35
+ input_class = "class Foo\n# Hello world\nend"
36
+ output_class = "class Foo\n # Hello world\nend"
37
+
38
+ @indent.indent(input).should == output
39
+ @indent.indent(input_class).should == output_class
40
+ end
41
+
42
+ it 'should indent separate lines' do
43
+ @indent.indent('def foo').should == 'def foo'
44
+ @indent.indent('return 10').should == ' return 10'
45
+ @indent.indent('end').should == 'end'
46
+ end
47
+
48
+ it 'should not indent single line statements' do
49
+ input = <<TXT.strip
50
+ def hello; end
51
+ puts "Hello"
52
+ TXT
53
+
54
+ @indent.indent(input).should == input
55
+ end
56
+
57
+ it 'should handle multiple open and closing tokens on a line' do
58
+ input = <<TXT.strip
59
+ [10, 15].each do |num|
60
+ puts num
61
+ end
62
+ TXT
63
+
64
+ output = <<TXT.strip
65
+ [10, 15].each do |num|
66
+ puts num
67
+ end
68
+ TXT
69
+
70
+ @indent.indent(input).should == output
71
+ end
72
+
73
+ it 'should properly indent nested code' do
74
+ input = <<TXT.strip
75
+ module A
76
+ module B
77
+ class C
78
+ attr_accessor :test
79
+ # keep
80
+ def number
81
+ return 10
82
+ end
83
+ end
84
+ end
85
+ end
86
+ TXT
87
+
88
+ output = <<TXT.strip
89
+ module A
90
+ module B
91
+ class C
92
+ attr_accessor :test
93
+ # keep
94
+ def number
95
+ return 10
96
+ end
97
+ end
98
+ end
99
+ end
100
+ TXT
101
+
102
+ @indent.indent(input).should == output
103
+ end
104
+
105
+ it 'should indent statements such as if, else, etc' do
106
+ input = <<TXT.strip
107
+ if a == 10
108
+ #
109
+ elsif a == 15
110
+ #
111
+ else
112
+ #
113
+ end
114
+ #
115
+ while true
116
+ #
117
+ end
118
+ #
119
+ for num in [10, 15, 20]
120
+ #
121
+ end
122
+ #
123
+ for num in [10, 15, 20] do
124
+ #
125
+ end
126
+ TXT
127
+
128
+ output = <<TXT.strip
129
+ if a == 10
130
+ #
131
+ elsif a == 15
132
+ #
133
+ else
134
+ #
135
+ end
136
+ #
137
+ while true
138
+ #
139
+ end
140
+ #
141
+ for num in [10, 15, 20]
142
+ #
143
+ end
144
+ #
145
+ for num in [10, 15, 20] do
146
+ #
147
+ end
148
+ TXT
149
+
150
+ @indent.indent(input).should == output
151
+ end
152
+
153
+ it "should ident case statements" do
154
+ input = <<TXT.strip
155
+ case foo
156
+ when 1
157
+ 2
158
+ when 2
159
+ if 3
160
+ 4
161
+ end
162
+ when 5
163
+ #
164
+ else
165
+ #
166
+ end
167
+ TXT
168
+
169
+ output = <<TXT.strip
170
+ case foo
171
+ when 1
172
+ 2
173
+ when 2
174
+ if 3
175
+ 4
176
+ end
177
+ when 5
178
+ #
179
+ else
180
+ #
181
+ end
182
+ TXT
183
+
184
+ @indent.indent(input).should == output
185
+ end
186
+
187
+ it "should indent correctly with nesting" do
188
+ @indent.indent("[[\n[]]\n]").should == "[[\n []]\n]"
189
+ @indent.reset.indent("[[\n[]]\n]").should == "[[\n []]\n]"
190
+ @indent.reset.indent("[[{\n[] =>\n[]}]\n]").should == "[[{\n [] =>\n []}]\n]"
191
+ end
192
+
193
+ it "should not indent single-line ifs" do
194
+ @indent.indent("foo if bar\n#").should == "foo if bar\n#"
195
+ @indent.reset.indent("foo() if bar\n#").should == "foo() if bar\n#"
196
+ @indent.reset.indent("foo 'hi' if bar\n#").should == "foo 'hi' if bar\n#"
197
+ @indent.reset.indent("foo 1 while bar\n#").should == "foo 1 while bar\n#"
198
+ end
199
+
200
+ it "should indent cunningly disguised ifs" do
201
+ @indent.indent("{1 => if bar\n#").should == "{1 => if bar\n #"
202
+ @indent.reset.indent("foo(if bar\n#").should == "foo(if bar\n #"
203
+ @indent.reset.indent("bar(baz, if bar\n#").should == "bar(baz, if bar\n #"
204
+ @indent.reset.indent("[if bar\n#").should == "[if bar\n #"
205
+ @indent.reset.indent("true; while bar\n#").should == "true; while bar\n #"
206
+ end
207
+
208
+ it "should differentiate single/multi-line unless" do
209
+ @indent.indent("foo unless bar\nunless foo\nbar\nend").should == "foo unless bar\nunless foo\n bar\nend"
210
+ end
211
+
212
+ it "should not indent single/multi-line until" do
213
+ @indent.indent("%w{baz} until bar\nuntil foo\nbar\nend").should == "%w{baz} until bar\nuntil foo\n bar\nend"
214
+ end
215
+
216
+ it "should indent begin rescue end" do
217
+ input = <<INPUT.strip
218
+ begin
219
+ doo :something => :wrong
220
+ rescue => e
221
+ doit :right
222
+ end
223
+ INPUT
224
+ output = <<OUTPUT.strip
225
+ begin
226
+ doo :something => :wrong
227
+ rescue => e
228
+ doit :right
229
+ end
230
+ OUTPUT
231
+
232
+ @indent.indent(input).should == output
233
+ end
234
+ end
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'helper'
2
3
 
3
4
  describe "Pry#input_stack" do
@@ -67,4 +68,16 @@ describe "Pry#input_stack" do
67
68
  str_output.string.should =~ /Error: Pry ran out of things to read/
68
69
  end
69
70
 
71
+ if "".respond_to?(:encoding)
72
+ it "should pass strings to Pry in the right encoding" do
73
+ input1 = "'f。。'.encoding.name" # utf-8, see coding declaration
74
+ input2 = input1.encode('Shift_JIS')
75
+
76
+ mock_pry(input1, input2).should == %{=> "UTF-8"\n=> "Shift_JIS"\n\n}
77
+ end
78
+
79
+ it "should be able to use unicode regexes on a UTF-8 terminal" do
80
+ mock_pry('":-Þ" =~ /\p{Upper}/').should == %{=> 2\n\n}
81
+ end
82
+ end
70
83
  end
@@ -0,0 +1,291 @@
1
+ require 'helper'
2
+
3
+ describe Pry::Method do
4
+ it "should use String names for compatibility" do
5
+ klass = Class.new { def hello; end }
6
+ Pry::Method.new(klass.instance_method(:hello)).name.should == "hello"
7
+ end
8
+
9
+ describe ".from_str" do
10
+ it 'should look up instance methods if no methods available and no options provided' do
11
+ klass = Class.new { def hello; end }
12
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
13
+ meth.should == klass.instance_method(:hello)
14
+ end
15
+
16
+ it 'should look up methods if no instance methods available and no options provided' do
17
+ klass = Class.new { def self.hello; end }
18
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
19
+ meth.should == klass.method(:hello)
20
+ end
21
+
22
+ it 'should look up instance methods first even if methods available and no options provided' do
23
+ klass = Class.new { def hello; end; def self.hello; end }
24
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass))
25
+ meth.should == klass.instance_method(:hello)
26
+ end
27
+
28
+ it 'should look up instance methods if "instance-methods" option provided' do
29
+ klass = Class.new { def hello; end; def self.hello; end }
30
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {"instance-methods" => true})
31
+ meth.should == klass.instance_method(:hello)
32
+ end
33
+
34
+ it 'should look up methods if :methods option provided' do
35
+ klass = Class.new { def hello; end; def self.hello; end }
36
+ meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {:methods => true})
37
+ meth.should == klass.method(:hello)
38
+ end
39
+
40
+ it 'should look up instance methods using the Class#method syntax' do
41
+ klass = Class.new { def hello; end; def self.hello; end }
42
+ meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding))
43
+ meth.should == klass.instance_method(:hello)
44
+ end
45
+
46
+ it 'should look up methods using the object.method syntax' do
47
+ klass = Class.new { def hello; end; def self.hello; end }
48
+ meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding))
49
+ meth.should == klass.method(:hello)
50
+ end
51
+
52
+ it 'should NOT look up instance methods using the Class#method syntax if no instance methods defined' do
53
+ klass = Class.new { def self.hello; end }
54
+ meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding))
55
+ meth.should == nil
56
+ end
57
+
58
+ it 'should NOT look up methods using the object.method syntax if no methods defined' do
59
+ klass = Class.new { def hello; end }
60
+ meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding))
61
+ meth.should == nil
62
+ end
63
+
64
+ it 'should look up methods using klass.new.method syntax' do
65
+ klass = Class.new { def hello; :hello; end }
66
+ meth = Pry::Method.from_str("klass.new.hello", Pry.binding_for(binding))
67
+ meth.name.should == "hello"
68
+ end
69
+
70
+ it 'should look up instance methods using klass.meth#method syntax' do
71
+ klass = Class.new { def self.meth; Class.new; end }
72
+ meth = Pry::Method.from_str("klass.meth#initialize", Pry.binding_for(binding))
73
+ meth.name.should == "initialize"
74
+ end
75
+ end
76
+
77
+ describe 'all_from_class' do
78
+ def should_find_method(name)
79
+ Pry::Method.all_from_class(@class).map(&:name).should.include(name)
80
+ end
81
+
82
+ it 'should be able to find public instance methods defined in a class' do
83
+ @class = Class.new{ def meth; 1; end }
84
+ should_find_method('meth')
85
+ end
86
+
87
+ it 'should be able to find private and protected instance methods defined in a class' do
88
+ @class = Class.new { protected; def prot; 1; end; private; def priv; 1; end }
89
+ should_find_method('priv')
90
+ should_find_method('prot')
91
+ end
92
+
93
+ it 'should find methods all the way up to Kernel' do
94
+ @class = Class.new
95
+ should_find_method('exit!')
96
+ end
97
+
98
+ it 'should be able to find instance methods defined in a super-class' do
99
+ @class = Class.new(Class.new{ def meth; 1; end }) {}
100
+ should_find_method('meth')
101
+ end
102
+
103
+ it 'should be able to find instance methods defined in modules included into this class' do
104
+ @class = Class.new{ include Module.new{ def meth; 1; end; } }
105
+ should_find_method('meth')
106
+ end
107
+
108
+ it 'should be able to find instance methods defined in modules included into super-classes' do
109
+ @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } })
110
+ should_find_method('meth')
111
+ end
112
+
113
+ it 'should attribute overridden methods to the sub-class' do
114
+ @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } }) { def meth; 2; end }
115
+ Pry::Method.all_from_class(@class).detect{ |x| x.name == 'meth' }.owner.should == @class
116
+ end
117
+
118
+ it 'should be able to find methods defined on a singleton class' do
119
+ @class = (class << Object.new; def meth; 1; end; self; end)
120
+ should_find_method('meth')
121
+ end
122
+
123
+ it 'should be able to find methods on super-classes when given a singleton class' do
124
+ @class = (class << Class.new{ def meth; 1; end}.new; self; end)
125
+ should_find_method('meth')
126
+ end
127
+ end
128
+
129
+ describe 'all_from_obj' do
130
+ describe 'on normal objects' do
131
+ def should_find_method(name)
132
+ Pry::Method.all_from_obj(@obj).map(&:name).should.include(name)
133
+ end
134
+
135
+ it "should find methods defined in the object's class" do
136
+ @obj = Class.new{ def meth; 1; end }.new
137
+ should_find_method('meth')
138
+ end
139
+
140
+ it "should find methods defined in modules included into the object's class" do
141
+ @obj = Class.new{ include Module.new{ def meth; 1; end } }.new
142
+ should_find_method('meth')
143
+ end
144
+
145
+ it "should find methods defined in the object's singleton class" do
146
+ @obj = Object.new
147
+ class << @obj; def meth; 1; end; end
148
+ should_find_method('meth')
149
+ end
150
+
151
+ it "should find methods in modules included into the object's singleton class" do
152
+ @obj = Object.new
153
+ @obj.extend Module.new{ def meth; 1; end }
154
+ should_find_method('meth')
155
+ end
156
+
157
+ it "should find methods all the way up to Kernel" do
158
+ @obj = Object.new
159
+ should_find_method('exit!')
160
+ end
161
+
162
+ it "should not find methods defined on the classes singleton class" do
163
+ @obj = Class.new{ class << self; def meth; 1; end; end }.new
164
+ Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth')
165
+ end
166
+
167
+ it "should work in the face of an overridden send" do
168
+ @obj = Class.new{ def meth; 1; end; def send; raise EOFError; end }.new
169
+ should_find_method('meth')
170
+ end
171
+ end
172
+
173
+ describe 'on classes' do
174
+ def should_find_method(name)
175
+ Pry::Method.all_from_obj(@class).map(&:name).should.include(name)
176
+ end
177
+
178
+ it "should find methods defined in the class' singleton class" do
179
+ @class = Class.new{ class << self; def meth; 1; end; end }
180
+ should_find_method('meth')
181
+ end
182
+
183
+ it "should find methods defined on modules extended into the class" do
184
+ @class = Class.new{ extend Module.new{ def meth; 1; end; } }
185
+ should_find_method('meth')
186
+ end
187
+
188
+ it "should find methods defined on the singleton class of super-classes" do
189
+ @class = Class.new(Class.new{ class << self; def meth; 1; end; end })
190
+ should_find_method('meth')
191
+ end
192
+
193
+ it "should not find methods defined within the class" do
194
+ @class = Class.new{ def meth; 1; end }
195
+ Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth')
196
+ end
197
+
198
+ it "should find methods defined on Class" do
199
+ @class = Class.new
200
+ should_find_method('allocate')
201
+ end
202
+
203
+ it "should find methods defined on Kernel" do
204
+ @class = Class.new
205
+ should_find_method('exit!')
206
+ end
207
+
208
+ it "should attribute overridden methods to the sub-class' singleton class" do
209
+ @class = Class.new(Class.new{ class << self; def meth; 1; end; end }) { class << self; def meth; 1; end; end }
210
+ Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end)
211
+ end
212
+
213
+ it "should attrbute overridden methods to the class not the module" do
214
+ @class = Class.new { class << self; def meth; 1; end; end; extend Module.new{ def meth; 1; end; } }
215
+ Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end)
216
+ end
217
+
218
+ it "should attribute overridden methods to the relevant singleton class in preference to Class" do
219
+ @class = Class.new { class << self; def allocate; 1; end; end }
220
+ Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'allocate' }.owner.should == (class << @class; self; end)
221
+ end
222
+ end
223
+
224
+ describe 'method resolution order' do
225
+ module LS
226
+ class Top; end
227
+
228
+ class Next < Top; end
229
+
230
+ module M; end
231
+ module N; include M; end
232
+ module O; include M; end
233
+ module P; end
234
+
235
+ class Low < Next; include N; include P; end
236
+ class Lower < Low; extend N; end
237
+ class Bottom < Lower; extend O; end
238
+ end
239
+
240
+ def singleton_class(obj); class << obj; self; end; end
241
+
242
+ it "should look at a class and then its superclass" do
243
+ Pry::Method.instance_resolution_order(LS::Next).should == [LS::Next] + Pry::Method.instance_resolution_order(LS::Top)
244
+ end
245
+
246
+ it "should include the included modules between a class and its superclass" do
247
+ Pry::Method.instance_resolution_order(LS::Low).should == [LS::Low, LS::P, LS::N, LS::M] + Pry::Method.instance_resolution_order(LS::Next)
248
+ end
249
+
250
+ it "should not include modules extended into the class" do
251
+ Pry::Method.instance_resolution_order(LS::Bottom).should == [LS::Bottom] + Pry::Method.instance_resolution_order(LS::Lower)
252
+ end
253
+
254
+ it "should include included modules for Modules" do
255
+ Pry::Method.instance_resolution_order(LS::O).should == [LS::O, LS::M]
256
+ end
257
+
258
+ it "should include the singleton class of objects" do
259
+ obj = LS::Low.new
260
+ Pry::Method.resolution_order(obj).should == [singleton_class(obj)] + Pry::Method.instance_resolution_order(LS::Low)
261
+ end
262
+
263
+ it "should not include singleton classes of numbers" do
264
+ Pry::Method.resolution_order(4).should == Pry::Method.instance_resolution_order(Fixnum)
265
+ end
266
+
267
+ it "should include singleton classes for classes" do
268
+ Pry::Method.resolution_order(LS::Low).should == [singleton_class(LS::Low)] + Pry::Method.resolution_order(LS::Next)
269
+ end
270
+
271
+ it "should include modules included into singleton classes" do
272
+ Pry::Method.resolution_order(LS::Lower).should == [singleton_class(LS::Lower), LS::N, LS::M] + Pry::Method.resolution_order(LS::Low)
273
+ end
274
+
275
+ it "should include modules at most once" do
276
+ Pry::Method.resolution_order(LS::Bottom).count(LS::M).should == 1
277
+ end
278
+
279
+ it "should include modules at the point which they would be reached" do
280
+ Pry::Method.resolution_order(LS::Bottom).should == [singleton_class(LS::Bottom), LS::O] + (Pry::Method.resolution_order(LS::Lower))
281
+ end
282
+
283
+ it "should include the Pry::Method.instance_resolution_order of Class after the singleton classes" do
284
+ Pry::Method.resolution_order(LS::Top).should ==
285
+ [singleton_class(LS::Top), singleton_class(Object), (defined? BasicObject) && singleton_class(BasicObject)].compact +
286
+ Pry::Method.instance_resolution_order(Class)
287
+ end
288
+ end
289
+ end
290
+ end
291
+