Completed
Push — master ( 93f6e0...a7ea34 )
by Aydin
27:25 queued 18:55
created

testThrowHttpExceptionHandledProperly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 17
rs 9.4286
cc 1
eloc 9
nc 1
nop 0
1
<?php
2
/**
3
 * Klein (klein.php) - A fast & flexible router for PHP
4
 *
5
 * @author      Chris O'Hara <[email protected]>
6
 * @author      Trevor Suarez (Rican7) (contributor and v2 refactorer)
7
 * @copyright   (c) Chris O'Hara
8
 * @link        https://github.com/chriso/klein.php
9
 * @license     MIT
10
 */
11
12
namespace Klein\Tests;
13
14
use Klein\App;
15
use Klein\DataCollection\RouteCollection;
16
use Klein\Exceptions\DispatchHaltedException;
17
use Klein\Exceptions\HttpException;
18
use Klein\Exceptions\RoutePathCompilationException;
19
use Klein\Klein;
20
use Klein\Request;
21
use Klein\Response;
22
use Klein\Route;
23
use Klein\ServiceProvider;
24
use Klein\Tests\Mocks\HeadersEcho;
25
use Klein\Tests\Mocks\HeadersSave;
26
use Klein\Tests\Mocks\MockRequestFactory;
27
28
/**
29
 * RoutingTest
30
 */
