flexmock 0.9.0 → 1.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +325 -177
- data/Rakefile +22 -8
- data/TAGS +772 -669
- data/doc/releases/flexmock-1.0.0.rdoc +128 -0
- data/lib/flexmock.rb +1 -1
- data/lib/flexmock/argument_matchers.rb +16 -3
- data/lib/flexmock/argument_matching.rb +33 -0
- data/lib/flexmock/argument_types.rb +5 -1
- data/lib/flexmock/base.rb +1 -1
- data/lib/flexmock/composite.rb +3 -3
- data/lib/flexmock/core.rb +32 -2
- data/lib/flexmock/core_class_methods.rb +1 -1
- data/lib/flexmock/default_framework_adapter.rb +1 -1
- data/lib/flexmock/deprecated_methods.rb +1 -1
- data/lib/flexmock/errors.rb +1 -1
- data/lib/flexmock/expectation.rb +15 -13
- data/lib/flexmock/expectation_director.rb +1 -1
- data/lib/flexmock/explicit_needed.rb +39 -0
- data/lib/flexmock/mock_container.rb +8 -2
- data/lib/flexmock/noop.rb +1 -1
- data/lib/flexmock/ordering.rb +1 -1
- data/lib/flexmock/partial_mock.rb +12 -2
- data/lib/flexmock/rails.rb +1 -1
- data/lib/flexmock/recorder.rb +1 -1
- data/lib/flexmock/rspec.rb +5 -1
- data/lib/flexmock/rspec_spy_matcher.rb +74 -0
- data/lib/flexmock/spy_describers.rb +60 -0
- data/lib/flexmock/test_unit.rb +1 -1
- data/lib/flexmock/test_unit_assert_spy_called.rb +34 -0
- data/lib/flexmock/test_unit_integration.rb +3 -1
- data/lib/flexmock/undefined.rb +1 -1
- data/lib/flexmock/validators.rb +1 -1
- data/lib/flexmock/version.rb +4 -2
- data/test/assert_spy_called_test.rb +89 -0
- data/test/container_methods_test.rb +1 -1
- data/test/default_framework_adapter_test.rb +1 -1
- data/test/deprecated_methods_test.rb +1 -1
- data/test/examples_from_readme_test.rb +1 -1
- data/test/extended_should_receive_test.rb +1 -1
- data/test/naming_test.rb +1 -2
- data/test/new_instances_test.rb +1 -3
- data/test/partial_mock_test.rb +7 -1
- data/test/record_mode_test.rb +1 -1
- data/test/rspec_integration/integration_spec.rb +11 -3
- data/test/rspec_integration/spy_example_spec.rb +141 -0
- data/test/samples_test.rb +1 -1
- data/test/should_ignore_missing_test.rb +6 -2
- data/test/should_receive_test.rb +31 -2
- data/test/spys_test.rb +148 -0
- data/test/test_unit_integration/auto_test_unit_test.rb +1 -1
- data/test/tu_integration_test.rb +1 -1
- data/test/undefined_test.rb +1 -1
- metadata +16 -8
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
class FlexMock
|
3
|
+
|
4
|
+
# Expectations on mocks with a base class can only be defined on
|
5
|
+
# methods supported by the base class. Attempting to add an stub to
|
6
|
+
# a method not defined on the base class will cause the expectation
|
7
|
+
# to be wrapped in an ExplicitNeeded wrapper. The wrapper will throw
|
8
|
+
# an exception unless the explicit method is immediately called on
|
9
|
+
# the expectation.
|
10
|
+
#
|
11
|
+
class ExplicitNeeded
|
12
|
+
def initialize(expectation, method_name, base_class)
|
13
|
+
@expectation = expectation
|
14
|
+
@explicit = false
|
15
|
+
@method_name = method_name
|
16
|
+
@base_class = base_class
|
17
|
+
end
|
18
|
+
|
19
|
+
def explicit
|
20
|
+
@explicit = true
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def explicit?
|
25
|
+
@explicit
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_missing(sym, *args, &block)
|
29
|
+
if explicit?
|
30
|
+
@expectation.send(sym, *args, &block)
|
31
|
+
else
|
32
|
+
fail NoMethodError, "Cannot stub methods not defined by the base class\n" +
|
33
|
+
" Method: #{@method_name}\n" +
|
34
|
+
" Base Class: #{@base_class}\n" +
|
35
|
+
" (Use explicit to override)"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
#---
|
4
|
-
# Copyright 2003-
|
4
|
+
# Copyright 2003-2012 by Jim Weirich (jim.weirich@gmail.com).
|
5
5
|
# All rights reserved.
|
6
6
|
|
7
7
|
# Permission is granted for use, copying, modification, distribution,
|
@@ -122,6 +122,7 @@ class FlexMock
|
|
122
122
|
domain_obj = nil
|
123
123
|
safe_mode = false
|
124
124
|
model_class = nil
|
125
|
+
base_class = nil
|
125
126
|
while ! args.empty?
|
126
127
|
case args.first
|
127
128
|
when :base, :safe
|
@@ -130,6 +131,10 @@ class FlexMock
|
|
130
131
|
when :model
|
131
132
|
args.shift
|
132
133
|
model_class = args.shift
|
134
|
+
when :on
|
135
|
+
args.shift
|
136
|
+
base_class = args.shift
|
137
|
+
name ||= "#{base_class} Mock"
|
133
138
|
when String, Symbol
|
134
139
|
name = args.shift.to_s
|
135
140
|
when Hash
|
@@ -153,6 +158,7 @@ class FlexMock
|
|
153
158
|
yield(mock) if block_given?
|
154
159
|
flexmock_remember(mock)
|
155
160
|
ContainerHelper.add_model_methods(mock, model_class, id) if model_class
|
161
|
+
mock.flexmock_spies_on(base_class) if base_class
|
156
162
|
result
|
157
163
|
end
|
158
164
|
alias flexstub flexmock
|
@@ -326,7 +332,7 @@ class FlexMock
|
|
326
332
|
end
|
327
333
|
end
|
328
334
|
|
329
|
-
METHOD_NAME_RE = /^([A-Za-z_][A-Za-z0-9_]*[=!?]?|\[\]=?||\*\*|<<|>>|<=>|[
|
335
|
+
METHOD_NAME_RE = /^([A-Za-z_][A-Za-z0-9_]*[=!?]?|\[\]=?||\*\*|<<|>>|<=>|[<>=!]=|[=!]~|===|[-+]@|[-+\*\/%&^|<>~`!])$/
|
330
336
|
|
331
337
|
# Check that all the names in the list are valid method names.
|
332
338
|
def check_method_names(names)
|
data/lib/flexmock/noop.rb
CHANGED
data/lib/flexmock/ordering.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
#---
|
4
|
-
# Copyright 2003-
|
4
|
+
# Copyright 2003-2012 by Jim Weirich (jim.weirich@gmail.com).
|
5
5
|
# All rights reserved.
|
6
6
|
|
7
7
|
# Permission is granted for use, copying, modification, distribution,
|
@@ -33,7 +33,8 @@ class FlexMock
|
|
33
33
|
|
34
34
|
MOCK_METHODS = [
|
35
35
|
:should_receive, :new_instances,
|
36
|
-
:flexmock_get, :flexmock_teardown, :flexmock_verify
|
36
|
+
:flexmock_get, :flexmock_teardown, :flexmock_verify,
|
37
|
+
:flexmock_was_called_with?,
|
37
38
|
]
|
38
39
|
|
39
40
|
# Initialize a PartialMockProxy object.
|
@@ -148,6 +149,10 @@ class FlexMock
|
|
148
149
|
end
|
149
150
|
private :invoke_original
|
150
151
|
|
152
|
+
def flexmock_invoke_original(method, args)
|
153
|
+
invoke_original(method, args)
|
154
|
+
end
|
155
|
+
|
151
156
|
# Verify that the mock has been properly called. After verification,
|
152
157
|
# detach the mocking infrastructure from the existing object.
|
153
158
|
def flexmock_verify
|
@@ -171,6 +176,11 @@ class FlexMock
|
|
171
176
|
@mock.flexmock_container
|
172
177
|
end
|
173
178
|
|
179
|
+
# Forward to the mock
|
180
|
+
def flexmock_was_called_with?(*args)
|
181
|
+
@mock.flexmock_was_called_with?(*args)
|
182
|
+
end
|
183
|
+
|
174
184
|
# Set the proxy's mock container. This set value is ignored
|
175
185
|
# because the proxy always uses the container of its mock.
|
176
186
|
def flexmock_container=(container)
|
data/lib/flexmock/rails.rb
CHANGED
data/lib/flexmock/recorder.rb
CHANGED
data/lib/flexmock/rspec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
#---
|
4
|
-
# Copyright 2003-
|
4
|
+
# Copyright 2003-2012 by Jim Weirich (jim.weirich@gmail.com).
|
5
5
|
# All rights reserved.
|
6
6
|
|
7
7
|
# Permission is granted for use, copying, modification, distribution,
|
@@ -9,6 +9,8 @@
|
|
9
9
|
# above copyright notice is included.
|
10
10
|
#+++
|
11
11
|
|
12
|
+
|
13
|
+
|
12
14
|
require 'flexmock/base'
|
13
15
|
|
14
16
|
class FlexMock
|
@@ -36,3 +38,5 @@ class FlexMock
|
|
36
38
|
|
37
39
|
@framework_adapter = RSpecFrameworkAdapter.new
|
38
40
|
end
|
41
|
+
|
42
|
+
require 'flexmock/rspec_spy_matcher'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'flexmock/spy_describers'
|
2
|
+
|
3
|
+
class FlexMock
|
4
|
+
module RSpecMatchers
|
5
|
+
|
6
|
+
class HaveReceived
|
7
|
+
include SpyDescribers
|
8
|
+
|
9
|
+
def initialize(method_name)
|
10
|
+
@method_name = method_name
|
11
|
+
@args = nil
|
12
|
+
@block = nil
|
13
|
+
@times = nil
|
14
|
+
@needs_block = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def matches?(spy)
|
18
|
+
@spy = spy
|
19
|
+
@options = {}
|
20
|
+
@options[:times] = @times if @times
|
21
|
+
@options[:with_block] = @needs_block unless @needs_block.nil?
|
22
|
+
@spy.flexmock_was_called_with?(@method_name, @args, @options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def failure_message_for_should
|
26
|
+
describe_spy_expectation(@spy, @method_name, @args, @options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def failure_message_for_should_not
|
30
|
+
describe_spy_negative_expectation(@spy, @method_name, @args, @options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def with(*args)
|
34
|
+
@args = args
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def with_a_block
|
39
|
+
@needs_block = true
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def without_a_block
|
44
|
+
@needs_block = false
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def times(n)
|
49
|
+
@times = n
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def never
|
54
|
+
times(0)
|
55
|
+
end
|
56
|
+
|
57
|
+
def once
|
58
|
+
times(1)
|
59
|
+
end
|
60
|
+
|
61
|
+
def twice
|
62
|
+
times(2)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def have_received(method_name)
|
67
|
+
HaveReceived.new(method_name)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
RSpec::configure do |config|
|
73
|
+
config.include(FlexMock::RSpecMatchers)
|
74
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class FlexMock
|
2
|
+
|
3
|
+
module SpyDescribers
|
4
|
+
def describe_spy_expectation(spy, sym, args, options={})
|
5
|
+
describe(spy, sym, args, options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def describe_spy_negative_expectation(spy, sym, args, options={})
|
9
|
+
describe(spy, sym, args, options, " NOT")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def describe(spy, sym, args, options, not_clause="")
|
15
|
+
result = "expected "
|
16
|
+
result << call_description(sym, args)
|
17
|
+
result << " to#{not_clause} be called on "
|
18
|
+
result << spy.inspect
|
19
|
+
result << times_description(options[:times])
|
20
|
+
result << block_description(options[:with_block])
|
21
|
+
result << "."
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def times_description(times)
|
26
|
+
case times
|
27
|
+
when 0
|
28
|
+
" never"
|
29
|
+
when 1
|
30
|
+
" once"
|
31
|
+
when 2
|
32
|
+
" twice"
|
33
|
+
when nil
|
34
|
+
""
|
35
|
+
else
|
36
|
+
" #{times} times"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def block_description(needs_block)
|
41
|
+
case needs_block
|
42
|
+
when true
|
43
|
+
" with a block"
|
44
|
+
when false
|
45
|
+
" without a block"
|
46
|
+
else
|
47
|
+
""
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def call_description(sym, args)
|
52
|
+
if args
|
53
|
+
"#{sym}(#{args.map { |o| o.inspect }.join(', ')})"
|
54
|
+
else
|
55
|
+
"#{sym}(...)"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/lib/flexmock/test_unit.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'flexmock/spy_describers'
|
2
|
+
|
3
|
+
class FlexMock
|
4
|
+
module TestUnitAssertions
|
5
|
+
include FlexMock::SpyDescribers
|
6
|
+
|
7
|
+
def assert_spy_called(spy, method_name, *args)
|
8
|
+
_assert_spy_called(false, spy, method_name, *args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def assert_spy_not_called(spy, method_name, *args)
|
12
|
+
_assert_spy_called(true, spy, method_name, *args)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def _assert_spy_called(negative, spy, method_name, *args)
|
18
|
+
options = {}
|
19
|
+
if method_name.is_a?(Hash)
|
20
|
+
options = method_name
|
21
|
+
method_name = args.shift
|
22
|
+
end
|
23
|
+
args = nil if args == [:_]
|
24
|
+
bool = spy.flexmock_was_called_with?(method_name, args, options)
|
25
|
+
if negative
|
26
|
+
bool = !bool
|
27
|
+
message = describe_spy_negative_expectation(spy, method_name, args, options)
|
28
|
+
else
|
29
|
+
message = describe_spy_expectation(spy, method_name, args, options)
|
30
|
+
end
|
31
|
+
assert bool, message
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
#---
|
4
|
-
# Copyright 2003-
|
4
|
+
# Copyright 2003-2012 by Jim Weirich (jim.weirich@gmail.com).
|
5
5
|
# All rights reserved.
|
6
6
|
|
7
7
|
# Permission is granted for use, copying, modification, distribution,
|
@@ -11,6 +11,7 @@
|
|
11
11
|
|
12
12
|
require 'test/unit'
|
13
13
|
require 'flexmock/base'
|
14
|
+
require 'flexmock/test_unit_assert_spy_called'
|
14
15
|
|
15
16
|
class FlexMock
|
16
17
|
|
@@ -29,6 +30,7 @@ class FlexMock
|
|
29
30
|
module TestCase
|
30
31
|
include ArgumentTypes
|
31
32
|
include MockContainer
|
33
|
+
include TestUnitAssertions
|
32
34
|
|
33
35
|
# Teardown the test case, verifying any mocks that might have been
|
34
36
|
# defined in this test case.
|
data/lib/flexmock/undefined.rb
CHANGED
data/lib/flexmock/validators.rb
CHANGED
data/lib/flexmock/version.rb
CHANGED
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/test_setup'
|
4
|
+
require 'flexmock/test_unit_assert_spy_called'
|
5
|
+
|
6
|
+
class AssertSpyCalledTest < Test::Unit::TestCase
|
7
|
+
include FlexMock::TestCase
|
8
|
+
|
9
|
+
class FooBar
|
10
|
+
def foo
|
11
|
+
end
|
12
|
+
def bar
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup
|
17
|
+
super
|
18
|
+
@spy = flexmock(:on, FooBar)
|
19
|
+
end
|
20
|
+
|
21
|
+
def spy
|
22
|
+
@spy
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_assert_detects_basic_call
|
26
|
+
spy.foo
|
27
|
+
assert_spy_called spy, :foo
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_assert_detects_basic_call_with_args
|
31
|
+
spy.foo(1,2)
|
32
|
+
assert_spy_called spy, :foo, 1, 2
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_assert_rejects_incorrect_args
|
36
|
+
spy.foo(1,2)
|
37
|
+
messages = assert_fails(/^expected foo\(1, 3\) to be called on <FlexMock:AssertSpyCalledTest::FooBar Mock>/i) do
|
38
|
+
assert_spy_called spy, :foo, 1, 3
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_assert_detects_multiple_calls
|
43
|
+
spy.foo
|
44
|
+
spy.foo
|
45
|
+
spy.foo
|
46
|
+
assert_spy_called spy, {times: 3}, :foo
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_assert_rejects_incorrect_type
|
50
|
+
spy.foo
|
51
|
+
spy.foo
|
52
|
+
assert_fails(/^expected foo\(\) to be called on <FlexMock:AssertSpyCalledTest::FooBar Mock> 3 times/i) do
|
53
|
+
assert_spy_called spy, {times: 3}, :foo
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_assert_detects_blocks
|
58
|
+
spy.foo { }
|
59
|
+
spy.bar
|
60
|
+
assert_spy_called spy, :foo, Proc
|
61
|
+
assert_spy_called spy, :bar
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_assert_detects_any_args
|
65
|
+
spy.foo
|
66
|
+
spy.foo(1)
|
67
|
+
spy.foo("HI")
|
68
|
+
spy.foo("Hello", "World", 10, options: true)
|
69
|
+
assert_spy_called spy, {times: 4}, :foo, :_
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_assert_rejects_bad_count_on_any_args
|
73
|
+
spy.foo
|
74
|
+
assert_fails(/^expected foo\(\.\.\.\) to be called on <FlexMock:AssertSpyCalledTest::FooBar Mock> twice/i) do
|
75
|
+
assert_spy_called spy, {times: 2}, :foo, :_
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def assert_fails(message_pattern)
|
82
|
+
ex = assert_raises(FlexMock.framework_adapter.assertion_failed_error) do
|
83
|
+
yield
|
84
|
+
end
|
85
|
+
assert_match(message_pattern, ex.message)
|
86
|
+
ex
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|