looksee 1.0.0-universal-java-1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/LICENSE +22 -0
- data/README.markdown +161 -0
- data/Rakefile +10 -0
- data/ext/extconf.rb +9 -0
- data/ext/mri/1.9.2/debug.h +36 -0
- data/ext/mri/1.9.2/id.h +170 -0
- data/ext/mri/1.9.2/method.h +103 -0
- data/ext/mri/1.9.2/node.h +483 -0
- data/ext/mri/1.9.2/thread_pthread.h +27 -0
- data/ext/mri/1.9.2/vm_core.h +707 -0
- data/ext/mri/1.9.2/vm_opts.h +51 -0
- data/ext/mri/env-1.8.h +27 -0
- data/ext/mri/eval_c-1.8.h +27 -0
- data/ext/mri/mri.c +269 -0
- data/ext/mri/node-1.9.h +35 -0
- data/ext/rbx/rbx.c +13 -0
- data/lib/looksee.rb +5 -0
- data/lib/looksee/adapter.rb +10 -0
- data/lib/looksee/adapter/base.rb +100 -0
- data/lib/looksee/adapter/rubinius.rb +73 -0
- data/lib/looksee/clean.rb +122 -0
- data/lib/looksee/columnizer.rb +73 -0
- data/lib/looksee/core_ext.rb +59 -0
- data/lib/looksee/editor.rb +58 -0
- data/lib/looksee/help.rb +54 -0
- data/lib/looksee/inspector.rb +55 -0
- data/lib/looksee/jruby.jar +0 -0
- data/lib/looksee/lookup_path.rb +95 -0
- data/lib/looksee/rbx.bundle +0 -0
- data/lib/looksee/shortcuts.rb +3 -0
- data/lib/looksee/version.rb +11 -0
- data/lib/looksee/wirble_compatibility.rb +86 -0
- data/spec/adapter_spec.rb +546 -0
- data/spec/columnizer_spec.rb +52 -0
- data/spec/core_ext_spec.rb +41 -0
- data/spec/editor_spec.rb +128 -0
- data/spec/inspector_spec.rb +178 -0
- data/spec/lookup_path_spec.rb +84 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/core_ext.rb +25 -0
- data/spec/support/temporary_classes.rb +102 -0
- data/spec/support/test_adapter.rb +72 -0
- data/spec/wirble_compatibility_spec.rb +116 -0
- metadata +158 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::Columnizer do
|
4
|
+
describe ".columnize" do
|
5
|
+
def columnize(strings, width)
|
6
|
+
Looksee::Columnizer.columnize(strings, width)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should an empty string if there are no strings to display" do
|
10
|
+
columnize([], 5).should == ''
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should render all strings on one line separated and indented by two spaces if they fit" do
|
14
|
+
columnize(['one', 'two'], 10).should == " one two\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should not wrap a string if it longer than the width" do
|
18
|
+
columnize(['looooooong'], 5).should == " looooooong\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should render a string on the next line if there's not enough room" do
|
22
|
+
columnize(['a', 'looooooong'], 5).should == " a \n looooooong\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should present 12 3-char strings 4 per line, sorted vertically, when the width is 20" do
|
26
|
+
strings = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff',
|
27
|
+
'ggg', 'hhh', 'iii', 'jjj', 'kkk', 'lll']
|
28
|
+
columnize(strings, 20).should == <<-EOS.gsub(/^ *\|/, '')
|
29
|
+
| aaa ddd ggg jjj
|
30
|
+
| bbb eee hhh kkk
|
31
|
+
| ccc fff iii lll
|
32
|
+
EOS
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should leave the last column short if there aren't enough strings to fill it" do
|
36
|
+
strings = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff',
|
37
|
+
'ggg', 'hhh', 'iii', 'jjj', 'kkk']
|
38
|
+
columnize(strings, 20).should == <<-EOS.gsub(/^ *\|/, '')
|
39
|
+
| aaa ddd ggg jjj
|
40
|
+
| bbb eee hhh kkk
|
41
|
+
| ccc fff iii
|
42
|
+
EOS
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should pad out strings that are shorter than their column" do
|
46
|
+
columnize(['aa', 'b', 'c', 'dd'], 8).should == <<-EOS.gsub(/^ *\|/, '')
|
47
|
+
| aa c
|
48
|
+
| b dd
|
49
|
+
EOS
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::ObjectMixin do
|
4
|
+
describe "#ls" do
|
5
|
+
before do
|
6
|
+
@object = Object.new
|
7
|
+
Looksee.stubs(:default_specifiers).returns([:public, :overridden])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return an Inspector for the object's lookup path" do
|
11
|
+
result = @object.ls
|
12
|
+
result.should be_a(Looksee::Inspector)
|
13
|
+
result.lookup_path.object.should.equal?(@object)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should use Looksee.default_specifiers if no args are given" do
|
17
|
+
@object.ls.visibilities.should == Set[:public, :overridden]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set visibilities from the given symbols" do
|
21
|
+
inspector = @object.ls(:private)
|
22
|
+
inspector.visibilities.should == Set[:public, :overridden, :private]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should unset visibilities from the given 'no' symbols" do
|
26
|
+
inspector = @object.ls(:nooverridden)
|
27
|
+
inspector.visibilities.should == Set[:public]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should set filters from the given strings and regexp" do
|
31
|
+
inspector = @object.ls('aa', /bb/)
|
32
|
+
inspector.filters.should == Set['aa', /bb/]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise an ArgumentError if an invalid argument is given" do
|
36
|
+
lambda do
|
37
|
+
@object.ls(Object.new)
|
38
|
+
end.should raise_error(ArgumentError)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/spec/editor_spec.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::Editor do
|
4
|
+
def editor_command(command)
|
5
|
+
Looksee::Editor.new(command).command_for('FILE', 'LINE')
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should infer the file and line arguments for 'vi'" do
|
9
|
+
editor_command('vi').should == ['vi', '+LINE', 'FILE']
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should infer the file and line arguments for 'vim'" do
|
13
|
+
editor_command('vim').should == ['vim', '+LINE', 'FILE']
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should infer the file and line arguments for 'gvim'" do
|
17
|
+
editor_command('gvim').should == ['gvim', '+LINE', 'FILE']
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should infer the file and line arguments for 'emacs'" do
|
21
|
+
editor_command('emacs').should == ['emacs', '+LINE', 'FILE']
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should infer the file and line arguments for 'xemacs'" do
|
25
|
+
editor_command('xemacs').should == ['xemacs', '+LINE', 'FILE']
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should infer the file and line arguments for 'aquamacs'" do
|
29
|
+
editor_command('aquamacs').should == ['aquamacs', '+LINE', 'FILE']
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should infer the file and line arguments for 'pico'" do
|
33
|
+
editor_command('pico').should == ['pico', '+LINE', 'FILE']
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should infer the file and line arguments for 'nano'" do
|
37
|
+
editor_command('nano').should == ['nano', '+LINE', 'FILE']
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should infer the file and line arguments for 'mate'" do
|
41
|
+
editor_command('mate').should == ['mate', '-lLINE', 'FILE']
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should support escaped '%'-signs" do
|
45
|
+
editor_command('%% %f %l').should == ['%', 'FILE', 'LINE']
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not infer file and line arguments for unknown editors" do
|
49
|
+
editor_command('wtfbbq').should == ['wtfbbq']
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#edit" do
|
53
|
+
TMP = "#{ROOT}/spec/tmp"
|
54
|
+
|
55
|
+
before do
|
56
|
+
FileUtils.mkdir_p TMP
|
57
|
+
make_editor "#{TMP}/edit"
|
58
|
+
@editor = Looksee::Editor.new("#{TMP}/edit %f %l")
|
59
|
+
end
|
60
|
+
|
61
|
+
after do
|
62
|
+
FileUtils.rm_rf TMP
|
63
|
+
end
|
64
|
+
|
65
|
+
def make_editor(path)
|
66
|
+
open(path, 'w') { |f| f.puts <<-EOS.demargin }
|
67
|
+
|#!/bin/sh
|
68
|
+
|echo $# $1 $2 > "#{TMP}/editor.out"
|
69
|
+
EOS
|
70
|
+
File.chmod 0755, path
|
71
|
+
end
|
72
|
+
|
73
|
+
def with_source_file
|
74
|
+
path = "#{TMP}/c.rb"
|
75
|
+
open(path, 'w') { |f| f.puts <<-EOS.demargin }
|
76
|
+
|class C
|
77
|
+
| def f
|
78
|
+
| end
|
79
|
+
|end
|
80
|
+
EOS
|
81
|
+
begin
|
82
|
+
load path
|
83
|
+
Looksee.adapter.set_methods(C, [:f], [], [], [])
|
84
|
+
yield path
|
85
|
+
ensure
|
86
|
+
Object.send(:remove_const, :C)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should run the editor on the method's source location if available" do
|
91
|
+
with_source_file do |path|
|
92
|
+
c = C.new
|
93
|
+
Looksee.adapter.ancestors[c] = [C, Object]
|
94
|
+
Looksee.adapter.set_source_location(C, :f, [path, 2])
|
95
|
+
@editor.edit(c, :f)
|
96
|
+
File.read("#{TMP}/editor.out").should == "2 #{path} 2\n"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should not run the editor if the source file does not exist" do
|
101
|
+
with_source_file do |path|
|
102
|
+
FileUtils.rm_f path
|
103
|
+
@editor.edit(C.new, :f)
|
104
|
+
File.should_not exist("#{TMP}/editor.out")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should not run the editor for methods defined with eval where no source file specified" do
|
109
|
+
eval <<-EOS.demargin
|
110
|
+
|class ::C
|
111
|
+
| def f
|
112
|
+
| end
|
113
|
+
|end
|
114
|
+
EOS
|
115
|
+
begin
|
116
|
+
@editor.edit(C.new, :f)
|
117
|
+
File.should_not exist("#{TMP}/editor.out")
|
118
|
+
ensure
|
119
|
+
Object.send(:remove_const, :C)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should not run the editor for primitives" do
|
124
|
+
@editor.edit('', :size)
|
125
|
+
File.should_not exist("#{TMP}/editor.out")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::Inspector do
|
4
|
+
include TemporaryClasses
|
5
|
+
|
6
|
+
describe "#inspect" do
|
7
|
+
before do
|
8
|
+
Looksee.stubs(:default_lookup_path_options).returns({})
|
9
|
+
Looksee.stubs(:styles).returns(Hash.new{'%s'})
|
10
|
+
|
11
|
+
@object = Object.new
|
12
|
+
temporary_module :M
|
13
|
+
temporary_class(:C) { include M }
|
14
|
+
Looksee.adapter.ancestors[@object] = [C, M]
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "output width" do
|
18
|
+
before do
|
19
|
+
Looksee.adapter.public_methods[C] = ['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'ii', 'jj']
|
20
|
+
Looksee.adapter.public_methods[M] = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh']
|
21
|
+
@lookup_path = Looksee::LookupPath.new(@object)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should columnize output to the given width, if any" do
|
25
|
+
inspector = Looksee::Inspector.new(@lookup_path, :visibilities => [:public], :width => 20)
|
26
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
27
|
+
|M
|
28
|
+
| aaa ccc eee ggg
|
29
|
+
| bbb ddd fff hhh
|
30
|
+
|C
|
31
|
+
| aa cc ee gg ii
|
32
|
+
| bb dd ff hh jj
|
33
|
+
EOS
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should columnize output to the current terminal width, if detectable" do
|
37
|
+
original_columns = ENV['COLUMNS']
|
38
|
+
ENV['COLUMNS'] = '20'
|
39
|
+
begin
|
40
|
+
inspector = Looksee::Inspector.new(@lookup_path, :visibilities => [:public])
|
41
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
42
|
+
|M
|
43
|
+
| aaa ccc eee ggg
|
44
|
+
| bbb ddd fff hhh
|
45
|
+
|C
|
46
|
+
| aa cc ee gg ii
|
47
|
+
| bb dd ff hh jj
|
48
|
+
EOS
|
49
|
+
ensure
|
50
|
+
ENV['COLUMNS'] = original_columns
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should columnize output to the configured default otherwise" do
|
55
|
+
Looksee.stubs(:default_width).returns(20)
|
56
|
+
inspector = Looksee::Inspector.new(@lookup_path, :visibilities => [:public])
|
57
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
58
|
+
|M
|
59
|
+
| aaa ccc eee ggg
|
60
|
+
| bbb ddd fff hhh
|
61
|
+
|C
|
62
|
+
| aa cc ee gg ii
|
63
|
+
| bb dd ff hh jj
|
64
|
+
EOS
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should not show any blank lines if a module has no methods" do
|
69
|
+
Looksee.adapter.public_methods[M] = [:public1, :public2]
|
70
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
71
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public])
|
72
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
73
|
+
|M
|
74
|
+
| public1 public2
|
75
|
+
|C
|
76
|
+
EOS
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should show singleton classes as class names in brackets" do
|
80
|
+
Looksee.adapter.ancestors[C] = [C.singleton_class]
|
81
|
+
Looksee.adapter.public_methods[C.singleton_class] = [:public1, :public2]
|
82
|
+
lookup_path = Looksee::LookupPath.new(C)
|
83
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public])
|
84
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
85
|
+
|[C]
|
86
|
+
| public1 public2
|
87
|
+
EOS
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should handle singleton classes of singleton classes correctly" do
|
91
|
+
Looksee.adapter.ancestors[C.singleton_class] = [C.singleton_class.singleton_class]
|
92
|
+
Looksee.adapter.public_methods[C.singleton_class.singleton_class] = [:public1, :public2]
|
93
|
+
lookup_path = Looksee::LookupPath.new(C.singleton_class)
|
94
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public])
|
95
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
96
|
+
|[[C]]
|
97
|
+
| public1 public2
|
98
|
+
EOS
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should only show methods of the selected visibilities" do
|
102
|
+
temporary_class :E
|
103
|
+
Looksee.adapter.set_methods(E, [:public], [:protected], [:private], [:undefined])
|
104
|
+
Looksee.adapter.ancestors[@object] = [E]
|
105
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
106
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:protected])
|
107
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
108
|
+
|E
|
109
|
+
| protected
|
110
|
+
EOS
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should show overridden methods if selected" do
|
114
|
+
Looksee.adapter.set_methods(C, [:public], [:protected], [:private], [:undefined])
|
115
|
+
Looksee.adapter.set_methods(M, [:public], [:protected], [:private], [:undefined])
|
116
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
117
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :overridden])
|
118
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
119
|
+
|M
|
120
|
+
| public
|
121
|
+
|C
|
122
|
+
| public
|
123
|
+
EOS
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not show overridden methods if not selected" do
|
127
|
+
Looksee.adapter.set_methods(C, [:public], [:protected], [:private], [:undefined])
|
128
|
+
Looksee.adapter.set_methods(M, [:public], [:protected], [:private], [:undefined])
|
129
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
130
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :nooverridden])
|
131
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
132
|
+
|M
|
133
|
+
|C
|
134
|
+
| public
|
135
|
+
EOS
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should only show methods that match the given filters, if any are given" do
|
139
|
+
Looksee.adapter.public_methods[C] = [:ab, :ax, :ba, :xa]
|
140
|
+
Looksee.adapter.public_methods[M] = [:ab, :ax, :ba, :xa]
|
141
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
142
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :overridden], :filters => [/^a/, 'b'])
|
143
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
144
|
+
|M
|
145
|
+
| ab ax ba
|
146
|
+
|C
|
147
|
+
| ab ax ba
|
148
|
+
EOS
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe ".styles" do
|
153
|
+
before do
|
154
|
+
styles = {
|
155
|
+
:module => "`%s'",
|
156
|
+
:public => "{%s}",
|
157
|
+
:protected => "[%s]",
|
158
|
+
:private => "<%s>",
|
159
|
+
:undefined => "~%s~",
|
160
|
+
:overridden => "(%s)",
|
161
|
+
}
|
162
|
+
Looksee.stubs(:styles).returns(styles)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should delimit each word with the configured delimiters" do
|
166
|
+
temporary_class :C
|
167
|
+
c = C.new
|
168
|
+
Looksee.adapter.ancestors[c] = [C]
|
169
|
+
Looksee.adapter.set_methods(C, [:public], [:protected], [:private], [:undefined])
|
170
|
+
lookup_path = Looksee::LookupPath.new(c)
|
171
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :protected, :private, :undefined, :overridden])
|
172
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
173
|
+
|\`C\'
|
174
|
+
| <private> [protected] {public} ~undefined~
|
175
|
+
EOS
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::LookupPath do
|
4
|
+
include TemporaryClasses
|
5
|
+
|
6
|
+
describe "#entries" do
|
7
|
+
before do
|
8
|
+
temporary_module :M
|
9
|
+
temporary_class(:C) { include M }
|
10
|
+
@object = Object.new
|
11
|
+
Looksee.adapter.ancestors[@object] = [C, M]
|
12
|
+
Looksee.adapter.set_methods(M, [:public1, :public2], [:protected1, :protected2], [:private1, :private2], [:undefined1, :undefined2])
|
13
|
+
Looksee.adapter.set_methods(C, [:public1, :public2], [:protected1, :protected2], [:private1, :private2], [:undefined1, :undefined2])
|
14
|
+
@lookup_path = Looksee::LookupPath.new(@object)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should contain an entry for each module in the object's lookup path" do
|
18
|
+
@lookup_path.entries.map{|entry| entry.module}.should == [C, M]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should include methods of all visibilities, including overridden ones" do
|
22
|
+
@lookup_path.entries[0].methods.should == {
|
23
|
+
'public1' => :public , 'public2' => :public,
|
24
|
+
'protected1' => :protected, 'protected2' => :protected,
|
25
|
+
'private1' => :private , 'private2' => :private,
|
26
|
+
'undefined1' => :undefined, 'undefined2' => :undefined,
|
27
|
+
}
|
28
|
+
@lookup_path.entries[1].methods.should == {
|
29
|
+
'public1' => :public , 'public2' => :public,
|
30
|
+
'protected1' => :protected, 'protected2' => :protected,
|
31
|
+
'private1' => :private , 'private2' => :private,
|
32
|
+
'undefined1' => :undefined, 'undefined2' => :undefined,
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should know which methods have been overridden" do
|
37
|
+
@lookup_path.entries[0].overridden?('public1').should be_false
|
38
|
+
@lookup_path.entries[1].overridden?('public1').should be_true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#find" do
|
43
|
+
before do
|
44
|
+
temporary_module(:M) { def f; end }
|
45
|
+
temporary_class(:C) { include M; def f; end }
|
46
|
+
@object = Object.new
|
47
|
+
Looksee.adapter.ancestors[@object] = [C, M]
|
48
|
+
Looksee.adapter.set_methods(M, [:f], [], [], [])
|
49
|
+
Looksee.adapter.set_methods(C, [:f], [], [], [])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return the unoverridden UnboundMethod for the given method name" do
|
53
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
54
|
+
method = lookup_path.find('f')
|
55
|
+
method.owner.should == C
|
56
|
+
method.name.should == (RUBY_VERSION < "1.9.0" ? 'f' : :f)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return nil if the method does not exist" do
|
60
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
61
|
+
lookup_path.find('g').should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should return nil if the method has been undefined" do
|
65
|
+
C.send(:undef_method, :f)
|
66
|
+
Looksee.adapter.public_methods[C].delete(:f)
|
67
|
+
Looksee.adapter.undefined_methods[C] << :f
|
68
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
69
|
+
lookup_path.find('f').should be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe Looksee::LookupPath::Entry do
|
74
|
+
it "should iterate over methods in alphabetical order" do
|
75
|
+
temporary_class(:C)
|
76
|
+
@object = Object.new
|
77
|
+
Looksee.adapter.public_methods[C] = [:a, :c, :b]
|
78
|
+
Looksee.adapter.ancestors[@object] = [C]
|
79
|
+
@lookup_path = Looksee::LookupPath.new(@object)
|
80
|
+
@lookup_path.entries.size.should == 1
|
81
|
+
@lookup_path.entries.first.map{|name, visibility| name}.should == ['a', 'b', 'c']
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|