aidmock 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/.gitignore +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +28 -0
- data/README.textile +5 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/aidmock.gemspec +71 -0
- data/examples/mock_spec.rb +50 -0
- data/lib/aidmock/basic_object.rb +25 -0
- data/lib/aidmock/errors.rb +7 -0
- data/lib/aidmock/frameworks/rspec.rb +158 -0
- data/lib/aidmock/frameworks.rb +27 -0
- data/lib/aidmock/interface.rb +57 -0
- data/lib/aidmock/matchers.rb +181 -0
- data/lib/aidmock/method_descriptor.rb +136 -0
- data/lib/aidmock/sanity.rb +79 -0
- data/lib/aidmock/void_class.rb +27 -0
- data/lib/aidmock.rb +105 -0
- data/spec/aidmock/frameworks/rspec_spec.rb +212 -0
- data/spec/aidmock/interface_spec.rb +66 -0
- data/spec/aidmock/matchers_spec.rb +237 -0
- data/spec/aidmock/method_descriptor_spec.rb +205 -0
- data/spec/aidmock/sanity_spec.rb +119 -0
- data/spec/aidmock_spec.rb +124 -0
- data/spec/spec_helper.rb +57 -0
- metadata +95 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
# Copyright (c) 2011 Wilker Lúcio
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Aidmock
|
22
|
+
class MethodDescriptor
|
23
|
+
attr_accessor :name, :type, :arguments, :class_method
|
24
|
+
alias :class_method? :class_method
|
25
|
+
|
26
|
+
def initialize(name, type, *arguments)
|
27
|
+
@name = name
|
28
|
+
@type = ::Aidmock::Matchers.create(type)
|
29
|
+
@arguments = arguments.map { |arg| ::Aidmock::Matchers.create(arg) }
|
30
|
+
@class_method = false
|
31
|
+
end
|
32
|
+
|
33
|
+
def verify(double)
|
34
|
+
verify_arguments(double)
|
35
|
+
verify_return(double)
|
36
|
+
end
|
37
|
+
|
38
|
+
def verify_arguments(double)
|
39
|
+
arguments = double.arguments
|
40
|
+
check_method_arity!(double)
|
41
|
+
current_matcher = 0
|
42
|
+
|
43
|
+
while arguments.length > 0
|
44
|
+
matcher = @arguments[current_matcher]
|
45
|
+
|
46
|
+
if matcher.instance_of? ::Aidmock::Matchers::SplatArgMatcher
|
47
|
+
arg = arguments
|
48
|
+
arguments = []
|
49
|
+
else
|
50
|
+
arg = arguments.shift
|
51
|
+
end
|
52
|
+
|
53
|
+
unless matcher.match?(arg)
|
54
|
+
raise Aidmock::MethodInterfaceArgumentsNotMatchError.new("argument value #{arg.inspect} doesn't match with #{matcher.inspect}")
|
55
|
+
end
|
56
|
+
|
57
|
+
current_matcher += 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def verify_return(double)
|
62
|
+
double.result.each do |value|
|
63
|
+
unless @type.match?(value)
|
64
|
+
raise Aidmock::MethodInterfaceReturnNotMatchError.new("Return value #{value.inspect} doesn't match with #{@type.inspect}")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def arity
|
70
|
+
@arity ||= begin
|
71
|
+
arity = 0
|
72
|
+
|
73
|
+
@arguments.each do |arg|
|
74
|
+
arity += 1
|
75
|
+
|
76
|
+
if optional_arg? arg
|
77
|
+
arity *= -1
|
78
|
+
return arity
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
arity
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def required_arity
|
87
|
+
@required_arity = begin
|
88
|
+
required = arity
|
89
|
+
|
90
|
+
if required < 0
|
91
|
+
required *= -1
|
92
|
+
required -= 1
|
93
|
+
end
|
94
|
+
|
95
|
+
required
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def max_number_of_arguments
|
100
|
+
return nil if has_a_splat?
|
101
|
+
|
102
|
+
@arguments.length
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
|
107
|
+
def check_method_arity!(double)
|
108
|
+
length = double.arguments.length
|
109
|
+
# in case of positive arity (fixed number of arguments)
|
110
|
+
if arity >= 0
|
111
|
+
if length != arity
|
112
|
+
raise Aidmock::MethodInterfaceArgumentsNotMatchError.new("error on mock method #{double.method.inspect}, expected #{arity} arguments, #{length} sent")
|
113
|
+
end
|
114
|
+
# on negative arity (variable number of arguments)
|
115
|
+
else
|
116
|
+
if length < required_arity
|
117
|
+
raise Aidmock::MethodInterfaceArgumentsNotMatchError.new("error on mock method #{double.method.inspect}, expected at least #{required_arity}, #{length} sent")
|
118
|
+
end
|
119
|
+
|
120
|
+
if max = max_number_of_arguments
|
121
|
+
if length > max
|
122
|
+
raise Aidmock::MethodInterfaceArgumentsNotMatchError.new("error on mock method #{double.method.inspect}, expected at most #{max}, #{length} sent")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def has_a_splat?
|
129
|
+
@arguments.last.instance_of? ::Aidmock::Matchers::SplatArgMatcher
|
130
|
+
end
|
131
|
+
|
132
|
+
def optional_arg?(arg)
|
133
|
+
arg.instance_of? Matchers::OptionalArgMatcher or arg.instance_of? Matchers::SplatArgMatcher
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright (c) 2011 Wilker Lúcio
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Aidmock
|
22
|
+
module Sanity
|
23
|
+
class << self
|
24
|
+
def sanitize
|
25
|
+
describe "Aidmock Sanity Checks:" do
|
26
|
+
Aidmock.interfaces.each_pair do |klass, interface|
|
27
|
+
context klass.to_s do
|
28
|
+
(interface.methods + interface.class_methods).each do |method|
|
29
|
+
it "have implemented interface for #{method.name}" do
|
30
|
+
Aidmock::Sanity.sanitize_method(interface.klass, method)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def sanitize_interfaces
|
39
|
+
Aidmock.interfaces.each_pair do |klass, interface|
|
40
|
+
sanitize_interface(interface)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def sanitize_interface(interface)
|
45
|
+
(interface.methods + interface.class_methods).each do |method|
|
46
|
+
sanitize_method(interface.klass, method)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def sanitize_method(klass, method)
|
51
|
+
verify_method_defined(klass, method)
|
52
|
+
verify_method_arity(klass, method)
|
53
|
+
end
|
54
|
+
|
55
|
+
def verify_method_defined(klass, method)
|
56
|
+
return if method.name.instance_of? Regexp
|
57
|
+
object = method.class_method? ? klass : klass.allocate
|
58
|
+
|
59
|
+
unless object.respond_to? method.name
|
60
|
+
raise "Aidmock Sanity: method '#{method.name}' is not defined for #{klass}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def verify_method_arity(klass, method)
|
65
|
+
return if method.name.instance_of? Regexp
|
66
|
+
object = method.class_method? ? klass : klass.allocate
|
67
|
+
defined_method = object.method(method.name)
|
68
|
+
|
69
|
+
unless method.arity == defined_method.arity
|
70
|
+
raise "Aidmock Sanity: method '#{method.name}' of #{klass} mismatch interface arity, #{defined_method.arity} for #{method.arity}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (c) 2011 Wilker Lúcio
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Aidmock
|
22
|
+
class VoidClass < BasicObject
|
23
|
+
def method_missing(name, *args, &block)
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/aidmock.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Copyright (c) 2011 Wilker Lúcio
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'aidmock/errors'
|
22
|
+
require 'aidmock/basic_object' unless Kernel.const_defined? :BasicObject
|
23
|
+
|
24
|
+
module Aidmock
|
25
|
+
autoload :Interface, 'aidmock/interface'
|
26
|
+
autoload :MethodDescriptor, 'aidmock/method_descriptor'
|
27
|
+
autoload :VoidClass, 'aidmock/void_class'
|
28
|
+
autoload :Frameworks, 'aidmock/frameworks'
|
29
|
+
autoload :Matchers, 'aidmock/matchers'
|
30
|
+
autoload :Sanity, 'aidmock/sanity'
|
31
|
+
|
32
|
+
class << self
|
33
|
+
attr_accessor :warn_undefined_interface
|
34
|
+
alias :warn_undefined_interface? :warn_undefined_interface
|
35
|
+
|
36
|
+
def interface(klass, &block)
|
37
|
+
interfaces[klass] = create_or_update_interface(klass, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def stub(klass, stubs = {})
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify
|
44
|
+
framework.mocks.each do |mock|
|
45
|
+
verify_double(mock)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def interfaces
|
50
|
+
@interfaces ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def verify_double(double)
|
56
|
+
klass = extract_class(double.object)
|
57
|
+
chain = chain_for(klass)
|
58
|
+
|
59
|
+
if chain.length > 0
|
60
|
+
verify_double_on_chain(double, chain)
|
61
|
+
else
|
62
|
+
puts "Aidmock Warning: unsafe mocking on class #{klass}, please interface it" if warn_undefined_interface?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def verify_double_on_chain(double, chain)
|
67
|
+
method = find_method_on_chain(double, chain)
|
68
|
+
|
69
|
+
if method
|
70
|
+
method.verify(double)
|
71
|
+
else
|
72
|
+
raise MethodInterfaceNotDefinedError.new(%Q{Aidmock: method "#{double.method}" was not defined for "#{extract_class(double.object)}" interface})
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def find_method_on_chain(double, chain)
|
77
|
+
chain.each do |interface|
|
78
|
+
method = interface.find_method(double)
|
79
|
+
return method if method
|
80
|
+
end
|
81
|
+
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def chain_for(klass)
|
86
|
+
klass.ancestors.select { |k| interfaces[k] }.map { |k| interfaces[k] }
|
87
|
+
end
|
88
|
+
|
89
|
+
def extract_class(object)
|
90
|
+
object.instance_of?(Class) ? object : object.class
|
91
|
+
end
|
92
|
+
|
93
|
+
def framework
|
94
|
+
::Aidmock::Frameworks::RSpec
|
95
|
+
end
|
96
|
+
|
97
|
+
def create_or_update_interface(klass, &block)
|
98
|
+
interface = interfaces[klass] || Interface.new(klass)
|
99
|
+
interface.instance_eval &block
|
100
|
+
interface
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
Aidmock.warn_undefined_interface = true
|
@@ -0,0 +1,212 @@
|
|
1
|
+
# Copyright (c) 2011 Wilker Lúcio
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require File.expand_path("../../../spec_helper", __FILE__)
|
22
|
+
|
23
|
+
class Sample; end;
|
24
|
+
class SampleWithInitializer
|
25
|
+
def initialize(name)
|
26
|
+
@name = name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe Aidmock::Frameworks::RSpec do
|
31
|
+
framework = Aidmock::Frameworks::RSpec
|
32
|
+
|
33
|
+
context ".mocks" do
|
34
|
+
context "caller object" do
|
35
|
+
it "return the object" do
|
36
|
+
obj = Sample.new
|
37
|
+
obj.stub(:some_method)
|
38
|
+
|
39
|
+
framework.mocks[0].object.should == obj
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "method name" do
|
44
|
+
it "return the method name as a symbol" do
|
45
|
+
obj = mock
|
46
|
+
obj.stub(:some_method)
|
47
|
+
|
48
|
+
framework.mocks[0].method.should == :some_method
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "method result" do
|
53
|
+
before :each do
|
54
|
+
@obj = mock
|
55
|
+
end
|
56
|
+
|
57
|
+
it "return an blank array if no return is defined" do
|
58
|
+
@obj.stub(:some_method)
|
59
|
+
framework.should have_mock_result([])
|
60
|
+
end
|
61
|
+
|
62
|
+
it "return an array with the valid argument if one is passed" do
|
63
|
+
@obj.stub(:some_method).and_return("one")
|
64
|
+
framework.should have_mock_result(["one"])
|
65
|
+
end
|
66
|
+
|
67
|
+
it "return an array with all the returns in case of a multiple return" do
|
68
|
+
@obj.stub(:some_method).and_return("one", "two", "three")
|
69
|
+
framework.should have_mock_result(["one", "two", "three"])
|
70
|
+
end
|
71
|
+
|
72
|
+
it "return the value if it's used as a block" do
|
73
|
+
@obj.stub(:some_method) { "value" }
|
74
|
+
framework.should have_mock_result(["value"])
|
75
|
+
end
|
76
|
+
|
77
|
+
it "handles params for return" do
|
78
|
+
@obj.stub(:some_method) { |param| "#{param.haha} messed up"}
|
79
|
+
|
80
|
+
framework.should have_mock_result([" messed up"])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "method arguments" do
|
85
|
+
before :each do
|
86
|
+
@obj = mock
|
87
|
+
end
|
88
|
+
|
89
|
+
it "return empty list if has no arguments" do
|
90
|
+
@obj.stub(:some_method)
|
91
|
+
|
92
|
+
args = framework.mocks[0].arguments
|
93
|
+
framework.mocks[0].arguments.should == []
|
94
|
+
end
|
95
|
+
|
96
|
+
it "return a list of arguments if they exists" do
|
97
|
+
@obj.stub(:some_method).with("hi", "dear")
|
98
|
+
|
99
|
+
framework.mocks[0].arguments.should have(2).items
|
100
|
+
end
|
101
|
+
|
102
|
+
context "any arg matcher" do
|
103
|
+
it "get nil as result" do
|
104
|
+
@obj.stub(:some_method).with(anything)
|
105
|
+
|
106
|
+
framework.should have_mock_arguments([nil])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "no arg matcher" do
|
111
|
+
it "get an empty array" do
|
112
|
+
@obj.stub(:some_method).with(no_args)
|
113
|
+
|
114
|
+
framework.should have_mock_arguments([])
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "boolean matcher" do
|
119
|
+
it "get true as result" do
|
120
|
+
@obj.stub(:some_method).with(boolean)
|
121
|
+
|
122
|
+
framework.should have_mock_arguments([true])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "hash including matcher" do
|
127
|
+
it "get a hash with key set" do
|
128
|
+
@obj.stub(:some_method).with(hash_including(:foo))
|
129
|
+
|
130
|
+
framework.should have_mock_arguments([{:foo => nil}])
|
131
|
+
end
|
132
|
+
|
133
|
+
it "get a hash with key and value set" do
|
134
|
+
@obj.stub(:some_method).with(hash_including(:foo => "bar"))
|
135
|
+
|
136
|
+
framework.should have_mock_arguments([{:foo => "bar"}])
|
137
|
+
end
|
138
|
+
|
139
|
+
it "get a hash with multiple keys and values" do
|
140
|
+
@obj.stub(:some_method).with(hash_including(:foo, :foo2 => "bar"))
|
141
|
+
|
142
|
+
framework.should have_mock_arguments([{:foo => nil, :foo2 => "bar"}])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "hash not including matcher" do
|
147
|
+
it "get a blank hash" do
|
148
|
+
@obj.stub(:some_method).with(hash_not_including(:foo))
|
149
|
+
|
150
|
+
framework.should have_mock_arguments([{}])
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "duck type matcher" do
|
155
|
+
it "get a object that responds to duck methods" do
|
156
|
+
@obj.stub(:some_method).with(duck_type(:foo, :bar))
|
157
|
+
|
158
|
+
result = framework.mocks[0].arguments[0]
|
159
|
+
result.should respond_to(:foo, :bar)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "instance of matcher" do
|
164
|
+
it "get a object that be an instance of that class" do
|
165
|
+
@obj.stub(:some_method).with(instance_of(String))
|
166
|
+
|
167
|
+
result = framework.mocks[0].arguments[0]
|
168
|
+
result.should be_an_instance_of(String)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "get an object even if object needs an initializer" do
|
172
|
+
@obj.stub(:some_method).with(instance_of(SampleWithInitializer))
|
173
|
+
|
174
|
+
result = framework.mocks[0].arguments[0]
|
175
|
+
result.should be_an_instance_of(SampleWithInitializer)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "kind of matcher" do
|
180
|
+
it "get a object that be an instance of that class" do
|
181
|
+
@obj.stub(:some_method).with(kind_of(String))
|
182
|
+
|
183
|
+
result = framework.mocks[0].arguments[0]
|
184
|
+
result.should be_a_kind_of(String)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "get an object even if object needs an initializer" do
|
188
|
+
@obj.stub(:some_method).with(kind_of(SampleWithInitializer))
|
189
|
+
|
190
|
+
result = framework.mocks[0].arguments[0]
|
191
|
+
result.should be_a_kind_of(SampleWithInitializer)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "equality proxy" do
|
196
|
+
it "get given value" do
|
197
|
+
@obj.stub(:some_method).with("foo")
|
198
|
+
|
199
|
+
framework.should have_mock_arguments(["foo"])
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context "regexp matcher" do
|
204
|
+
it "get the regexp" do
|
205
|
+
@obj.stub(:some_method).with(/foo/)
|
206
|
+
|
207
|
+
framework.should have_mock_arguments(["(?-mix:foo)"])
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Copyright (c) 2011 Wilker Lúcio
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
describe Aidmock::Interface do
|
22
|
+
Interface = Aidmock::Interface
|
23
|
+
MockDescriptor = Aidmock::Frameworks::MockDescriptor
|
24
|
+
|
25
|
+
context "finding the method" do
|
26
|
+
it "find the method defined by exact name" do
|
27
|
+
interface = Interface.new(Object)
|
28
|
+
method = interface.method(:some, nil)
|
29
|
+
double = MockDescriptor.new(nil, :some, nil, [])
|
30
|
+
|
31
|
+
interface.find_method(double).should == method
|
32
|
+
end
|
33
|
+
|
34
|
+
it "find the method defined by and regular expression" do
|
35
|
+
interface = Interface.new(Object)
|
36
|
+
method = interface.method(/find_by_.+/, nil)
|
37
|
+
double = MockDescriptor.new(nil, :find_by_name, nil, [])
|
38
|
+
|
39
|
+
interface.find_method(double).should == method
|
40
|
+
end
|
41
|
+
|
42
|
+
it "find method on class" do
|
43
|
+
interface = Interface.new(Object)
|
44
|
+
method = interface.class_method(:some, nil)
|
45
|
+
double = MockDescriptor.new(Object, :some, nil, [])
|
46
|
+
|
47
|
+
interface.find_method(double).should == method
|
48
|
+
end
|
49
|
+
|
50
|
+
it "not find an class method on instance search" do
|
51
|
+
interface = Interface.new(Object)
|
52
|
+
method = interface.class_method(:some, nil)
|
53
|
+
double = MockDescriptor.new(nil, :some, nil, [])
|
54
|
+
|
55
|
+
interface.find_method(double).should == nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "not find an instance method on class search" do
|
59
|
+
interface = Interface.new(Object)
|
60
|
+
method = interface.method(:some, nil)
|
61
|
+
double = MockDescriptor.new(Object, :some, nil, [])
|
62
|
+
|
63
|
+
interface.find_method(double).should == nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|