mocha 3.0.0.pre.rc.1 → 3.0.0.pre.rc.2

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. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -37
  3. data/.yardopts +2 -0
  4. data/Gemfile +2 -5
  5. data/RELEASE.md +42 -0
  6. data/Rakefile +39 -19
  7. data/lib/mocha/any_instance_method.rb +4 -4
  8. data/lib/mocha/api.rb +1 -1
  9. data/lib/mocha/class_methods.rb +9 -5
  10. data/lib/mocha/configuration.rb +1 -1
  11. data/lib/mocha/deprecation.rb +1 -1
  12. data/lib/mocha/expectation.rb +2 -2
  13. data/lib/mocha/expectation_list.rb +1 -1
  14. data/lib/mocha/hooks.rb +4 -4
  15. data/lib/mocha/ignoring_warning.rb +20 -0
  16. data/lib/mocha/instance_method.rb +4 -4
  17. data/lib/mocha/integration/minitest/adapter.rb +4 -3
  18. data/lib/mocha/integration/minitest.rb +1 -1
  19. data/lib/mocha/integration/test_unit/adapter.rb +7 -4
  20. data/lib/mocha/integration/test_unit.rb +1 -1
  21. data/lib/mocha/integration.rb +5 -0
  22. data/lib/mocha/mock.rb +8 -4
  23. data/lib/mocha/mockery.rb +20 -12
  24. data/lib/mocha/object_methods.rb +13 -1
  25. data/lib/mocha/parameter_matchers/all_of.rb +24 -22
  26. data/lib/mocha/parameter_matchers/any_of.rb +30 -28
  27. data/lib/mocha/parameter_matchers/any_parameters.rb +22 -20
  28. data/lib/mocha/parameter_matchers/anything.rb +19 -17
  29. data/lib/mocha/parameter_matchers/{base.rb → base_methods.rb} +6 -4
  30. data/lib/mocha/parameter_matchers/equals.rb +25 -23
  31. data/lib/mocha/parameter_matchers/equivalent_uri.rb +28 -24
  32. data/lib/mocha/parameter_matchers/has_entries.rb +25 -23
  33. data/lib/mocha/parameter_matchers/has_entry.rb +66 -66
  34. data/lib/mocha/parameter_matchers/has_key.rb +25 -23
  35. data/lib/mocha/parameter_matchers/has_keys.rb +25 -23
  36. data/lib/mocha/parameter_matchers/has_value.rb +25 -23
  37. data/lib/mocha/parameter_matchers/includes.rb +63 -61
  38. data/lib/mocha/parameter_matchers/instance_methods.rb +2 -2
  39. data/lib/mocha/parameter_matchers/instance_of.rb +25 -23
  40. data/lib/mocha/parameter_matchers/is_a.rb +26 -24
  41. data/lib/mocha/parameter_matchers/kind_of.rb +25 -23
  42. data/lib/mocha/parameter_matchers/not.rb +25 -23
  43. data/lib/mocha/parameter_matchers/optionally.rb +35 -33
  44. data/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb +2 -2
  45. data/lib/mocha/parameter_matchers/regexp_matches.rb +25 -23
  46. data/lib/mocha/parameter_matchers/responds_with.rb +49 -47
  47. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +24 -22
  48. data/lib/mocha/parameter_matchers.rb +5 -2
  49. data/lib/mocha/state_machine.rb +1 -1
  50. data/lib/mocha/stubbed_method.rb +7 -7
  51. data/lib/mocha/version.rb +1 -1
  52. data/lib/mocha.rb +15 -0
  53. metadata +9 -4
@@ -4,14 +4,21 @@ require 'mocha/mockery'
4
4
  require 'mocha/instance_method'
5
5
  require 'mocha/argument_iterator'
6
6
  require 'mocha/expectation_error_factory'
7
+ require 'mocha/ignoring_warning'
7
8
 
8
9
  module Mocha
9
10
  # Methods added to all objects to allow mocking and stubbing on real (i.e. non-mock) objects.
10
11
  #
11
12
  # Both {#expects} and {#stubs} return an {Expectation} which can be further modified by methods on {Expectation}.
12
13
  module ObjectMethods
14
+ extend IgnoringWarning
15
+
13
16
  # @private