31
class RoutingTest extends AbstractKleinTest
32
{
33
34
    public function testBasic()
35
    {
36
        $this->expectOutputString('x');
37
38
        $this->klein_app->respond(
39
            '/',
40
            function () {
41
                echo 'x';
42
            }
43
        );
44
        $this->klein_app->respond(
45
            '/something',
46
            function () {
47
                echo 'y';
48
            }
49
        );
50
51
        $this->klein_app->dispatch(
52
            MockRequestFactory::create('/')
53
        );
54
    }
55
56
    public function testCallable()
57
    {
58
        $this->expectOutputString('okok');
59
60
        $this->klein_app->respond('/', array(__NAMESPACE__ . '\Mocks\TestClass', 'GET'));
61
        $this->klein_app->respond('/', __NAMESPACE__ . '\Mocks\TestClass::GET');
62
63
        $this->klein_app->dispatch(
64
            MockRequestFactory::create('/')
65
        );
66
    }
67
68
    public function testCallbackArguments()
69
    {
70
        // Create expected objects
71
        $expected_objects = array(
72
            'request'         => null,
73
            'response'        => null,
74
            'service'         => null,
75
            'app'             => null,
76
            'klein'           => null,
77
            'matched'         => null,
78
            'methods_matched' => null,
79
        );
80
81
        $this->klein_app->respond(
82
            function ($a, $b, $c, $d, $e, $f, $g) use (&$expected_objects) {
83
                $expected_objects['request']         = $a;
84
                $expected_objects['response']        = $b;
85
                $expected_objects['service']         = $c;
86
                $expected_objects['app']             = $d;
87
                $expected_objects['klein']           = $e;
88
                $expected_objects['matched']         = $f;
89
                $expected_objects['methods_matched'] = $g;
90
            }
91
        );
92
93
        $this->klein_app->dispatch();
94
95
        $this->assertTrue($expected_objects['request'] instanceof Request);
96
        $this->assertTrue($expected_objects['response'] instanceof Response);
97
        $this->assertTrue($expected_objects['service'] instanceof ServiceProvider);
98
        $this->assertTrue($expected_objects['app'] instanceof App);
99
        $this->assertTrue($expected_objects['klein'] instanceof Klein);
100
        $this->assertTrue($expected_objects['matched'] instanceof RouteCollection);
101
        $this->assertTrue(is_array($expected_objects['methods_matched']));
102
103
        $this->assertSame($expected_objects['request'], $this->klein_app->request());
104
        $this->assertSame($expected_objects['response'], $this->klein_app->response());
105
        $this->assertSame($expected_objects['service'], $this->klein_app->service());
106
        $this->assertSame($expected_objects['app'], $this->klein_app->app());
107
        $this->assertSame($expected_objects['klein'], $this->klein_app);
108
    }
109
110
    public function testAppReference()
111
    {
112
        $this->expectOutputString('ab');
113
114
        $this->klein_app->respond(
115
            '/',
116
            function ($r, $r, $s, $a) {
0 ignored issues
show
Bug introduced by
The parameter $r is used multiple times.
Loading history...
117
                $a->state = 'a';
118
            }
119
        );
120
        $this->klein_app->respond(
121
            '/',
122
            function ($r, $r, $s, $a) {
0 ignored issues
show
Bug introduced by
The parameter $r is used multiple times.
Loading history...
123
                $a->state .= 'b';
124
            }
125
        );
126
        $this->klein_app->respond(
127
            '/',
128
            function ($r, $r, $s, $a) {
0 ignored issues
show
Bug introduced by
The parameter $r is used multiple times.
Loading history...
129
                print $a->state;
130
            }
131
        );
132
133
        $this->klein_app->dispatch(
134
            MockRequestFactory::create('/')
135
        );
136
    }
137
138
    public function testDispatchOutput()
139
    {
140
        $expectedOutput = array(
141
            'returned1' => 'alright!',
142
            'returned2' => 'woot!',
143
        );
144
145
        $this->klein_app->respond(
146
            function () use ($expectedOutput) {
147
                return $expectedOutput['returned1'];
148
            }
149
        );
150
        $this->klein_app->respond(
151
            function () use ($expectedOutput) {
152
                return $expectedOutput['returned2'];
153
            }
154
        );
155
156
        $this->klein_app->dispatch();
157
158
        // Expect our output to match our ECHO'd output
159
        $this->expectOutputString(
160
            $expectedOutput['returned1'] . $expectedOutput['returned2']
161
        );
162
163
        // Make sure our response body matches the concatenation of what we returned in each callback
164
        $this->assertSame(
165
            $expectedOutput['returned1'] . $expectedOutput['returned2'],
166
            $this->klein_app->response()->body()
167
        );
168
    }
169
170 View Code Duplication
    public function testDispatchOutputNotSent()
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...
171
    {
172
        $this->klein_app->respond(
173
            function () {
174
                return 'test output';
175
            }
176
        );
177
178
        $this->klein_app->dispatch(null, null, false);
179
180
        $this->expectOutputString('');
181
182
        $this->assertSame(
183
            'test output',
184
            $this->klein_app->response()->body()
185
        );
186
    }
187
188
    public function testDispatchOutputCaptured()
189
    {
190
        $expectedOutput = array(
191
            'echoed' => 'yup',
192
            'returned' => 'nope',
193
        );
194
195
        $this->klein_app->respond(
196
            function () use ($expectedOutput) {
197
                echo $expectedOutput['echoed'];
198
            }
199
        );
200
        $this->klein_app->respond(
201
            function () use ($expectedOutput) {
202
                return $expectedOutput['returned'];
203
            }
204
        );
205
206
        $output = $this->klein_app->dispatch(null, null, true, Klein::DISPATCH_CAPTURE_AND_RETURN);
207
208
        // Make sure nothing actually printed to the screen
209
        $this->expectOutputString('');
210
211
        // Make sure our returned output matches what we ECHO'd
212
        $this->assertSame($expectedOutput['echoed'], $output);
213
214
        // Make sure our response body matches what we returned
215
        $this->assertSame($expectedOutput['returned'], $this->klein_app->response()->body());
216
    }
217
218
    public function testDispatchOutputReplaced()
219
    {
220
        $expectedOutput = array(
221
            'echoed' => 'yup',
222
            'returned' => 'nope',
223
        );
224
225
        $this->klein_app->respond(
226
            function () use ($expectedOutput) {
227
                echo $expectedOutput['echoed'];
228
            }
229
        );
230
        $this->klein_app->respond(
231
            function () use ($expectedOutput) {
232
                return $expectedOutput['returned'];
233
            }
234
        );
235
236
        $this->klein_app->dispatch(null, null, false, Klein::DISPATCH_CAPTURE_AND_REPLACE);
237
238
        // Make sure nothing actually printed to the screen
239
        $this->expectOutputString('');
240
241
        // Make sure our response body matches what we echoed
242
        $this->assertSame($expectedOutput['echoed'], $this->klein_app->response()->body());
243
    }
244
245 View Code Duplication
    public function testDispatchOutputPrepended()
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...
246
    {
247
        $expectedOutput = array(
248
            'echoed' => 'yup',
249
            'returned' => 'nope',
250
            'echoed2' => 'sure',
251
        );
252
253
        $this->klein_app->respond(
254
            function () use ($expectedOutput) {
255
                echo $expectedOutput['echoed'];
256
            }
257
        );
258
        $this->klein_app->respond(
259
            function () use ($expectedOutput) {
260
                return $expectedOutput['returned'];
261
            }
262
        );
263
        $this->klein_app->respond(
264
            function () use ($expectedOutput) {
265
                echo $expectedOutput['echoed2'];
266
            }
267
        );
268
269
        $this->klein_app->dispatch(null, null, false, Klein::DISPATCH_CAPTURE_AND_PREPEND);
270
271
        // Make sure nothing actually printed to the screen
272
        $this->expectOutputString('');
273
274
        // Make sure our response body matches what we echoed
275
        $this->assertSame(
276
            $expectedOutput['echoed'] . $expectedOutput['echoed2'] . $expectedOutput['returned'],
277
            $this->klein_app->response()->body()
278
        );
279
    }
280
281 View Code Duplication
    public function testDispatchOutputAppended()
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...
282
    {
283
        $expectedOutput = array(
284
            'echoed' => 'yup',
285
            'returned' => 'nope',
286
            'echoed2' => 'sure',
287
        );
288
289
        $this->klein_app->respond(
290
            function () use ($expectedOutput) {
291
                echo $expectedOutput['echoed'];
292
            }
293
        );
294
        $this->klein_app->respond(
295
            function () use ($expectedOutput) {
296
                return $expectedOutput['returned'];
297
            }
298
        );
299
        $this->klein_app->respond(
300
            function () use ($expectedOutput) {
301
                echo $expectedOutput['echoed2'];
302
            }
303
        );
304
305
        $this->klein_app->dispatch(null, null, false, Klein::DISPATCH_CAPTURE_AND_APPEND);
306
307
        // Make sure nothing actually printed to the screen
308
        $this->expectOutputString('');
309
310
        // Make sure our response body matches what we echoed
311
        $this->assertSame(
312
            $expectedOutput['returned'] . $expectedOutput['echoed'] . $expectedOutput['echoed2'],
313
            $this->klein_app->response()->body()
314
        );
315
    }
316
317
    public function testDispatchResponseReplaced()
318
    {
319
        $expected_body = 'You SHOULD see this';
320
        $expected_code = 201;
321
322
        $expected_append = 'This should be appended?';
323
324
        $this->klein_app->respond(
325
            '/',
326
            function ($request, $response) {
327
                // Set our response code
328
                $response->code(569);
329
330
                return 'This should disappear';
331
            }
332
        );
333
        $this->klein_app->respond(
334
            '/',
335
            function () use ($expected_body, $expected_code) {
336
                return new Response($expected_body, $expected_code);
337
            }
338
        );
339
        $this->klein_app->respond(
340
            '/',
341
            function () use ($expected_append) {
342
                return $expected_append;
343
            }
344
        );
345
346
        $this->klein_app->dispatch(null, null, false, Klein::DISPATCH_CAPTURE_AND_RETURN);
347
348
        // Make sure our response body and code match up
349
        $this->assertSame(
350
            $expected_body . $expected_append,
351
            $this->klein_app->response()->body()
352
        );
353
        $this->assertSame(
354
            $expected_code,
355
            $this->klein_app->response()->code()
356
        );
357
    }
358
359
    public function testRespondReturn()
360
    {
361
        $return_one = $this->klein_app->respond(
362
            function () {
363
                return 1337;
364
            }
365
        );
366
        $return_two = $this->klein_app->respond(
367
            function () {
368
                return 'dog';
369
            }
370
        );
371
372
        $this->klein_app->dispatch(null, null, false);
373
374
        $this->assertTrue(is_callable($return_one));
375
        $this->assertTrue(is_callable($return_two));
376
    }
377
378
    public function testRespondReturnChaining()
379
    {
380
        $return_one = $this->klein_app->respond(
381
            function () {
382
                return 1337;
383
            }
384
        );
385
        $return_two = $this->klein_app->respond(
386
            function () {
387
                return 1337;
388
            }
389
        )->getPath();
390
391
        $this->assertSame($return_one->getPath(), $return_two);
392
    }
393
394 View Code Duplication
    public function testCatchallImplicit()
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...
395
    {
396
        $this->expectOutputString('b');
397
398
        $this->klein_app->respond(
399
            '/one',
400
            function () {
401
                echo 'a';
402
            }
403
        );
404
        $this->klein_app->respond(
405
            function () {
406
                echo 'b';
407
            }
408
        );
409
        $this->klein_app->respond(
410
            '/two',
411
            function () {
412
413
            }
414
        );
415
        $this->klein_app->respond(
416
            '/three',
417
            function () {
418
                echo 'c';
419
            }
420
        );
421
422
        $this->klein_app->dispatch(
423
            MockRequestFactory::create('/two')
424
        );
425
    }
426
427 View Code Duplication
    public function testCatchallAsterisk()
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...
428
    {
429
        $this->expectOutputString('b');
430
431
        $this->klein_app->respond(
432
            '/one',
433
            function () {
434
                echo 'a';
435
            }
436
        );
437
        $this->klein_app->respond(
438
            '*',
439
            function () {
440
                echo 'b';
441
            }
442
        );
443
        $this->klein_app->respond(
444
            '/two',
445
            function () {
446
447
            }
448
        );
449
        $this->klein_app->respond(
450
            '/three',
451
            function () {
452
                echo 'c';
453
            }
454
        );
455
456
        $this->klein_app->dispatch(
457
            MockRequestFactory::create('/two')
458
        );
459
    }
460
461
    public function testCatchallImplicitTriggers404()
462
    {
463
        $this->expectOutputString("b404\n");
464
465
        $this->klein_app->onHttpError(
466
            function ($code) {
467
                if (404 === $code) {
468
                    echo "404\n";
469
                }
470
            }
471
        );
472
473
        $this->klein_app->respond(
474
            function () {
475
                echo 'b';
476
            }
477
        );
478
479
        $this->klein_app->dispatch(
480
            MockRequestFactory::create('/')
481
        );
482
    }
483
484
    public function testRegex()
485
    {
486
        $this->expectOutputString('zz');
487
488
        $this->klein_app->respond(
489
            '@/bar',
490
            function () {
491
                echo 'z';
492
            }
493
        );
494
495
        $this->klein_app->respond(
496
            '@/[0-9]s',
497
            function () {
498
                echo 'z';
499
            }
500
        );
501
502
        $this->klein_app->dispatch(
503
            MockRequestFactory::create('/bar')
504
        );
505
        $this->klein_app->dispatch(
506
            MockRequestFactory::create('/8s')
507
        );
508
        $this->klein_app->dispatch(
509
            MockRequestFactory::create('/88s')
510
        );
511
    }
512
513
    public function testRegexNegate()
514
    {
515
        $this->expectOutputString("y");
516
517
        $this->klein_app->respond(
518
            '!@/foo',
519
            function () {
520
                echo 'y';
521
            }
522
        );
523
524
        $this->klein_app->dispatch(
525
            MockRequestFactory::create('/bar')
526
        );
527
    }
528
529
    public function testNormalNegate()
530
    {
531
        $this->expectOutputString('');
532
533
        $this->klein_app->respond(
534
            '!/foo',
535
            function () {
536
                echo 'y';
537
            }
538
        );
539
540
        $this->klein_app->dispatch(
541
            MockRequestFactory::create('/foo')
542
        );
543
    }
544
545
    public function test404()
546
    {
547
        $this->expectOutputString("404\n");
548
549
        $this->klein_app->onHttpError(
550
            function ($code) {
551
                if (404 === $code) {
552
                    echo "404\n";
553
                }
554
            }
555
        );
556
557
        $this->klein_app->respond(
558
            '/',
559
            function () {
560
                echo 'a';
561
            }
562
        );
563
564
        $this->klein_app->dispatch(
565
            MockRequestFactory::create('/foo')
566
        );
567
568
        $this->assertSame(404, $this->klein_app->response()->code());
569
    }
570
571
    public function testParamsBasic()
572
    {
573
        $this->expectOutputString('blue');
574
575
        $this->klein_app->respond(
576
            '/[:color]',
577
            function ($request) {
578
                echo $request->param('color');
579
            }
580
        );
581
582
        $this->klein_app->dispatch(
583
            MockRequestFactory::create('/blue')
584
        );
585
    }
586
587
    public function testParamsIntegerSuccess()
588
    {
589
        $this->expectOutputString("string(3) \"987\"\n");
590
591
        $this->klein_app->respond(
592
            '/[i:age]',
593
            function ($request) {
594
                var_dump($request->param('age'));
0 ignored issues
show
Security Debugging Code introduced by
var_dump($request->param('age')); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
595
            }
596
        );
597
598
        $this->klein_app->dispatch(
599
            MockRequestFactory::create('/987')
600
        );
601
    }
602
603
    public function testParamsIntegerFail()
604
    {
605
        $this->expectOutputString('404 Code');
606
607
        $this->klein_app->onHttpError(
608
            function ($code) {
609
                if (404 === $code) {
610
                    echo '404 Code';
611
                }
612
            }
613
        );
614
615
        $this->klein_app->respond(
616
            '/[i:age]',
617
            function ($request) {
618
                var_dump($request->param('age'));
0 ignored issues
show
Security Debugging Code introduced by
var_dump($request->param('age')); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
619
            }
620
        );
621
622
        $this->klein_app->dispatch(
623
            MockRequestFactory::create('/blue')
624
        );
625
    }
626
627
    public function testParamsAlphaNum()
628
    {
629
        $this->klein_app->respond(
630
            '/[a:audible]',
631
            function ($request) {
632
                echo $request->param('audible');
633
            }
634
        );
635
636
637
        $this->assertSame(
638
            'blue42',
639
            $this->dispatchAndReturnOutput(
640
                MockRequestFactory::create('/blue42')
641
            )
642
        );
643
        $this->assertSame(
644
            '',
645
            $this->dispatchAndReturnOutput(
646
                MockRequestFactory::create('/texas-29')
647
            )
648
        );
649
        $this->assertSame(
650
            '',
651
            $this->dispatchAndReturnOutput(
652
                MockRequestFactory::create('/texas29!')
653
            )
654
        );
655
    }
656
657
    public function testParamsHex()
658
    {
659
        $this->klein_app->respond(
660
            '/[h:hexcolor]',
661
            function ($request) {
662
                echo $request->param('hexcolor');
663
            }
664
        );
665
666
667
        $this->assertSame(
668
            '00f',
669
            $this->dispatchAndReturnOutput(
670
                MockRequestFactory::create('/00f')
671
            )
672
        );
673
        $this->assertSame(
674
            'abc123',
675
            $this->dispatchAndReturnOutput(
676
                MockRequestFactory::create('/abc123')
677
            )
678
        );
679
        $this->assertSame(
680
            '',
681
            $this->dispatchAndReturnOutput(
682
                MockRequestFactory::create('/876zih')
683
            )
684
        );
685
        $this->assertSame(
686
            '',
687
            $this->dispatchAndReturnOutput(
688
                MockRequestFactory::create('/00g')
689
            )
690
        );
691
        $this->assertSame(
692
            '',
693
            $this->dispatchAndReturnOutput(
694
                MockRequestFactory::create('/hi23')
695
            )
696
        );
697
    }
698
699
    public function testParamsSlug()
700
    {
701
        $this->klein_app->respond(
702
            '/[s:slug_name]',
703
            function ($request) {
704
                echo $request->param('slug_name');
705
            }
706
        );
707
708
709
        $this->assertSame(
710
            'dog-thing',
711
            $this->dispatchAndReturnOutput(
712
                MockRequestFactory::create('/dog-thing')
713
            )
714
        );
715
        $this->assertSame(
716
            'a_badass_slug',
717
            $this->dispatchAndReturnOutput(
718
                MockRequestFactory::create('/a_badass_slug')
719
            )
720
        );
721
        $this->assertSame(
722
            'AN_UPERCASE_SLUG',
723
            $this->dispatchAndReturnOutput(
724
                MockRequestFactory::create('/AN_UPERCASE_SLUG')
725
            )
726
        );
727
        $this->assertSame(
728
            'sample-wordpress-like-post-slug-based-on-the-title-2013-edition',
729
            $this->dispatchAndReturnOutput(
730
                MockRequestFactory::create('/sample-wordpress-like-post-slug-based-on-the-title-2013-edition')
731
            )
732
        );
733
        $this->assertSame(
734
            '',
735
            $this->dispatchAndReturnOutput(
736
                MockRequestFactory::create('/%!@#')
737
            )
738
        );
739
        $this->assertSame(
740
            '',
741
            $this->dispatchAndReturnOutput(
742
                MockRequestFactory::create('/')
743
            )
744
        );
745
        $this->assertSame(
746
            '',
747
            $this->dispatchAndReturnOutput(
748
                MockRequestFactory::create('/dog-%thing')
749
            )
750
        );
751
    }
752
753 View Code Duplication
    public function testPathParamsAreUrlDecoded()
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...
754
    {
755
        $this->klein_app->respond(
756
            '/[:test]',
757
            function ($request) {
758
                echo $request->param('test');
759
            }
760
        );
761
762
        $this->assertSame(
763
            'Knife Party',
764
            $this->dispatchAndReturnOutput(
765
                MockRequestFactory::create('/Knife%20Party')
766
            )
767
        );
768
769
        $this->assertSame(
770
            'and/or',
771
            $this->dispatchAndReturnOutput(
772
                MockRequestFactory::create('/and%2For')
773
            )
774
        );
775
    }
776
777 View Code Duplication
    public function testPathParamsAreUrlDecodedToRFC3986Spec()
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...
778
    {
779
        $this->klein_app->respond(
780
            '/[:test]',
781
            function ($request) {
782
                echo $request->param('test');
783
            }
784
        );
785
786
        $this->assertNotSame(
787
            'Knife Party',
788
            $this->dispatchAndReturnOutput(
789
                MockRequestFactory::create('/Knife+Party')
790
            )
791
        );
792
793
        $this->assertSame(
794
            'Knife+Party',
795
            $this->dispatchAndReturnOutput(
796
                MockRequestFactory::create('/Knife+Party')
797
            )
798
        );
799
    }
800
801
    public function test404TriggersOnce()
802
    {
803
        $this->expectOutputString('d404 Code');
804
805
        $this->klein_app->onHttpError(
806
            function ($code) {
807
                if (404 === $code) {
808
                    echo '404 Code';
809
                }
810
            }
811
        );
812
813
        $this->klein_app->respond(
814
            function () {
815
                echo "d";
816
            }
817
        );
818
819
        $this->klein_app->dispatch(
820
            MockRequestFactory::create('/notroute')
821
        );
822
    }
823
824
    public function test404RouteDefinitionOrderDoesntEffectWhen404HandlersCalled()
825
    {
826
        $this->expectOutputString('onetwo404 Code');
827
828
        $this->klein_app->respond(
829
            function () {
830
                echo 'one';
831
            }
832
        );
833
        $this->klein_app->respond(
834
            '404',
835
            function () {
836
                echo '404 Code';
837
            }
838
        );
839
        $this->klein_app->respond(
840
            function () {
841
                echo 'two';
842
            }
843
        );
844
845
        // Ignore our deprecation error
846
        $old_error_val = error_reporting();
847
        error_reporting(E_ALL ^ E_USER_DEPRECATED);
848
849
        $this->klein_app->dispatch(
850
            MockRequestFactory::create('/notroute')
851
        );
852
853
        error_reporting($old_error_val);
854
    }
855
856
    public function testMethodCatchAll()
857
    {
858
        $this->expectOutputString('yup!123');
859
860
        $this->klein_app->respond(
861
            'POST',
862
            null,
863
            function ($request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
864
                echo 'yup!';
865
            }
866
        );
867
        $this->klein_app->respond(
868
            'POST',
869
            '*',
870
            function ($request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
871
                echo '1';
872
            }
873
        );
874
        $this->klein_app->respond(
875
            'POST',
876
            '/',
877
            function ($request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
878
                echo '2';
879
            }
880
        );
881
        $this->klein_app->respond(
882
            function ($request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
883
                echo '3';
884
            }
885
        );
886
887
        $this->klein_app->dispatch(
888
            MockRequestFactory::create('/', 'POST')
889
        );
890
    }
891
892 View Code Duplication
    public function testLazyTrailingMatch()
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...
893
    {
894
        $this->expectOutputString('this-is-a-title-123');
895
896
        $this->klein_app->respond(
897
            '/posts/[*:title][i:id]',
898
            function ($request) {
899
                echo $request->param('title')
900
                . $request->param('id');
901
            }
902
        );
903
904
        $this->klein_app->dispatch(
905
            MockRequestFactory::create('/posts/this-is-a-title-123')
906
        );
907
    }
908
909
    public function testFormatMatch()
910
    {
911
        $this->expectOutputString('xml');
912
913
        $this->klein_app->respond(
914
            '/output.[xml|json:format]',
915
            function ($request) {
916
                echo $request->param('format');
917
            }
918
        );
919
920
        $this->klein_app->dispatch(
921
            MockRequestFactory::create('/output.xml')
922
        );
923
    }
924
925
    public function testDotSeparator()
926
    {
927
        $this->expectOutputString('matchA:slug=ABCD_E--matchB:slug=ABCD_E--');
928
929
        $this->klein_app->respond(
930
            '/[*:cpath]/[:slug].[:format]',
931
            function ($rq) {
932
                echo 'matchA:slug='.$rq->param("slug").'--';
933
            }
934
        );
935
        $this->klein_app->respond(
936
            '/[*:cpath]/[:slug].[:format]?',
937
            function ($rq) {
938
                echo 'matchB:slug='.$rq->param("slug").'--';
939
            }
940
        );
941
        $this->klein_app->respond(
942
            '/[*:cpath]/[a:slug].[:format]?',
943
            function ($rq) {
944
                echo 'matchC:slug='.$rq->param("slug").'--';
945
            }
946
        );
947
948
        $this->klein_app->dispatch(
949
            MockRequestFactory::create("/category1/categoryX/ABCD_E.php")
950
        );
951
952
        $this->assertSame(
953
            'matchA:slug=ABCD_E--matchB:slug=ABCD_E--',
954
            $this->dispatchAndReturnOutput(
955
                MockRequestFactory::create('/category1/categoryX/ABCD_E.php')
956
            )
957
        );
958
        $this->assertSame(
959
            'matchB:slug=ABCD_E--',
960
            $this->dispatchAndReturnOutput(
961
                MockRequestFactory::create('/category1/categoryX/ABCD_E')
962
            )
963
        );
964
    }
965
966 View Code Duplication
    public function testControllerActionStyleRouteMatch()
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...
967
    {
968
        $this->expectOutputString('donkey-kick');
969
970
        $this->klein_app->respond(
971
            '/[:controller]?/[:action]?',
972
            function ($request) {
973
                echo $request->param('controller')
974
                     . '-' . $request->param('action');
975
            }
976
        );
977
978
        $this->klein_app->dispatch(
979
            MockRequestFactory::create('/donkey/kick')
980
        );
981
    }
982
983
    public function testRespondArgumentOrder()
984
    {
985
        $this->expectOutputString('abcdef');
986
987
        $this->klein_app->respond(
988
            function () {
989
                echo 'a';
990
            }
991
        );
992
        $this->klein_app->respond(
993
            null,
994
            function () {
995
                echo 'b';
996
            }
997
        );
998
        $this->klein_app->respond(
999
            '/endpoint',
1000
            function () {
1001
                echo 'c';
1002
            }
1003
        );
1004
        $this->klein_app->respond(
1005
            'GET',
1006
            null,
1007
            function () {
1008
                echo 'd';
1009
            }
1010
        );
1011
        $this->klein_app->respond(
1012
            array('GET', 'POST'),
1013
            null,
1014
            function () {
1015
                echo 'e';
1016
            }
1017
        );
1018
        $this->klein_app->respond(
1019
            array('GET', 'POST'),
1020
            '/endpoint',
1021
            function () {
1022
                echo 'f';
1023
            }
1024
        );
1025
1026
        $this->klein_app->dispatch(
1027
            MockRequestFactory::create('/endpoint')
1028
        );
1029
    }
1030
1031 View Code Duplication
    public function testTrailingMatch()
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...
1032
    {
1033
        $this->klein_app->respond(
1034
            '/?[*:trailing]/dog/?',
1035
            function ($request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1036
                echo 'yup';
1037
            }
1038
        );
1039
1040
1041
        $this->assertSame(
1042
            'yup',
1043
            $this->dispatchAndReturnOutput(
1044
                MockRequestFactory::create('/cat/dog')
1045
            )
1046
        );
1047
        $this->assertSame(
1048
            'yup',
1049
            $this->dispatchAndReturnOutput(
1050
                MockRequestFactory::create('/cat/cheese/dog')
1051
            )
1052
        );
1053
        $this->assertSame(
1054
            'yup',
1055
            $this->dispatchAndReturnOutput(
1056
                MockRequestFactory::create('/cat/ball/cheese/dog/')
1057
            )
1058
        );
1059
        $this->assertSame(
1060
            'yup',
1061
            $this->dispatchAndReturnOutput(
1062
                MockRequestFactory::create('/cat/ball/cheese/dog')
1063
            )
1064
        );
1065
        $this->assertSame(
1066
            'yup',
1067
            $this->dispatchAndReturnOutput(
1068
                MockRequestFactory::create('cat/ball/cheese/dog/')
1069
            )
1070
        );
1071
        $this->assertSame(
1072
            'yup',
1073
            $this->dispatchAndReturnOutput(
1074
                MockRequestFactory::create('cat/ball/cheese/dog')
1075
            )
1076
        );
1077
    }
1078
1079
    public function testTrailingPossessiveMatch()
1080
    {
1081
        $this->klein_app->respond(
1082
            '/sub-dir/[**:trailing]',
1083
            function ($request) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1084
                echo 'yup';
1085
            }
1086
        );
1087
1088
1089
        $this->assertSame(
1090
            'yup',
1091
            $this->dispatchAndReturnOutput(
1092
                MockRequestFactory::create('/sub-dir/dog')
1093
            )
1094
        );
1095
1096
        $this->assertSame(
1097
            'yup',
1098
            $this->dispatchAndReturnOutput(
1099
                MockRequestFactory::create('/sub-dir/cheese/dog')
1100
            )
1101
        );
1102
1103
        $this->assertSame(
1104
            'yup',
1105
            $this->dispatchAndReturnOutput(
1106
                MockRequestFactory::create('/sub-dir/ball/cheese/dog/')
1107
            )
1108
        );
1109
1110
        $this->assertSame(
1111
            'yup',
1112
            $this->dispatchAndReturnOutput(
1113
                MockRequestFactory::create('/sub-dir/ball/cheese/dog')
1114
            )
1115
        );
1116
    }
