PageRenderTime 49ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Test/Pockito/DefaultMatcher.pm

https://bitbucket.org/exussum/pockito
Perl | 165 lines | 111 code | 53 blank | 1 comment | 12 complexity | f04a400d2d31601e219af9e303448158 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. package Test::Pockito::DefaultMatcher;
  2. use strict;
  3. use warnings;
  4. use Scalar::Util::Reftype;
  5. use Exporter 'import';
  6. =head1 NAME
  7. Test::Pockito::DefaultMatcher
  8. =head1 SYNOPSIS
  9. Default matching for Pockito
  10. =head1 DESCRIPTION
  11. Default implementation of matching. If none of the any_* subs are used for matching, then it reverts to a ne op for matching.
  12. =head1 SUBROUTINES
  13. =over 1
  14. =item default_call_match( $package, $method, \@params_found, \@params_expected )
  15. This is the default matching metchanism for Pockito though you are at will to implement your own. Passing an implementation with this signature overrides the matching sub. The default implementation does not use $package nor $method, but they will be of use if you have multiple, different ways to define parameters as equal.
  16. =back
  17. =cut
  18. our %lookup = ();
  19. our @EXPORT_OK = qw(is_defined);
  20. sub default_call_match {
  21. my $package = shift;
  22. my $method = shift;
  23. my $param_found_ref = shift;
  24. my $param_expected_ref = shift;
  25. my (@left) = @{$param_found_ref};
  26. my (@right) = @{$param_expected_ref};
  27. if ( $#left < $#right ) {
  28. (@left) = @{$param_expected_ref};
  29. (@right) = @{$param_found_ref};
  30. }
  31. foreach my $y ( 0 .. $#left ) {
  32. my $l = $left[$y] || 0;
  33. my $r = $right[$y] || 0;
  34. if ( exists $lookup{$l} ) {
  35. return 0 if !&{ $lookup{$l} }($r);
  36. }
  37. elsif ( exists $lookup{$r} ) {
  38. return 0 if !&{ $lookup{$r} }($l);
  39. }
  40. elsif ( $l ne $r ) {
  41. return 0;
  42. }
  43. }
  44. return 1;
  45. }
  46. =head1 MATCHERS
  47. All the following matchers can be exported or refered to by package name. They use Scalar::Util::Reftype under the hood except for is_defined.
  48. is_defined
  49. is_scalar
  50. is_array
  51. is_hash
  52. is_code
  53. is_global
  54. is_lvalue
  55. is_regexp
  56. is_scalar_object
  57. is_array_object
  58. is_hash_object
  59. is_code_object
  60. is_glob_object
  61. is_lvalue_object
  62. is_ref_object
  63. is_io_object
  64. is_regexp_object
  65. With these, one can write:
  66. $pocket->when( $mock->( is_defined, is_regexp, 1, 2, is_code_object )->...
  67. to match
  68. any defined value
  69. any regular expression ref
  70. the value 1
  71. the value 2
  72. any blessed code ref
  73. =cut
  74. our @types =
  75. qw(scalar array hash code global lvalue regexp scalar_object array_object hash_object code_object glob_object lvalue_object ref_object io_object regexp_object);
  76. foreach my $type (@types) {
  77. #Going to hell for this.
  78. my $sub_name = __PACKAGE__ . "::is_" . $type;
  79. my $check = sub {
  80. return reftype(shift)->$type();
  81. };
  82. my $wrapper = sub { return $check };
  83. no strict "refs";
  84. *$sub_name = $wrapper;
  85. use strict "refs";
  86. $lookup{$check} = $check;
  87. push( @EXPORT_OK, "is_" . $type );
  88. }
  89. sub check_is_defined {
  90. return defined shift;
  91. }
  92. sub is_defined {
  93. return \&check_is_defined;
  94. }
  95. $lookup{ \&check_is_defined } = \&check_is_defined;
  96. =head1 SUPPORT
  97. exussum@gmail.com
  98. =head1 AUTHOR
  99. Spencer Portee
  100. CPAN ID: EXUSSUM
  101. exussum@gmail.com
  102. =head1 SOURCE
  103. http://bitbucket.org/exussum/pockito/
  104. =head1 COPYRIGHT
  105. This program is free software licensed under the...
  106. The BSD License
  107. The full text of the license can be found in the
  108. LICENSE file included with this module.
  109. =head1 SEE ALSO
  110. perl(1).
  111. =cut
  112. 1;