looksee 3.0.0-universal-java-1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +66 -0
- data/LICENSE +22 -0
- data/README.markdown +175 -0
- data/Rakefile +13 -0
- data/ext/extconf.rb +19 -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/1.9.3/atomic.h +56 -0
- data/ext/mri/1.9.3/debug.h +41 -0
- data/ext/mri/1.9.3/id.h +175 -0
- data/ext/mri/1.9.3/internal.h +227 -0
- data/ext/mri/1.9.3/internal_falcon.h +248 -0
- data/ext/mri/1.9.3/method.h +105 -0
- data/ext/mri/1.9.3/node.h +503 -0
- data/ext/mri/1.9.3/thread_pthread.h +51 -0
- data/ext/mri/1.9.3/vm_core.h +755 -0
- data/ext/mri/1.9.3/vm_opts.h +51 -0
- data/ext/mri/2.0.0/internal.h +378 -0
- data/ext/mri/2.0.0/method.h +138 -0
- data/ext/mri/2.1.0/internal.h +889 -0
- data/ext/mri/2.1.0/method.h +142 -0
- data/ext/mri/2.2.0/internal.h +1182 -0
- data/ext/mri/2.2.0/method.h +141 -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 +309 -0
- data/ext/mri/node-1.9.h +35 -0
- data/ext/rbx/rbx.c +13 -0
- data/lib/looksee.rb +2 -0
- data/lib/looksee/JRuby.jar +0 -0
- data/lib/looksee/adapter.rb +8 -0
- data/lib/looksee/adapter/base.rb +105 -0
- data/lib/looksee/adapter/rubinius.rb +84 -0
- data/lib/looksee/clean.rb +169 -0
- data/lib/looksee/columnizer.rb +73 -0
- data/lib/looksee/core_ext.rb +48 -0
- data/lib/looksee/editor.rb +64 -0
- data/lib/looksee/help.rb +54 -0
- data/lib/looksee/inspector.rb +70 -0
- data/lib/looksee/lookup_path.rb +95 -0
- data/lib/looksee/rbx.bundle +0 -0
- data/lib/looksee/version.rb +11 -0
- data/spec/looksee/adapter_spec.rb +588 -0
- data/spec/looksee/clean_spec.rb +41 -0
- data/spec/looksee/columnizer_spec.rb +52 -0
- data/spec/looksee/core_ext_spec.rb +17 -0
- data/spec/looksee/editor_spec.rb +107 -0
- data/spec/looksee/inspector_spec.rb +179 -0
- data/spec/looksee/lookup_path_spec.rb +87 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/core_ext.rb +25 -0
- data/spec/support/temporary_classes.rb +78 -0
- data/spec/support/test_adapter.rb +83 -0
- metadata +116 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee do
|
4
|
+
describe ".[]" do
|
5
|
+
before do
|
6
|
+
@object = Object.new
|
7
|
+
Looksee.stub(default_specifiers: [:public, :overridden])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return an Inspector for the object's lookup path" do
|
11
|
+
result = Looksee[@object]
|
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
|
+
Looksee[@object].visibilities.should == Set[:public, :overridden]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set visibilities from the given symbols" do
|
21
|
+
inspector = Looksee[@object, :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 = Looksee[@object, :nooverridden]
|
27
|
+
inspector.visibilities.should == Set[:public]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should set filters from the given strings and regexp" do
|
31
|
+
inspector = Looksee[@object, '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
|
+
Looksee[@object, Object.new]
|
38
|
+
end.should raise_error(ArgumentError)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -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,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::ObjectMixin do
|
4
|
+
describe "#ls" do
|
5
|
+
before do
|
6
|
+
@object = Object.new
|
7
|
+
Looksee.stub(:default_specifiers).and_return([])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return an Inspector for the object's lookup path using the given arguments" do
|
11
|
+
result = @object.ls(:private)
|
12
|
+
result.should be_a(Looksee::Inspector)
|
13
|
+
result.lookup_path.object.should.equal?(@object)
|
14
|
+
result.visibilities.should == Set[:private]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::Editor do
|
4
|
+
describe "#command_for" do
|
5
|
+
def editor_command(command)
|
6
|
+
Looksee::Editor.new(command).command_for('FILE', 'LINE')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should infer the file and line arguments for 'vi'" do
|
10
|
+
editor_command('vi').should == ['vi', '+LINE', 'FILE']
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should infer the file and line arguments for 'vim'" do
|
14
|
+
editor_command('vim').should == ['vim', '+LINE', 'FILE']
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should infer the file and line arguments for 'gvim'" do
|
18
|
+
editor_command('gvim').should == ['gvim', '+LINE', 'FILE']
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should infer the file and line arguments for 'emacs'" do
|
22
|
+
editor_command('emacs').should == ['emacs', '+LINE', 'FILE']
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should infer the file and line arguments for 'xemacs'" do
|
26
|
+
editor_command('xemacs').should == ['xemacs', '+LINE', 'FILE']
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should infer the file and line arguments for 'aquamacs'" do
|
30
|
+
editor_command('aquamacs').should == ['aquamacs', '+LINE', 'FILE']
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should infer the file and line arguments for 'pico'" do
|
34
|
+
editor_command('pico').should == ['pico', '+LINE', 'FILE']
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should infer the file and line arguments for 'nano'" do
|
38
|
+
editor_command('nano').should == ['nano', '+LINE', 'FILE']
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should infer the file and line arguments for 'mate'" do
|
42
|
+
editor_command('mate').should == ['mate', '-lLINE', 'FILE']
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should support escaped '%'-signs" do
|
46
|
+
editor_command('%% %f %l').should == ['%', 'FILE', 'LINE']
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should not infer file and line arguments for unknown editors" do
|
50
|
+
editor_command('wtfbbq').should == ['wtfbbq']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#edit" do
|
55
|
+
let(:tmp) { "#{ROOT}/spec/tmp" }
|
56
|
+
let(:editor_path) { "#{tmp}/edit" }
|
57
|
+
let(:editor_output) { "#{tmp}/edit.out" }
|
58
|
+
let(:editor) { Looksee::Editor.new("#{editor_path} %f %l") }
|
59
|
+
let(:editor_invocation) { File.exist?(editor_output) ? File.read(editor_output) : nil }
|
60
|
+
let(:source_location) { ["#{tmp}/c.rb", 2] }
|
61
|
+
let(:object) { C.new }
|
62
|
+
|
63
|
+
before do
|
64
|
+
FileUtils.mkdir_p tmp
|
65
|
+
set_up_editor
|
66
|
+
|
67
|
+
file, line = *source_location
|
68
|
+
open(file, 'w') { |f| f.puts "class C\n def f\n end\nend" }
|
69
|
+
load file
|
70
|
+
end
|
71
|
+
|
72
|
+
after do
|
73
|
+
Object.send(:remove_const, :C)
|
74
|
+
FileUtils.rm_rf tmp
|
75
|
+
end
|
76
|
+
|
77
|
+
def set_up_editor
|
78
|
+
open(editor_path, 'w') { |f| f.puts <<-EOS.demargin }
|
79
|
+
|#!/bin/sh
|
80
|
+
|echo $# $1 $2 > "#{editor_output}"
|
81
|
+
EOS
|
82
|
+
File.chmod 0755, editor_path
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should run the editor on the method's source location if available" do
|
86
|
+
editor.edit(object, :f)
|
87
|
+
editor_invocation.should == "2 #{source_location.join(' ')}\n"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should raise NoMethodError and not run the editor if the method does not exist" do
|
91
|
+
expect { editor.edit(object, :x) }.to raise_error(Looksee::NoMethodError)
|
92
|
+
editor_invocation.should be_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should raise NoSourceFileError and not run the editor if the source file does not exist" do
|
96
|
+
FileUtils.rm_f source_location.first
|
97
|
+
expect { editor.edit(object, :f) }.to raise_error(Looksee::NoSourceFileError)
|
98
|
+
editor_invocation.should be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should raise NoSourceLocationError and not run the editor if no source location is available" do
|
102
|
+
Looksee.adapter.stub(source_location: nil)
|
103
|
+
expect { editor.edit(object, :f) }.to raise_error(Looksee::NoSourceLocationError)
|
104
|
+
editor_invocation.should be_nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::Inspector do
|
4
|
+
include TemporaryClasses
|
5
|
+
use_test_adapter
|
6
|
+
|
7
|
+
describe "#inspect" do
|
8
|
+
before do
|
9
|
+
Looksee.stub(:default_lookup_path_options).and_return({})
|
10
|
+
Looksee.stub(:styles).and_return(Hash.new{'%s'})
|
11
|
+
|
12
|
+
@object = Object.new
|
13
|
+
temporary_module :M
|
14
|
+
temporary_class(:C) { include M }
|
15
|
+
Looksee.adapter.ancestors[@object] = [C, M]
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "output width" do
|
19
|
+
before do
|
20
|
+
Looksee.adapter.public_methods[C] = ['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'ii', 'jj']
|
21
|
+
Looksee.adapter.public_methods[M] = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh']
|
22
|
+
@lookup_path = Looksee::LookupPath.new(@object)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should columnize output to the given width, if any" do
|
26
|
+
inspector = Looksee::Inspector.new(@lookup_path, :visibilities => [:public], :width => 20)
|
27
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
28
|
+
|M
|
29
|
+
| aaa ccc eee ggg
|
30
|
+
| bbb ddd fff hhh
|
31
|
+
|C
|
32
|
+
| aa cc ee gg ii
|
33
|
+
| bb dd ff hh jj
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should columnize output to the current terminal width, if detectable" do
|
38
|
+
original_columns = ENV['COLUMNS']
|
39
|
+
ENV['COLUMNS'] = '20'
|
40
|
+
begin
|
41
|
+
inspector = Looksee::Inspector.new(@lookup_path, :visibilities => [:public])
|
42
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
43
|
+
|M
|
44
|
+
| aaa ccc eee ggg
|
45
|
+
| bbb ddd fff hhh
|
46
|
+
|C
|
47
|
+
| aa cc ee gg ii
|
48
|
+
| bb dd ff hh jj
|
49
|
+
EOS
|
50
|
+
ensure
|
51
|
+
ENV['COLUMNS'] = original_columns
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should columnize output to the configured default otherwise" do
|
56
|
+
Looksee.stub(:default_width).and_return(20)
|
57
|
+
inspector = Looksee::Inspector.new(@lookup_path, :visibilities => [:public])
|
58
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
59
|
+
|M
|
60
|
+
| aaa ccc eee ggg
|
61
|
+
| bbb ddd fff hhh
|
62
|
+
|C
|
63
|
+
| aa cc ee gg ii
|
64
|
+
| bb dd ff hh jj
|
65
|
+
EOS
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not show any blank lines if a module has no methods" do
|
70
|
+
Looksee.adapter.public_methods[M] = [:public1, :public2]
|
71
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
72
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public])
|
73
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
74
|
+
|M
|
75
|
+
| public1 public2
|
76
|
+
|C
|
77
|
+
EOS
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should show singleton classes as class names in brackets" do
|
81
|
+
Looksee.adapter.ancestors[C] = [C.singleton_class]
|
82
|
+
Looksee.adapter.public_methods[C.singleton_class] = [:public1, :public2]
|
83
|
+
lookup_path = Looksee::LookupPath.new(C)
|
84
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public])
|
85
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
86
|
+
|[C]
|
87
|
+
| public1 public2
|
88
|
+
EOS
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should handle singleton classes of singleton classes correctly" do
|
92
|
+
Looksee.adapter.ancestors[C.singleton_class] = [C.singleton_class.singleton_class]
|
93
|
+
Looksee.adapter.public_methods[C.singleton_class.singleton_class] = [:public1, :public2]
|
94
|
+
lookup_path = Looksee::LookupPath.new(C.singleton_class)
|
95
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public])
|
96
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
97
|
+
|[[C]]
|
98
|
+
| public1 public2
|
99
|
+
EOS
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should only show methods of the selected visibilities" do
|
103
|
+
temporary_class :E
|
104
|
+
Looksee.adapter.set_methods(E, [:public], [:protected], [:private], [:undefined])
|
105
|
+
Looksee.adapter.ancestors[@object] = [E]
|
106
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
107
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:protected])
|
108
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
109
|
+
|E
|
110
|
+
| protected
|
111
|
+
EOS
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should show overridden methods if selected" do
|
115
|
+
Looksee.adapter.set_methods(C, [:public], [:protected], [:private], [:undefined])
|
116
|
+
Looksee.adapter.set_methods(M, [:public], [:protected], [:private], [:undefined])
|
117
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
118
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :overridden])
|
119
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
120
|
+
|M
|
121
|
+
| public
|
122
|
+
|C
|
123
|
+
| public
|
124
|
+
EOS
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should not show overridden methods if not selected" do
|
128
|
+
Looksee.adapter.set_methods(C, [:public], [:protected], [:private], [:undefined])
|
129
|
+
Looksee.adapter.set_methods(M, [:public], [:protected], [:private], [:undefined])
|
130
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
131
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :nooverridden])
|
132
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
133
|
+
|M
|
134
|
+
|C
|
135
|
+
| public
|
136
|
+
EOS
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should only show methods that match the given filters, if any are given" do
|
140
|
+
Looksee.adapter.public_methods[C] = [:ab, :ax, :ba, :xa]
|
141
|
+
Looksee.adapter.public_methods[M] = [:ab, :ax, :ba, :xa]
|
142
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
143
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :overridden], :filters => [/^a/, 'b'])
|
144
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
145
|
+
|M
|
146
|
+
| ab ax ba
|
147
|
+
|C
|
148
|
+
| ab ax ba
|
149
|
+
EOS
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe ".styles" do
|
154
|
+
before do
|
155
|
+
styles = {
|
156
|
+
:module => "`%s'",
|
157
|
+
:public => "{%s}",
|
158
|
+
:protected => "[%s]",
|
159
|
+
:private => "<%s>",
|
160
|
+
:undefined => "~%s~",
|
161
|
+
:overridden => "(%s)",
|
162
|
+
}
|
163
|
+
Looksee.stub(:styles).and_return(styles)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should delimit each word with the configured delimiters" do
|
167
|
+
temporary_class :C
|
168
|
+
c = C.new
|
169
|
+
Looksee.adapter.ancestors[c] = [C]
|
170
|
+
Looksee.adapter.set_methods(C, [:public], [:protected], [:private], [:undefined])
|
171
|
+
lookup_path = Looksee::LookupPath.new(c)
|
172
|
+
inspector = Looksee::Inspector.new(lookup_path, :visibilities => [:public, :protected, :private, :undefined, :overridden])
|
173
|
+
inspector.inspect.should == <<-EOS.demargin.chomp
|
174
|
+
|\`C\'
|
175
|
+
| <private> [protected] {public} ~undefined~
|
176
|
+
EOS
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Looksee::LookupPath do
|
4
|
+
include TemporaryClasses
|
5
|
+
|
6
|
+
describe "#entries" do
|
7
|
+
use_test_adapter
|
8
|
+
|
9
|
+
before do
|
10
|
+
temporary_module :M
|
11
|
+
temporary_class(:C) { include M }
|
12
|
+
@object = Object.new
|
13
|
+
Looksee.adapter.ancestors[@object] = [C, M]
|
14
|
+
Looksee.adapter.set_methods(M, [:public1, :public2], [:protected1, :protected2], [:private1, :private2], [:undefined1, :undefined2])
|
15
|
+
Looksee.adapter.set_methods(C, [:public1, :public2], [:protected1, :protected2], [:private1, :private2], [:undefined1, :undefined2])
|
16
|
+
@lookup_path = Looksee::LookupPath.new(@object)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should contain an entry for each module in the object's lookup path" do
|
20
|
+
@lookup_path.entries.map{|entry| entry.module}.should == [C, M]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should include methods of all visibilities, including overridden ones" do
|
24
|
+
@lookup_path.entries[0].methods.should == {
|
25
|
+
'public1' => :public , 'public2' => :public,
|
26
|
+
'protected1' => :protected, 'protected2' => :protected,
|
27
|
+
'private1' => :private , 'private2' => :private,
|
28
|
+
'undefined1' => :undefined, 'undefined2' => :undefined,
|
29
|
+
}
|
30
|
+
@lookup_path.entries[1].methods.should == {
|
31
|
+
'public1' => :public , 'public2' => :public,
|
32
|
+
'protected1' => :protected, 'protected2' => :protected,
|
33
|
+
'private1' => :private , 'private2' => :private,
|
34
|
+
'undefined1' => :undefined, 'undefined2' => :undefined,
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should know which methods have been overridden" do
|
39
|
+
@lookup_path.entries[0].overridden?('public1').should == false
|
40
|
+
@lookup_path.entries[1].overridden?('public1').should == true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#find" do
|
45
|
+
before do
|
46
|
+
temporary_module(:M) { def f; end }
|
47
|
+
temporary_class(:C) { include M; def f; end }
|
48
|
+
@object = C.new
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return the unoverridden UnboundMethod for the given method name" do
|
52
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
53
|
+
method = lookup_path.find('f')
|
54
|
+
method.owner.should == C
|
55
|
+
method.name.should == (RUBY_VERSION < "1.9.0" ? 'f' : :f)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should find methods in included modules" do
|
59
|
+
M.class_eval { def g; end }
|
60
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
61
|
+
method = lookup_path.find('g')
|
62
|
+
method.owner.should == M
|
63
|
+
method.name.should == (RUBY_VERSION < "1.9.0" ? 'g' : :g)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return nil if the method does not exist" do
|
67
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
68
|
+
lookup_path.find('g').should be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should return nil if the method has been undefined" do
|
72
|
+
C.send(:undef_method, :f)
|
73
|
+
lookup_path = Looksee::LookupPath.new(@object)
|
74
|
+
lookup_path.find('f').should be_nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe Looksee::LookupPath::Entry do
|
79
|
+
it "should iterate over methods in alphabetical order" do
|
80
|
+
temporary_class(:C)
|
81
|
+
@object = C.new
|
82
|
+
Looksee.adapter.stub(internal_public_instance_methods: [:a, :c, :b])
|
83
|
+
@lookup_path = Looksee::LookupPath.new(@object)
|
84
|
+
@lookup_path.entries.first.map{|name, visibility| name}.should == ['a', 'b', 'c']
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|