1117
1118
    public function testNSDispatch()
1119
    {
1120
        $this->klein_app->with(
1121
            '/u',
1122
            function ($klein_app) {
1123
                $klein_app->respond(
1124
                    'GET',
1125
                    '/?',
1126
                    function ($request, $response) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $response is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1127
                        echo "slash";
1128
                    }
1129
                );
1130
                $klein_app->respond(
1131
                    'GET',
1132
                    '/[:id]',
1133
                    function ($request, $response) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $response is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1134
                        echo "id";
1135
                    }
1136
                );
1137
            }
1138
        );
1139
1140
        $this->klein_app->onHttpError(
1141
            function ($code) {
1142
                if (404 === $code) {
1143
                    echo "404";
1144
                }
1145
            }
1146
        );
1147
1148
1149
        $this->assertSame(
1150
            "slash",
1151
            $this->dispatchAndReturnOutput(
1152
                MockRequestFactory::create("/u")
1153
            )
1154
        );
1155
        $this->assertSame(
1156
            "slash",
1157
            $this->dispatchAndReturnOutput(
1158
                MockRequestFactory::create("/u/")
1159
            )
1160
        );
1161
        $this->assertSame(
1162
            "id",
1163
            $this->dispatchAndReturnOutput(
1164
                MockRequestFactory::create("/u/35")
1165
            )
1166
        );