14
- alias_method :_method, :method
17
+ JRUBY_ALIAS_SPECIAL_METHODS_WARNING = /accesses caller method's state and should not be aliased/.freeze
18
+
19
+ ignoring_warning(JRUBY_ALIAS_SPECIAL_METHODS_WARNING, if_: RUBY_ENGINE == 'jruby') do
20
+ alias_method :_method, :method
21
+ end
15
22
 
16
23
  # @private
17
24
  def mocha(instantiate: true)
@@ -42,6 +49,11 @@ module Mocha
42
49
  singleton_class
43
50
  end
44
51
 
52
+ # @private
53
+ def stubba_respond_to?(symbol)
54
+ respond_to?(symbol)
55
+ end
56
+
45
57
  # Adds an expectation that the specified method must be called exactly once with any parameters.
46
58
  #
47
59
  # 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 visibility as the original method.
@@ -1,34 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mocha/parameter_matchers/base'
3
+ require 'mocha/parameter_matchers/base_methods'
4
4
 
5
5
  module Mocha
6
6
  module ParameterMatchers
7
- # Matches if all +matchers+ match.
8
- #
9
- # @param [*Array<Base>] matchers parameter matchers.
10
- # @return [AllOf] parameter matcher.
11
- #
12
- # @see Expectation#with
13
- #
14
- # @example All parameter matchers match.
15
- # object = mock()
16
- # object.expects(:method_1).with(all_of(includes(1), includes(3)))
17
- # object.method_1([1, 3])
18
- # # no error raised
19
- #
20
- # @example One of the parameter matchers does not match.
21
- # object = mock()
22
- # object.expects(:method_1).with(all_of(includes(1), includes(3)))
23
- # object.method_1([1, 2])
24
- # # error raised, because method_1 was not called with object including 1 and 3
25
- def all_of(*matchers)
26
- AllOf.new(*matchers)
7
+ module Methods
8
+ # Matches if all +matchers+ match.
9
+ #
10
+ # @param [*Array<BaseMethods>] matchers parameter matchers.
11
+ # @return [AllOf] parameter matcher.
12
+ #
13
+ # @see Expectation#with
14
+ #
15
+ # @example All parameter matchers match.
16
+ # object = mock()
17
+ # object.expects(:method_1).with(all_of(includes(1), includes(3)))
18
+ # object.method_1([1, 3])
19
+ # # no error raised
20
+ #
21
+ # @example One of the parameter matchers does not match.
22
+ # object = mock()
23
+ # object.expects(:method_1).with(all_of(includes(1), includes(3)))
24
+ # object.method_1([1, 2])
25
+ # # error raised, because method_1 was not called with object including 1 and 3
26
+ def all_of(*matchers)
27
+ AllOf.new(*matchers)
28
+ end
27
29
  end
28
30
 
29
31
  # Parameter matcher which combines a number of other matchers using a logical AND.
30
32
  class AllOf
31
- include Base
33
+ include BaseMethods
32
34
 
33
35
  # @private
34
36
  def initialize(*matchers)
@@ -1,40 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mocha/parameter_matchers/base'
3
+ require 'mocha/parameter_matchers/base_methods'
4
4
 
5
5
  module Mocha
6
6
  module ParameterMatchers
7
- # Matches if any +matchers+ match.
8
- #
9
- # @param [*Array<Base>] matchers parameter matchers.
10
- # @return [AnyOf] parameter matcher.
11
- #
12
- # @see Expectation#with
13
- #
14
- # @example One parameter matcher matches.
15
- # object = mock()
16
- # object.expects(:method_1).with(any_of(1, 3))
17
- # object.method_1(1)
18
- # # no error raised
19
- #
20
- # @example The other parameter matcher matches.
21
- # object = mock()
22
- # object.expects(:method_1).with(any_of(1, 3))
23
- # object.method_1(3)
24
- # # no error raised
25
- #
26
- # @example Neither parameter matcher matches.
27
- # object = mock()
28
- # object.expects(:method_1).with(any_of(1, 3))
29
- # object.method_1(2)
30
- # # error raised, because method_1 was not called with 1 or 3
31
- def any_of(*matchers)
32
- AnyOf.new(*matchers)
7
+ module Methods
8
+ # Matches if any +matchers+ match.
9
+ #
10
+ # @param [*Array<BaseMethods>] matchers parameter matchers.
11
+ # @return [AnyOf] parameter matcher.
12
+ #
13
+ # @see Expectation#with
14
+ #
15
+ # @example One parameter matcher matches.
16
+ # object = mock()
17
+ # object.expects(:method_1).with(any_of(1, 3))
18
+ # object.method_1(1)
19
+ # # no error raised
20
+ #
21
+ # @example The other parameter matcher matches.
22
+ # object = mock()
23
+ # object.expects(:method_1).with(any_of(1, 3))
24
+ # object.method_1(3)
25
+ # # no error raised
26
+ #
27
+ # @example Neither parameter matcher matches.
28
+ # object = mock()
29
+ # object.expects(:method_1).with(any_of(1, 3))
30
+ # object.method_1(2)
31
+ # # error raised, because method_1 was not called with 1 or 3
32
+ def any_of(*matchers)
33
+ AnyOf.new(*matchers)
34
+ end
33
35
  end
