Completed
Pull Request — master (#272)
by Gonçalo
03:57
created

ScopeTest   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 424
Duplicated Lines 12.03 %

Coupling/Cohesion

Components 2
Dependencies 12

Importance

Changes 12
Bugs 7 Features 3
Metric Value
wmc 21
c 12
b 7
f 3
lcom 2
cbo 12
dl 51
loc 424
rs 10

21 Methods

Rating   Name   Duplication   Size   Complexity  
A testEmbedChildScope() 0 13 1
A testGetManager() 9 9 1
A testGetResource() 10 10 1
A testToArray() 0 13 1
A testToJson() 0 20 1
A testGetCurrentScope() 16 16 1
A testGetIdentifier() 16 16 1
A testGetParentScopes() 0 16 1
A testIsRequested() 0 19 1
A testIsExcluded() 0 19 1
A testScopeRequiresConcreteImplementation() 0 13 1
A testToArrayWithIncludes() 0 18 1
B testToArrayWithSideloadedIncludes() 0 33 1
A testPushParentScope() 0 16 1
A testRunAppropriateTransformerWithItem() 0 15 1
A testRunAppropriateTransformerWithCollection() 0 16 1
A testCreateDataWithClassFuckKnows() 0 10 1
A testPaginatorOutput() 0 54 1
B testCursorOutput() 0 37 1
A testDefaultIncludeSuccess() 0 20 1
A tearDown() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php namespace League\Fractal\Test;
2
3
use League\Fractal\Manager;
4
use League\Fractal\Pagination\Cursor;
5
use League\Fractal\Resource\Collection;
6
use League\Fractal\Resource\Item;
7
use League\Fractal\Scope;
8
use League\Fractal\Serializer\ArraySerializer;
9
use League\Fractal\Test\Stub\Transformer\DefaultIncludeBookTransformer;
10
use Mockery;
11
12
class ScopeTest extends \PHPUnit_Framework_TestCase
13
{
14
    protected $simpleItem = ['foo' => 'bar'];
15
    protected $simpleCollection = [['foo' => 'bar']];
16
17
    public function testEmbedChildScope()
18
    {
19
        $manager = new Manager();
20
21
        $resource = new Item(['foo' => 'bar'], function () {
22
        });
23
24
        $scope = new Scope($manager, $resource, 'book');
25
        $this->assertSame($scope->getScopeIdentifier(), 'book');
26
        $childScope = $scope->embedChildScope('author', $resource);
27
28
        $this->assertInstanceOf('League\Fractal\Scope', $childScope);
29
    }
30
31 View Code Duplication
    public function testGetManager()
32
    {
33
        $resource = new Item(['foo' => 'bar'], function () {
34
        });
35
36
        $scope = new Scope(new Manager(), $resource, 'book');
37
38
        $this->assertInstanceOf('League\Fractal\Manager', $scope->getManager());
39
    }
40
41 View Code Duplication
    public function testGetResource()
42
    {
43
        $resource = new Item(['foo' => 'bar'], function () {
44
        });
45
46
        $scope = new Scope(new Manager(), $resource, 'book');
47
48
        $this->assertInstanceOf('League\Fractal\Resource\ResourceAbstract', $scope->getResource());
49
        $this->assertInstanceOf('League\Fractal\Resource\Item', $scope->getResource());
50
    }
51
52
    /**
53
     * @covers League\Fractal\Scope::toArray
54
     */
55
    public function testToArray()
56
    {
57
        $manager = new Manager();
58
59
        $resource = new Item(['foo' => 'bar'], function ($data) {
60
            return $data;
61
        });
62
63
        $scope = new Scope($manager, $resource);
64
65
66
        $this->assertSame(['data' => ['foo' => 'bar']], $scope->toArray());
67
    }
68
69
    public function testToJson()
70
    {
71
        $data = [
72
            'foo' => 'bar',
73
        ];
74
75
        $manager = new Manager();
76
77
        $resource = new Item($data, function ($data) {
78
            return $data;
79
        });
80
81
        $scope = new Scope($manager, $resource);
82
83
        $expected = json_encode([
84
            'data' => $data,
85
        ]);
86
87
        $this->assertSame($expected, $scope->toJson());
88
    }
89
90 View Code Duplication
    public function testGetCurrentScope()
91
    {
92
        $manager = new Manager();
93
94
        $resource = new Item(['name' => 'Larry Ullman'], function () {
95
        });
96
97
        $scope = new Scope($manager, $resource, 'book');
98
        $this->assertSame('book', $scope->getScopeIdentifier());
99
100
        $childScope = $scope->embedChildScope('author', $resource);
101
        $this->assertSame('author', $childScope->getScopeIdentifier());
102
103
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
104
        $this->assertSame('profile', $grandChildScope->getScopeIdentifier());
105
    }
106
107 View Code Duplication
    public function testGetIdentifier()
108
    {
109
        $manager = new Manager();
110
111
        $resource = new Item(['name' => 'Larry Ullman'], function () {
112
        });
113
114
        $scope = new Scope($manager, $resource, 'book');
115
        $this->assertSame('book', $scope->getIdentifier());
116
117
        $childScope = $scope->embedChildScope('author', $resource);
118
        $this->assertSame('book.author', $childScope->getIdentifier());
119
120
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
121
        $this->assertSame('book.author.profile', $grandChildScope->getIdentifier());
122
    }
123
124
    public function testGetParentScopes()
125
    {
126
        $manager = new Manager();
127
128
        $resource = new Item(['name' => 'Larry Ullman'], function () {
129
        });
130
131
        $scope = new Scope($manager, $resource, 'book');
132
133
        $childScope = $scope->embedChildScope('author', $resource);
134
135
        $this->assertSame(['book'], $childScope->getParentScopes());
136
137
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
138
        $this->assertSame(['book', 'author'], $grandChildScope->getParentScopes());
139
    }
140
141
    public function testIsRequested()
142
    {
143
        $manager = new Manager();
144
        $manager->parseIncludes(['foo', 'bar', 'baz.bart']);
145
146
        $scope = new Scope($manager, Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
147
148
        $this->assertTrue($scope->isRequested('foo'));
149
        $this->assertTrue($scope->isRequested('bar'));
150
        $this->assertTrue($scope->isRequested('baz'));
151
        $this->assertTrue($scope->isRequested('baz.bart'));
152
        $this->assertFalse($scope->isRequested('nope'));
153
154
        $childScope = $scope->embedChildScope('baz', Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
155
        $this->assertTrue($childScope->isRequested('bart'));
156
        $this->assertFalse($childScope->isRequested('foo'));
157
        $this->assertFalse($childScope->isRequested('bar'));
158
        $this->assertFalse($childScope->isRequested('baz'));
159
    }
160
161
    public function testIsExcluded()
162
    {
163
        $manager = new Manager();
164
        $manager->parseIncludes(['foo', 'bar', 'baz.bart']);
165
166
        $scope = new Scope($manager, Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
167
        $childScope = $scope->embedChildScope('baz', Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
0 ignored issues
show
Unused Code introduced by
$childScope is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
168
169
        $manager->parseExcludes('bar');
170
171
        $this->assertFalse($scope->isExcluded('foo'));
172
        $this->assertTrue($scope->isExcluded('bar'));
173
        $this->assertFalse($scope->isExcluded('baz.bart'));
174
175
        $manager->parseExcludes('baz.bart');
176
177
        $this->assertFalse($scope->isExcluded('baz'));
178
        $this->assertTrue($scope->isExcluded('baz.bart'));
179
    }
180
181
    /**
182
     * @expectedException InvalidArgumentException
183
     */
184
    public function testScopeRequiresConcreteImplementation()
185
    {
186
        $manager = new Manager();
187
        $manager->parseIncludes('book');
188
189
        $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', [
190
            ['bar' => 'baz'],
191
            function () {},
192
        ])->makePartial();
193
194
        $scope = new Scope($manager, $resource);
195
        $scope->toArray();
196
    }
197
198
    public function testToArrayWithIncludes()
199
    {
200
        $manager = new Manager();
201
        $manager->parseIncludes('book');
202
203
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
204
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn(['book']);
205
        $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
206
            return $data;
207
        });
208
        $transformer->shouldReceive('processIncludedResources')->once()->andReturn(['book' => ['yin' => 'yang']]);
209
210
        $resource = new Item(['bar' => 'baz'], $transformer);
211
212
        $scope = new Scope($manager, $resource);
213
214
        $this->assertSame(['data' => ['bar' => 'baz', 'book' => ['yin' => 'yang']]], $scope->toArray());
215
    }
216
217
    public function testToArrayWithSideloadedIncludes()
218
    {
219
        $serializer = Mockery::mock('League\Fractal\Serializer\ArraySerializer')->makePartial();
220
        $serializer->shouldReceive('sideloadIncludes')->andReturn(true);
221
        $serializer->shouldReceive('item')->andReturnUsing(function ($key, $data) {
222
            return ['data' => $data];
223
        });
224
        $serializer->shouldReceive('includedData')->andReturnUsing(function ($key, $data) {
225
            return ['sideloaded' => array_pop($data)];
226
        });
227
228
        $manager = new Manager();
229
        $manager->parseIncludes('book');
230
        $manager->setSerializer($serializer);
231
232
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
233
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn(['book']);
234
        $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
235
            return $data;
236
        });
237
        $transformer->shouldReceive('processIncludedResources')->once()->andReturn(['book' => ['yin' => 'yang']]);
238
239
        $resource = new Item(['bar' => 'baz'], $transformer);
240
241
        $scope = new Scope($manager, $resource);
242
243
        $expected = [
244
            'data' => ['bar' => 'baz'],
245
            'sideloaded' => ['book' => ['yin' => 'yang']],
246
        ];
247
248
        $this->assertSame($expected, $scope->toArray());
249
    }
