Completed
Push — master ( aa3af0...5ad1e8 )
by Arnold
03:08
created

ClassLoaderTest   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 71
dl 0
loc 149
rs 10
c 0
b 0
f 0
wmc 13
1
<?php
2
3
namespace Jasny\Container\Tests\Loader;
4
5
use Jasny\Autowire\AutowireInterface;
6
use Jasny\Container\Loader\ClassLoader;
7
use PHPUnit\Framework\TestCase;
8
use Psr\Container\ContainerInterface;
9
10
/**
11
 * @covers \Jasny\Container\Loader\ClassLoader
12
 * @covers \Jasny\Container\Loader\AbstractLoader
13
 */
14
class ClassLoaderTest extends TestCase
15
{
16
    public function testIterate()
17
    {
18
        $entries = new ClassLoader(new \ArrayIterator(['Foo', 'Bar', 'App\Qux']));
19
20
        $foo = new \stdClass();
21
        $bar = new \stdClass();
22
        $qux = new \stdClass();
23
24
        $autowire = $this->createMock(AutowireInterface::class);
25
        $autowire->expects($this->exactly(3))->method('instantiate')
26
            ->withConsecutive(['Foo'], ['Bar'], ['App\Qux'])->willReturnOnConsecutiveCalls($foo, $bar, $qux);
27
28
        $container = $this->createMock(ContainerInterface::class);
29
        $container->expects($this->any())->method('get')->with('Jasny\Autowire\AutowireInterface')
30
            ->willReturn($autowire);
31
32
        $result = [];
33
34
        foreach ($entries as $class => $callback) {
35
            $this->assertInternalType('string', $class);
36
            $this->assertInstanceOf(\Closure::class, $callback);
37
38
            $result[$class] = $callback($container);
39
        }
40
41
        $this->assertSame(['Foo' => $foo, 'Bar' => $bar, 'App\Qux' => $qux], $result);
42
    }
43
44
    public function testIterateCallback()
45
    {
46
        $apply = function ($class) {
47
            return [
48
                "$class.one" => function () use ($class) { return substr($class, 0, 1) . "1"; },
49
                "$class.two" => function () use ($class) { return substr($class, 0, 1) . "2"; }
50
            ];
51
        };
52
53
        $entries = new ClassLoader(new \ArrayIterator(['Foo', 'Bar']), $apply);
54
55
        $result = [];
56
57
        foreach ($entries as $class => $callback) {
58
            $this->assertInternalType('string', $class);
59
            $this->assertInstanceOf(\Closure::class, $callback);
60
61
            $result[$class] = $callback();
62
        }
63
64
        $this->assertSame(['Foo.one' => "F1", "Foo.two" => "F2", 'Bar.one' => "B1", 'Bar.two' => "B2"], $result);
65
    }
66
67
    public function testIterateSkip()
68
    {
69
        $apply = function ($class) {
70
            if ($class === 'Nop') {
71
                return [];
72
            }
73
74
            return [
75
                "$class.one" => function () use ($class) { return substr($class, 0, 1) . "1"; },
76
                "$class.two" => function () use ($class) { return substr($class, 0, 1) . "2"; }
77
            ];
78
        };
79
80
        $entries = new ClassLoader(new \ArrayIterator(['Foo', 'Nop', 'Bar']), $apply);
81
82
        $result = [];
83
84
        foreach ($entries as $class => $callback) {
85
            $this->assertInternalType('string', $class);
86
            $this->assertInstanceOf(\Closure::class, $callback);
87
88
            $result[$class] = $callback();
89
        }
90
91
        $this->assertSame(['Foo.one' => "F1", "Foo.two" => "F2", 'Bar.one' => "B1", 'Bar.two' => "B2"], $result);
92
    }
93
94
    public function testIteratorToArray()
95
    {
96
        $apply = function ($class) {
97
            return [
98
                "$class.one" => function () use ($class) { return substr($class, 0, 1) . "1"; },
99
                "$class.two" => function () use ($class) { return substr($class, 0, 1) . "2"; }
100
            ];
101
        };
102
103
        $entries = new ClassLoader(new \ArrayIterator(['Foo', 'Bar']), $apply);
104
105
        $result = iterator_to_array($entries);
106
107
        $this->assertEquals(['Foo.one', 'Foo.two', 'Bar.one', 'Bar.two'], array_keys($result));
108
        $this->assertContainsOnlyInstancesOf(\Closure::class, $result);
109
    }
110
111
    public function testIteratorToArrayEmpty()
112
    {
113
        $iterator = new \ArrayIterator([]);
114
        $entries = new ClassLoader($iterator);
115
116
        $result = iterator_to_array($entries);
117
118
        $this->assertEquals([], $result);
119
    }
120
121
    public function testIteratorToArrayRewind()
122
    {
123
        $apply = function ($class) {
124
            return [
125
                "$class.one" => function () use ($class) { return substr($class, 0, 1) . "1"; },
126
                "$class.two" => function () use ($class) { return substr($class, 0, 1) . "2"; }
127
            ];
128
        };
129
130
        $entries = new ClassLoader(new \ArrayIterator(['Foo', 'Bar']), $apply);
131
132
        $first = iterator_to_array($entries);
133
        $this->assertEquals(['Foo.one', 'Foo.two', 'Bar.one', 'Bar.two'], array_keys($first));
134
135
        $second = iterator_to_array($entries);
136
        $this->assertEquals(['Foo.one', 'Foo.two', 'Bar.one', 'Bar.two'], array_keys($second));
137
    }
138
139
    /**
140
     * @expectedException \UnexpectedValueException
141
     * @expectedExceptionMessage Failed to load container entries for 'Foo': Expected array, callback returned Closure object
142
     */
143
    public function testIterateUnexpectedValue()
144
    {
145
        $apply = function () {
146
            return function() {};
147
        };
148
149
        $iterator = new \ArrayIterator(['Foo']);
150
        $entries = new ClassLoader($iterator, $apply);
151
152
        foreach ($entries as $key => $callback) {
153
            $callback();
154
        }
155
    }
156
157
    public function testGetInnerIterator()
158
    {
159
        $iterator = new \ArrayIterator([]);
160
        $entries = new ClassLoader($iterator);
161
162
        $this->assertSame($iterator, $entries->getInnerIterator());
163
    }
164
}
165