Completed
Push — master ( c62b77...a54f79 )
by Bernhard
02:35
created

testRemoveBindingsWithExpression()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 15

Duplication

Lines 21
Ratio 100 %

Code Coverage

Tests 16
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 21
loc 21
ccs 16
cts 16
cp 1
rs 9.3142
cc 1
eloc 15
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * This file is part of the puli/discovery package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Discovery\Test;
13
14
use Puli\Discovery\Api\Binding\Binding;
15
use Puli\Discovery\Api\Binding\Initializer\BindingInitializer;
16
use Puli\Discovery\Api\Discovery;
17
use Puli\Discovery\Api\EditableDiscovery;
18
use Puli\Discovery\Api\Type\BindingParameter;
19
use Puli\Discovery\Api\Type\BindingType;
20
use Puli\Discovery\Test\Fixtures\Bar;
21
use Puli\Discovery\Test\Fixtures\Foo;
22
use Puli\Discovery\Test\Fixtures\StringBinding;
23
use stdClass;
24
use Webmozart\Expression\Expr;
25
26
/**
27
 * @since  1.0
28
 *
29
 * @author Bernhard Schussek <[email protected]>
30
 */
31
abstract class AbstractEditableDiscoveryTest extends AbstractDiscoveryTest
32
{
33
    /**
34
     * Creates a discovery that can be written in the test.
35
     *
36
     * @param BindingInitializer[] $initializers
37
     *
38
     * @return EditableDiscovery
39
     */
40
    abstract protected function createDiscovery(array $initializers = array());
41
42
    /**
43
     * Creates a discovery that can be read in the test.
44
     *
45
     * This method is needed to test whether the discovery actually synchronized
46
     * all in-memory changes to the backing data store:
47
     *
48
     *  * If the method returns the passed $discovery, the in-memory data
49
     *    structures are tested.
50
     *  * If the method returns a new discovery with the same backing data store,
51
     *    that data store is tested.
52
     *
53
     * @param EditableDiscovery    $discovery
54
     * @param BindingInitializer[] $initializers
55
     *
56
     * @return EditableDiscovery
57
     */
58
    abstract protected function loadDiscoveryFromStorage(EditableDiscovery $discovery, array $initializers = array());
59
60
    /**
61
     * @param BindingType[]        $types
62
     * @param Binding[]            $bindings
63
     * @param BindingInitializer[] $initializers
64
     *
65
     * @return Discovery
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use EditableDiscovery.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
66
     */
67 100
    protected function createLoadedDiscovery(array $types = array(), array $bindings = array(), array $initializers = array())
68
    {
69 100
        $discovery = $this->createDiscovery($initializers);
70
71 100
        foreach ($types as $type) {
72 50
            $discovery->addBindingType($type);
73
        }
74
75 100
        foreach ($bindings as $binding) {
76 30
            $discovery->addBinding($binding);
77
        }
78
79 100
        return $this->loadDiscoveryFromStorage($discovery);
80
    }
81
82 5 View Code Duplication
    public function testAddBinding()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
    {
84 5
        $binding = new StringBinding('string', Foo::clazz);
85
86 5
        $discovery = $this->createDiscovery();
87 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
88 5
        $discovery->addBinding($binding);
89
90 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
91
92 5
        $this->assertCount(1, $discovery->findBindings(Foo::clazz));
93 5
        $this->assertCount(1, $discovery->getBindings());
94 5
    }
95
96
    /**
97
     * @expectedException \Puli\Discovery\Api\Type\NoSuchTypeException
98
     * @expectedExceptionMessage Foo
99
     */
100 5
    public function testAddBindingFailsIfTypeNotFound()
101
    {
102 5
        $discovery = $this->createDiscovery();
103 5
        $discovery->addBinding(new StringBinding('string', Foo::clazz));
104
    }
105
106
    /**
107
     * @expectedException \Puli\Discovery\Api\Type\BindingNotAcceptedException
108
     * @expectedExceptionMessage Foo
109
     */
110 5
    public function testAddBindingFailsIfTypeDoesNotAcceptBinding()
111
    {
112 5
        $discovery = $this->createDiscovery();
113 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::CLASS_BINDING));
114 5
        $discovery->addBinding(new StringBinding('string', Foo::clazz));