250
251
    public function testPushParentScope()
252
    {
253
        $manager = new Manager();
254
255
        $resource = new Item(['name' => 'Larry Ullman'], function () {
256
        });
257
258
        $scope = new Scope($manager, $resource);
259
260
        $this->assertSame(1, $scope->pushParentScope('book'));
261
        $this->assertSame(2, $scope->pushParentScope('author'));
262
        $this->assertSame(3, $scope->pushParentScope('profile'));
263
264
265
        $this->assertSame(['book', 'author', 'profile'], $scope->getParentScopes());
266
    }
267
268
    public function testRunAppropriateTransformerWithItem()
269
    {
270
        $manager = new Manager();
271
272
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
273
        $transformer->shouldReceive('transform')->once()->andReturn($this->simpleItem);
274
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn([]);
275
        $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn([]);
276
        $transformer->shouldReceive('setCurrentScope')->once()->andReturn([]);
277
278
        $resource = new Item($this->simpleItem, $transformer);
279
        $scope = $manager->createData($resource);
280
281
        $this->assertSame(['data' => $this->simpleItem], $scope->toArray());
282
    }
283
284
    public function testRunAppropriateTransformerWithCollection()
285
    {
286
        $manager = new Manager();
287
288
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
289
        $transformer->shouldReceive('transform')->once()->andReturn(['foo' => 'bar']);
290
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn([]);
291
        $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn([]);
292
        $transformer->shouldReceive('setCurrentScope')->once()->andReturn([]);
293
294
        $resource = new Collection([['foo' => 'bar']], $transformer);
295
        $scope = $manager->createData($resource);
296
297
        $this->assertSame(['data' => [['foo' => 'bar']]], $scope->toArray());
298
299
    }
