mocha 0.14.0 → 1.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +28 -8
  3. data/RELEASE.md +40 -0
  4. data/bin/build-matrix +71 -0
  5. data/lib/mocha.rb +0 -7
  6. data/lib/mocha/any_instance_method.rb +2 -2
  7. data/lib/mocha/class_method.rb +5 -2
  8. data/lib/mocha/detection/mini_test.rb +25 -0
  9. data/lib/mocha/detection/test_unit.rb +29 -0
  10. data/lib/mocha/expectation_list.rb +6 -2
  11. data/lib/mocha/integration.rb +2 -2
  12. data/lib/mocha/integration/mini_test.rb +6 -11
  13. data/lib/mocha/integration/test_unit.rb +4 -9
  14. data/lib/mocha/mini_test.rb +3 -0
  15. data/lib/mocha/mock.rb +73 -8
  16. data/lib/mocha/mockery.rb +3 -2
  17. data/lib/mocha/object_methods.rb +4 -2
  18. data/lib/mocha/parameter_matchers/responds_with.rb +1 -1
  19. data/lib/mocha/receivers.rb +49 -0
  20. data/lib/mocha/setup.rb +0 -1
  21. data/lib/mocha/test_unit.rb +3 -0
  22. data/lib/mocha/unexpected_invocation.rb +10 -5
  23. data/lib/mocha/version.rb +1 -1
  24. data/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb +34 -0
  25. data/test/acceptance/stub_any_instance_method_test.rb +1 -0
  26. data/test/acceptance/stub_class_method_defined_on_class_test.rb +3 -0
  27. data/test/acceptance/stub_class_method_defined_on_superclass_test.rb +40 -3
  28. data/test/acceptance/stub_instance_method_defined_on_class_test.rb +3 -0
  29. data/test/acceptance/unexpected_invocation_test.rb +25 -0
  30. data/test/assertions.rb +6 -0
  31. data/test/integration/mini_test_test.rb +4 -18
  32. data/test/integration/test_unit_test.rb +2 -3
  33. data/test/test_helper.rb +6 -2
  34. data/test/test_runner.rb +22 -18
  35. data/test/unit/expectation_list_test.rb +11 -0
  36. data/test/unit/parameter_matchers/responds_with_test.rb +7 -0
  37. data/test/unit/receivers_test.rb +66 -0
  38. data/yard-templates/default/layout/html/google_analytics.erb +9 -9
  39. metadata +93 -109
  40. data/build-matrix.rb +0 -71
@@ -1,6 +1,7 @@
1
1
  require 'mocha/central'
2
2
  require 'mocha/mock'
3
3
  require 'mocha/names'
4
+ require 'mocha/receivers'
4
5
  require 'mocha/state_machine'
5
6
  require 'mocha/logger'
6
7
  require 'mocha/configuration'
@@ -40,11 +41,11 @@ module Mocha
40
41
  end
41
42
 
42
43
  def mock_impersonating(object, &block)
43
- add_mock(Mock.new(self, ImpersonatingName.new(object), &block))
44
+ add_mock(Mock.new(self, ImpersonatingName.new(object), ObjectReceiver.new(object), &block))
44
45
  end
45
46
 
46
47
  def mock_impersonating_any_instance_of(klass, &block)
47
- add_mock(Mock.new(self, ImpersonatingAnyInstanceName.new(klass), &block))
48
+ add_mock(Mock.new(self, ImpersonatingAnyInstanceName.new(klass), AnyInstanceReceiver.new(klass), &block))
48
49
  end
49
50
 
50
51
  def new_state_machine(name)
@@ -35,7 +35,7 @@ module Mocha
35
35
 
36
36
  # Adds an expectation that the specified method must be called exactly once with any parameters.
37
37
  #
38
- # The original implementation of the method is replaced during the test and then restored at the end of the test.
38
+ # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibilty as the original method.
39
39
  #
40
40
  # @param [Symbol,String] method_name name of expected method
41
41
  # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times.
@@ -84,6 +84,8 @@ module Mocha
84
84
 
85
85
  # Adds an expectation that the specified method may be called any number of times with any parameters.
86
86
  #
87
+ # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibilty as the original method.
88
+ #
87
89
  # @param [Symbol,String] method_name name of stubbed method
88
90
  # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times.
89
91
  #
@@ -128,7 +130,7 @@ module Mocha
128
130
 
129
131
  # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them.
130
132
  #