1167
        $this->assertSame(
1168
            "404",
1169
            $this->dispatchAndReturnOutput(
1170
                MockRequestFactory::create("/35")
1171
            )
1172
        );
1173
    }
1174
1175 View Code Duplication
    public function testNSDispatchExternal()
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...
1176
    {
1177
        $ext_namespaces = $this->loadExternalRoutes();
1178
1179
        $this->klein_app->respond(
1180
            404,
1181
            function ($request, $response) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $response is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1182
                echo "404";
1183
            }
1184
        );
1185
1186
        foreach ($ext_namespaces as $namespace) {
1187
1188
            $this->assertSame(
1189
                'yup',
1190
                $this->dispatchAndReturnOutput(
1191
                    MockRequestFactory::create($namespace . '/')
1192
                )
1193
            );
1194
1195
            $this->assertSame(
1196
                'yup',
1197
                $this->dispatchAndReturnOutput(
1198
                    MockRequestFactory::create($namespace . '/testing/')
1199
                )
1200
            );
1201
        }
1202
    }
1203
1204 View Code Duplication
    public function testNSDispatchExternalRerequired()
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...
1205
    {
1206
        $ext_namespaces = $this->loadExternalRoutes();
1207
1208
        $this->klein_app->respond(
1209
            404,
1210
            function ($request, $response) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $response is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1211
                echo "404";
1212
            }
1213
        );
