looksee 3.0.0-universal-java-1.8
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.
- 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
|