131
- # Restores the original behaviour of the methods before they were stubbed.
133
+ # Restores the original behaviour of the methods before they were stubbed. This is normally done automatically at the end of each test, but in some circumstances you may want to do it *before* the end of the test.
132
134
  #
133
135
  # WARNING: If you {#unstub} a method which still has unsatisfied expectations, you may be removing the only way those expectations can be satisfied. Use {#unstub} with care.
134
136
  #
@@ -39,7 +39,7 @@ module Mocha
39
39
  # @private
40
40
  def matches?(available_parameters)
41
41
  parameter = available_parameters.shift
42
- parameter.__send__(@message) == @result
42
+ @result.to_matcher.matches?( [parameter.__send__(@message)] )
43
43
  end
44
44
 
45
45
  # @private
@@ -0,0 +1,49 @@
1
+ module Mocha
2
+
3
+ class ObjectReceiver
4
+
5
+ def initialize(object)
6
+ @object = object
7
+ end
8
+
9
+ def mocks
10
+ object, mocks = @object, []
11
+ while object do
12
+ mocks << object.mocha
13
+ object = object.is_a?(Class) ? object.superclass : nil
14
+ end
15
+ mocks
16
+ end
17
+
18
+ end
19
+
20
+ class AnyInstanceReceiver
21
+
22
+ def initialize(klass)
23
+ @klass = klass
24
+ end
25
+
26
+ def mocks
27
+ klass, mocks = @klass, []
28
+ while klass do
29
+ mocks << klass.any_instance.mocha
30
+ klass = klass.superclass
31
+ end
32
+ mocks
33
+ end
34
+
35
+ end
36
+
37
+ class DefaultReceiver
38
+
39
+ def initialize(mock)
40
+ @mock = mock
41
+ end
42
+
43
+ def mocks
44
+ [@mock]
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -1,4 +1,3 @@
1
- require 'mocha/version'
2
1
  require 'mocha/integration'
3
2
 
4
3
  module Mocha
@@ -0,0 +1,3 @@
1
+ require "mocha/integration/test_unit"
2
+
3
+ Mocha::Integration::TestUnit.activate
@@ -5,17 +5,22 @@ module Mocha
5
5
 
6
6
  # @private
7
7
  def initialize(mock, symbol, *arguments)
8
- @mock = mock
9
- @method_matcher = MethodMatcher.new(symbol)
10
- @parameters_matcher = ParametersMatcher.new(arguments)
8
+ @mock, @symbol, @arguments = mock, symbol, arguments
11
9
  end
12
10
 
13
11
  # @private
14
- def to_s
15
- method_signature = "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"
12
+ def full_description
13
+ method_matcher = MethodMatcher.new(@symbol)
14
+ parameters_matcher = ParametersMatcher.new(@arguments)
15
+ method_signature = "#{@mock.mocha_inspect}.#{method_matcher.mocha_inspect}#{parameters_matcher.mocha_inspect}"
16
16
  "unexpected invocation: #{method_signature}\n"
17
17
  end
18
18
 
19
+ # @private
20
+ def short_description
21
+ "unexpected invocation: #{@symbol}(#{@arguments.join(', ')})"
22
+ end
23
+
19
24
  end
20
25
 
21
26
  end
@@ -1,3 +1,3 @@
1
1
  module Mocha
2
- VERSION = "0.14.0"
2
+ VERSION = "1.0.0.alpha"
3
3
  end
@@ -0,0 +1,34 @@
1
+ require File.expand_path('../acceptance_test_helper', __FILE__)
2
+ require 'mocha/setup'
3
+
4
+ class StubAnyInstanceMethodDefinedOnSuperclassTest < Mocha::TestCase
5
+
6
+ include AcceptanceTest
7
+
8
+ def setup
9
+ setup_acceptance_test
10
+ end
11
+
12
+ def teardown
13
+ teardown_acceptance_test
14
+ end
15
+
16
+ def test_should_stub_method_and_leave_it_unchanged_after_test
17
+ superklass = Class.new do
18
+ def my_superclass_method
19
+ :original_return_value
20
+ end
21
+ public :my_superclass_method
22
+ end
23
+ klass = Class.new(superklass)
24
+ instance = klass.new
25
+ assert_snapshot_unchanged(instance) do
26
+ test_result = run_as_test do
27
+ superklass.any_instance.stubs(:my_superclass_method).returns(:new_return_value)
28
+ assert_equal :new_return_value, instance.my_superclass_method
29
+ end
30
+ assert_passed(test_result)
31
+ end
32
+ assert_equal :original_return_value, instance.my_superclass_method
33
+ end
34
+ end
@@ -22,6 +22,7 @@ class StubAnyInstanceMethodTest < Mocha::TestCase
22
22
  instance = klass.new