115
    }
116
117 5 View Code Duplication
    public function testAddBindingIgnoresDuplicates()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
    {
119 5
        $binding = new StringBinding('string', Foo::clazz);
120
121 5
        $discovery = $this->createDiscovery();
122 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
123 5
        $discovery->addBinding($binding);
124 5
        $discovery->addBinding($binding);
125
126 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
127
128 5
        $this->assertCount(1, $discovery->findBindings(Foo::clazz));
129 5
        $this->assertCount(1, $discovery->getBindings());
130 5
    }
131
132 5
    public function testRemoveBindings()
133
    {
134 5
        $binding1 = new StringBinding('string1', Foo::clazz);
135 5
        $binding2 = new StringBinding('string2', Foo::clazz);
136
137 5
        $discovery = $this->createDiscovery();
138 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
139 5
        $discovery->addBinding($binding1);
140 5
        $discovery->addBinding($binding2);
141 5
        $discovery->removeBindings();
142
143 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
144
145 5
        $this->assertCount(0, $discovery->findBindings(Foo::clazz));
146 5
        $this->assertCount(0, $discovery->getBindings());
147 5
    }
148
149 5 View Code Duplication
    public function testRemoveBindingsDoesNothingIfNoneFound()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150
    {
151 5
        $discovery = $this->createDiscovery();
152 5
        $discovery->removeBindings();
153
154 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
155
156 5
        $this->assertCount(0, $discovery->getBindings());
157 5
    }
158
159 5
    public function testRemoveBindingsWithType()
160
    {
161 5
        $binding1 = new StringBinding('string1', Foo::clazz);
162 5
        $binding2 = new StringBinding('string2', Foo::clazz);
163 5
        $binding3 = new StringBinding('string3', Bar::clazz);
164
165 5
        $discovery = $this->createDiscovery();
166 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
167 5
        $discovery->addBindingType(new BindingType(Bar::clazz, self::STRING_BINDING));
168 5
        $discovery->addBinding($binding1);
169 5
        $discovery->addBinding($binding2);
170 5
        $discovery->addBinding($binding3);
171 5
        $discovery->removeBindings(Foo::clazz);
172
173 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
174
175 5
        $this->assertEquals(array(), $discovery->findBindings(Foo::clazz));
176 5
        $this->assertEquals(array($binding3), $discovery->findBindings(Bar::clazz));
177 5
        $this->assertEquals(array($binding3), $discovery->getBindings());
178 5
    }
179
180 5 View Code Duplication
    public function testRemoveBindingsWithTypeDoesNothingIfNoneFound()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
    {
182 5
        $discovery = $this->createDiscovery();
183 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
184 5
        $discovery->removeBindings(Foo::clazz);
185
186 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
187
188 5
        $this->assertCount(0, $discovery->getBindings());
189 5
    }
190
191 5 View Code Duplication
    public function testRemoveBindingsWithTypeDoesNothingIfTypeNotFound()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192
    {
193 5
        $discovery = $this->createDiscovery();
194 5
        $discovery->removeBindings(Foo::clazz);
195
196 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
197
198 5
        $this->assertCount(0, $discovery->getBindings());
199 5
    }
200
201
    /**
202
     * @expectedException \InvalidArgumentException
203
     * @expectedExceptionMessage stdClass
204
     */
205 5
    public function testRemoveBindingsWithTypeFailsIfInvalidType()
206
    {
207 5
        $discovery = $this->createDiscovery();
208 5
        $discovery->removeBindings(new stdClass());
0 ignored issues
show
Documentation introduced by
new \stdClass() is of type object<stdClass>, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
209
    }
210
211 5 View Code Duplication
    public function testRemoveBindingsWithExpression()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