1214
1215
        foreach ($ext_namespaces as $namespace) {
1216
1217
            $this->assertSame(
1218
                'yup',
1219
                $this->dispatchAndReturnOutput(
1220
                    MockRequestFactory::create($namespace . '/')
1221
                )
1222
            );
1223
1224
            $this->assertSame(
1225
                'yup',
1226
                $this->dispatchAndReturnOutput(
1227
                    MockRequestFactory::create($namespace . '/testing/')
1228
                )
1229
            );
1230
        }
1231
    }
1232
1233 View Code Duplication
    public function test405DefaultRequest()
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...
1234
    {
1235
        $this->klein_app->respond(
1236
            array('GET', 'POST'),
1237
            '/',
1238
            function () {
1239
                echo 'fail';
1240
            }
1241
        );
1242
1243
        $this->klein_app->dispatch(
1244
            MockRequestFactory::create('/', 'DELETE')
1245
        );
1246
1247
        $this->assertEquals('405 Method Not Allowed', $this->klein_app->response()->status()->getFormattedString());
1248
        $this->assertEquals('GET, POST', $this->klein_app->response()->headers()->get('Allow'));
1249
    }
1250
1251
    public function testNo405OnNonMatchRoutes()
1252
    {
1253
        $this->klein_app->respond(
1254
            array('GET', 'POST'),
1255
            null,
1256
            function () {
1257
                echo 'this shouldn\'t cause a 405 since this route doesn\'t count as a match anyway';
1258
            }
1259
        );
1260
1261
        $this->klein_app->dispatch(
1262
            MockRequestFactory::create('/', 'DELETE')
1263
        );
1264
1265
        $this->assertEquals(404, $this->klein_app->response()->code());
1266
    }
1267
1268
    public function test405Routes()
1269
    {
1270
        $resultArray = array();
1271
1272
        $this->expectOutputString('_');
1273
1274
        $this->klein_app->respond(
1275
            function () {
1276
                echo '_';
1277
            }
1278
        );
1279
        $this->klein_app->respond(
1280
            'GET',
1281
            '/sure',
1282
            function () {
1283
                echo 'fail';
1284
            }
1285
        );
1286
        $this->klein_app->respond(
1287
            array('GET', 'POST'),
1288
            '/sure',
1289
            function () {
1290
                echo 'fail';
1291
            }
1292
        );
1293
        $this->klein_app->respond(
1294
            405,
1295
            function ($a, $b, $c, $d, $e, $f, $methods) use (&$resultArray) {
1296
                $resultArray = $methods;
1297
            }
1298
        );
1299
1300
        // Ignore our deprecation error
1301
        $old_error_val = error_reporting();
1302
        error_reporting(E_ALL ^ E_USER_DEPRECATED);
1303
1304
        $this->klein_app->dispatch(
1305
            MockRequestFactory::create('/sure', 'DELETE')
1306
        );
1307
1308
        error_reporting($old_error_val);
1309
1310
        $this->assertCount(2, $resultArray);
1311
        $this->assertContains('GET', $resultArray);
1312
        $this->assertContains('POST', $resultArray);
1313
        $this->assertSame(405, $this->klein_app->response()->code());
1314
    }
1315
1316
    public function test405ErrorHandler()
1317
    {
1318
        $resultArray = array();
1319
1320
        $this->expectOutputString('_');
1321
1322
        $this->klein_app->respond(
1323
            function () {
1324
                echo '_';
1325
            }
1326
        );
1327
        $this->klein_app->respond(
1328
            'GET',
1329
            '/sure',
1330
            function () {
1331
                echo 'fail';
1332
            }
1333
        );
1334
        $this->klein_app->respond(
1335
            array('GET', 'POST'),
1336
            '/sure',
1337
            function () {
1338
                echo 'fail';
1339
            }
1340
        );
1341
        $this->klein_app->onHttpError(
1342
            function ($code, $klein, $matched, $methods, $exception) use (&$resultArray) {
0 ignored issues
show
Unused Code introduced by
The parameter $exception is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1343
                $resultArray = $methods;
1344
            }
1345
        );
1346
1347
        $this->klein_app->dispatch(
1348
            MockRequestFactory::create('/sure', 'DELETE')
1349
        );
1350
1351
        $this->assertCount(2, $resultArray);
1352
        $this->assertContains('GET', $resultArray);
1353
        $this->assertContains('POST', $resultArray);
1354
        $this->assertSame(405, $this->klein_app->response()->code());
1355
    }
1356
1357 View Code Duplication
    public function testOptionsDefaultRequest()
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...
1358
    {
1359
        $this->klein_app->respond(
1360
            function ($request, $response) {
1361
                $response->code(200);
1362
            }
1363
        );
1364
        $this->klein_app->respond(
1365
            array('GET', 'POST'),
1366
            '/',
1367
            function () {
1368
                echo 'fail';
1369
            }
1370
        );
1371
1372
        $this->klein_app->dispatch(
1373
            MockRequestFactory::create('/', 'OPTIONS')
1374
        );
1375
1376
        $this->assertEquals('200 OK', $this->klein_app->response()->status()->getFormattedString());
1377
        $this->assertEquals('GET, POST', $this->klein_app->response()->headers()->get('Allow'));
1378
    }
1379
1380
    public function testOptionsRoutes()
1381
    {
1382
        $access_control_headers = array(
1383
            array(
1384
                'key' => 'Access-Control-Allow-Origin',
1385
                'val' => 'http://example.com',
1386
            ),
1387
            array(
1388
                'key' => 'Access-Control-Allow-Methods',
1389
                'val' => 'POST, GET, DELETE, OPTIONS, HEAD',
1390
            ),
1391
        );
1392
1393
        $this->klein_app->respond(
1394
            'GET',
1395
            '/',
1396
            function () {
1397
                echo 'fail';
1398
            }
1399
        );
1400
        $this->klein_app->respond(
1401
            array('GET', 'POST'),
1402
            '/',
1403
            function () {
1404
                echo 'fail';
1405
            }
1406
        );
1407
        $this->klein_app->respond(
1408
            'OPTIONS',
1409
            null,
1410
            function ($request, $response) use ($access_control_headers) {
1411
                // Add access control headers
1412
                foreach ($access_control_headers as $header) {
1413
                    $response->header($header['key'], $header['val']);
1414
                }
1415
            }
1416
        );
1417
1418
        $this->klein_app->dispatch(
1419
            MockRequestFactory::create('/', 'OPTIONS')
1420
        );
1421
1422
1423
        // Assert headers were passed
1424
        $this->assertEquals('GET, POST', $this->klein_app->response()->headers()->get('Allow'));
1425
1426 View Code Duplication
        foreach ($access_control_headers as $header) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1427
            $this->assertEquals($header['val'], $this->klein_app->response()->headers()->get($header['key']));
1428
        }
1429
    }
1430
1431
    public function testHeadDefaultRequest()