23
23
  test_result = run_as_test do
24
24
  klass.any_instance.stubs(:my_instance_method).returns(:new_return_value)
25
+ assert_method_visiblity instance, :my_instance_method, :public
25
26
  assert_equal :new_return_value, instance.my_instance_method
26
27
  end
27
28
  assert_passed(test_result)
@@ -26,6 +26,7 @@ class StubClassMethodDefinedOnClassTest < Mocha::TestCase
26
26
  assert_snapshot_unchanged(klass) do
27
27
  test_result = run_as_test do
28
28
  klass.stubs(:my_class_method).returns(:new_return_value)
29
+ assert_method_visiblity klass, :my_class_method, :public
29
30
  assert_equal :new_return_value, klass.my_class_method
30
31
  end
31
32
  assert_passed(test_result)
@@ -46,6 +47,7 @@ class StubClassMethodDefinedOnClassTest < Mocha::TestCase
46
47
  assert_snapshot_unchanged(klass) do
47
48
  test_result = run_as_test do
48
49
  klass.stubs(:my_class_method).returns(:new_return_value)
50
+ assert_method_visiblity klass, :my_class_method, :protected
49
51
  assert_equal :new_return_value, klass.send(:my_class_method)
50
52
  end
51
53
  assert_passed(test_result)
@@ -66,6 +68,7 @@ class StubClassMethodDefinedOnClassTest < Mocha::TestCase
66
68
  assert_snapshot_unchanged(klass) do
67
69
  test_result = run_as_test do
68
70
  klass.stubs(:my_class_method).returns(:new_return_value)
71
+ assert_method_visiblity klass, :my_class_method, :private
69
72
  assert_equal :new_return_value, klass.send(:my_class_method)
70
73
  end
71
74
  assert_passed(test_result)
@@ -13,7 +13,7 @@ class StubClassMethodDefinedOnSuperclassTest < Mocha::TestCase
13
13
  teardown_acceptance_test
14
14
  end
15
15
 
16
- def test_should_stub_public_method_and_leave_it_unchanged_after_test
16
+ def test_should_stub_public_method_on_child_class_and_leave_it_unchanged_after_test
17
17
  superklass = Class.new do
18
18
  class << self
19
19
  def my_class_method
@@ -33,7 +33,7 @@ class StubClassMethodDefinedOnSuperclassTest < Mocha::TestCase
33
33
  assert_equal :original_return_value, klass.my_class_method
34
34
  end
35
35
 
36
- def test_should_stub_protected_method_and_leave_it_unchanged_after_test
36
+ def test_should_stub_protected_method_on_child_class_and_leave_it_unchanged_after_test
37
37
  superklass = Class.new do
38
38
  class << self
39
39
  def my_class_method
@@ -53,7 +53,7 @@ class StubClassMethodDefinedOnSuperclassTest < Mocha::TestCase
53
53
  assert_equal :original_return_value, klass.send(:my_class_method)
54
54
  end
55
55
 
56
- def test_should_stub_private_method_and_leave_it_unchanged_after_test
56
+ def test_should_stub_private_method_on_child_class_and_leave_it_unchanged_after_test
57
57
  superklass = Class.new do
58
58
  class << self
59
59
  def my_class_method
@@ -72,4 +72,41 @@ class StubClassMethodDefinedOnSuperclassTest < Mocha::TestCase
72
72
  end
73
73
  assert_equal :original_return_value, klass.send(:my_class_method)
74
74
  end
75
+
76
+ def test_should_stub_method_on_superclass_and_leave_it_unchanged_after_test
77
+ superklass = Class.new do
78
+ class << self
79
+ def my_class_method
80
+ :original_return_value
81
+ end
82
+ public :my_class_method
83
+ end
84
+ end
85
+ klass = Class.new(superklass)
86
+ assert_snapshot_unchanged(klass) do
87
+ test_result = run_as_test do
88
+ superklass.stubs(:my_class_method).returns(:new_return_value)
89
+ assert_equal :new_return_value, klass.my_class_method
90
+ end
91
+ assert_passed(test_result)
92
+ end
93
+ assert_equal :original_return_value, klass.my_class_method
94
+ end
95
+
96
+ def test_stub_on_earliest_receiver_should_take_priority
97
+ superklass = Class.new do
98
+ class << self
99
+ def my_class_method
100
+ :original_return_value
101
+ end
102
+ end
103
+ end
104
+ klass = Class.new(superklass)
105
+ test_result = run_as_test do
106
+ klass.stubs(:my_class_method).returns(:klass_return_value)
107
+ superklass.stubs(:my_class_method).returns(:superklass_return_value)
108
+ assert_equal :klass_return_value, klass.my_class_method
109
+ end
110
+ assert_passed(test_result)
111
+ end
75
112
  end