300
301
    /**
302
     * @covers League\Fractal\Scope::executeResourceTransformers
303
     * @expectedException InvalidArgumentException
304
     * @expectedExceptionMessage Argument $resource should be an instance of League\Fractal\Resource\Item or League\Fractal\Resource\Collection
305
     */
306
    public function testCreateDataWithClassFuckKnows()
307
    {
308
        $manager = new Manager();
309
310
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
311
312
        $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', [$this->simpleItem, $transformer])->makePartial();
313
        $scope = $manager->createData($resource);
314
        $scope->toArray();
315
    }
316
317
    public function testPaginatorOutput()
318
    {
319
        $manager = new Manager();
320
321
        $collection = new Collection([['foo' => 'bar', 'baz' => 'ban']], function (array $data) {
322
            return $data;
323
        });
324
325
        $paginator = Mockery::mock('League\Fractal\Pagination\IlluminatePaginatorAdapter')->makePartial();
326
327
        $total = 100;
328
        $perPage = $count = 5;
329
        $currentPage = 2;
330
        $lastPage = 20;
331
332
        $paginator->shouldReceive('getTotal')->once()->andReturn($total);
333
        $paginator->shouldReceive('getCount')->once()->andReturn($count);
334
        $paginator->shouldReceive('getPerPage')->once()->andReturn($perPage);
335
        $paginator->shouldReceive('getCurrentPage')->once()->andReturn($currentPage);
336
        $paginator->shouldReceive('getLastPage')->once()->andReturn($lastPage);
337
        $paginator->shouldReceive('getUrl')->times(2)->andReturnUsing(function ($page) {
338
            return 'http://example.com/foo?page='.$page;
339
        });
340
341
        $collection->setPaginator($paginator);
342
343
        $rootScope = $manager->createData($collection);
344
345
346
        $expectedOutput = [
347
            'data' => [
348
                [
349
                    'foo' => 'bar',
350
                    'baz' => 'ban',
351
                ],
352
            ],
353
            'meta' => [
354
                'pagination' => [
355
                    'total' => $total,
356
                    'count' => $count,
357
                    'per_page' => $perPage,
358
                    'current_page' => $currentPage,
359
                    'total_pages' => $lastPage,
360
                    'links' => [
361
                        'previous' => 'http://example.com/foo?page=1',
362
                        'next' => 'http://example.com/foo?page=3',
363
364
                    ],
365
                ],
366
            ],
367
        ];
368
369
        $this->assertSame($expectedOutput, $rootScope->toArray());
370
    }