212
    {
213 5
        $binding1 = new StringBinding('string1', Foo::clazz, array('param1' => 'foo', 'param2' => 'bar'));
214 5
        $binding2 = new StringBinding('string2', Foo::clazz, array('param1' => 'foo'));
215 5
        $binding3 = new StringBinding('string3', Foo::clazz, array('param1' => 'bar'));
216
217 5
        $discovery = $this->createDiscovery();
218 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING, array(
219 5
            new BindingParameter('param1'),
220 5
            new BindingParameter('param2'),
221
        )));
222 5
        $discovery->addBinding($binding1);
223 5
        $discovery->addBinding($binding2);
224 5
        $discovery->addBinding($binding3);
225 5
        $discovery->removeBindings(null, Expr::method('getParameterValue', 'param1', Expr::same('foo')));
226
227 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
228
229 5
        $this->assertEquals(array($binding3), $discovery->findBindings(Foo::clazz));
230 5
        $this->assertEquals(array($binding3), $discovery->getBindings());
231 5
    }
232
233 5 View Code Duplication
    public function testRemoveBindingsWithTypeAndExpression()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
234
    {
235 5
        $binding1 = new StringBinding('string1', Foo::clazz, array('param1' => 'foo', 'param2' => 'bar'));
236 5
        $binding2 = new StringBinding('string2', Foo::clazz, array('param1' => 'foo'));
237 5
        $binding3 = new StringBinding('string3', Foo::clazz, array('param1' => 'bar'));
238
239 5
        $discovery = $this->createDiscovery();
240 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING, array(
241 5
            new BindingParameter('param1'),
242 5
            new BindingParameter('param2'),
243
        )));
244 5
        $discovery->addBinding($binding1);
245 5
        $discovery->addBinding($binding2);
246 5
        $discovery->addBinding($binding3);
247 5
        $discovery->removeBindings(Foo::clazz, Expr::method('getParameterValue', 'param1', Expr::same('foo')));
248
249 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
250
251 5
        $this->assertEquals(array($binding3), $discovery->findBindings(Foo::clazz));
252 5
        $this->assertEquals(array($binding3), $discovery->getBindings());
253 5
    }
254
255 5
    public function testRemoveBindingsWithTypeAndParametersDoesNothingIfNoneFound()
256
    {
257 5
        $discovery = $this->createDiscovery();
258 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
259 5
        $discovery->removeBindings(Foo::clazz, Expr::method('getParameterValue', 'param1', Expr::same('foo')));
260
261 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
262
263 5
        $this->assertCount(0, $discovery->getBindings());
264 5
    }
265
266 5
    public function testRemoveBindingsWithTypeAndParametersDoesNothingIfTypeNotFound()
267
    {
268 5
        $discovery = $this->createDiscovery();
269 5
        $discovery->removeBindings(Foo::clazz, Expr::method('getParameterValue', 'param1', Expr::same('foo')));
270
271 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
272
273 5
        $this->assertCount(0, $discovery->getBindings());
274 5
    }
275
276 5 View Code Duplication
    public function testAddBindingType()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
277
    {
278 5
        $type = new BindingType(Foo::clazz, self::STRING_BINDING);
279
280 5
        $discovery = $this->createDiscovery();
281 5
        $discovery->addBindingType($type);
282
283 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
284
285 5
        $this->assertEquals($type, $discovery->getBindingType(Foo::clazz));
286 5
    }
287
288 5
    public function testAddBindingTypeAfterReadingStorage()
289
    {
290 5
        $type1 = new BindingType(Foo::clazz, self::STRING_BINDING);
291 5
        $type2 = new BindingType(Bar::clazz, self::STRING_BINDING);
292
293 5
        $discovery = $this->createDiscovery();
294 5
        $discovery->addBindingType($type1);
295
296
        // Make sure that the previous call to addBindingType() stored all
297
        // necessary information in order to add further types (e.g. nextId)
298 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
299 5
        $discovery->addBindingType($type2);
300
301 5
        $this->assertEquals($type1, $discovery->getBindingType(Foo::clazz));
302 5
        $this->assertEquals($type2, $discovery->getBindingType(Bar::clazz));
303 5
    }