1432
    {
1433
        $expected_headers = array(
1434
            array(
1435
                'key' => 'X-Some-Random-Header',
1436
                'val' => 'This was a GET route',
1437
            ),
1438
        );
1439
1440
        $this->klein_app->respond(
1441
            'GET',
1442
            null,
1443
            function ($request, $response) use ($expected_headers) {
1444
                $response->code(200);
1445
1446
                // Add access control headers
1447
                foreach ($expected_headers as $header) {
1448
                    $response->header($header[ 'key' ], $header[ 'val' ]);
1449
                }
1450
            }
1451
        );
1452
        $this->klein_app->respond(
1453
            'GET',
1454
            '/',
1455
            function () {
1456
                echo 'GET!';
1457
                return 'more text';
1458
            }
1459
        );
1460
        $this->klein_app->respond(
1461
            'POST',
1462
            '/',
1463
            function () {
1464
                echo 'POST!';
1465
            }
1466
        );
1467
1468
        $this->klein_app->dispatch(
1469
            MockRequestFactory::create('/', 'HEAD')
1470
        );
1471
1472
        // Make sure we don't get a response body
1473
        $this->expectOutputString('');
1474
1475
        // Assert headers were passed
1476 View Code Duplication
        foreach ($expected_headers as $header) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1477
            $this->assertEquals($header['val'], $this->klein_app->response()->headers()->get($header['key']));
1478
        }
1479
    }
1480
1481
    public function testHeadMethodMatch()
1482
    {
1483
        $test_strings = array(
1484
            'oh, hello',
1485
            'yea',
1486
        );
1487
1488
        $test_result = null;
1489
1490
        $this->klein_app->respond(
1491
            array('GET', 'HEAD'),
1492
            null,
1493
            function ($request, $response) use ($test_strings, &$test_result) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $response is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1494
                $test_result .= $test_strings[0];
1495
            }
1496
        );
1497
        $this->klein_app->respond(
1498
            'GET',
1499
            '/',
1500
            function ($request, $response) use ($test_strings, &$test_result) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $response is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1501
                $test_result .= $test_strings[1];
1502
            }
1503
        );
1504
        $this->klein_app->respond(
1505
            'POST',
1506
            '/',
1507
            function ($request, $response) use ($test_strings, &$test_result) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $response is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1508
                $test_result .= 'nope';
1509
            }
1510
        );
1511
1512
        $this->klein_app->dispatch(
1513
            MockRequestFactory::create('/', 'HEAD')
1514
        );
1515
1516
        $this->assertSame(
1517
            implode('', $test_strings),
1518
            $test_result
1519
        );
1520
    }
1521
1522
    public function testGetPathFor()
1523
    {
1524
        $this->klein_app->respond(
1525
            '/dogs',
1526
            function () {
1527
            }
1528
        )->setName('dogs');
1529
1530
        $this->klein_app->respond(
1531
            '/dogs/[i:dog_id]/collars',
1532
            function () {
1533
            }
1534
        )->setName('dog-collars');
1535
1536
        $this->klein_app->respond(
1537
            '/dogs/[i:dog_id]/collars/[a:collar_slug]/?',
1538
            function () {
1539
            }
1540
        )->setName('dog-collar-details');
1541
1542
        $this->klein_app->respond(
1543
            '/dog/foo',
1544
            function () {
1545
            }
1546
        )->setName('dog-foo');
1547
1548
        $this->klein_app->respond(
1549
            '/dog/[i:dog_id]?',
1550
            function () {
1551
            }
1552
        )->setName('dog-optional-details');
1553
1554
        $this->klein_app->respond(
1555
            '@/dog/regex',
1556
            function () {
1557
            }
1558
        )->setName('dog-regex');
1559
1560
        $this->klein_app->respond(
1561
            '!@/dog/regex',
1562
            function () {
1563
            }
1564
        )->setName('dog-neg-regex');
1565
1566
        $this->klein_app->respond(
1567
            '@\.(json|csv)$',
1568
            function () {
1569
            }
1570
        )->setName('complex-regex');
1571
1572
        $this->klein_app->respond(
1573
            '!@^/admin/',
1574
            function () {
1575
            }
1576
        )->setName('complex-neg-regex');
1577
1578
        $this->klein_app->dispatch(
1579
            MockRequestFactory::create('/', 'HEAD')
1580
        );
1581
1582
        $this->assertSame(
1583
            '/dogs',
1584
            $this->klein_app->getPathFor('dogs')
1585
        );
1586
        $this->assertSame(
1587
            '/dogs/[i:dog_id]/collars',
1588
            $this->klein_app->getPathFor('dog-collars')
1589
        );
1590
        $this->assertSame(
1591
            '/dogs/idnumberandstuff/collars',
1592
            $this->klein_app->getPathFor(
1593
                'dog-collars',
1594
                array(
1595
                    'dog_id' => 'idnumberandstuff',
1596
                )
1597
            )
1598
        );
1599
        $this->assertSame(
1600
            '/dogs/[i:dog_id]/collars/[a:collar_slug]/?',
1601
            $this->klein_app->getPathFor('dog-collar-details')
1602
        );
1603
        $this->assertSame(
1604
            '/dogs/idnumberandstuff/collars/d12f3d1f2d3/?',
1605
            $this->klein_app->getPathFor(
1606
                'dog-collar-details',
1607
                array(
1608
                    'dog_id' => 'idnumberandstuff',
1609
                    'collar_slug' => 'd12f3d1f2d3',
1610
                )
1611
            )
1612
        );
1613
        $this->assertSame(
1614
            '/dog/foo',
1615
            $this->klein_app->getPathFor('dog-foo')
1616
        );
1617
        $this->assertSame(
1618
            '/dog',
1619
            $this->klein_app->getPathFor('dog-optional-details')
1620
        );
1621
        $this->assertSame(
1622
            '/',
1623
            $this->klein_app->getPathFor('dog-regex')
1624
        );
1625
        $this->assertSame(
1626
            '/',
1627
            $this->klein_app->getPathFor('dog-neg-regex')
1628
        );
1629
        $this->assertSame(
1630
            '@/dog/regex',
1631
            $this->klein_app->getPathFor('dog-regex', null, false)
1632
        );
1633
        $this->assertNotSame(
1634
            '/',
1635
            $this->klein_app->getPathFor('dog-neg-regex', null, false)
1636
        );
1637
        $this->assertSame(
1638
            '/',
1639
            $this->klein_app->getPathFor('complex-regex')
1640
        );
1641
        $this->assertSame(
1642
            '/',
1643
            $this->klein_app->getPathFor('complex-neg-regex')
1644
        );
1645
        $this->assertSame(
1646
            '@\.(json|csv)$',
1647
            $this->klein_app->getPathFor('complex-regex', null, false)
1648
        );
1649
        $this->assertNotSame(
1650
            '/',
1651
            $this->klein_app->getPathFor('complex-neg-regex', null, false)
1652
        );
1653
    }
1654
1655
    public function testDispatchHalt()
1656
    {
1657
        $this->expectOutputString('2,4,7,8,');
1658
1659
        $this->klein_app->respond(
1660
            function ($a, $b, $c, $d, $klein_app) {
1661
                $klein_app->skipThis();
1662
                echo '1,';
1663
            }
1664
        );
1665
        $this->klein_app->respond(
1666
            function ($a, $b, $c, $d, $klein_app) {
1667
                echo '2,';
1668
                $klein_app->skipNext();
1669
            }
1670
        );
1671
        $this->klein_app->respond(
1672
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1673
                echo '3,';
1674
            }
1675
        );
1676
        $this->klein_app->respond(
1677
            function ($a, $b, $c, $d, $klein_app) {
1678
                echo '4,';
1679
                $klein_app->skipNext(2);
1680
            }
1681
        );
1682
        $this->klein_app->respond(
1683
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1684
                echo '5,';
1685
            }
1686
        );
1687
        $this->klein_app->respond(
1688
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1689
                echo '6,';
1690
            }
1691
        );
1692
        $this->klein_app->respond(
1693
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1694
                echo '7,';
1695
            }
1696
        );
1697
        $this->klein_app->respond(
1698
            function ($a, $b, $c, $d, $klein_app) {
1699
                echo '8,';
1700
                $klein_app->skipRemaining();
1701
            }
1702
        );
1703
        $this->klein_app->respond(
1704
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1705
                echo '9,';
1706
            }
1707
        );
1708
        $this->klein_app->respond(
1709
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1710
                echo '10,';
1711
            }
1712
        );
1713
1714
        $this->klein_app->dispatch();
1715
    }
1716
1717
    public function testDispatchSkipCauses404()