371
372
    public function testCursorOutput()
373
    {
374
        $manager = new Manager();
375
376
        $inputData = [
377
            [
378
                'foo' => 'bar',
379
                'baz' => 'ban',
380
            ],
381
        ];
382
383
        $collection = new Collection($inputData, function (array $data) {
384
            return $data;
385
        });
386
387
        $cursor = new Cursor(0, 'ban', 'ban', 2);
388
389
        $collection->setCursor($cursor);
390
391
        $rootScope = $manager->createData($collection);
392
393
394
        $expectedOutput = [
395
            'data' => $inputData,
396
            'meta' => [
397
                'cursor' => [
398
                    'current' => 0,
399
                    'prev' => 'ban',
400
                    'next' => 'ban',
401
                    'count' => 2,
402
403
                ],
404
            ],
405
        ];
406
407
        $this->assertSame($expectedOutput, $rootScope->toArray());
408
    }
409
410
    public function testDefaultIncludeSuccess()
411
    {
412
        $manager = new Manager();
413
        $manager->setSerializer(new ArraySerializer());
414
415
        // Send this stub junk, it has a specific format anyhow
416
        $resource = new Item([], new DefaultIncludeBookTransformer());
417
418
        // Try without metadata
419
        $scope = new Scope($manager, $resource);
420
421
        $expected = [
422
            'a' => 'b',
423
            'author' => [
424
                'c' => 'd',
425
            ],
426
        ];
427
428
        $this->assertSame($expected, $scope->toArray());
429
    }
430
431
    public function tearDown()
432
    {
433
        Mockery::close();
434
    }
435
}
436