304
305
    /**
306
     * @expectedException \Puli\Discovery\Api\Type\DuplicateTypeException
307
     * @expectedExceptionMessage Foo
308
     */
309 5
    public function testAddBindingTypeFailsIfAlreadyDefined()
310
    {
311 5
        $discovery = $this->createDiscovery();
312 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
313 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
314
    }
315
316 5 View Code Duplication
    public function testRemoveBindingType()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
317
    {
318 5
        $discovery = $this->createDiscovery();
319 5
        $discovery->addBindingType($type1 = new BindingType(Foo::clazz, self::STRING_BINDING));
320 5
        $discovery->addBindingType(new BindingType(Bar::clazz, self::STRING_BINDING));
321 5
        $discovery->removeBindingType(Bar::clazz);
322
323 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
324
325 5
        $this->assertEquals(array($type1), $discovery->getBindingTypes());
326 5
        $this->assertTrue($discovery->hasBindingType(Foo::clazz));
327 5
        $this->assertFalse($discovery->hasBindingType(Bar::clazz));
328 5
    }
329
330 5
    public function testRemoveBindingTypeIgnoresUnknownTypes()
331
    {
332 5
        $discovery = $this->createDiscovery();
333 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
334 5
        $discovery->removeBindingType(Bar::clazz);
335
336 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
337
338 5
        $this->assertTrue($discovery->hasBindingType(Foo::clazz));
339 5
        $this->assertFalse($discovery->hasBindingType(Bar::clazz));
340 5
    }
341
342
    /**
343
     * @expectedException \InvalidArgumentException
344
     * @expectedExceptionMessage stdClass
345
     */
346 5
    public function testRemoveBindingTypeFailsIfInvalidType()
347
    {
348 5
        $discovery = $this->createDiscovery();
349 5
        $discovery->removeBindingType(new stdClass());
0 ignored issues
show
Documentation introduced by
new \stdClass() is of type object<stdClass>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
350
    }
351
352 5
    public function testRemoveBindingTypeRemovesCorrespondingBindings()
353
    {
354 5
        $discovery = $this->createDiscovery();
355 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
356 5
        $discovery->addBindingType(new BindingType(Bar::clazz, self::STRING_BINDING));
357 5
        $discovery->addBinding($binding1 = new StringBinding('string1', Foo::clazz));
358 5
        $discovery->addBinding($binding2 = new StringBinding('string2', Foo::clazz));
359 5
        $discovery->addBinding($binding3 = new StringBinding('string3', Bar::clazz));
360
361 5
        $discovery->removeBindingType(Foo::clazz);
362
363 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
364
365 5
        $this->assertEquals(array($binding3), $discovery->getBindings());
366 5
    }
367
368 5 View Code Duplication
    public function testRemoveBindingTypes()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
369
    {
370 5
        $discovery = $this->createDiscovery();
371 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
372 5
        $discovery->addBindingType(new BindingType(Bar::clazz, self::STRING_BINDING));
373 5
        $discovery->removeBindingTypes();
374
375 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
376
377 5
        $this->assertEquals(array(), $discovery->getBindingTypes());
378 5
        $this->assertFalse($discovery->hasBindingType(Foo::clazz));
379 5
        $this->assertFalse($discovery->hasBindingType(Bar::clazz));
380 5
    }
381
382 5
    public function testRemoveBindingTypesRemovesBindings()
383
    {
384 5
        $discovery = $this->createDiscovery();
385 5
        $discovery->addBindingType(new BindingType(Foo::clazz, self::STRING_BINDING));
386 5
        $discovery->addBindingType(new BindingType(Bar::clazz, self::STRING_BINDING));
387 5
        $discovery->addBinding($binding1 = new StringBinding('string1', Foo::clazz));
388 5
        $discovery->addBinding($binding2 = new StringBinding('string2', Bar::clazz));
389 5
        $discovery->removeBindingTypes();
390
391 5
        $discovery = $this->loadDiscoveryFromStorage($discovery);
392
393 5
        $this->assertCount(0, $discovery->getBindings());
394 5
    }
395
}
396