@@ -23,6 +23,7 @@ class StubInstanceMethodDefinedOnClassTest < Mocha::TestCase
23
23
  assert_snapshot_unchanged(instance) do
24
24
  test_result = run_as_test do
25
25
  instance.stubs(:my_instance_method).returns(:new_return_value)
26
+ assert_method_visiblity instance, :my_instance_method, :public
26
27
  assert_equal :new_return_value, instance.my_instance_method
27
28
  end
28
29
  assert_passed(test_result)
@@ -40,6 +41,7 @@ class StubInstanceMethodDefinedOnClassTest < Mocha::TestCase
40
41
  assert_snapshot_unchanged(instance) do
41
42
  test_result = run_as_test do
42
43
  instance.stubs(:my_instance_method).returns(:new_return_value)
44
+ assert_method_visiblity instance, :my_instance_method, :protected
43
45
  assert_equal :new_return_value, instance.send(:my_instance_method)
44
46
  end
45
47
  assert_passed(test_result)
@@ -57,6 +59,7 @@ class StubInstanceMethodDefinedOnClassTest < Mocha::TestCase
57
59
  assert_snapshot_unchanged(instance) do
58
60
  test_result = run_as_test do
59
61
  instance.stubs(:my_instance_method).returns(:new_return_value)
62
+ assert_method_visiblity instance, :my_instance_method, :private
60
63
  assert_equal :new_return_value, instance.send(:my_instance_method)
61
64
  end
62
65
  assert_passed(test_result)
@@ -0,0 +1,25 @@
1
+ require File.expand_path('../acceptance_test_helper', __FILE__)
2
+ require 'mocha/setup'
3
+
4
+ class UnexpectedInvocationTest < Mocha::TestCase
5
+
6
+ include AcceptanceTest
7
+
8
+ def setup
9
+ setup_acceptance_test
10
+ end
11
+
12
+ def teardown
13
+ teardown_acceptance_test
14
+ end
15
+
16
+ def test_avoid_recursion_when_unexpected_invocation_exception_message_depends_on_uninspectable_object
17
+ test_result = run_as_test do
18
+ instance = Class.new.new
19
+ instance.expects(:inspect).never
20
+ instance.inspect(1, 2, 'foo')
21
+ end
22
+ assert_failed(test_result)
23
+ assert_equal "unexpected invocation: inspect(1, 2, foo)", test_result.failure_message_lines[0]
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ module Assertions
2
+ def assert_method_visiblity(object, method_name, visiblity)
3
+ method_key = RUBY_VERSION < '1.9' ? method_name.to_s : method_name.to_sym
4
+ assert object.send("#{visiblity}_methods", false).include?(method_key)
5
+ end
6
+ end
@@ -1,22 +1,8 @@
1
1
  require File.expand_path('../../test_helper', __FILE__)
2
2
 
3
- begin
4
- require "minitest"
5
- rescue LoadError
6
- end
7
- begin
8
- require "minitest/unit"
9
- rescue LoadError
10
- end
11
-
12
- require "mocha/setup"
3
+ require "mocha/mini_test"
13
4
  require "integration/shared_tests"
14
5
 
15
- if defined?(::Minitest) || defined?(MiniTest)
16
- testcase = defined?(Minitest::Test) ? Minitest::Test : MiniTest::Unit::TestCase
17
- class MiniTestTest < testcase
18
- include SharedTests
19
- end
20
- else
21
- puts "MiniTest not available - no point in running tests."
22
- end
6
+ class MiniTestTest < Mocha::TestCase
7
+ include SharedTests
8
+ end
@@ -1,9 +1,8 @@
1
1
  require File.expand_path('../../test_helper', __FILE__)
2
2
 
3
- require "test/unit"
4
- require "mocha/setup"
3
+ require "mocha/test_unit"
5
4
  require "integration/shared_tests"
6
5
 