1718
    {
1719
        $this->expectOutputString('404');
1720
1721
        $this->klein_app->onHttpError(
1722
            function ($code) {
1723
                if (404 === $code) {
1724
                    echo '404';
1725
                }
1726
            }
1727
        );
1728
1729
        $this->klein_app->respond(
1730
            'POST',
1731
            '/steez',
1732
            function ($a, $b, $c, $d, $klein_app) {
1733
                $klein_app->skipThis();
1734
                echo 'Style... with ease';
1735
            }
1736
        );
1737
        $this->klein_app->respond(
1738
            'GET',
1739
            '/nope',
1740
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1741
                echo 'How did I get here?!';
1742
            }
1743
        );
1744
1745
        $this->klein_app->dispatch(
1746
            MockRequestFactory::create('/steez', 'POST')
1747
        );
1748
    }
1749
1750 View Code Duplication
    public function testDispatchAbort()
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...
1751
    {
1752
        $this->expectOutputString('1,');
1753
1754
        $this->klein_app->respond(
1755
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1756
                echo '1,';
1757
            }
1758
        );
1759
        $this->klein_app->respond(
1760
            function ($a, $b, $c, $d, $klein_app) {
1761
                $klein_app->abort();
1762
                echo '2,';
1763
            }
1764
        );
1765
        $this->klein_app->respond(
1766
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1767
                echo '3,';
1768
            }
1769
        );
1770
1771
        $this->klein_app->dispatch();
1772
1773
        $this->assertSame(404, $this->klein_app->response()->code());
1774
    }
1775
1776 View Code Duplication
    public function testDispatchAbortWithCode()
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...
1777
    {
1778
        $this->expectOutputString('1,');
1779
1780
        $this->klein_app->respond(
1781
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1782
                echo '1,';
1783
            }
1784
        );
1785
        $this->klein_app->respond(
1786
            function ($a, $b, $c, $d, $klein_app) {
1787
                $klein_app->abort(404);
1788
                echo '2,';
1789
            }
1790
        );
1791
        $this->klein_app->respond(
1792
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1793
                echo '3,';
1794
            }
1795
        );
1796
1797
        $this->klein_app->dispatch();
1798
1799
        $this->assertSame(404, $this->klein_app->response()->code());
1800
    }
1801
1802
    public function testDispatchAbortCallsHttpError()
1803
    {
1804
        $test_code = 666;
1805
        $this->expectOutputString('1,aborted,'. $test_code);
1806
1807
        $this->klein_app->onHttpError(
1808
            function ($code, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1809
                echo 'aborted,';
1810
                echo $code;
1811
            }
1812
        );
1813
1814
        $this->klein_app->respond(
1815
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1816
                echo '1,';
1817
            }
1818
        );
1819
        $this->klein_app->respond(
1820
            function ($a, $b, $c, $d, $klein_app) use ($test_code) {
1821
                $klein_app->abort($test_code);
1822
                echo '2,';
1823
            }
1824
        );
1825
        $this->klein_app->respond(
1826
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1827
                echo '3,';
1828
            }
1829
        );
1830
1831
        $this->klein_app->dispatch();
1832
1833
        $this->assertSame($test_code, $this->klein_app->response()->code());
1834
    }
1835
1836
    /**
1837
     * @expectedException Klein\Exceptions\UnhandledException
1838
     */
1839
    public function testDispatchExceptionRethrowsUnknownCode()
1840
    {
1841
        $this->expectOutputString('');
1842
1843
        $test_message = 'whatever';
1844
        $test_code = 666;
1845
1846
        $this->klein_app->respond(
1847
            function ($a, $b, $c, $d, $klein_app) use ($test_message, $test_code) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1848
                throw new DispatchHaltedException($test_message, $test_code);
1849
            }
1850
        );
1851
1852
        $this->klein_app->dispatch();
1853
1854
        $this->assertSame(404, $this->klein_app->response()->code());
1855
    }
1856
1857
    public function testThrowHttpExceptionHandledProperly()
1858
    {
1859
        $this->expectOutputString('');
1860
1861
        $this->klein_app->respond(
1862
            '/',
1863
            function ($a, $b, $c, $d, $klein_app) {
0 ignored issues
show
Unused Code introduced by
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $d is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $klein_app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1864
                throw HttpException::createFromCode(400);
1865
1866
                echo 'hi!';
0 ignored issues
show
Unused Code introduced by
echo 'hi!'; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1867
            }
1868
        );
1869
1870
        $this->klein_app->dispatch();
1871
1872
        $this->assertSame(400, $this->klein_app->response()->code());
1873
    }
1874
1875
    public function testHttpExceptionStopsRouteMatching()
1876
    {
1877
        $this->expectOutputString('one');
1878
1879
        $this->klein_app->respond(
1880
            function () {
1881
                echo 'one';
1882
1883
                throw HttpException::createFromCode(404);
1884
            }
1885
        );
1886
        $this->klein_app->respond(
1887
            function () {
1888
                echo 'two';
1889
            }
1890
        );
1891
1892
        $this->klein_app->dispatch(
1893
            MockRequestFactory::create('/notroute')
1894
        );
1895
    }
1896
1897
    public function testOptionsAlias()
1898
    {
1899
        $this->expectOutputString('1,2,');
1900
1901
        // With path
1902
        $this->klein_app->options(
1903
            '/',
1904
            function () {
1905
                echo '1,';
1906
            }
1907
        );
1908
1909
        // Without path
1910
        $this->klein_app->options(
1911
            function () {
1912
                echo '2,';
1913
            }
1914
        );
1915
1916
        $this->klein_app->dispatch(
1917
            MockRequestFactory::create('/', 'OPTIONS')
1918
        );
1919
    }
1920
1921
    public function testHeadAlias()
1922
    {
1923
        // HEAD requests shouldn't return data
1924
        $this->expectOutputString('');
1925
1926
        // With path
1927
        $this->klein_app->head(
1928
            '/',
1929
            function ($request, $response) {
1930
                echo '1,';
1931
                $response->headers()->set('Test-1', 'yup');
1932
            }
1933
        );
1934
1935
        // Without path
1936
        $this->klein_app->head(
1937
            function ($request, $response) {
1938
                echo '2,';
1939
                $response->headers()->set('Test-2', 'yup');
1940
            }
1941
        );
1942
1943
        $this->klein_app->dispatch(
1944
            MockRequestFactory::create('/', 'HEAD')
1945
        );
1946
1947
        $this->assertTrue($this->klein_app->response()->headers()->exists('Test-1'));
1948
        $this->assertTrue($this->klein_app->response()->headers()->exists('Test-2'));
1949
        $this->assertFalse($this->klein_app->response()->headers()->exists('Test-3'));
1950
    }
1951
1952
    public function testGetAlias()
1953
    {
1954
        $this->expectOutputString('1,2,');
1955
1956
        // With path
1957
        $this->klein_app->get(
1958
            '/',
1959
            function () {
1960
                echo '1,';
1961
            }
1962
        );
1963
1964
        // Without path
1965
        $this->klein_app->get(
1966
            function () {
1967
                echo '2,';
1968
            }
1969
        );
1970
1971
        $this->klein_app->dispatch(
1972
            MockRequestFactory::create('/')
1973
        );
1974
    }
1975
1976
    public function testPostAlias()
1977
    {
1978
        $this->expectOutputString('1,2,');
1979
1980
        // With path
1981
        $this->klein_app->post(
1982
            '/',
1983
            function () {
1984
                echo '1,';
1985
            }
1986
        );
1987
1988
        // Without path
1989
        $this->klein_app->post(
1990
            function () {
1991
                echo '2,';
1992
            }
1993
        );
1994
1995
        $this->klein_app->dispatch(
1996
            MockRequestFactory::create('/', 'POST')
1997
        );
1998
    }
1999
2000
    public function testPutAlias()
2001
    {
2002
        $this->expectOutputString('1,2,');
2003
2004
        // With path
2005
        $this->klein_app->put(
2006
            '/',
2007
            function () {
2008
                echo '1,';
2009
            }
2010
        );
2011
2012
        // Without path
2013
        $this->klein_app->put(
2014
            function () {
2015
                echo '2,';
2016
            }
2017
        );
2018
2019
        $this->klein_app->dispatch(
2020
            MockRequestFactory::create('/', 'PUT')
2021
        );
2022
    }
