markevans-method_call_recorder 0.1.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.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.markdown +26 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/lib/method_call_recorder/method_call.rb +70 -0
- data/lib/method_call_recorder/method_call_recorder.rb +58 -0
- data/lib/method_call_recorder.rb +3 -0
- data/method_call_recorder.gemspec +51 -0
- data/spec/method_call_recorder_spec.rb +125 -0
- data/spec/method_call_spec.rb +161 -0
- data/spec/spec_helper.rb +2 -0
- metadata +68 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Mark Evans
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Method call recorder
|
2
|
+
===================
|
3
|
+
A method call recorder is an object on which you can call any method, with any arguments (and continue doing so on child objects).
|
4
|
+
|
5
|
+
rec = MethodCallRecorder.new
|
6
|
+
rec[:this].is(:a, 'nice')[:little, :object].isnt.it? # This does very little, but it works!
|
7
|
+
|
8
|
+
You can then play methods back on other objects.
|
9
|
+
|
10
|
+
rec[1].upcase # first record the method chain
|
11
|
+
rec._play(['hello','there']) # => 'THERE'
|
12
|
+
|
13
|
+
You can also inspect the method chain if you wish (shows all methods called including arguments). This is an array of `MethodCall` objects.
|
14
|
+
Using the last example:
|
15
|
+
|
16
|
+
method_call = rec._method_chain.first
|
17
|
+
method_call.method # :[] (a symbol representing the method call)
|
18
|
+
method_call.args # [1] (an array of the args)
|
19
|
+
|
20
|
+
Install
|
21
|
+
-------
|
22
|
+
Install from github gems in usual way
|
23
|
+
|
24
|
+
Copyright
|
25
|
+
--------
|
26
|
+
Copyright (c) 2009 Mark Evans. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "method_call_recorder"
|
8
|
+
gem.summary = "An object on which you can call anything, where nothing happens, but the whole method chain is recorded"
|
9
|
+
gem.email = "mark@new-bamboo.co.uk"
|
10
|
+
gem.homepage = "http://github.com/markevans/method_call_recorder"
|
11
|
+
gem.authors = ["Mark Evans"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
end
|
14
|
+
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'spec/rake/spectask'
|
20
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
21
|
+
spec.libs << 'lib' << 'spec'
|
22
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
28
|
+
spec.rcov = true
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task :default => :spec
|
33
|
+
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
if File.exist?('VERSION.yml')
|
37
|
+
config = YAML.load(File.read('VERSION.yml'))
|
38
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
39
|
+
else
|
40
|
+
version = ""
|
41
|
+
end
|
42
|
+
|
43
|
+
rdoc.rdoc_dir = 'rdoc'
|
44
|
+
rdoc.title = "method_call_recorder #{version}"
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
48
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class MethodCall
|
2
|
+
|
3
|
+
|
4
|
+
def initialize(meth, *args, &blk)
|
5
|
+
@method, @args = meth, args
|
6
|
+
@block = blk
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :method, :args, :block
|
10
|
+
|
11
|
+
def call_on(obj)
|
12
|
+
obj.send(method, *args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_a
|
16
|
+
[method, *args]
|
17
|
+
end
|
18
|
+
|
19
|
+
def setter?
|
20
|
+
!!(method.to_s =~ /=$/)
|
21
|
+
end
|
22
|
+
|
23
|
+
def getter?
|
24
|
+
!setter?
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_setter(value)
|
28
|
+
new_method_call = self.deep_dup
|
29
|
+
if setter?
|
30
|
+
new_method_call.args[-1] = value
|
31
|
+
else
|
32
|
+
new_method_call.args << value
|
33
|
+
new_method_call.method = "#{new_method_call.method}=".to_sym
|
34
|
+
end
|
35
|
+
new_method_call
|
36
|
+
end
|
37
|
+
|
38
|
+
def type
|
39
|
+
case method.to_s
|
40
|
+
when '[]' then (args.first.is_a?(Fixnum) ? :array_reader : :hash_reader)
|
41
|
+
when '[]=' then (args.first.is_a?(Fixnum) ? :array_writer : :hash_writer)
|
42
|
+
when /\=$/ then :attr_writer
|
43
|
+
else :attr_reader
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def guess_receiver_type
|
48
|
+
case type
|
49
|
+
when :array_reader, :array_writer then Array
|
50
|
+
when :hash_reader, :hash_writer then Hash
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def ==(other)
|
55
|
+
self.method == other.method && self.args == other.args
|
56
|
+
end
|
57
|
+
|
58
|
+
def deep_dup
|
59
|
+
self.class.new(method, *args, &block)
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s
|
63
|
+
to_a.to_s
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
attr_writer :method
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class MethodCallRecorder
|
2
|
+
|
3
|
+
def _play(object, &blk)
|
4
|
+
i = 0
|
5
|
+
_method_chain.inject(object) do |obj, method_call|
|
6
|
+
i += 1
|
7
|
+
yield(obj, method_call, _method_chain[i]) if block_given?
|
8
|
+
method_call.call_on(obj)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def _first_method
|
13
|
+
_method_chain.first
|
14
|
+
end
|
15
|
+
|
16
|
+
def _empty?
|
17
|
+
_method_chain.empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
_method_chain.inspect
|
22
|
+
end
|
23
|
+
|
24
|
+
def _method_chain
|
25
|
+
@_method_chain ||= []
|
26
|
+
end
|
27
|
+
|
28
|
+
def _to_setter(value)
|
29
|
+
new_rec = self.dup
|
30
|
+
new_rec._method_chain = self._method_chain.dup
|
31
|
+
new_rec._method_chain[-1] = self._method_chain[-1].to_setter(value)
|
32
|
+
new_rec
|
33
|
+
end
|
34
|
+
|
35
|
+
def _reset!
|
36
|
+
_method_chain = []
|
37
|
+
end
|
38
|
+
|
39
|
+
def _select(meth, args=nil)
|
40
|
+
_method_chain.select do |method_call|
|
41
|
+
selected = (method_call.method == meth)
|
42
|
+
selected &&= (method_call.args == args) if args
|
43
|
+
selected
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
attr_writer :_method_chain
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def method_missing(meth, *args)
|
54
|
+
_method_chain << MethodCall.new(meth, *args)
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{method_call_recorder}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Mark Evans"]
|
9
|
+
s.date = %q{2009-07-04}
|
10
|
+
s.email = %q{mark@new-bamboo.co.uk}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"LICENSE",
|
13
|
+
"README.markdown"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README.markdown",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"lib/method_call_recorder.rb",
|
23
|
+
"lib/method_call_recorder/method_call.rb",
|
24
|
+
"lib/method_call_recorder/method_call_recorder.rb",
|
25
|
+
"method_call_recorder.gemspec",
|
26
|
+
"spec/method_call_recorder_spec.rb",
|
27
|
+
"spec/method_call_spec.rb",
|
28
|
+
"spec/spec_helper.rb"
|
29
|
+
]
|
30
|
+
s.has_rdoc = true
|
31
|
+
s.homepage = %q{http://github.com/markevans/method_call_recorder}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.1}
|
35
|
+
s.summary = %q{An object on which you can call anything, where nothing happens, but the whole method chain is recorded}
|
36
|
+
s.test_files = [
|
37
|
+
"spec/method_call_recorder_spec.rb",
|
38
|
+
"spec/method_call_spec.rb",
|
39
|
+
"spec/spec_helper.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 2
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
47
|
+
else
|
48
|
+
end
|
49
|
+
else
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper"
|
2
|
+
|
3
|
+
def stub_method_call(*args)
|
4
|
+
method_call = mock('method_call')
|
5
|
+
MethodCall.stub!(:new).with(*args).and_return method_call
|
6
|
+
method_call
|
7
|
+
end
|
8
|
+
|
9
|
+
describe MethodCallRecorder do
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@rec = MethodCallRecorder.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should allow any combination of chained methods on it" do
|
16
|
+
lambda do
|
17
|
+
MethodCallRecorder.new.egg[23]['fish'].another = 5
|
18
|
+
MethodCallRecorder.new[:twenty].what.the / 8 * 4 + 1
|
19
|
+
end.should_not raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should save methods called on it in it's 'method chain'" do
|
23
|
+
mc1 = stub_method_call(:this, :should)
|
24
|
+
mc2 = stub_method_call(:[], 'be')
|
25
|
+
mc3 = stub_method_call(:saved)
|
26
|
+
@rec.this(:should)['be'].saved
|
27
|
+
@rec._method_chain.should == [mc1, mc2, mc3]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be able to play back its method chain on another object" do
|
31
|
+
inner = mock('inner', :duck => 'hello')
|
32
|
+
struct = mock('struct', :fish => inner)
|
33
|
+
obj = { :a => [struct, 2] }
|
34
|
+
@rec[:a][0].fish.duck
|
35
|
+
@rec._play(obj).should == 'hello'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should just return the object on play if its method chain is empty" do
|
39
|
+
obj = Object.new
|
40
|
+
@rec._play(obj).should == obj
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should record append to the method chain if you record twice" do
|
44
|
+
mc1 = stub_method_call(:once)
|
45
|
+
mc2 = stub_method_call(:twice)
|
46
|
+
@rec.once
|
47
|
+
@rec._method_chain.should == [mc1]
|
48
|
+
@rec.twice
|
49
|
+
@rec._method_chain.should == [mc1, mc2]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should allow resetting the method chain" do
|
53
|
+
mc1 = stub_method_call(:once)
|
54
|
+
mc2 = stub_method_call(:twice)
|
55
|
+
@rec.once
|
56
|
+
@rec._method_chain.should == [mc1]
|
57
|
+
@rec._reset!
|
58
|
+
@rec.twice
|
59
|
+
@rec._method_chain.should == [mc1, mc2]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should yield the current sub object, and the next two methods to be called as it plays back" do
|
63
|
+
mc1 = MethodCall.new(:[], :hello)
|
64
|
+
mc2 = MethodCall.new(:[], 2)
|
65
|
+
mc3 = MethodCall.new(:eggy_bread)
|
66
|
+
str = 'yes'
|
67
|
+
def str.eggy_bread; 'egg'; end
|
68
|
+
@rec[:hello][2].eggy_bread
|
69
|
+
yielded_values = []
|
70
|
+
@rec._play({:hello => ['no','and',str]}) do |obj, method_call, next_method_call|
|
71
|
+
yielded_values << [obj, method_call, next_method_call]
|
72
|
+
end
|
73
|
+
yielded_values.should == [
|
74
|
+
[ {:hello => ['no','and',str]}, mc1, mc2 ],
|
75
|
+
[ ['no','and',str], mc2, mc3 ],
|
76
|
+
[ str, mc3, nil ]
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should return the first method called on it" do
|
81
|
+
@rec.hello.how.are['you']
|
82
|
+
@rec._first_method.should == MethodCall.new(:hello)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should return itself" do
|
86
|
+
@rec.hello[4].this(:is).now('innit').should == @rec
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return a clone of itself with the last method as a setter" do
|
90
|
+
mc1 = MethodCall.new(:[], :hello)
|
91
|
+
mc2 = MethodCall.new(:there)
|
92
|
+
mc3 = MethodCall.new(:there=, 4)
|
93
|
+
@rec[:hello].there
|
94
|
+
other_rec = @rec._to_setter(4)
|
95
|
+
@rec._method_chain.should == [mc1, mc2]
|
96
|
+
other_rec._method_chain.should == [mc1, mc3]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should say if empty" do
|
100
|
+
@rec._empty?.should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should say if not empty" do
|
104
|
+
@rec.hello._empty?.should be_false
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "selecting methods" do
|
108
|
+
before :each do
|
109
|
+
@rec.this[:is, 2].a(3, 'go').metho[:call].a('yo')
|
110
|
+
@m1, @m2, @m3, @m4, @m5, @m6 = @rec._method_chain
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should select matching only on method" do
|
114
|
+
@rec._select(:[]).should == [@m2, @m5]
|
115
|
+
@rec._select(:a).should == [@m3, @m6]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should select matching on method and args" do
|
119
|
+
@rec._select(:[], [:call]).should == [@m5]
|
120
|
+
@rec._select(:a, ['yo']).should == [@m6]
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper"
|
2
|
+
|
3
|
+
describe MethodCall do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@method_call = MethodCall.new(:hello, 4, 'yo')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return the method name" do
|
10
|
+
|
11
|
+
@method_call.method.should == :hello
|
12
|
+
end
|
13
|
+
it "should return the args" do
|
14
|
+
@method_call.args.should == [4, 'yo']
|
15
|
+
end
|
16
|
+
it "should return the block as nil if not given" do
|
17
|
+
@method_call.block.should be_nil
|
18
|
+
end
|
19
|
+
it "should return the block if given" do
|
20
|
+
method_call = MethodCall.new(:hi){ |doobie| puts doobie }
|
21
|
+
method_call.block.should be_kind_of(Proc)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "call_on" do
|
25
|
+
it "should call the method on the passed in object and return the value" do
|
26
|
+
string = 'yoh washup'
|
27
|
+
method_call = MethodCall.new(:gsub, 'h', 'e')
|
28
|
+
method_call.call_on(string).should == 'yoe waseup'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "to array" do
|
33
|
+
it "should return the method and args as an array" do
|
34
|
+
MethodCall.new(:egg, 'cheese', 5).to_a.should == [:egg, 'cheese', 5]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "setter?" do
|
39
|
+
it "should return true for a setter" do
|
40
|
+
MethodCall.new(:doobie=, '4').setter?.should be_true
|
41
|
+
MethodCall.new(:[]=, 2, 3).setter?.should be_true
|
42
|
+
end
|
43
|
+
it "should return false for a getter" do
|
44
|
+
MethodCall.new(:doobie, '4').setter?.should be_false
|
45
|
+
MethodCall.new(:[], 2, 3).setter?.should be_false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "getter?" do
|
50
|
+
it "should be false if setter is true" do
|
51
|
+
@method_call.should_receive(:setter?).and_return true
|
52
|
+
@method_call.getter?.should be_false
|
53
|
+
end
|
54
|
+
it "should be true if setter is false" do
|
55
|
+
@method_call.should_receive(:setter?).and_return false
|
56
|
+
@method_call.getter?.should be_true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "duplication" do
|
61
|
+
before(:each) do
|
62
|
+
@mc1 = MethodCall.new(:[], 3)
|
63
|
+
@mc2 = @mc1.deep_dup
|
64
|
+
end
|
65
|
+
it "should be able to duplicate itself" do
|
66
|
+
@mc2.should be_instance_of(MethodCall)
|
67
|
+
end
|
68
|
+
it "should deep clone its method" do
|
69
|
+
@mc2.send(:method=, :hi)
|
70
|
+
@mc2.method.should == :hi # Just to check
|
71
|
+
@mc1.method.should == :[]
|
72
|
+
end
|
73
|
+
it "should deep clone its args" do
|
74
|
+
@mc2.args << :gog
|
75
|
+
@mc2.args.should == [3, :gog] # Just to check
|
76
|
+
@mc1.args.should == [3]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "making methods into setters" do
|
81
|
+
|
82
|
+
it "should turn [] into a setter" do
|
83
|
+
MethodCall.new(:[], 3).to_setter('hello').to_a.should == [:[]=, 3, 'hello']
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should leave []= as it is but assign new value" do
|
87
|
+
MethodCall.new(:[]=, 3, 5).to_setter('hello').to_a.should == [:[]=, 3, 'hello']
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should turn an arbitrary method call into a setter by adding the value at the end of the args" do
|
91
|
+
MethodCall.new(:hello, 'there').to_setter(65).to_a.should == [:hello=, 'there', 65]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should not change an arbitrary method which is already a setter but assign a new value" do
|
95
|
+
MethodCall.new(:hello=, 'there').to_setter(65).to_a.should == [:hello=, 65]
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should not change itself" do
|
99
|
+
method_call = MethodCall.new(:[], 3)
|
100
|
+
setter = method_call.to_setter('yo')
|
101
|
+
method_call.to_a.should == [:[], 3]
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "getting the type" do
|
107
|
+
it "should detect hash readers" do
|
108
|
+
MethodCall.new(:[], 'there').type.should == :hash_reader
|
109
|
+
end
|
110
|
+
it "should detect hash writers" do
|
111
|
+
MethodCall.new(:[]=, 'there', 4).type.should == :hash_writer
|
112
|
+
end
|
113
|
+
it "should detect array readers" do
|
114
|
+
MethodCall.new(:[], 7).type.should == :array_reader
|
115
|
+
end
|
116
|
+
it "should detect array writer" do
|
117
|
+
MethodCall.new(:[]=, 3, 5).type.should == :array_writer
|
118
|
+
end
|
119
|
+
it "should detect getters" do
|
120
|
+
MethodCall.new(:undre).type.should == :attr_reader
|
121
|
+
end
|
122
|
+
it "should detect setters" do
|
123
|
+
MethodCall.new(:bob=, 'there').type.should == :attr_writer
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "comparing with other method calls" do
|
129
|
+
it "should return as equal if both have same method and args" do
|
130
|
+
MethodCall.new(:yes, 'sadf', :ue, 4).should == MethodCall.new(:yes, 'sadf', :ue, 4)
|
131
|
+
end
|
132
|
+
it "should return as not equal if same method but different args" do
|
133
|
+
MethodCall.new(:yes, 'sadf', 4).should_not == MethodCall.new(:yes, 'sadf', :ue, 4)
|
134
|
+
end
|
135
|
+
it "should return as not equal if same args but different method" do
|
136
|
+
MethodCall.new(:yes, 'sadf', :ue, 4).should_not == MethodCall.new(:no, 'sadf', :ue, 4)
|
137
|
+
end
|
138
|
+
it "should return as not equal if different method and args" do
|
139
|
+
MethodCall.new(:yes, 'sadf', :ue, 4).should_not == MethodCall.new(:no, 3, 5, 'sdf')
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "guessing receiver type for square brackets calls" do
|
144
|
+
|
145
|
+
[:hello, 'hello', 4.3].each do |key|
|
146
|
+
it "should return Hash if key is #{key.inspect}" do
|
147
|
+
MethodCall.new(:[],:hello).guess_receiver_type.should == Hash
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should return Array if key is an integer" do
|
152
|
+
MethodCall.new(:[],4).guess_receiver_type.should == Array
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should return nil if it can't guess" do
|
156
|
+
MethodCall.new(:yo_man, 'diggerdy').guess_receiver_type.should be_nil
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: markevans-method_call_recorder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Evans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-04 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: mark@new-bamboo.co.uk
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.markdown
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.markdown
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- lib/method_call_recorder.rb
|
33
|
+
- lib/method_call_recorder/method_call.rb
|
34
|
+
- lib/method_call_recorder/method_call_recorder.rb
|
35
|
+
- method_call_recorder.gemspec
|
36
|
+
- spec/method_call_recorder_spec.rb
|
37
|
+
- spec/method_call_spec.rb
|
38
|
+
- spec/spec_helper.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/markevans/method_call_recorder
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.2.0
|
62
|
+
signing_key:
|
63
|
+
specification_version: 2
|
64
|
+
summary: An object on which you can call anything, where nothing happens, but the whole method chain is recorded
|
65
|
+
test_files:
|
66
|
+
- spec/method_call_recorder_spec.rb
|
67
|
+
- spec/method_call_spec.rb
|
68
|
+
- spec/spec_helper.rb
|