flexmock 0.9.0 → 1.0.0.beta.1
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/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
|