34
36
 
35
37
  # Parameter matcher which combines a number of other matchers using a logical OR.
36
38
  class AnyOf
37
- include Base
39
+ include BaseMethods
38
40
 
39
41
  # @private
40
42
  def initialize(*matchers)
@@ -1,32 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mocha/parameter_matchers/base'
3
+ require 'mocha/parameter_matchers/base_methods'
4
4
 
5
5
  module Mocha
6
6
  module ParameterMatchers
7
- # Matches any parameters. This is used as the default for a newly built expectation.
8
- #
9
- # @return [AnyParameters] parameter matcher.
10
- #
11
- # @see Expectation#with
12
- #
13
- # @example Any parameters will match.
14
- # object = mock()
15
- # object.expects(:method_1).with(any_parameters)
16
- # object.method_1(1, 2, 3, 4)
17
- # # no error raised
18
- #
19
- # object = mock()
20
- # object.expects(:method_1).with(any_parameters)
21
- # object.method_1(5, 6, 7, 8, 9, 0)
22
- # # no error raised
23
- def any_parameters
24
- AnyParameters.new
7
+ module Methods
8
+ # Matches any parameters. This is used as the default for a newly built expectation.
9
+ #
10
+ # @return [AnyParameters] parameter matcher.
11
+ #
12
+ # @see Expectation#with
13
+ #
14
+ # @example Any parameters will match.
15
+ # object = mock()
16
+ # object.expects(:method_1).with(any_parameters)
17
+ # object.method_1(1, 2, 3, 4)
18
+ # # no error raised
19
+ #
20
+ # object = mock()
21
+ # object.expects(:method_1).with(any_parameters)
22
+ # object.method_1(5, 6, 7, 8, 9, 0)
23
+ # # no error raised
24
+ def any_parameters
25
+ AnyParameters.new
26
+ end
25
27
  end
26
28
 
27
29
  # Parameter matcher which always matches whatever the parameters.
28
30
  class AnyParameters
29
- include Base
31
+ include BaseMethods
30
32
 
31
33
  # @private
32
34
  def matches?(available_parameters)
@@ -1,29 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mocha/parameter_matchers/base'
3
+ require 'mocha/parameter_matchers/base_methods'
4
4
 
5
5
  module Mocha
6
6
  module ParameterMatchers
7
- # Matches any object.
8
- #
9
- # @return [Anything] parameter matcher.
10
- #
11
- # @see Expectation#with
12
- #
13
- # @example Any object will match.
14
- # object = mock()
15
- # object.expects(:method_1).with(anything)
16
- # object.method_1('foo')
17
- # object.method_1(789)
18
- # object.method_1(:bar)
19
- # # no error raised
20
- def anything
21
- Anything.new
7
+ module Methods
8
+ # Matches any object.
9
+ #
10
+ # @return [Anything] parameter matcher.
11
+ #
12
+ # @see Expectation#with
13
+ #
14
+ # @example Any object will match.
15
+ # object = mock()
16
+ # object.expects(:method_1).with(anything)
17
+ # object.method_1('foo')
18
+ # object.method_1(789)
19
+ # object.method_1(:bar)
20
+ # # no error raised
21
+ def anything
22
+ Anything.new
23
+ end
22
24
  end
23
25
 
24
26
  # Parameter matcher which always matches a single parameter.
25
27
  class Anything
26
- include Base
28
+ include BaseMethods
27
29
 
28
30
  # @private
29
31
  def matches?(available_parameters)
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'mocha/deprecation'
4
+
3
5
  module Mocha
4
6
  module ParameterMatchers
