1<?php
2/*
3 * This file is part of php-token-stream.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11use PHPUnit\Framework\TestCase;
12
13class PHP_Token_InterfaceTest extends TestCase
14{
15    /**
16     * @var PHP_Token_CLASS
17     */
18    private $class;
19
20    /**
21     * @var PHP_Token_INTERFACE[]
22     */
23    private $interfaces;
24
25    protected function setUp()
26    {
27        $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source4.php');
28        $i  = 0;
29
30        foreach ($ts as $token) {
31            if ($token instanceof PHP_Token_CLASS) {
32                $this->class = $token;
33            } elseif ($token instanceof PHP_Token_INTERFACE) {
34                $this->interfaces[$i] = $token;
35                $i++;
36            }
37        }
38    }
39
40    /**
41     * @covers PHP_Token_INTERFACE::getName
42     */
43    public function testGetName()
44    {
45        $this->assertEquals(
46            'iTemplate', $this->interfaces[0]->getName()
47        );
48    }
49
50    /**
51     * @covers PHP_Token_INTERFACE::getParent
52     */
53    public function testGetParentNotExists()
54    {
55        $this->assertFalse(
56            $this->interfaces[0]->getParent()
57        );
58    }
59
60    /**
61     * @covers PHP_Token_INTERFACE::hasParent
62     */
63    public function testHasParentNotExists()
64    {
65        $this->assertFalse(
66            $this->interfaces[0]->hasParent()
67        );
68    }
69
70    /**
71     * @covers PHP_Token_INTERFACE::getParent
72     */
73    public function testGetParentExists()
74    {
75        $this->assertEquals(
76            'a', $this->interfaces[2]->getParent()
77        );
78    }
79
80    /**
81     * @covers PHP_Token_INTERFACE::hasParent
82     */
83    public function testHasParentExists()
84    {
85        $this->assertTrue(
86            $this->interfaces[2]->hasParent()
87        );
88    }
89
90    /**
91     * @covers PHP_Token_INTERFACE::getInterfaces
92     */
93    public function testGetInterfacesExists()
94    {
95        $this->assertEquals(
96            ['b'],
97            $this->class->getInterfaces()
98        );
99    }
100
101    /**
102     * @covers PHP_Token_INTERFACE::hasInterfaces
103     */
104    public function testHasInterfacesExists()
105    {
106        $this->assertTrue(
107            $this->class->hasInterfaces()
108        );
109    }
110
111    /**
112     * @covers PHP_Token_INTERFACE::getPackage
113     */
114    public function testGetPackageNamespace()
115    {
116        $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php');
117        foreach ($tokenStream as $token) {
118            if ($token instanceof PHP_Token_INTERFACE) {
119                $package = $token->getPackage();
120                $this->assertSame('Foo\\Bar', $package['namespace']);
121            }
122        }
123    }
124
125
126    public function provideFilesWithClassesWithinMultipleNamespaces()
127    {
128        return [
129            [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingBraces.php'],
130            [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingNonBraceSyntax.php'],
131        ];
132    }
133
134    /**
135     * @dataProvider provideFilesWithClassesWithinMultipleNamespaces
136     * @covers PHP_Token_INTERFACE::getPackage
137     */
138    public function testGetPackageNamespaceForFileWithMultipleNamespaces($filepath)
139    {
140        $tokenStream     = new PHP_Token_Stream($filepath);
141        $firstClassFound = false;
142        foreach ($tokenStream as $token) {
143            if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
144                $package = $token->getPackage();
145                $this->assertSame('TestClassInBar', $token->getName());
146                $this->assertSame('Foo\\Bar', $package['namespace']);
147                $firstClassFound = true;
148                continue;
149            }
150            // Secound class
151            if ($token instanceof PHP_Token_INTERFACE) {
152                $package = $token->getPackage();
153                $this->assertSame('TestClassInBaz', $token->getName());
154                $this->assertSame('Foo\\Baz', $package['namespace']);
155
156                return;
157            }
158        }
159        $this->fail('Seachring for 2 classes failed');
160    }
161
162    public function testGetPackageNamespaceIsEmptyForInterfacesThatAreNotWithinNamespaces()
163    {
164        foreach ($this->interfaces as $token) {
165            $package = $token->getPackage();
166            $this->assertSame('', $package['namespace']);
167        }
168    }
169
170    /**
171     * @covers PHP_Token_INTERFACE::getPackage
172     */
173    public function testGetPackageNamespaceWhenExtentingFromNamespaceClass()
174    {
175        $tokenStream     = new PHP_Token_Stream(TEST_FILES_PATH . 'classExtendsNamespacedClass.php');
176        $firstClassFound = false;
177        foreach ($tokenStream as $token) {
178            if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
179                $package = $token->getPackage();
180                $this->assertSame('Baz', $token->getName());
181                $this->assertSame('Foo\\Bar', $package['namespace']);
182                $firstClassFound = true;
183                continue;
184            }
185            if ($token instanceof PHP_Token_INTERFACE) {
186                $package = $token->getPackage();
187                $this->assertSame('Extender', $token->getName());
188                $this->assertSame('Other\\Space', $package['namespace']);
189
190                return;
191            }
192        }
193        $this->fail('Searching for 2 classes failed');
194    }
195}
196