matthew-method_lister 0.2.0

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,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,41 @@
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}]: #{expected.inspect}
22
+ Got[#{n}]: #{got.inspect}
23
+
24
+ MESSAGE
25
+ end
26
+ n += 1
27
+ end
28
+ str
29
+ end
30
+
31
+ def negative_failure_message
32
+ "Did not expect these findings: #{@expected.inspect}"
33
+ end
34
+
35
+ private
36
+
37
+ def render_find_results(results)
38
+ results.map {|result| " #{result.inspect}" }.join("\n")
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ def result(object, options)
2
+ MethodLister::FindResult.new(options.merge(:object => object))
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,36 @@
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
+ result(@object, :public => ["eigen_public", "common_public" ],
26
+ :protected => ["eigen_protected", "common_protected"],
27
+ :private => ["eigen_private" ]),
28
+ # :private => ["eigen_private", "common_private" ]),
29
+ result(MyModule, :public => ["module_public", "common_public" ],
30
+ :protected => ["module_protected", "common_protected"],
31
+ :private => ["module_private", "common_private" ]),
32
+ result(Klass, :public => ["klass_public", "common_public" ],
33
+ :protected => ["klass_protected", "common_protected"],
34
+ :private => ["klass_private", "common_private" ])
35
+ ]
36
+ 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
@@ -0,0 +1,14 @@
1
+ module FindScenarioNameSpace
2
+
3
+ class Klass
4
+ private
5
+
6
+ def private_method_from_class
7
+ end
8
+ end
9
+
10
+ @object = Klass.new
11
+ @expected = [
12
+ result(Klass, :private => ["private_method_from_class"])
13
+ ]
14
+ end
@@ -0,0 +1,11 @@
1
+ module FindScenarioNameSpace
2
+ class Klass
3
+ def method_in_class
4
+ end
5
+ end
6
+
7
+ @object = Klass.new
8
+ @expected = [
9
+ result(Klass, :public => ["method_in_class"])
10
+ ]
11
+ end
@@ -0,0 +1,19 @@
1
+ module FindScenarioNameSpace
2
+ module MyModule
3
+ def method_in_module
4
+ end
5
+ end
6
+
7
+ class Klass
8
+ include MyModule
9
+
10
+ def method_in_class
11
+ end
12
+ end
13
+
14
+ @object = Klass.new
15
+ @expected = [
16
+ result(Klass, :public => ["method_in_class"]),
17
+ result(MyModule, :public => ["method_in_module"])
18
+ ]
19
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ describe MethodLister::SimpleDisplay do
4
+ describe "#display" do
5
+ before do
6
+ @results = [
7
+ result(Object.new, :public => ["foo"], :private => ["secret"]),
8
+ result(Array, :private => ["secret"]),
9
+ result(Object, :public => ["bar"]),
10
+ result(Kernel, :public => ["baz"]),
11
+ ]
12
+
13
+ @displayer = MethodLister::SimpleDisplay.new
14
+
15
+ @output = ""
16
+ stub(@displayer).puts do |*args|
17
+ @output += args.map {|arg| arg.to_s}.join("") + "\n"
18
+ end
19
+ end
20
+
21
+ it "attempts to write out the relevant information" do
22
+ @displayer.display @results
23
+ @output.should =~ /Module Kernel.*baz.*Class Object.*bar.*Eigenclass.*foo/m
24
+ end
25
+
26
+ it "does not show private methods by default" do
27
+ @displayer.display @results
28
+ @output.should_not =~ /PRIVATE/
29
+ @output.should_not =~ /Class Array/
30
+ end
31
+
32
+ it "shows private methods if told to" do
33
+ @displayer.display @results, true
34
+ @output.should =~ /PRIVATE/
35
+ @output.should =~ /Class Array/
36
+ end
37
+ end
38
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,7 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
5
+ --timeout 20
6
+ --diff
7
+ --backtrace
@@ -0,0 +1,14 @@
1
+ require 'rubygems' rescue nil
2
+ require 'spec'
3
+
4
+ SPEC_DIR = File.dirname(__FILE__)
5
+
6
+ require File.expand_path("#{SPEC_DIR}/../lib/method_lister")
7
+ Dir["#{SPEC_DIR}/helpers/**/*.rb"].each do |file|
8
+ require file
9
+ end
10
+
11
+ Spec::Runner.configure do |config|
12
+ config.mock_with :rr
13
+ config.include MethodListerMatchers
14
+ end