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
use Mockery\ClosureWrapper;
22
use Mockery\ExpectationInterface;
23
use Mockery\Generator\CachingGenerator;
24
use Mockery\Generator\Generator;
25
use Mockery\Generator\MockConfigurationBuilder;
26
use Mockery\Generator\MockNameBuilder;
27
use Mockery\Generator\StringManipulationGenerator;
28
use Mockery\Loader\EvalLoader;
29
use Mockery\Loader\Loader;
30
use Mockery\Matcher\MatcherAbstract;
31
use Mockery\Reflector;
32
 
33
class Mockery
34
{
35
    const BLOCKS = 'Mockery_Forward_Blocks';
36
 
37
    /**
38
     * Global container to hold all mocks for the current unit test running.
39
     *
40
     * @var \Mockery\Container|null
41
     */
42
    protected static $_container = null;
43
 
44
    /**
45
     * Global configuration handler containing configuration options.
46
     *
47
     * @var \Mockery\Configuration
48
     */
49
    protected static $_config = null;
50
 
51
    /**
52
     * @var \Mockery\Generator\Generator
53
     */
54
    protected static $_generator;
55
 
56
    /**
57
     * @var \Mockery\Loader\Loader
58
     */
59
    protected static $_loader;
60
 
61
    /**
62
     * @var array
63
     */
64
    private static $_filesToCleanUp = [];
65
 
66
    /**
67
     * Defines the global helper functions
68
     *
69
     * @return void
70
     */
71
    public static function globalHelpers()
72
    {
73
        require_once __DIR__ . '/helpers.php';
74
    }
75
 
76
    /**
77
     * @return array
78
     *
79
     * @deprecated since 1.3.2 and will be removed in 2.0.
80
     */
81
    public static function builtInTypes()
82
    {
83
        return array(
84
            'array',
85
            'bool',
86
            'callable',
87
            'float',
88
            'int',
89
            'iterable',
90
            'object',
91
            'self',
92
            'string',
93
            'void',
94
        );
95
    }
96
 
97
    /**
98
     * @param string $type
99
     * @return bool
100
     *
101
     * @deprecated since 1.3.2 and will be removed in 2.0.
102
     */
103
    public static function isBuiltInType($type)
104
    {
105
        return in_array($type, \Mockery::builtInTypes());
106
    }
107
 
108
    /**
109
     * Static shortcut to \Mockery\Container::mock().
110
     *
111
     * @param mixed ...$args
112
     *
113
     * @return \Mockery\MockInterface|\Mockery\LegacyMockInterface
114
     */
115
    public static function mock(...$args)
116
    {
117
        return call_user_func_array(array(self::getContainer(), 'mock'), $args);
118
    }
119
 
120
    /**
121
     * Static and semantic shortcut for getting a mock from the container
122
     * and applying the spy's expected behavior into it.
123
     *
124
     * @param mixed ...$args
125
     *
126
     * @return \Mockery\MockInterface|\Mockery\LegacyMockInterface
127
     */
128
    public static function spy(...$args)
129
    {
130
        if (count($args) && $args[0] instanceof \Closure) {
131
            $args[0] = new ClosureWrapper($args[0]);
132
        }
133
 
134
        return call_user_func_array(array(self::getContainer(), 'mock'), $args)->shouldIgnoreMissing();
135
    }
136
 
137
    /**
138
     * Static and Semantic shortcut to \Mockery\Container::mock().
139
     *
140
     * @param mixed ...$args
141
     *
142
     * @return \Mockery\MockInterface|\Mockery\LegacyMockInterface
143
     */
144
    public static function instanceMock(...$args)
145
    {
146
        return call_user_func_array(array(self::getContainer(), 'mock'), $args);
147
    }
148
 
149
    /**
150
     * Static shortcut to \Mockery\Container::mock(), first argument names the mock.
151
     *
152
     * @param mixed ...$args
153
     *
154
     * @return \Mockery\MockInterface|\Mockery\LegacyMockInterface
155
     */
156
    public static function namedMock(...$args)
157
    {
158
        $name = array_shift($args);
159
 
160
        $builder = new MockConfigurationBuilder();
161
        $builder->setName($name);
162
 
163
        array_unshift($args, $builder);
164
 
165
        return call_user_func_array(array(self::getContainer(), 'mock'), $args);
166
    }
167
 
168
    /**
169
     * Static shortcut to \Mockery\Container::self().
170
     *
171
     * @throws LogicException
172
     *
173
     * @return \Mockery\MockInterface|\Mockery\LegacyMockInterface
174
     */
175
    public static function self()
176
    {
177
        if (is_null(self::$_container)) {
178
            throw new \LogicException('You have not declared any mocks yet');
179
        }
180
 
181
        return self::$_container->self();
182
    }
183
 
184
    /**
185
     * Static shortcut to closing up and verifying all mocks in the global
186
     * container, and resetting the container static variable to null.
187
     *
188
     * @return void
189
     */
190
    public static function close()
191
    {
192
        foreach (self::$_filesToCleanUp as $fileName) {
193
            @unlink($fileName);
194
        }
195
        self::$_filesToCleanUp = [];
196
 
197
        if (is_null(self::$_container)) {
198
            return;
199
        }
200
 
201
        $container = self::$_container;
202
        self::$_container = null;
203
 
204
        $container->mockery_teardown();
205
        $container->mockery_close();
206
    }
207
 
208
    /**
209
     * Static fetching of a mock associated with a name or explicit class poser.
210
     *
211
     * @param string $name
212
     *
213
     * @return \Mockery\Mock
214
     */
215
    public static function fetchMock($name)
216
    {
217
        return self::getContainer()->fetchMock($name);
218
    }
219
 
220
    /**
221
     * Lazy loader and getter for
222
     * the container property.
223
     *
224
     * @return Mockery\Container
225
     */
226
    public static function getContainer()
227
    {
228
        if (is_null(self::$_container)) {
229
            self::$_container = new Mockery\Container(self::getGenerator(), self::getLoader());
230
        }
231
 
232
        return self::$_container;
233
    }
234
 
235
    /**
236
     * Setter for the $_generator static property.
237
     *
238
     * @param \Mockery\Generator\Generator $generator
239
     */
240
    public static function setGenerator(Generator $generator)
241
    {
242
        self::$_generator = $generator;
243
    }
244
 
245
    /**
246
     * Lazy loader method and getter for
247
     * the generator property.
248
     *
249
     * @return Generator
250
     */
251
    public static function getGenerator()
252
    {
253
        if (is_null(self::$_generator)) {
254
            self::$_generator = self::getDefaultGenerator();
255
        }
256
 
257
        return self::$_generator;
258
    }
259
 
260
    /**
261
     * Creates and returns a default generator
262
     * used inside this class.
263
     *
264
     * @return CachingGenerator
265
     */
266
    public static function getDefaultGenerator()
267
    {
268
        return new CachingGenerator(StringManipulationGenerator::withDefaultPasses());
269
    }
270
 
271
    /**
272
     * Setter for the $_loader static property.
273
     *
274
     * @param Loader $loader
275
     */
276
    public static function setLoader(Loader $loader)
277
    {
278
        self::$_loader = $loader;
279
    }
280
 
281
    /**
282
     * Lazy loader method and getter for
283
     * the $_loader property.
284
     *
285
     * @return Loader
286
     */
287
    public static function getLoader()
288
    {
289
        if (is_null(self::$_loader)) {
290
            self::$_loader = self::getDefaultLoader();
291
        }
292
 
293
        return self::$_loader;
294
    }
295
 
296
    /**
297
     * Gets an EvalLoader to be used as default.
298
     *
299
     * @return EvalLoader
300
     */
301
    public static function getDefaultLoader()
302
    {
303
        return new EvalLoader();
304
    }
305
 
306
    /**
307
     * Set the container.
308
     *
309
     * @param \Mockery\Container $container
310
     *
311
     * @return \Mockery\Container
312
     */
313
    public static function setContainer(Mockery\Container $container)
314
    {
315
        return self::$_container = $container;
316
    }
317
 
318
    /**
319
     * Reset the container to null.
320
     *
321
     * @return void
322
     */
323
    public static function resetContainer()
324
    {
325
        self::$_container = null;
326
    }
327
 
328
    /**
329
     * Return instance of ANY matcher.
330
     *
331
     * @return \Mockery\Matcher\Any
332
     */
333
    public static function any()
334
    {
335
        return new \Mockery\Matcher\Any();
336
    }
337
 
338
    /**
339
     * Return instance of AndAnyOtherArgs matcher.
340
     *
341
     * An alternative name to `andAnyOtherArgs` so
342
     * the API stays closer to `any` as well.
343
     *
344
     * @return \Mockery\Matcher\AndAnyOtherArgs
345
     */
346
    public static function andAnyOthers()
347
    {
348
        return new \Mockery\Matcher\AndAnyOtherArgs();
349
    }
350
 
351
    /**
352
     * Return instance of AndAnyOtherArgs matcher.
353
     *
354
     * @return \Mockery\Matcher\AndAnyOtherArgs
355
     */
356
    public static function andAnyOtherArgs()
357
    {
358
        return new \Mockery\Matcher\AndAnyOtherArgs();
359
    }
360
 
361
    /**
362
     * Return instance of TYPE matcher.
363
     *
364
     * @param mixed $expected
365
     *
366
     * @return \Mockery\Matcher\Type
367
     */
368
    public static function type($expected)
369
    {
370
        return new \Mockery\Matcher\Type($expected);
371
    }
372
 
373
    /**
374
     * Return instance of DUCKTYPE matcher.
375
     *
376
     * @param array ...$args
377
     *
378
     * @return \Mockery\Matcher\Ducktype
379
     */
380
    public static function ducktype(...$args)
381
    {
382
        return new \Mockery\Matcher\Ducktype($args);
383
    }
384
 
385
    /**
386
     * Return instance of SUBSET matcher.
387
     *
388
     * @param array $part
389
     * @param bool $strict - (Optional) True for strict comparison, false for loose
390
     *
391
     * @return \Mockery\Matcher\Subset
392
     */
393
    public static function subset(array $part, $strict = true)
394
    {
395
        return new \Mockery\Matcher\Subset($part, $strict);
396
    }
397
 
398
    /**
399
     * Return instance of CONTAINS matcher.
400
     *
401
     * @param mixed $args
402
     *
403
     * @return \Mockery\Matcher\Contains
404
     */
405
    public static function contains(...$args)
406
    {
407
        return new \Mockery\Matcher\Contains($args);
408
    }
409
 
410
    /**
411
     * Return instance of HASKEY matcher.
412
     *
413
     * @param mixed $key
414
     *
415
     * @return \Mockery\Matcher\HasKey
416
     */
417
    public static function hasKey($key)
418
    {
419
        return new \Mockery\Matcher\HasKey($key);
420
    }
421
 
422
    /**
423
     * Return instance of HASVALUE matcher.
424
     *
425
     * @param mixed $val
426
     *
427
     * @return \Mockery\Matcher\HasValue
428
     */
429
    public static function hasValue($val)
430
    {
431
        return new \Mockery\Matcher\HasValue($val);
432
    }
433
 
434
    /**
435
     * Return instance of CLOSURE matcher.
436
     *
437
     * @param $reference
438
     *
439
     * @return \Mockery\Matcher\Closure
440
     */
441
    public static function capture(&$reference)
442
    {
443
        $closure = function ($argument) use (&$reference) {
444
            $reference = $argument;
445
            return true;
446
        };
447
 
448
        return new \Mockery\Matcher\Closure($closure);
449
    }
450
 
451
    /**
452
     * Return instance of CLOSURE matcher.
453
     *
454
     * @param mixed $closure
455
     *
456
     * @return \Mockery\Matcher\Closure
457
     */
458
    public static function on($closure)
459
    {
460
        return new \Mockery\Matcher\Closure($closure);
461
    }
462
 
463
    /**
464
     * Return instance of MUSTBE matcher.
465
     *
466
     * @param mixed $expected
467
     *
468
     * @return \Mockery\Matcher\MustBe
469
     */
470
    public static function mustBe($expected)
471
    {
472
        return new \Mockery\Matcher\MustBe($expected);
473
    }
474
 
475
    /**
476
     * Return instance of NOT matcher.
477
     *
478
     * @param mixed $expected
479
     *
480
     * @return \Mockery\Matcher\Not
481
     */
482
    public static function not($expected)
483
    {
484
        return new \Mockery\Matcher\Not($expected);
485
    }
486
 
487
    /**
488
     * Return instance of ANYOF matcher.
489
     *
490
     * @param array ...$args
491
     *
492
     * @return \Mockery\Matcher\AnyOf
493
     */
494
    public static function anyOf(...$args)
495
    {
496
        return new \Mockery\Matcher\AnyOf($args);
497
    }
498
 
499
    /**
500
     * Return instance of NOTANYOF matcher.
501
     *
502
     * @param array ...$args
503
     *
504
     * @return \Mockery\Matcher\NotAnyOf
505
     */
506
    public static function notAnyOf(...$args)
507
    {
508
        return new \Mockery\Matcher\NotAnyOf($args);
509
    }
510
 
511
    /**
512
     * Return instance of PATTERN matcher.
513
     *
514
     * @param mixed $expected
515
     *
516
     * @return \Mockery\Matcher\Pattern
517
     */
518
    public static function pattern($expected)
519
    {
520
        return new \Mockery\Matcher\Pattern($expected);
521
    }
522
 
523
    /**
524
     * Lazy loader and Getter for the global
525
     * configuration container.
526
     *
527
     * @return \Mockery\Configuration
528
     */
529
    public static function getConfiguration()
530
    {
531
        if (is_null(self::$_config)) {
532
            self::$_config = new \Mockery\Configuration();
533
        }
534
 
535
        return self::$_config;
536
    }
537
 
538
    /**
539
     * Utility method to format method name and arguments into a string.
540
     *
541
     * @param string $method
542
     * @param array $arguments
543
     *
544
     * @return string
545
     */
546
    public static function formatArgs($method, array $arguments = null)
547
    {
548
        if (is_null($arguments)) {
549
            return $method . '()';
550
        }
551
 
552
        $formattedArguments = array();
553
        foreach ($arguments as $argument) {
554
            $formattedArguments[] = self::formatArgument($argument);
555
        }
556
 
557
        return $method . '(' . implode(', ', $formattedArguments) . ')';
558
    }
559
 
560
    /**
561
     * Gets the string representation
562
     * of any passed argument.
563
     *
564
     * @param mixed $argument
565
     * @param int $depth
566
     *
567
     * @return mixed
568
     */
569
    private static function formatArgument($argument, $depth = 0)
570
    {
571
        if ($argument instanceof MatcherAbstract) {
572
            return (string) $argument;
573
        }
574
 
575
        if (is_object($argument)) {
576
            return 'object(' . get_class($argument) . ')';
577
        }
578
 
579
        if (is_int($argument) || is_float($argument)) {
580
            return $argument;
581
        }
582
 
583
        if (is_array($argument)) {
584
            if ($depth === 1) {
585
                $argument = '[...]';
586
            } else {
587
                $sample = array();
588
                foreach ($argument as $key => $value) {
589
                    $key = is_int($key) ? $key : "'$key'";
590
                    $value = self::formatArgument($value, $depth + 1);
591
                    $sample[] = "$key => $value";
592
                }
593
 
594
                $argument = "[" . implode(", ", $sample) . "]";
595
            }
596
 
597
            return ((strlen($argument) > 1000) ? substr($argument, 0, 1000) . '...]' : $argument);
598
        }
599
 
600
        if (is_bool($argument)) {
601
            return $argument ? 'true' : 'false';
602
        }
603
 
604
        if (is_resource($argument)) {
605
            return 'resource(...)';
606
        }
607
 
608
        if (is_null($argument)) {
609
            return 'NULL';
610
        }
611
 
612
        return "'" . (string) $argument . "'";
613
    }
614
 
615
    /**
616
     * Utility function to format objects to printable arrays.
617
     *
618
     * @param array $objects
619
     *
620
     * @return string
621
     */
622
    public static function formatObjects(array $objects = null)
623
    {
624
        static $formatting;
625
 
626
        if ($formatting) {
627
            return '[Recursion]';
628
        }
629
 
630
        if (is_null($objects)) {
631
            return '';
632
        }
633
 
634
        $objects = array_filter($objects, 'is_object');
635
        if (empty($objects)) {
636
            return '';
637
        }
638
 
639
        $formatting = true;
640
        $parts = array();
641
 
642
        foreach ($objects as $object) {
643
            $parts[get_class($object)] = self::objectToArray($object);
644
        }
645
 
646
        $formatting = false;
647
 
648
        return 'Objects: ( ' . var_export($parts, true) . ')';
649
    }
650
 
651
    /**
652
     * Utility function to turn public properties and public get* and is* method values into an array.
653
     *
654
     * @param object $object
655
     * @param int $nesting
656
     *
657
     * @return array
658
     */
659
    private static function objectToArray($object, $nesting = 3)
660
    {
661
        if ($nesting == 0) {
662
            return array('...');
663
        }
664
 
665
        $defaultFormatter = function ($object, $nesting) {
666
            return array('properties' => self::extractInstancePublicProperties($object, $nesting));
667
        };
668
 
669
        $class = get_class($object);
670
 
671
        $formatter = self::getConfiguration()->getObjectFormatter($class, $defaultFormatter);
672
 
673
        $array = array(
674
          'class' => $class,
675
          'identity' => '#' . md5(spl_object_hash($object))
676
        );
677
 
678
        $array = array_merge($array, $formatter($object, $nesting));
679
 
680
        return $array;
681
    }
682
 
683
    /**
684
     * Returns all public instance properties.
685
     *
686
     * @param mixed $object
687
     * @param int $nesting
688
     *
689
     * @return array
690
     */
691
    private static function extractInstancePublicProperties($object, $nesting)
692
    {
693
        $reflection = new \ReflectionClass(get_class($object));
694
        $properties = $reflection->getProperties(\ReflectionProperty::IS_PUBLIC);
695
        $cleanedProperties = array();
696
 
697
        foreach ($properties as $publicProperty) {
698
            if (!$publicProperty->isStatic()) {
699
                $name = $publicProperty->getName();
700
                try {
701
                    $cleanedProperties[$name] = self::cleanupNesting($object->$name, $nesting);
702
                } catch (\Exception $exception) {
703
                    $cleanedProperties[$name] = $exception->getMessage();
704
                }
705
            }
706
        }
707
 
708
        return $cleanedProperties;
709
    }
710
 
711
    /**
712
     * Utility method used for recursively generating
713
     * an object or array representation.
714
     *
715
     * @param mixed $argument
716
     * @param int $nesting
717
     *
718
     * @return mixed
719
     */
720
    private static function cleanupNesting($argument, $nesting)
721
    {
722
        if (is_object($argument)) {
723
            $object = self::objectToArray($argument, $nesting - 1);
724
            $object['class'] = get_class($argument);
725
 
726
            return $object;
727
        }
728
 
729
        if (is_array($argument)) {
730
            return self::cleanupArray($argument, $nesting - 1);
731
        }
732
 
733
        return $argument;
734
    }
735
 
736
    /**
737
     * Utility method for recursively
738
     * gerating a representation
739
     * of the given array.
740
     *
741
     * @param array $argument
742
     * @param int $nesting
743
     *
744
     * @return mixed
745
     */
746
    private static function cleanupArray($argument, $nesting = 3)
747
    {
748
        if ($nesting == 0) {
749
            return '...';
750
        }
751
 
752
        foreach ($argument as $key => $value) {
753
            if (is_array($value)) {
754
                $argument[$key] = self::cleanupArray($value, $nesting - 1);
755
            } elseif (is_object($value)) {
756
                $argument[$key] = self::objectToArray($value, $nesting - 1);
757
            }
758
        }
759
 
760
        return $argument;
761
    }
762
 
763
    /**
764
     * Utility function to parse shouldReceive() arguments and generate
765
     * expectations from such as needed.
766
     *
767
     * @param Mockery\LegacyMockInterface $mock
768
     * @param array ...$args
769
     * @param callable $add
770
     * @return \Mockery\CompositeExpectation
771
     */
772
    public static function parseShouldReturnArgs(\Mockery\LegacyMockInterface $mock, $args, $add)
773
    {
774
        $composite = new \Mockery\CompositeExpectation();
775
 
776
        foreach ($args as $arg) {
777
            if (is_array($arg)) {
778
                foreach ($arg as $k => $v) {
779
                    $expectation = self::buildDemeterChain($mock, $k, $add)->andReturn($v);
780
                    $composite->add($expectation);
781
                }
782
            } elseif (is_string($arg)) {
783
                $expectation = self::buildDemeterChain($mock, $arg, $add);
784
                $composite->add($expectation);
785
            }
786
        }
787
 
788
        return $composite;
789
    }
790
 
791
    /**
792
     * Sets up expectations on the members of the CompositeExpectation and
793
     * builds up any demeter chain that was passed to shouldReceive.
794
     *
795
     * @param \Mockery\LegacyMockInterface $mock
796
     * @param string $arg
797
     * @param callable $add
798
     * @throws Mockery\Exception
799
     * @return \Mockery\ExpectationInterface
800
     */
801
    protected static function buildDemeterChain(\Mockery\LegacyMockInterface $mock, $arg, $add)
802
    {
803
        /** @var Mockery\Container $container */
804
        $container = $mock->mockery_getContainer();
805
        $methodNames = explode('->', $arg);
806
        reset($methodNames);
807
 
808
        if (!\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed()
809
            && !$mock->mockery_isAnonymous()
810
            && !in_array(current($methodNames), $mock->mockery_getMockableMethods())
811
        ) {
812
            throw new \Mockery\Exception(
813
                'Mockery\'s configuration currently forbids mocking the method '
814
                . current($methodNames) . ' as it does not exist on the class or object '
815
                . 'being mocked'
816
            );
817
        }
818
 
819
        /** @var ExpectationInterface|null $expectations */
820
        $expectations = null;
821
 
822
        /** @var Callable $nextExp */
823
        $nextExp = function ($method) use ($add) {
824
            return $add($method);
825
        };
826
 
827
        $parent = get_class($mock);
828
 
829
        while (true) {
830
            $method = array_shift($methodNames);
831
            $expectations = $mock->mockery_getExpectationsFor($method);
832
 
833
            if (is_null($expectations) || self::noMoreElementsInChain($methodNames)) {
834
                $expectations = $nextExp($method);
835
                if (self::noMoreElementsInChain($methodNames)) {
836
                    break;
837
                }
838
 
839
                $mock = self::getNewDemeterMock($container, $parent, $method, $expectations);
840
            } else {
841
                $demeterMockKey = $container->getKeyOfDemeterMockFor($method, $parent);
842
                if ($demeterMockKey) {
843
                    $mock = self::getExistingDemeterMock($container, $demeterMockKey);
844
                }
845
            }
846
 
847
            $parent .= '->' . $method;
848
 
849
            $nextExp = function ($n) use ($mock) {
850
                return $mock->shouldReceive($n);
851
            };
852
        }
853
 
854
        return $expectations;
855
    }
856
 
857
    /**
858
     * Gets a new demeter configured
859
     * mock from the container.
860
     *
861
     * @param \Mockery\Container $container
862
     * @param string $parent
863
     * @param string $method
864
     * @param Mockery\ExpectationInterface $exp
865
     *
866
     * @return \Mockery\Mock
867
     */
868
    private static function getNewDemeterMock(
869
        Mockery\Container $container,
870
        $parent,
871
        $method,
872
        Mockery\ExpectationInterface $exp
873
    ) {
874
        $newMockName = 'demeter_' . md5($parent) . '_' . $method;
875
 
876
        $parRef = null;
877
        $parRefMethod = null;
878
        $parRefMethodRetType = null;
879
 
880
        $parentMock = $exp->getMock();
881
        if ($parentMock !== null) {
882
            $parRef = new ReflectionObject($parentMock);
883
        }
884
 
885
        if ($parRef !== null && $parRef->hasMethod($method)) {
886
            $parRefMethod = $parRef->getMethod($method);
887
            $parRefMethodRetType = Reflector::getReturnType($parRefMethod, true);
888
 
889
            if ($parRefMethodRetType !== null && $parRefMethodRetType !== 'mixed') {
890
                $nameBuilder = new MockNameBuilder();
891
                $nameBuilder->addPart('\\' . $newMockName);
892
                $mock = self::namedMock($nameBuilder->build(), $parRefMethodRetType);
893
                $exp->andReturn($mock);
894
 
895
                return $mock;
896
            }
897
        }
898
 
899
        $mock = $container->mock($newMockName);
900
        $exp->andReturn($mock);
901
 
902
        return $mock;
903
    }
904
 
905
    /**
906
     * Gets an specific demeter mock from
907
     * the ones kept by the container.
908
     *
909
     * @param \Mockery\Container $container
910
     * @param string $demeterMockKey
911
     *
912
     * @return mixed
913
     */
914
    private static function getExistingDemeterMock(
915
        Mockery\Container $container,
916
        $demeterMockKey
917
    ) {
918
        $mocks = $container->getMocks();
919
        $mock = $mocks[$demeterMockKey];
920
 
921
        return $mock;
922
    }
923
 
924
    /**
925
     * Checks if the passed array representing a demeter
926
     * chain with the method names is empty.
927
     *
928
     * @param array $methodNames
929
     *
930
     * @return bool
931
     */
932
    private static function noMoreElementsInChain(array $methodNames)
933
    {
934
        return empty($methodNames);
935
    }
936
 
937
    public static function declareClass($fqn)
938
    {
939
        return static::declareType($fqn, "class");
940
    }
941
 
942
    public static function declareInterface($fqn)
943
    {
944
        return static::declareType($fqn, "interface");
945
    }
946
 
947
    private static function declareType($fqn, $type)
948
    {
949
        $targetCode = "<?php ";
950
        $shortName = $fqn;
951
 
952
        if (strpos($fqn, "\\")) {
953
            $parts = explode("\\", $fqn);
954
 
955
            $shortName = trim(array_pop($parts));
956
            $namespace = implode("\\", $parts);
957
 
958
            $targetCode.= "namespace $namespace;\n";
959
        }
960
 
961
        $targetCode.= "$type $shortName {} ";
962
 
963
        /*
964
         * We could eval here, but it doesn't play well with the way
965
         * PHPUnit tries to backup global state and the require definition
966
         * loader
967
         */
968
        $tmpfname = tempnam(sys_get_temp_dir(), "Mockery");
969
        file_put_contents($tmpfname, $targetCode);
970
        require $tmpfname;
971
        \Mockery::registerFileForCleanUp($tmpfname);
972
    }
973
 
974
    /**
975
     * Register a file to be deleted on tearDown.
976
     *
977
     * @param string $fileName
978
     */
979
    public static function registerFileForCleanUp($fileName)
980
    {
981
        self::$_filesToCleanUp[] = $fileName;
982
    }
983
}