method_lister 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,161 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ describe MethodLister::FindResult do
4
+ before do
5
+ names = %w{foo bar baz}
6
+ @public = names.map {|m| "public_#{m}"}
7
+ @protected = names.map {|m| "protected_#{m}"}
8
+ @private = names.map {|m| "private_#{m}"}
9
+ @all = @public + @protected + @private
10
+
11
+ @object = Object.new
12
+ @empty_result = MethodLister::FindResult.new(@object)
13
+ @only_public = MethodLister::FindResult.new(@object,
14
+ :public => @public)
15
+ @only_protected = MethodLister::FindResult.new(@object,
16
+ :protected => @protected)
17
+ @only_private = MethodLister::FindResult.new(@object,
18
+ :private => @private)
19
+ @mixed_result = MethodLister::FindResult.new(@object,
20
+ :public => @public,
21
+ :protected => @protected,
22
+ :private => @private)
23
+ end
24
+
25
+ describe "#object" do
26
+ it "works even if object is nil" do
27
+ result = MethodLister::FindResult.new(nil, :public => @public)
28
+ result.object.should be_nil
29
+ end
30
+
31
+ it "knows its associated object" do
32
+ @empty_result.object.should == @object
33
+ end
34
+ end
35
+
36
+ describe "#methods" do
37
+ it "knows all its methods" do
38
+ @empty_result.methods(:all).should be_empty
39
+ @only_public.methods(:all).should == @public.sort
40
+ @only_protected.methods(:all).should == @protected.sort
41
+ @only_private.methods(:all).should == @private.sort
42
+ @mixed_result.methods(:all).should == @all.sort
43
+ end
44
+
45
+ it "knows its public methods" do
46
+ @empty_result.methods(:public).should be_empty
47
+ @only_public.methods(:public).should == @public.sort
48
+ @only_protected.methods(:public).should be_empty
49
+ @only_private.methods(:public).should be_empty
50
+ @mixed_result.methods(:public).should == @public.sort
51
+ end
52
+
53
+ it "knows its protected methods" do
54
+ @empty_result.methods(:protected).should be_empty
55
+ @only_public.methods(:protected).should be_empty
56
+ @only_protected.methods(:protected).should == @protected.sort
57
+ @only_private.methods(:protected).should be_empty
58
+ @mixed_result.methods(:protected).should == @protected.sort
59
+ end
60
+
61
+ it "knows its private methods" do
62
+ @empty_result.methods(:private).should be_empty
63
+ @only_public.methods(:private).should be_empty
64
+ @only_protected.methods(:private).should be_empty
65
+ @only_private.methods(:private).should == @private.sort
66
+ @mixed_result.methods(:private).should == @private.sort
67
+ end
68
+
69
+ it "raises an exception if given an unknown visibility" do
70
+ lambda do
71
+ @empty_result.methods(:foobar)
72
+ end.should raise_error(ArgumentError)
73
+ end
74
+ end
75
+
76
+ describe "#has_methods?" do
77
+ it "knows if it has methods of any visibility" do
78
+ @empty_result.should_not have_methods
79
+ @only_public.should have_methods
80
+ @only_protected.should have_methods
81
+ @only_private.should have_methods
82
+ @mixed_result.should have_methods
83
+ end
84
+
85
+ it "knows if it has methods of visibility :all" do
86
+ @empty_result.should_not have_methods(:all)
87
+ @only_public.should have_methods(:all)
88
+ @only_protected.should have_methods(:all)
89
+ @only_private.should have_methods(:all)
90
+ @mixed_result.should have_methods(:all)
91
+ end
92
+
93
+ it "knows if it has methods of visibility :public" do
94
+ @empty_result.should_not have_methods(:public)
95
+ @only_public.should have_methods(:public)
96
+ @only_protected.should_not have_methods(:public)
97
+ @only_private.should_not have_methods(:public)
98
+ @mixed_result.should have_methods(:public)
99
+ end
100
+
101
+ it "knows if it has methods of visibility :protected" do
102
+ @empty_result.should_not have_methods(:protected)
103
+ @only_public.should_not have_methods(:protected)
104
+ @only_protected.should have_methods(:protected)
105
+ @only_private.should_not have_methods(:protected)
106
+ @mixed_result.should have_methods(:protected)
107
+ end
108
+
109
+ it "knows if it has methods of visibility :private" do
110
+ @empty_result.should_not have_methods(:private)
111
+ @only_public.should_not have_methods(:private)
112
+ @only_protected.should_not have_methods(:private)
113
+ @only_private.should have_methods(:private)
114
+ @mixed_result.should have_methods(:private)
115
+ end
116
+ end
117
+
118
+ describe "#narrow_to_methods_matching!" do
119
+ it "removes all methods not matching the given regex" do
120
+ rx = /foo/
121
+ @mixed_result.methods(:all).select {|meth| meth !~ rx}.should_not be_empty
122
+ @mixed_result.narrow_to_methods_matching!(rx)
123
+ @mixed_result.methods(:all).select {|meth| meth !~ rx}.should be_empty
124
+ end
125
+
126
+ it "never removes method_missing" do
127
+ @private << "method_missing"
128
+ rx = /foo/
129
+ @mixed_result.methods(:all).select {|meth| meth !~ rx}.should_not be_empty
130
+ @mixed_result.narrow_to_methods_matching!(rx)
131
+ @mixed_result.methods(:all).select {|meth| meth !~ rx}.should be_include("method_missing")
132
+ end
133
+ end
134
+
135
+ describe "#==" do
136
+ it "is equal if both have the same methods and object" do
137
+ @mixed_result.should == MethodLister::FindResult.new(
138
+ @mixed_result.object,
139
+ :public => @mixed_result.methods(:public),
140
+ :protected => @mixed_result.methods(:protected),
141
+ :private => @mixed_result.methods(:private)
142
+ )
143
+ end
144
+
145
+ it "is not equal if both have same methods but different objects" do
146
+ @mixed_result.should_not == MethodLister::FindResult.new(
147
+ Object.new,
148
+ :public => @mixed_result.methods(:public),
149
+ :protected => @mixed_result.methods(:protected),
150
+ :private => @mixed_result.methods(:private)
151
+ )
152
+ end
153
+
154
+ it "is not equal if both have the same object but different methods" do
155
+ @mixed_result.should_not == MethodLister::FindResult.new(
156
+ @mixed_result.object,
157
+ :public => ["something_else"]
158
+ )
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ describe MethodLister::Finder do
4
+ before do
5
+ @finder = MethodLister::Finder.new
6
+ end
7
+
8
+ describe "#find_all" do
9
+ before do
10
+ class UltraKlass; def method_ultra; end; end
11
+ class SuperKlass < UltraKlass; end
12
+ class Klass < SuperKlass; def method_klass; end; end
13
+ @object = Klass.new
14
+ end
15
+
16
+ after do
17
+ Object.send(:remove_const, :Klass)
18
+ Object.send(:remove_const, :SuperKlass)
19
+ Object.send(:remove_const, :UltraKlass)
20
+ end
21
+
22
+ it "does not filter results which have no methods" do
23
+ @finder.find_all(@object).should list_methods([
24
+ result(@object, :public => []),
25
+ result(Klass, :public => ["method_klass"]),
26
+ result(SuperKlass, :public => []),
27
+ result(UltraKlass, :public => ["method_ultra"])
28
+ ])
29
+ end
30
+ end
31
+
32
+ describe "#ls" do
33
+ it "should have more than one scenario" do
34
+ all_find_scenarios.should_not be_empty
35
+ end
36
+
37
+ all_find_scenarios.each do |scenario|
38
+ it "finds method according to scenario #{scenario.name}" do
39
+ scenario.setup!
40
+ @finder.ls(scenario.object).should list_methods(scenario.expected)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "auxillary methods" do
46
+ before do
47
+ @object = Object.new
48
+ end
49
+
50
+ describe "with results" do
51
+ before do
52
+ stub(@finder).ls(@object) do
53
+ [
54
+ result(@object, :public => ["bar", "foo", "foo2"]),
55
+ result(Object, :public => ["foo", "foo3", "qux"]),
56
+ result(Kernel, :public => ["baz"]),
57
+ ]
58
+ end
59
+ end
60
+
61
+ describe "#grep" do
62
+ it "narrows down the find results based on the given regex" do
63
+ @finder.grep(/foo/, @object).should == [
64
+ result(@object, :public => ["foo", "foo2"]),
65
+ result(Object, :public => ["foo", "foo3"])
66
+ ]
67
+ end
68
+ end
69
+
70
+ describe "#which" do
71
+ it "attempts to regex escape the method name passed in" do
72
+ mock(Regexp).escape("foo").twice
73
+ @finder.which("foo", @object)
74
+ @finder.which(:foo, @object)
75
+ end
76
+
77
+ it "returns the classes and objects hold the method" do
78
+ @finder.which("foo", @object).should == [
79
+ result(@object, :public => ["foo"]),
80
+ result(Object, :public => ["foo"])
81
+ ]
82
+
83
+ @finder.which("foo3", @object).should == [
84
+ result(Object, :public => ["foo3"])
85
+ ]
86
+ end
87
+
88
+ it "works correctly with symbols" do
89
+ @finder.which(:foo, @object).should == [
90
+ result(@object, :public => ["foo"]),
91
+ result(Object, :public => ["foo"])
92
+ ]
93
+
94
+ @finder.which(:foo3, @object).should == [
95
+ result(Object, :public => ["foo3"])
96
+ ]
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "without results" do
102
+ before do
103
+ stub(@finder).ls(@object) { Array.new }
104
+ end
105
+
106
+ describe "#grep" do
107
+ it "returns the empty list if nothing can be found" do
108
+ @finder.grep(/I_MATCH_NOTHING/, @object).should == []
109
+ end
110
+ end
111
+
112
+ describe "#which" do
113
+ it "returns the empty list if nothing can be found" do
114
+ @finder.which("I_MATCH_NOTHING", @object).should == []
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "with results containing method_missing" do
120
+ before do
121
+ stub(@finder).ls(@object) do
122
+ [
123
+ result(Array, :public => ["sort1", "sort2"]),
124
+ result(Object, :public => ["method_missing", "sort3"])
125
+ ]
126
+ end
127
+ end
128
+
129
+ describe "#grep" do
130
+ it "returns method_missing its list of results if found" do
131
+ @finder.grep(/I_MATCH_NOTHING/, @object).should == [
132
+ result(Object, :public => ["method_missing"]),
133
+ ]
134
+ end
135
+ end
136
+
137
+ describe "#which" do
138
+ it "returns method_missing its list of results if found" do
139
+ @finder.which("I_MATCH_NOTHING", @object).should == [
140
+ result(Object, :public => ["method_missing"]),
141
+ ]
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,42 @@
1
+ module MethodListerMatchers
2
+ def list_methods(method_list)
3
+ ListMethods.new(method_list)
4
+ end
5
+
6
+ class ListMethods
7
+ def initialize(expected)
8
+ @expected = expected
9
+ end
10
+
11
+ def matches?(target)
12
+ @target = target.slice(0, @expected.length) # Trim extras from Rspec, Ruby, etc.
13
+ @target == @expected
14
+ end
15
+
16
+ def failure_message
17
+ str, n = "", 0
18
+ @expected.zip(@target).each do |expected, got|
19
+ if expected != got
20
+ str += <<-MESSAGE
21
+ Expected[#{n}]:
22
+ #{expected.inspect}
23
+ Got[#{n}]:
24
+ #{got.inspect}
25
+ MESSAGE
26
+ end
27
+ n += 1
28
+ end
29
+ str
30
+ end
31
+
32
+ def negative_failure_message
33
+ "Did not expect these findings: #{@expected.inspect}"
34
+ end
35
+
36
+ private
37
+
38
+ def render_find_results(results)
39
+ results.map {|result| " #{result.inspect}" }.join("\n")
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ def result(object, options)
2
+ MethodLister::FindResult.new(object, options)
3
+ end
@@ -0,0 +1,45 @@
1
+ def all_find_scenarios
2
+ FindScenario.load_all
3
+ end
4
+
5
+ class FindScenario
6
+ attr_reader :name, :object, :expected
7
+
8
+ def initialize(filename)
9
+ @filename = filename
10
+ @name = File.basename(@filename).gsub(/\.rb$/, "")
11
+ end
12
+
13
+ def setup!
14
+ FindScenarioNameSpace.reset!
15
+ load @filename
16
+ @object = FindScenarioNameSpace.object
17
+ @expected = FindScenarioNameSpace.expected
18
+ end
19
+
20
+ class << self
21
+ def load_all
22
+ Dir["#{scenario_dir}/*.rb"].map {|file| new(file)}
23
+ end
24
+
25
+ private
26
+
27
+ def scenario_dir
28
+ File.expand_path(File.dirname(__FILE__) + "/../../scenarios")
29
+ end
30
+ end
31
+ end
32
+
33
+ module FindScenarioNameSpace
34
+ class << self
35
+ attr_reader :object, :expected
36
+
37
+ def reset!
38
+ constants.each do |constant|
39
+ remove_const(constant)
40
+ end
41
+ @object = nil
42
+ @expected = nil
43
+ end
44
+ end
45
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1,6 @@
1
+ --include lib
2
+ --exclude "spec/*,gems/*"
3
+ --aggregate coverage.data
4
+ --sort coverage
5
+ --text-summary
6
+ --html
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ describe "Method Lister Ruby Extensions" do
4
+ describe Kernel do
5
+ before do
6
+ mock.instance_of(MethodLister::ColorDisplay).display(:mcguffin, anything) { nil }
7
+ @finder_class_double = mock.instance_of(MethodLister::Finder)
8
+ @object = Object.new
9
+ end
10
+
11
+ describe "#ls" do
12
+ before do
13
+ @finder_class_double.ls(@object) { :mcguffin }
14
+ end
15
+
16
+ it "works correctly with the ls command" do
17
+ @object.ls
18
+ end
19
+
20
+ it "works correctly with the mls command" do
21
+ @object.mls
22
+ end
23
+ end
24
+
25
+ describe "#grep" do
26
+ before do
27
+ @rx = /object_id/
28
+ @finder_class_double.grep(@rx, @object) { :mcguffin }
29
+ end
30
+
31
+ it "works correctly with the grep command" do
32
+ @object.grep @rx
33
+ end
34
+
35
+ it "works correctly with the mgrep command" do
36
+ @object.mgrep @rx
37
+ end
38
+ end
39
+
40
+ describe "#which" do
41
+ before do
42
+ @method = :object_id
43
+ @finder_class_double.which(@method, @object) { :mcguffin }
44
+ end
45
+
46
+ it "works correctly with the which command" do
47
+ @object.which @method
48
+ end
49
+
50
+ it "works correctly with the mwhich command" do
51
+ @object.mwhich @method
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,17 @@
1
+ module FindScenarioNameSpace
2
+ class SuperKlass
3
+ def method_from_superclass
4
+ end
5
+ end
6
+
7
+ class Klass < SuperKlass
8
+ def method_from_class
9
+ end
10
+ end
11
+
12
+ @object = Klass.new
13
+ @expected = [
14
+ result(Klass, :public => ["method_from_class"]),
15
+ result(SuperKlass, :public => ["method_from_superclass"])
16
+ ]
17
+ end
@@ -0,0 +1,25 @@
1
+ module FindScenarioNameSpace
2
+ module MyModule
3
+ def method_from_module
4
+ end
5
+ end
6
+
7
+ class SuperKlass
8
+ def method_from_superclass
9
+ end
10
+ end
11
+
12
+ class Klass < SuperKlass
13
+ include MyModule
14
+
15
+ def method_from_class
16
+ end
17
+ end
18
+
19
+ @object = Klass.new
20
+ @expected = [
21
+ result(Klass, :public => ["method_from_class"]),
22
+ result(MyModule, :public => ["method_from_module"]),
23
+ result(SuperKlass, :public => ["method_from_superclass"])
24
+ ]
25
+ end
@@ -0,0 +1,18 @@
1
+ module FindScenarioNameSpace
2
+ class Klass
3
+ def method_from_class
4
+ end
5
+ end
6
+
7
+ @object = Klass.new
8
+
9
+ class << @object
10
+ def method_from_eigenclass
11
+ end
12
+ end
13
+
14
+ @expected = [
15
+ result(@object, :public => ["method_from_eigenclass"]),
16
+ result(Klass, :public => ["method_from_class"]),
17
+ ]
18
+ end
@@ -0,0 +1,26 @@
1
+ module FindScenarioNameSpace
2
+ module MyModule
3
+ def method_from_module
4
+ end
5
+ end
6
+
7
+ class Klass
8
+ def method_from_class
9
+ end
10
+ end
11
+
12
+ @object = Klass.new
13
+
14
+ class << @object
15
+ include MyModule
16
+
17
+ def method_from_eigenclass
18
+ end
19
+ end
20
+
21
+ @expected = [
22
+ result(@object, :public => ["method_from_eigenclass"]),
23
+ result(MyModule, :public => ["method_from_module"]),
24
+ result(Klass, :public => ["method_from_class"]),
25
+ ]
26
+ end
@@ -0,0 +1,20 @@
1
+ module FindScenarioNameSpace
2
+ class UltraKlass
3
+ def method_from_ultraclass
4
+ end
5
+ end
6
+
7
+ class SuperKlass < UltraKlass
8
+ end
9
+
10
+ class Klass < SuperKlass
11
+ def method_from_klass
12
+ end
13
+ end
14
+
15
+ @object = Klass.new
16
+ @expected = [
17
+ result(Klass, :public => ["method_from_klass"]),
18
+ result(UltraKlass, :public => ["method_from_ultraclass"]),
19
+ ]
20
+ end
@@ -0,0 +1,39 @@
1
+ module FindScenarioNameSpace
2
+ module MyModule
3
+ public; def module_public; end; def common_public; end
4
+ protected; def module_protected; end; def common_protected; end
5
+ private; def module_private; end; def common_private; end
6
+ end
7
+
8
+ class Klass
9
+ public; def klass_public; end; def common_public; end
10
+ protected; def klass_protected; end; def common_protected; end
11
+ private; def klass_private; end; def common_private; end
12
+ end
13
+
14
+ @object = Klass.new
15
+
16
+ class << @object
17
+ include MyModule
18
+
19
+ public; def eigen_public; end; def common_public; end
20
+ protected; def eigen_protected; end; def common_protected; end
21
+ private; def eigen_private; end; def common_private; end
22
+ end
23
+
24
+ @expected = [
25
+ # The commented out lines is the desired result, but can't make it work.
26
+ # result(@object, :public => ["eigen_public", "common_public" ],
27
+ # :protected => ["eigen_protected", "common_protected"],
28
+ # :private => ["eigen_private", "common_private" ]),
29
+ result(@object, :public => ["eigen_public"],
30
+ :protected => ["eigen_protected"],
31
+ :private => ["eigen_private"]),
32
+ result(MyModule, :public => ["module_public", "common_public" ],
33
+ :protected => ["module_protected", "common_protected"],
34
+ :private => ["module_private", "common_private" ]),
35
+ result(Klass, :public => ["klass_public", "common_public" ],
36
+ :protected => ["klass_protected", "common_protected"],
37
+ :private => ["klass_private", "common_private" ])
38
+ ]
39
+ end
@@ -0,0 +1,4 @@
1
+ module FindScenarioNameSpace
2
+ @object = :object_that_can_not_have_an_eigenclass
3
+ @expected = []
4
+ end
@@ -0,0 +1,35 @@
1
+ module FindScenarioNameSpace
2
+ class K1;
3
+ def method_k1; end;
4
+ def common_method; end;
5
+ end
6
+
7
+ class K2 < K1;
8
+ def method_k2; end;
9
+ def common_method; end;
10
+ end
11
+
12
+ class K3 < K2;
13
+ def method_k3; end;
14
+ def common_method; end;
15
+ end
16
+
17
+ class K4 < K3;
18
+ def method_k4; end;
19
+ def common_method; end;
20
+ end
21
+
22
+ class K5 < K4;
23
+ def method_k5; end;
24
+ def common_method; end;
25
+ end
26
+
27
+ @object = K5.new
28
+ @expected = [
29
+ result(K5, :public => ["common_method", "method_k5"]),
30
+ result(K4, :public => ["common_method", "method_k4"]),
31
+ result(K3, :public => ["common_method", "method_k3"]),
32
+ result(K2, :public => ["common_method", "method_k2"]),
33
+ result(K1, :public => ["common_method", "method_k1"])
34
+ ]
35
+ end
@@ -0,0 +1,26 @@
1
+ module FindScenarioNameSpace
2
+ module M1; def method_m1; end; end
3
+ module M2; def method_m2; end; end
4
+ module M3; def method_m3; end; end
5
+ module M4; def method_m4; end; end
6
+ module M5; def method_m5; end; end
7
+ class K1; include M1; def method_k1; end; end
8
+ class K2 < K1; include M2; def method_k2; end; end
9
+ class K3 < K2; include M3; def method_k3; end; end
10
+ class K4 < K3; include M4; def method_k4; end; end
11
+ class K5 < K4; include M5; def method_k5; end; end
12
+
13
+ @object = K5.new
14
+ @expected = [
15
+ result(K5, :public => ["method_k5"]),
16
+ result(M5, :public => ["method_m5"]),
17
+ result(K4, :public => ["method_k4"]),
18
+ result(M4, :public => ["method_m4"]),
19
+ result(K3, :public => ["method_k3"]),
20
+ result(M3, :public => ["method_m3"]),
21
+ result(K2, :public => ["method_k2"]),
22
+ result(M2, :public => ["method_m2"]),
23
+ result(K1, :public => ["method_k1"]),
24
+ result(M1, :public => ["method_m1"]),
25
+ ]
26
+ end