1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Config\Tests\Loader;
13
14use PHPUnit\Framework\TestCase;
15use Symfony\Component\Config\FileLocator;
16use Symfony\Component\Config\Loader\FileLoader;
17use Symfony\Component\Config\Loader\LoaderResolver;
18
19class FileLoaderTest extends TestCase
20{
21    public function testImportWithFileLocatorDelegation()
22    {
23        $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
24
25        $locatorMockForAdditionalLoader = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
26        $locatorMockForAdditionalLoader->expects($this->any())->method('locate')->will($this->onConsecutiveCalls(
27                ['path/to/file1'],                    // Default
28                ['path/to/file1', 'path/to/file2'],   // First is imported
29                ['path/to/file1', 'path/to/file2'],   // Second is imported
30                ['path/to/file1'],                    // Exception
31                ['path/to/file1', 'path/to/file2']    // Exception
32                ));
33
34        $fileLoader = new TestFileLoader($locatorMock);
35        $fileLoader->setSupports(false);
36        $fileLoader->setCurrentDir('.');
37
38        $additionalLoader = new TestFileLoader($locatorMockForAdditionalLoader);
39        $additionalLoader->setCurrentDir('.');
40
41        $fileLoader->setResolver($loaderResolver = new LoaderResolver([$fileLoader, $additionalLoader]));
42
43        // Default case
44        $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));
45
46        // Check first file is imported if not already loading
47        $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));
48
49        // Check second file is imported if first is already loading
50        $fileLoader->addLoading('path/to/file1');
51        $this->assertSame('path/to/file2', $fileLoader->import('my_resource'));
52
53        // Check exception throws if first (and only available) file is already loading
54        try {
55            $fileLoader->import('my_resource');
56            $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
57        } catch (\Exception $e) {
58            $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
59        }
60
61        // Check exception throws if all files are already loading
62        try {
63            $fileLoader->addLoading('path/to/file2');
64            $fileLoader->import('my_resource');
65            $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
66        } catch (\Exception $e) {
67            $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
68        }
69    }
70
71    public function testImportWithGlobLikeResource()
72    {
73        $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
74        $loader = new TestFileLoader($locatorMock);
75
76        $this->assertSame('[foo]', $loader->import('[foo]'));
77    }
78
79    public function testImportWithNoGlobMatch()
80    {
81        $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
82        $loader = new TestFileLoader($locatorMock);
83
84        $this->assertNull($loader->import('./*.abc'));
85    }
86
87    public function testImportWithSimpleGlob()
88    {
89        $loader = new TestFileLoader(new FileLocator(__DIR__));
90
91        $this->assertSame(__FILE__, strtr($loader->import('FileLoaderTest.*'), '/', \DIRECTORY_SEPARATOR));
92    }
93}
94
95class TestFileLoader extends FileLoader
96{
97    private $supports = true;
98
99    public function load($resource, $type = null)
100    {
101        return $resource;
102    }
103
104    public function supports($resource, $type = null)
105    {
106        return $this->supports;
107    }
108
109    public function addLoading($resource)
110    {
111        self::$loading[$resource] = true;
112    }
113
114    public function removeLoading($resource)
115    {
116        unset(self::$loading[$resource]);
117    }
118
119    public function clearLoading()
120    {
121        self::$loading = [];
122    }
123
124    public function setSupports($supports)
125    {
126        $this->supports = $supports;
127    }
128}
129