2023
2024
    public function testDeleteAlias()
2025
    {
2026
        $this->expectOutputString('1,2,');
2027
2028
        // With path
2029
        $this->klein_app->delete(
2030
            '/',
2031
            function () {
2032
                echo '1,';
2033
            }
2034
        );
2035
2036
        // Without path
2037
        $this->klein_app->delete(
2038
            function () {
2039
                echo '2,';
2040
            }
2041
        );
2042
2043
        $this->klein_app->dispatch(
2044
            MockRequestFactory::create('/', 'DELETE')
2045
        );
2046
    }
2047
2048
2049
    /**
2050
     * Advanced string route matching tests
2051
     *
2052
     * As the original Klein project was designed as a PHP version of Sinatra,
2053
     * many of the following tests are ports of the Sinatra ruby equivalents:
2054
     * https://github.com/sinatra/sinatra/blob/cd82a57154d57c18acfadbfefbefc6ea6a5035af/test/routing_test.rb
2055
     */
2056
2057 View Code Duplication
    public function testMatchesEncodedSlashes()
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...
2058
    {
2059
        $this->klein_app->respond(
2060
            '/[:a]',
2061
            function ($request) {
2062
                return $request->param('a');
2063
            }
2064
        );
2065
2066
        $this->klein_app->dispatch(
2067
            MockRequestFactory::create('/foo%2Fbar'),
2068
            null,
2069
            true,
2070
            Klein::DISPATCH_CAPTURE_AND_RETURN
2071
        );
2072
2073
        $this->assertSame(200, $this->klein_app->response()->code());
2074
        $this->assertSame('foo/bar', $this->klein_app->response()->body());
2075
    }
2076
2077 View Code Duplication
    public function testMatchesDotAsNamedParam()
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...
2078
    {
2079
        $this->klein_app->respond(
2080
            '/[:foo]/[:bar]',
2081
            function ($request) {
2082
                return $request->param('foo');
2083
            }
2084
        );
2085
2086
        $this->klein_app->dispatch(
2087
            MockRequestFactory::create('/[email protected]/name'),
2088
            null,
2089
            true,
2090
            Klein::DISPATCH_CAPTURE_AND_RETURN
2091
        );
2092
2093
        $this->assertSame(200, $this->klein_app->response()->code());
2094
        $this->assertSame('[email protected]', $this->klein_app->response()->body());
2095
    }
2096
2097
    public function testMatchesDotOutsideOfNamedParam()
2098
    {
2099
        $file = null;
2100
        $ext  = null;
2101
2102
        $this->klein_app->respond(
2103
            '/[:file].[:ext]',
2104
            function ($request) use (&$file, &$ext) {
2105
                $file = $request->param('file');
2106
                $ext = $request->param('ext');
2107
2108
                return 'woot!';
2109
            }
2110
        );
2111
2112
        $this->klein_app->dispatch(
2113
            MockRequestFactory::create('/unicorn.png'),
2114
            null,
2115
            true,
2116
            Klein::DISPATCH_CAPTURE_AND_RETURN
2117
        );
2118
2119
        $this->assertSame(200, $this->klein_app->response()->code());
2120
        $this->assertSame('woot!', $this->klein_app->response()->body());
2121
        $this->assertSame('unicorn', $file);
2122
        $this->assertSame('png', $ext);
2123
    }
2124
2125 View Code Duplication
    public function testMatchesLiteralDotsInPaths()
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...
2126
    {
2127
        $this->klein_app->respond(
2128
            '/file.ext',
2129
            function () {
2130
            }
2131
        );
2132
2133
        // Should match
2134
        $this->klein_app->dispatch(
2135
            MockRequestFactory::create('/file.ext')
2136
        );
2137
        $this->assertSame(200, $this->klein_app->response()->code());
2138
2139
        // Shouldn't match
2140
        $this->klein_app->dispatch(
2141
            MockRequestFactory::create('/file0ext')
2142
        );
2143
        $this->assertSame(404, $this->klein_app->response()->code());
2144
    }
2145
2146 View Code Duplication
    public function testMatchesLiteralDotsInPathBeforeNamedParam()
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...
2147
    {
2148
        $this->klein_app->respond(
2149
            '/file.[:ext]',
2150
            function () {
2151
            }
2152
        );
2153
2154
        // Should match
2155
        $this->klein_app->dispatch(
2156
            MockRequestFactory::create('/file.ext')
2157
        );
2158
        $this->assertSame(200, $this->klein_app->response()->code());
2159
2160
        // Shouldn't match
2161
        $this->klein_app->dispatch(
2162
            MockRequestFactory::create('/file0ext')
2163
        );
2164
        $this->assertSame(404, $this->klein_app->response()->code());
2165
    }
2166
2167 View Code Duplication
    public function testMultipleUnsafeCharactersArentOverQuoted()
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...
2168
    {
2169
        $this->klein_app->respond(
2170
            '/[a:site].[:format]?/[:id].[:format2]?',
2171
            function () {
2172
            }
2173
        );
2174
2175
        $this->klein_app->dispatch(
2176
            MockRequestFactory::create('/site.main/id.json')
2177
        );
2178
        $this->assertSame(200, $this->klein_app->response()->code());
2179
    }
2180
2181 View Code Duplication
    public function testMatchesLiteralPlusSignsInPaths()
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...
2182
    {
2183
        $this->klein_app->respond(
2184
            '/te+st',
2185
            function () {
2186
            }
2187
        );
2188
2189
        // Should match
2190
        $this->klein_app->dispatch(
2191
            MockRequestFactory::create('/te+st')
2192
        );
2193
        $this->assertSame(200, $this->klein_app->response()->code());
2194
2195
        // Shouldn't match
2196
        $this->klein_app->dispatch(
2197
            MockRequestFactory::create('/teeeeeeeeest')
2198
        );
2199
        $this->assertSame(404, $this->klein_app->response()->code());
2200
    }
2201
2202 View Code Duplication
    public function testMatchesParenthesesInPaths()
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...
2203
    {
2204
        $this->klein_app->respond(
2205
            '/test(bar)',
2206
            function () {
2207
            }
2208
        );
2209
2210
        $this->klein_app->dispatch(
2211
            MockRequestFactory::create('/test(bar)')
2212
        );
2213
        $this->assertSame(200, $this->klein_app->response()->code());
2214
    }
2215
2216 View Code Duplication
    public function testMatchesAdvancedRegularExpressions()
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...
2217
    {
2218
        $this->klein_app->respond(
2219
            '@^/foo.../bar$',
2220
            function () {
2221
            }
2222
        );
2223
2224
        $this->klein_app->dispatch(
2225
            MockRequestFactory::create('/foooom/bar')
2226
        );
2227
        $this->assertSame(200, $this->klein_app->response()->code());
2228
    }
2229
2230 View Code Duplication
    public function testApcDependencyFailsGracefully()
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...
2231
    {
2232
        // Custom apc function
2233
        implement_custom_apc_cache_functions();
2234
2235
        $this->klein_app->respond(
2236
            '/test',
2237
            function () {
2238
            }
2239
        );
2240
2241
        $this->klein_app->dispatch(
2242
            MockRequestFactory::create('/test')
2243
        );
2244
        $this->assertSame(200, $this->klein_app->response()->code());
2245
    }
2246
2247
    public function testRoutePathCompilationFailure()
2248
    {
2249
        $this->klein_app->respond(
2250
            '/users/[i:id]/friends/[i:id]/',
2251
            function () {
2252
                echo 'yup';
2253
            }
2254
        );
2255
2256
        $exception = null;
2257
2258
        try {
2259
            $this->klein_app->dispatch(
2260
                MockRequestFactory::create('/users/1738197/friends/7828316')
2261
            );
2262
        } catch (\Exception $e) {
2263
            $exception = $e->getPrevious();
2264
        }
2265
2266
        $this->assertTrue($exception instanceof RoutePathCompilationException);
2267
        $this->assertTrue($exception->getRoute() instanceof Route);
2268
    }
2269
2270
    public function testRoutePathCompilationFailureWithoutWarnings()
2271
    {
2272
        $old_error_val = error_reporting();
2273
        error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
2274
2275
        $this->testRoutePathCompilationFailure();
2276
2277
        error_reporting($old_error_val);
2278
    }
2279
}
2280