5
- # @abstract Include and implement +#matches?+ and +#mocha_inspect+ to define a custom matcher. Also add a suitably named instance method to {ParameterMatchers} to build an instance of the new matcher c.f. {#equals}.
6
- module Base
7
+ # @abstract Include and implement +#matches?+ and +#mocha_inspect+ to define a custom matcher. Also add a suitably named instance method to {Methods} to build an instance of the new matcher c.f. {Methods#equals}.
8
+ module BaseMethods
7
9
  # A shorthand way of combining two matchers when both must match.
8
10
  #
9
11
  # Returns a new {AllOf} parameter matcher combining two matchers using a logical AND.
10
12
  #
11
13
  # This shorthand will not work with an implicit equals match. Instead, an explicit {Equals} matcher should be used.
12
14
  #
13
- # @param [Base] other parameter matcher.
15
+ # @param [BaseMethods] other parameter matcher.
14
16
  # @return [AllOf] parameter matcher.
15
17
  #
16
18
  # @see Expectation#with
@@ -34,7 +36,7 @@ module Mocha
34
36
  #
35
37
  # This shorthand will not work with an implicit equals match. Instead, an explicit {Equals} matcher should be used.
36
38
  #
37
- # @param [Base] other parameter matcher.
39
+ # @param [BaseMethods] other parameter matcher.
38
40
  # @return [AnyOf] parameter matcher.
39
41
  #
40
42
  # @see Expectation#with
@@ -1,35 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mocha/parameter_matchers/base'
3
+ require 'mocha/parameter_matchers/base_methods'
4
4
 
5
5
  module Mocha
6
6
  module ParameterMatchers
7
- # Matches any +Object+ equalling +value+.
8
- #
9
- # @param [Object] value expected value.
10
- # @return [Equals] parameter matcher.
11
- #
12
- # @see Expectation#with
13
- # @see Object#==
14
- #
15
- # @example Actual parameter equals expected parameter.
16
- # object = mock()
17
- # object.expects(:method_1).with(equals(2))
18
- # object.method_1(2)
19
- # # no error raised
20
- #
21
- # @example Actual parameter does not equal expected parameter.
22
- # object = mock()
23
- # object.expects(:method_1).with(equals(2))
24
- # object.method_1(3)
25
- # # error raised, because method_1 was not called with an +Object+ that equals 2
26
- def equals(value)
27
- Equals.new(value)
7
+ module Methods
8
+ # Matches any +Object+ equalling +value+.
9
+ #
10
+ # @param [Object] value expected value.
11
+ # @return [Equals] parameter matcher.
12
+ #
13
+ # @see Expectation#with
14
+ # @see Object#==
15
+ #
16
+ # @example Actual parameter equals expected parameter.
17
+ # object = mock()
18
+ # object.expects(:method_1).with(equals(2))
19
+ # object.method_1(2)
20
+ # # no error raised
21
+ #
22
+ # @example Actual parameter does not equal expected parameter.
23
+ # object = mock()
24
+ # object.expects(:method_1).with(equals(2))
25
+ # object.method_1(3)
26
+ # # error raised, because method_1 was not called with an +Object+ that equals 2
27
+ def equals(value)
28
+ Equals.new(value)
29
+ end
28
30
  end
29
31
 
30
32
  # Parameter matcher which matches when actual parameter equals expected value.
31
33
  class Equals
32
- include Base
34
+ include BaseMethods
33
35
 
34
36
  # @private
35
37
  def initialize(value)
@@ -1,36 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mocha/parameter_matchers/base'
3
+ require 'mocha/parameter_matchers/base_methods'
4
4
  require 'uri'
5
- require 'cgi'
6
5
 
7
6
  module Mocha
8
7
  module ParameterMatchers