7
- class TestUnitTest < Test::Unit::TestCase
6
+ class TestUnitTest < Mocha::TestCase
8
7
  include SharedTests
9
8
  end
@@ -8,6 +8,8 @@ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit'))
8
8
  $:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit', 'parameter_matchers'))
9
9
  $:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'acceptance'))
10
10
 
11
+ require 'mocha/detection/mini_test'
12
+
11
13
  begin
12
14
  require 'minitest'
13
15
  rescue LoadError
@@ -17,13 +19,15 @@ begin
17
19
  rescue LoadError
18
20
  end
19
21
 
20
- if defined?(::Minitest) || defined?(MiniTest)
22
+ module Mocha; end
23
+
24
+ if (minitest_testcase = Mocha::Detection::MiniTest.testcase) && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit')
21
25
  begin
22
26
  require 'minitest/autorun'
23
27
  rescue LoadError
24
28
  MiniTest::Unit.autorun
25
29
  end
26
- class Mocha::TestCase < defined?(Minitest::Test) ? Minitest::Test : MiniTest::Unit::TestCase
30
+ class Mocha::TestCase < minitest_testcase
27
31
  def assert_nothing_raised(exception = StandardError)
28
32
  yield
29
33
  rescue exception => e
@@ -1,10 +1,6 @@
1
- if defined?(::Minitest::VERSION) && (Gem::Version.new(::Minitest::VERSION) >= Gem::Version.new('5.0.0'))
2
- require File.expand_path('../minitest_result', __FILE__)
3
- elsif defined?(::MiniTest::Unit::VERSION) && (Gem::Version.new(::MiniTest::Unit::VERSION) < Gem::Version.new('5.0.0'))
4
- require File.expand_path('../mini_test_result', __FILE__)
5
- else
6
- require File.expand_path('../test_unit_result', __FILE__)
7
- end
1
+ require 'assertions'
2
+
3
+ require 'mocha/detection/mini_test'
8
4
 
9
5
  module TestRunner
10
6
  def run_as_test(&block)
@@ -14,6 +10,8 @@ module TestRunner
14
10
  def run_as_tests(methods = {})
15
11
  base_class = Mocha::TestCase
16
12
  test_class = Class.new(base_class) do
13
+ include Assertions
14
+
17
15
  methods.each do |(method_name, proc)|
18
16
  define_method(method_name, proc)
19
17
  end
@@ -21,19 +19,25 @@ module TestRunner
21
19
 
22
20
  tests = methods.keys.select { |m| m.to_s[/^test/] }.map { |m| test_class.new(m) }
23
21
 
24
- if defined?(::Minitest::VERSION) && (Gem::Version.new(::Minitest::VERSION) >= Gem::Version.new('5.0.0'))
25
- tests.each do |test|
26
- test.run
27
- end
28
- Minitest::Runnable.runnables.delete(test_class)
29
- test_result = MinitestResult.new(tests)
30
- elsif defined?(::MiniTest::Unit::VERSION) && (Gem::Version.new(::MiniTest::Unit::VERSION) < Gem::Version.new('5.0.0'))
31
- runner = MiniTest::Unit.new
32
- tests.each do |test|
33
- test.run(runner)
22
+ if Mocha::Detection::MiniTest.testcase && (ENV['MOCHA_RUN_INTEGRATION_TESTS'] != 'test-unit')
23
+ minitest_version = Gem::Version.new(Mocha::Detection::MiniTest.version)
24
+ if Gem::Requirement.new('>= 5.0.0').satisfied_by?(minitest_version)
25
+ require File.expand_path('../minitest_result', __FILE__)
26
+ tests.each do |test|
27
+ test.run
28
+ end
29
+ Minitest::Runnable.runnables.delete(test_class)
30
+ test_result = MinitestResult.new(tests)
31
+ elsif Gem::Requirement.new('> 0.0.0', '< 5.0.0').satisfied_by?(minitest_version)
32
+ require File.expand_path('../mini_test_result', __FILE__)
33
+ runner = MiniTest::Unit.new
34
+ tests.each do |test|
35
+ test.run(runner)
36
+ end
37
+ test_result = MiniTestResult.new(runner, tests)
34
38
  end
35
- test_result = MiniTestResult.new(runner, tests)
36
39
  else
40
+ require File.expand_path('../test_unit_result', __FILE__)
37
41
  test_result = TestUnitResult.build_test_result
38
42
  tests.each do |test|
39
43
  test.run(test_result) {}