method_lister 0.3.2

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.
@@ -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