Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
/**
3
 * Mockery
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.txt.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://github.com/padraic/mockery/blob/master/LICENSE
11
 * If you did not receive a copy of the license and are unable to
12
 * obtain it through the world-wide-web, please send an email
13
 * to padraic@php.net so we can send you a copy immediately.
14
 *
15
 * @category   Mockery
16
 * @package    Mockery
17
 * @copyright  Copyright (c) 2010 Pádraic Brady (http://blog.astrumfutura.com)
18
 * @license    http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
19
 */
20
 
21
namespace Mockery;
22
 
23
use Mockery\Exception\BadMethodCallException;
24
use Mockery\ExpectsHigherOrderMessage;
25
use Mockery\HigherOrderMessage;
26
use Mockery\LegacyMockInterface;
27
use Mockery\MockInterface;
28
use Mockery\Reflector;
29
 
30
class Mock implements MockInterface
31
{
32
    /**
33
     * Stores an array of all expectation directors for this mock
34
     *
35
     * @var array
36
     */
37
    protected $_mockery_expectations = array();
38
 
39
    /**
40
     * Stores an initial number of expectations that can be manipulated
41
     * while using the getter method.
42
     *
43
     * @var int
44
     */
45
    protected $_mockery_expectations_count = 0;
46
 
47
    /**
48
     * Flag to indicate whether we can ignore method calls missing from our
49
     * expectations
50
     *
51
     * @var bool
52
     */
53
    protected $_mockery_ignoreMissing = false;
54
 
55
    /**
56
     * Flag to indicate whether we want to set the ignoreMissing flag on
57
     * mocks generated form this calls to this one
58
     *
59
     * @var bool
60
     */
61
    protected $_mockery_ignoreMissingRecursive = false;
62
 
63
    /**
64
     * Flag to indicate whether we can defer method calls missing from our
65
     * expectations
66
     *
67
     * @var bool
68
     */
69
    protected $_mockery_deferMissing = false;
70
 
71
    /**
72
     * Flag to indicate whether this mock was verified
73
     *
74
     * @var bool
75
     */
76
    protected $_mockery_verified = false;
77
 
78
    /**
79
     * Given name of the mock
80
     *
81
     * @var string
82
     */
83
    protected $_mockery_name = null;
84
 
85
    /**
86
     * Order number of allocation
87
     *
88
     * @var int
89
     */
90
    protected $_mockery_allocatedOrder = 0;
91
 
92
    /**
93
     * Current ordered number
94
     *
95
     * @var int
96
     */
97
    protected $_mockery_currentOrder = 0;
98
 
99
    /**
100
     * Ordered groups
101
     *
102
     * @var array
103
     */
104
    protected $_mockery_groups = array();
105
 
106
    /**
107
     * Mock container containing this mock object
108
     *
109
     * @var \Mockery\Container
110
     */
111
    protected $_mockery_container = null;
112
 
113
    /**
114
     * Instance of a core object on which methods are called in the event
115
     * it has been set, and an expectation for one of the object's methods
116
     * does not exist. This implements a simple partial mock proxy system.
117
     *
118
     * @var object
119
     */
120
    protected $_mockery_partial = null;
121
 
122
    /**
123
     * Flag to indicate we should ignore all expectations temporarily. Used
124
     * mainly to prevent expectation matching when in the middle of a mock
125
     * object recording session.
126
     *
127
     * @var bool
128
     */
129
    protected $_mockery_disableExpectationMatching = false;
130
 
131
    /**
132
     * Stores all stubbed public methods separate from any on-object public
133
     * properties that may exist.
134
     *
135
     * @var array
136
     */
137
    protected $_mockery_mockableProperties = array();
138
 
139
    /**
140
     * @var array
141
     */
142
    protected $_mockery_mockableMethods = array();
143
 
144
    /**
145
     * Just a local cache for this mock's target's methods
146
     *
147
     * @var \ReflectionMethod[]
148
     */
149
    protected static $_mockery_methods;
150
 
151
    protected $_mockery_allowMockingProtectedMethods = false;
152
 
153
    protected $_mockery_receivedMethodCalls;
154
 
155
    /**
156
     * If shouldIgnoreMissing is called, this value will be returned on all calls to missing methods
157
     * @var mixed
158
     */
159
    protected $_mockery_defaultReturnValue = null;
160
 
161
    /**
162
     * Tracks internally all the bad method call exceptions that happened during runtime
163
     *
164
     * @var array
165
     */
166
    protected $_mockery_thrownExceptions = [];
167
 
168
    protected $_mockery_instanceMock = true;
169
 
170
    /**
171
     * We want to avoid constructors since class is copied to Generator.php
172
     * for inclusion on extending class definitions.
173
     *
174
     * @param \Mockery\Container $container
175
     * @param object $partialObject
176
     * @param bool $instanceMock
177
     * @return void
178
     */
179
    public function mockery_init(\Mockery\Container $container = null, $partialObject = null, $instanceMock = true)
180
    {
181
        if (is_null($container)) {
182
            $container = new \Mockery\Container();
183
        }
184
        $this->_mockery_container = $container;
185
        if (!is_null($partialObject)) {
186
            $this->_mockery_partial = $partialObject;
187
        }
188
 
189
        if (!\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed()) {
190
            foreach ($this->mockery_getMethods() as $method) {
191
                if ($method->isPublic()) {
192
                    $this->_mockery_mockableMethods[] = $method->getName();
193
                }
194
            }
195
        }
196
 
197
        $this->_mockery_instanceMock = $instanceMock;
198
    }
199
 
200
    /**
201
     * Set expected method calls
202
     *
203
     * @param string ...$methodNames one or many methods that are expected to be called in this mock
204
     *
205
     * @return \Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
206
     */
207
    public function shouldReceive(...$methodNames)
208
    {
209
        if (count($methodNames) === 0) {
210
            return new HigherOrderMessage($this, "shouldReceive");
211
        }
212
 
213
        foreach ($methodNames as $method) {
214
            if ("" == $method) {
215
                throw new \InvalidArgumentException("Received empty method name");
216
            }
217
        }
218
 
219
        $self = $this;
220
        $allowMockingProtectedMethods = $this->_mockery_allowMockingProtectedMethods;
221
 
222
        $lastExpectation = \Mockery::parseShouldReturnArgs(
223
            $this,
224
            $methodNames,
225
            function ($method) use ($self, $allowMockingProtectedMethods) {
226
                $rm = $self->mockery_getMethod($method);
227
                if ($rm) {
228
                    if ($rm->isPrivate()) {
229
                        throw new \InvalidArgumentException("$method() cannot be mocked as it is a private method");
230
                    }
231
                    if (!$allowMockingProtectedMethods && $rm->isProtected()) {
232
                        throw new \InvalidArgumentException("$method() cannot be mocked as it is a protected method and mocking protected methods is not enabled for the currently used mock object. Use shouldAllowMockingProtectedMethods() to enable mocking of protected methods.");
233
                    }
234
                }
235
 
236
                $director = $self->mockery_getExpectationsFor($method);
237
                if (!$director) {
238
                    $director = new \Mockery\ExpectationDirector($method, $self);
239
                    $self->mockery_setExpectationsFor($method, $director);
240
                }
241
                $expectation = new \Mockery\Expectation($self, $method);
242
                $director->addExpectation($expectation);
243
                return $expectation;
244
            }
245
        );
246
        return $lastExpectation;
247
    }
248
 
249
    // start method allows
250
    /**
251
     * @param mixed $something  String method name or map of method => return
252
     * @return self|\Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
253
     */
254
    public function allows($something = [])
255
    {
256
        if (is_string($something)) {
257
            return $this->shouldReceive($something);
258
        }
259
 
260
        if (empty($something)) {
261
            return $this->shouldReceive();
262
        }
263
 
264
        foreach ($something as $method => $returnValue) {
265
            $this->shouldReceive($method)->andReturn($returnValue);
266
        }
267
 
268
        return $this;
269
    }
270
    // end method allows
271
 
272
    // start method expects
273
    /**
274
    /**
275
     * @param mixed $something  String method name (optional)
276
     * @return \Mockery\ExpectationInterface|\Mockery\Expectation|ExpectsHigherOrderMessage
277
     */
278
    public function expects($something = null)
279
    {
280
        if (is_string($something)) {
281
            return $this->shouldReceive($something)->once();
282
        }
283
 
284
        return new ExpectsHigherOrderMessage($this);
285
    }
286
    // end method expects
287
 
288
    /**
289
     * Shortcut method for setting an expectation that a method should not be called.
290
     *
291
     * @param string ...$methodNames one or many methods that are expected not to be called in this mock
292
     * @return \Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
293
     */
294
    public function shouldNotReceive(...$methodNames)
295
    {
296
        if (count($methodNames) === 0) {
297
            return new HigherOrderMessage($this, "shouldNotReceive");
298
        }
299
 
300
        $expectation = call_user_func_array(array($this, 'shouldReceive'), $methodNames);
301
        $expectation->never();
302
        return $expectation;
303
    }
304
 
305
    /**
306
     * Allows additional methods to be mocked that do not explicitly exist on mocked class
307
     * @param String $method name of the method to be mocked
308
     * @return Mock
309
     */
310
    public function shouldAllowMockingMethod($method)
311
    {
312
        $this->_mockery_mockableMethods[] = $method;
313
        return $this;
314
    }
315
 
316
    /**
317
     * Set mock to ignore unexpected methods and return Undefined class
318
     * @param mixed $returnValue the default return value for calls to missing functions on this mock
319
     * @param bool $recursive Specify if returned mocks should also have shouldIgnoreMissing set
320
     * @return Mock
321
     */
322
    public function shouldIgnoreMissing($returnValue = null, $recursive = false)
323
    {
324
        $this->_mockery_ignoreMissing = true;
325
        $this->_mockery_ignoreMissingRecursive = $recursive;
326
        $this->_mockery_defaultReturnValue = $returnValue;
327
        return $this;
328
    }
329
 
330
    public function asUndefined()
331
    {
332
        $this->_mockery_ignoreMissing = true;
333
        $this->_mockery_defaultReturnValue = new \Mockery\Undefined();
334
        return $this;
335
    }
336
 
337
    /**
338
     * @return Mock
339
     */
340
    public function shouldAllowMockingProtectedMethods()
341
    {
342
        if (!\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed()) {
343
            foreach ($this->mockery_getMethods() as $method) {
344
                if ($method->isProtected()) {
345
                    $this->_mockery_mockableMethods[] = $method->getName();
346
                }
347
            }
348
        }
349
 
350
        $this->_mockery_allowMockingProtectedMethods = true;
351
        return $this;
352
    }
353
 
354
 
355
    /**
356
     * Set mock to defer unexpected methods to it's parent
357
     *
358
     * This is particularly useless for this class, as it doesn't have a parent,
359
     * but included for completeness
360
     *
361
     * @deprecated 2.0.0 Please use makePartial() instead
362
     *
363
     * @return Mock
364
     */
365
    public function shouldDeferMissing()
366
    {
367
        return $this->makePartial();
368
    }
369
 
370
    /**
371
     * Set mock to defer unexpected methods to it's parent
372
     *
373
     * It was an alias for shouldDeferMissing(), which will be removed
374
     * in 2.0.0.
375
     *
376
     * @return Mock
377
     */
378
    public function makePartial()
379
    {
380
        $this->_mockery_deferMissing = true;
381
        return $this;
382
    }
383
 
384
    /**
385
     * In the event shouldReceive() accepting one or more methods/returns,
386
     * this method will switch them from normal expectations to default
387
     * expectations
388
     *
389
     * @return self
390
     */
391
    public function byDefault()
392
    {
393
        foreach ($this->_mockery_expectations as $director) {
394
            $exps = $director->getExpectations();
395
            foreach ($exps as $exp) {
396
                $exp->byDefault();
397
            }
398
        }
399
        return $this;
400
    }
401
 
402
    /**
403
     * Capture calls to this mock
404
     */
405
    public function __call($method, array $args)
406
    {
407
        return $this->_mockery_handleMethodCall($method, $args);
408
    }
409
 
410
    public static function __callStatic($method, array $args)
411
    {
412
        return self::_mockery_handleStaticMethodCall($method, $args);
413
    }
414
 
415
    /**
416
     * Forward calls to this magic method to the __call method
417
     */
418
    public function __toString()
419
    {
420
        return $this->__call('__toString', array());
421
    }
422
 
423
    /**
424
     * Iterate across all expectation directors and validate each
425
     *
426
     * @throws \Mockery\CountValidator\Exception
427
     * @return void
428
     */
429
    public function mockery_verify()
430
    {
431
        if ($this->_mockery_verified) {
432
            return;
433
        }
434
        if (isset($this->_mockery_ignoreVerification)
435
            && $this->_mockery_ignoreVerification == true) {
436
            return;
437
        }
438
        $this->_mockery_verified = true;
439
        foreach ($this->_mockery_expectations as $director) {
440
            $director->verify();
441
        }
442
    }
443
 
444
    /**
445
     * Gets a list of exceptions thrown by this mock
446
     *
447
     * @return array
448
     */
449
    public function mockery_thrownExceptions()
450
    {
451
        return $this->_mockery_thrownExceptions;
452
    }
453
 
454
    /**
455
     * Tear down tasks for this mock
456
     *
457
     * @return void
458
     */
459
    public function mockery_teardown()
460
    {
461
    }
462
 
463
    /**
464
     * Fetch the next available allocation order number
465
     *
466
     * @return int
467
     */
468
    public function mockery_allocateOrder()
469
    {
470
        $this->_mockery_allocatedOrder += 1;
471
        return $this->_mockery_allocatedOrder;
472
    }
473
 
474
    /**
475
     * Set ordering for a group
476
     *
477
     * @param mixed $group
478
     * @param int $order
479
     */
480
    public function mockery_setGroup($group, $order)
481
    {
482
        $this->_mockery_groups[$group] = $order;
483
    }
484
 
485
    /**
486
     * Fetch array of ordered groups
487
     *
488
     * @return array
489
     */
490
    public function mockery_getGroups()
491
    {
492
        return $this->_mockery_groups;
493
    }
494
 
495
    /**
496
     * Set current ordered number
497
     *
498
     * @param int $order
499
     */
500
    public function mockery_setCurrentOrder($order)
501
    {
502
        $this->_mockery_currentOrder = $order;
503
        return $this->_mockery_currentOrder;
504
    }
505
 
506
    /**
507
     * Get current ordered number
508
     *
509
     * @return int
510
     */
511
    public function mockery_getCurrentOrder()
512
    {
513
        return $this->_mockery_currentOrder;
514
    }
515
 
516
    /**
517
     * Validate the current mock's ordering
518
     *
519
     * @param string $method
520
     * @param int $order
521
     * @throws \Mockery\Exception
522
     * @return void
523
     */
524
    public function mockery_validateOrder($method, $order)
525
    {
526
        if ($order < $this->_mockery_currentOrder) {
527
            $exception = new \Mockery\Exception\InvalidOrderException(
528
                'Method ' . __CLASS__ . '::' . $method . '()'
529
                . ' called out of order: expected order '
530
                . $order . ', was ' . $this->_mockery_currentOrder
531
            );
532
            $exception->setMock($this)
533
                ->setMethodName($method)
534
                ->setExpectedOrder($order)
535
                ->setActualOrder($this->_mockery_currentOrder);
536
            throw $exception;
537
        }
538
        $this->mockery_setCurrentOrder($order);
539
    }
540
 
541
    /**
542
     * Gets the count of expectations for this mock
543
     *
544
     * @return int
545
     */
546
    public function mockery_getExpectationCount()
547
    {
548
        $count = $this->_mockery_expectations_count;
549
        foreach ($this->_mockery_expectations as $director) {
550
            $count += $director->getExpectationCount();
551
        }
552
        return $count;
553
    }
554
 
555
    /**
556
     * Return the expectations director for the given method
557
     *
558
     * @var string $method
559
     * @return \Mockery\ExpectationDirector|null
560
     */
561
    public function mockery_setExpectationsFor($method, \Mockery\ExpectationDirector $director)
562
    {
563
        $this->_mockery_expectations[$method] = $director;
564
    }
565
 
566
    /**
567
     * Return the expectations director for the given method
568
     *
569
     * @var string $method
570
     * @return \Mockery\ExpectationDirector|null
571
     */
572
    public function mockery_getExpectationsFor($method)
573
    {
574
        if (isset($this->_mockery_expectations[$method])) {
575
            return $this->_mockery_expectations[$method];
576
        }
577
    }
578
 
579
    /**
580
     * Find an expectation matching the given method and arguments
581
     *
582
     * @var string $method
583
     * @var array $args
584
     * @return \Mockery\Expectation|null
585
     */
586
    public function mockery_findExpectation($method, array $args)
587
    {
588
        if (!isset($this->_mockery_expectations[$method])) {
589
            return null;
590
        }
591
        $director = $this->_mockery_expectations[$method];
592
 
593
        return $director->findExpectation($args);
594
    }
595
 
596
    /**
597
     * Return the container for this mock
598
     *
599
     * @return \Mockery\Container
600
     */
601
    public function mockery_getContainer()
602
    {
603
        return $this->_mockery_container;
604
    }
605
 
606
    /**
607
     * Return the name for this mock
608
     *
609
     * @return string
610
     */
611
    public function mockery_getName()
612
    {
613
        return __CLASS__;
614
    }
615
 
616
    /**
617
     * @return array
618
     */
619
    public function mockery_getMockableProperties()
620
    {
621
        return $this->_mockery_mockableProperties;
622
    }
623
 
624
    public function __isset($name)
625
    {
626
        if (false === stripos($name, '_mockery_') && get_parent_class($this) && method_exists(get_parent_class($this), '__isset')) {
627
            return call_user_func(get_parent_class($this) . '::__isset', $name);
628
        }
629
 
630
        return false;
631
    }
632
 
633
    public function mockery_getExpectations()
634
    {
635
        return $this->_mockery_expectations;
636
    }
637
 
638
    /**
639
     * Calls a parent class method and returns the result. Used in a passthru
640
     * expectation where a real return value is required while still taking
641
     * advantage of expectation matching and call count verification.
642
     *
643
     * @param string $name
644
     * @param array $args
645
     * @return mixed
646
     */
647
    public function mockery_callSubjectMethod($name, array $args)
648
    {
649
        if (!method_exists($this, $name) && get_parent_class($this) && method_exists(get_parent_class($this), '__call')) {
650
            return call_user_func(get_parent_class($this) . '::__call', $name, $args);
651
        }
652
        return call_user_func_array(get_parent_class($this) . '::' . $name, $args);
653
    }
654
 
655
    /**
656
     * @return string[]
657
     */
658
    public function mockery_getMockableMethods()
659
    {
660
        return $this->_mockery_mockableMethods;
661
    }
662
 
663
    /**
664
     * @return bool
665
     */
666
    public function mockery_isAnonymous()
667
    {
668
        $rfc = new \ReflectionClass($this);
669
 
670
        // PHP 8 has Stringable interface
671
        $interfaces = array_filter($rfc->getInterfaces(), function ($i) {
672
            return $i->getName() !== 'Stringable';
673
        });
674
 
675
        return false === $rfc->getParentClass() && 2 === count($interfaces);
676
    }
677
 
678
    public function mockery_isInstance()
679
    {
680
        return $this->_mockery_instanceMock;
681
    }
682
 
683
    public function __wakeup()
684
    {
685
        /**
686
         * This does not add __wakeup method support. It's a blind method and any
687
         * expected __wakeup work will NOT be performed. It merely cuts off
688
         * annoying errors where a __wakeup exists but is not essential when
689
         * mocking
690
         */
691
    }
692
 
693
    public function __destruct()
694
    {
695
        /**
696
         * Overrides real class destructor in case if class was created without original constructor
697
         */
698
    }
699
 
700
    public function mockery_getMethod($name)
701
    {
702
        foreach ($this->mockery_getMethods() as $method) {
703
            if ($method->getName() == $name) {
704
                return $method;
705
            }
706
        }
707
 
708
        return null;
709
    }
710
 
711
    /**
712
     * @param string $name Method name.
713
     *
714
     * @return mixed Generated return value based on the declared return value of the named method.
715
     */
716
    public function mockery_returnValueForMethod($name)
717
    {
718
        $rm = $this->mockery_getMethod($name);
719
 
720
        if ($rm === null) {
721
            return null;
722
        }
723
 
724
        $returnType = Reflector::getSimplestReturnType($rm);
725
 
726
        switch ($returnType) {
727
            case null:     return null;
728
            case 'string': return '';
729
            case 'int':    return 0;
730
            case 'float':  return 0.0;
731
            case 'bool':   return false;
732
 
733
            case 'array':
734
            case 'iterable':
735
                return [];
736
 
737
            case 'callable':
738
            case '\Closure':
739
                return function () {
740
                };
741
 
742
            case '\Traversable':
743
            case '\Generator':
744
                $generator = function () { yield; };
745
                return $generator();
746
 
747
            case 'void':
748
                return null;
749
 
750
            case 'static':
751
                return $this;
752
 
753
            case 'object':
754
                $mock = \Mockery::mock();
755
                if ($this->_mockery_ignoreMissingRecursive) {
756
                    $mock->shouldIgnoreMissing($this->_mockery_defaultReturnValue, true);
757
                }
758
                return $mock;
759
 
760
            default:
761
                $mock = \Mockery::mock($returnType);
762
                if ($this->_mockery_ignoreMissingRecursive) {
763
                    $mock->shouldIgnoreMissing($this->_mockery_defaultReturnValue, true);
764
                }
765
                return $mock;
766
        }
767
    }
768
 
769
    public function shouldHaveReceived($method = null, $args = null)
770
    {
771
        if ($method === null) {
772
            return new HigherOrderMessage($this, "shouldHaveReceived");
773
        }
774
 
775
        $expectation = new \Mockery\VerificationExpectation($this, $method);
776
        if (null !== $args) {
777
            $expectation->withArgs($args);
778
        }
779
        $expectation->atLeast()->once();
780
        $director = new \Mockery\VerificationDirector($this->_mockery_getReceivedMethodCalls(), $expectation);
781
        $this->_mockery_expectations_count++;
782
        $director->verify();
783
        return $director;
784
    }
785
 
786
    public function shouldHaveBeenCalled()
787
    {
788
        return $this->shouldHaveReceived("__invoke");
789
    }
790
 
791
    public function shouldNotHaveReceived($method = null, $args = null)
792
    {
793
        if ($method === null) {
794
            return new HigherOrderMessage($this, "shouldNotHaveReceived");
795
        }
796
 
797
        $expectation = new \Mockery\VerificationExpectation($this, $method);
798
        if (null !== $args) {
799
            $expectation->withArgs($args);
800
        }
801
        $expectation->never();
802
        $director = new \Mockery\VerificationDirector($this->_mockery_getReceivedMethodCalls(), $expectation);
803
        $this->_mockery_expectations_count++;
804
        $director->verify();
805
        return null;
806
    }
807
 
808
    public function shouldNotHaveBeenCalled(array $args = null)
809
    {
810
        return $this->shouldNotHaveReceived("__invoke", $args);
811
    }
812
 
813
    protected static function _mockery_handleStaticMethodCall($method, array $args)
814
    {
815
        $associatedRealObject = \Mockery::fetchMock(__CLASS__);
816
        try {
817
            return $associatedRealObject->__call($method, $args);
818
        } catch (BadMethodCallException $e) {
819
            throw new BadMethodCallException(
820
                'Static method ' . $associatedRealObject->mockery_getName() . '::' . $method
821
                . '() does not exist on this mock object',
822
                0,
823
                $e
824
            );
825
        }
826
    }
827
 
828
    protected function _mockery_getReceivedMethodCalls()
829
    {
830
        return $this->_mockery_receivedMethodCalls ?: $this->_mockery_receivedMethodCalls = new \Mockery\ReceivedMethodCalls();
831
    }
832
 
833
    /**
834
     * Called when an instance Mock was created and its constructor is getting called
835
     *
836
     * @see \Mockery\Generator\StringManipulation\Pass\InstanceMockPass
837
     * @param array $args
838
     */
839
    protected function _mockery_constructorCalled(array $args)
840
    {
841
        if (!isset($this->_mockery_expectations['__construct']) /* _mockery_handleMethodCall runs the other checks */) {
842
            return;
843
        }
844
        $this->_mockery_handleMethodCall('__construct', $args);
845
    }
846
 
847
    protected function _mockery_findExpectedMethodHandler($method)
848
    {
849
        if (isset($this->_mockery_expectations[$method])) {
850
            return $this->_mockery_expectations[$method];
851
        }
852
 
853
        $lowerCasedMockeryExpectations = array_change_key_case($this->_mockery_expectations, CASE_LOWER);
854
        $lowerCasedMethod = strtolower($method);
855
 
856
        if (isset($lowerCasedMockeryExpectations[$lowerCasedMethod])) {
857
            return $lowerCasedMockeryExpectations[$lowerCasedMethod];
858
        }
859
 
860
        return null;
861
    }
862
 
863
    protected function _mockery_handleMethodCall($method, array $args)
864
    {
865
        $this->_mockery_getReceivedMethodCalls()->push(new \Mockery\MethodCall($method, $args));
866
 
867
        $rm = $this->mockery_getMethod($method);
868
        if ($rm && $rm->isProtected() && !$this->_mockery_allowMockingProtectedMethods) {
869
            if ($rm->isAbstract()) {
870
                return;
871
            }
872
 
873
            try {
874
                $prototype = $rm->getPrototype();
875
                if ($prototype->isAbstract()) {
876
                    return;
877
                }
878
            } catch (\ReflectionException $re) {
879
                // noop - there is no hasPrototype method
880
            }
881
 
882
            return call_user_func_array(get_parent_class($this) . '::' . $method, $args);
883
        }
884
 
885
        $handler = $this->_mockery_findExpectedMethodHandler($method);
886
 
887
        if ($handler !== null && !$this->_mockery_disableExpectationMatching) {
888
            try {
889
                return $handler->call($args);
890
            } catch (\Mockery\Exception\NoMatchingExpectationException $e) {
891
                if (!$this->_mockery_ignoreMissing && !$this->_mockery_deferMissing) {
892
                    throw $e;
893
                }
894
            }
895
        }
896
 
897
        if (!is_null($this->_mockery_partial) &&
898
            (method_exists($this->_mockery_partial, $method) || method_exists($this->_mockery_partial, '__call'))
899
        ) {
900
            return call_user_func_array(array($this->_mockery_partial, $method), $args);
901
        } elseif ($this->_mockery_deferMissing && is_callable(get_parent_class($this) . '::' . $method)
902
            && (!$this->hasMethodOverloadingInParentClass() || (get_parent_class($this) && method_exists(get_parent_class($this), $method)))) {
903
            return call_user_func_array(get_parent_class($this) . '::' . $method, $args);
904
        } elseif ($this->_mockery_deferMissing && get_parent_class($this) && method_exists(get_parent_class($this), '__call')) {
905
            return call_user_func(get_parent_class($this) . '::__call', $method, $args);
906
        } elseif ($method == '__toString') {
907
            // __toString is special because we force its addition to the class API regardless of the
908
            // original implementation.  Thus, we should always return a string rather than honor
909
            // _mockery_ignoreMissing and break the API with an error.
910
            return sprintf("%s#%s", __CLASS__, spl_object_hash($this));
911
        } elseif ($this->_mockery_ignoreMissing) {
912
            if (\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed() || (!is_null($this->_mockery_partial) && method_exists($this->_mockery_partial, $method)) || is_callable(get_parent_class($this) . '::' . $method)) {
913
                if ($this->_mockery_defaultReturnValue instanceof \Mockery\Undefined) {
914
                    return call_user_func_array(array($this->_mockery_defaultReturnValue, $method), $args);
915
                } elseif (null === $this->_mockery_defaultReturnValue) {
916
                    return $this->mockery_returnValueForMethod($method);
917
                }
918
 
919
                return $this->_mockery_defaultReturnValue;
920
            }
921
        }
922
 
923
        $message = 'Method ' . __CLASS__ . '::' . $method .
924
            '() does not exist on this mock object';
925
 
926
        if (!is_null($rm)) {
927
            $message = 'Received ' . __CLASS__ .
928
                '::' . $method . '(), but no expectations were specified';
929
        }
930
 
931
        $bmce = new BadMethodCallException($message);
932
        $this->_mockery_thrownExceptions[] = $bmce;
933
        throw $bmce;
934
    }
935
 
936
    /**
937
     * Uses reflection to get the list of all
938
     * methods within the current mock object
939
     *
940
     * @return array
941
     */
942
    protected function mockery_getMethods()
943
    {
944
        if (static::$_mockery_methods && \Mockery::getConfiguration()->reflectionCacheEnabled()) {
945
            return static::$_mockery_methods;
946
        }
947
 
948
        if (isset($this->_mockery_partial)) {
949
            $reflected = new \ReflectionObject($this->_mockery_partial);
950
        } else {
951
            $reflected = new \ReflectionClass($this);
952
        }
953
 
954
        return static::$_mockery_methods = $reflected->getMethods();
955
    }
956
 
957
    private function hasMethodOverloadingInParentClass()
958
    {
959
        // if there's __call any name would be callable
960
        return is_callable(get_parent_class($this) . '::aFunctionNameThatNoOneWouldEverUseInRealLife12345');
961
    }
962
 
963
    /**
964
     * @return array
965
     */
966
    private function getNonPublicMethods()
967
    {
968
        return array_map(
969
            function ($method) {
970
                return $method->getName();
971
            },
972
            array_filter($this->mockery_getMethods(), function ($method) {
973
                return !$method->isPublic();
974
            })
975
        );
976
    }
977
}