9
- # Matches a URI without regard to the ordering of parameters in the query string.
10
- #
11
- # @param [String] uri URI to match.
12
- # @return [EquivalentUri] parameter matcher.
13
- #
14
- # @see Expectation#with
15
- #
16
- # @example Actual URI is equivalent.
17
- # object = mock()
18
- # object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2))
19
- # object.method_1('http://example.com/foo?b=2&a=1')
20
- # # no error raised
21
- #
22
- # @example Actual URI is not equivalent.
23
- # object = mock()
24
- # object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2))
25
- # object.method_1('http://example.com/foo?a=1&b=3')
26
- # # error raised, because the query parameters were different
27
- def equivalent_uri(uri)
28
- EquivalentUri.new(uri)
8
+ module Methods
9
+ # Matches a URI without regard to the ordering of parameters in the query string.
10
+ #
11
+ # @param [String] uri URI to match.
12
+ # @return [EquivalentUri] parameter matcher.
13
+ #
14
+ # @see Expectation#with
15
+ #
16
+ # @example Actual URI is equivalent.
17
+ # object = mock()
18
+ # object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2'))
19
+ # object.method_1('http://example.com/foo?b=2&a=1')
20
+ # # no error raised
21
+ #
22
+ # @example Actual URI is not equivalent.
23
+ # object = mock()
24
+ # object.expects(:method_1).with(equivalent_uri('http://example.com/foo?a=1&b=2'))
25
+ # object.method_1('http://example.com/foo?a=1&b=3')
26
+ # # error raised, because the query parameters were different
27
+ def equivalent_uri(uri)
28
+ EquivalentUri.new(uri)
29
+ end
29
30
  end
30
31
 
31
32
  # Parameter matcher which matches URIs with equivalent query strings.
32
33
  class EquivalentUri
33
- include Base
34
+ include BaseMethods
34
35
 
35
36
  # @private
36
37
  def initialize(uri)
@@ -53,7 +54,10 @@ module Mocha
53
54
 
54
55
  # @private
55
56
  def explode(uri)
56
- query_hash = CGI.parse(uri.query || '')
57
+ query_hash = Hash.new { |hash, key| hash[key] = [] }
58
+ URI.decode_www_form(uri.query || '').each do |key, value|
59
+ query_hash[key] << value
60
+ end
57
61
  URI::Generic::COMPONENT.inject({}) { |h, k| h.merge(k => uri.__send__(k)) }.merge(query: query_hash)
58
62
  end
59
63
  end
@@ -1,37 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mocha/parameter_matchers/base'
3
+ require 'mocha/parameter_matchers/base_methods'
4
4
  require 'mocha/parameter_matchers/all_of'
5
5
  require 'mocha/parameter_matchers/has_entry'
6
6
 
7
7
  module Mocha
8
8
  module ParameterMatchers
9
- # Matches +Hash+ containing all +entries+.
10
- #
11
- # @param [Hash] entries expected +Hash+ entries.
12
- # @return [HasEntries] parameter matcher.
13
- #
14
- # @see Expectation#with
15
- #
16
- # @example Actual parameter contains all expected entries.
17
- # object = mock()
18
- # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
19
- # object.method_1('key_1' => 1, 'key_2' => 2, 'key_3' => 3)
20
- # # no error raised
21
- #
22
- # @example Actual parameter does not contain all expected entries.
23
- # object = mock()
24
- # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
25
- # object.method_1('key_1' => 1, 'key_2' => 99)
26
- # # error raised, because method_1 was not called with Hash containing entries: 'key_1' => 1, 'key_2' => 2
27
- #
28
- def has_entries(entries) # rubocop:disable Naming/PredicateName
29
- HasEntries.new(entries)
9
+ module Methods
10
+ # Matches +Hash+ containing all +entries+.
11
+ #
12
+ # @param [Hash] entries expected +Hash+ entries.
13
+ # @return [HasEntries] parameter matcher.
14
+ #
15
+ # @see Expectation#with
16
+ #
17
+ # @example Actual parameter contains all expected entries.
18
+ # object = mock()
19
+ # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
20
+ # object.method_1('key_1' => 1, 'key_2' => 2, 'key_3' => 3)
21
+ # # no error raised
22
+ #
23
+ # @example Actual parameter does not contain all expected entries.
24
+ # object = mock()
25
+ # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
26
+ # object.method_1('key_1' => 1, 'key_2' => 99)
27
+ # # error raised, because method_1 was not called with Hash containing entries: 'key_1' => 1, 'key_2' => 2
28
+ #
29
+ def has_entries(entries) # rubocop:disable Naming/PredicatePrefix
30
+ HasEntries.new(entries)
31
+ end
30
32
  end
31
33
 
32
34
  # Parameter matcher which matches when actual parameter contains all expected +Hash+ entries.
33
35
  class HasEntries
34
- include Base
36
+ include BaseMethods
35
37
 
36
38
  # @private
37
39
  def initialize(entries, exact: false)