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.
Files changed (53) hide show
  1. data/README.rdoc +325 -177
  2. data/Rakefile +22 -8
  3. data/TAGS +772 -669
  4. data/doc/releases/flexmock-1.0.0.rdoc +128 -0
  5. data/lib/flexmock.rb +1 -1
  6. data/lib/flexmock/argument_matchers.rb +16 -3
  7. data/lib/flexmock/argument_matching.rb +33 -0
  8. data/lib/flexmock/argument_types.rb +5 -1
  9. data/lib/flexmock/base.rb +1 -1
  10. data/lib/flexmock/composite.rb +3 -3
  11. data/lib/flexmock/core.rb +32 -2
  12. data/lib/flexmock/core_class_methods.rb +1 -1
  13. data/lib/flexmock/default_framework_adapter.rb +1 -1
  14. data/lib/flexmock/deprecated_methods.rb +1 -1
  15. data/lib/flexmock/errors.rb +1 -1
  16. data/lib/flexmock/expectation.rb +15 -13
  17. data/lib/flexmock/expectation_director.rb +1 -1
  18. data/lib/flexmock/explicit_needed.rb +39 -0
  19. data/lib/flexmock/mock_container.rb +8 -2
  20. data/lib/flexmock/noop.rb +1 -1
  21. data/lib/flexmock/ordering.rb +1 -1
  22. data/lib/flexmock/partial_mock.rb +12 -2
  23. data/lib/flexmock/rails.rb +1 -1
  24. data/lib/flexmock/recorder.rb +1 -1
  25. data/lib/flexmock/rspec.rb +5 -1
  26. data/lib/flexmock/rspec_spy_matcher.rb +74 -0
  27. data/lib/flexmock/spy_describers.rb +60 -0
  28. data/lib/flexmock/test_unit.rb +1 -1
  29. data/lib/flexmock/test_unit_assert_spy_called.rb +34 -0
  30. data/lib/flexmock/test_unit_integration.rb +3 -1
  31. data/lib/flexmock/undefined.rb +1 -1
  32. data/lib/flexmock/validators.rb +1 -1
  33. data/lib/flexmock/version.rb +4 -2
  34. data/test/assert_spy_called_test.rb +89 -0
  35. data/test/container_methods_test.rb +1 -1
  36. data/test/default_framework_adapter_test.rb +1 -1
  37. data/test/deprecated_methods_test.rb +1 -1
  38. data/test/examples_from_readme_test.rb +1 -1
  39. data/test/extended_should_receive_test.rb +1 -1
  40. data/test/naming_test.rb +1 -2
  41. data/test/new_instances_test.rb +1 -3
  42. data/test/partial_mock_test.rb +7 -1
  43. data/test/record_mode_test.rb +1 -1
  44. data/test/rspec_integration/integration_spec.rb +11 -3
  45. data/test/rspec_integration/spy_example_spec.rb +141 -0
  46. data/test/samples_test.rb +1 -1
  47. data/test/should_ignore_missing_test.rb +6 -2
  48. data/test/should_receive_test.rb +31 -2
  49. data/test/spys_test.rb +148 -0
  50. data/test/test_unit_integration/auto_test_unit_test.rb +1 -1
  51. data/test/tu_integration_test.rb +1 -1
  52. data/test/undefined_test.rb +1 -1
  53. metadata +16 -8
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -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-2011 by Jim Weirich (jim@weirichhouse.org).
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim.weirich@gmail.com).
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -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-2011 by Jim Weirich (jim@weirichhouse.org).
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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  #---
4
- # Copyright 2003-2011 by Jim Weirich (jim@weirichhouse.org).
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,
@@ -1,9 +1,11 @@
1
1
  class FlexMock
2
2
  module Version
3
3
  NUMBERS = [
4
- MAJOR = 0,
5
- MINOR = 9,
4
+ MAJOR = 1,
5
+ MINOR = 0,
6
6
  BUILD = 0,
7
+ BETA = 'beta',
8
+ REV = 1,
7
9
  ]
8
10
  end
9
11
 
@@ -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