GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — develop ( 7af216...ebf010 )
by Baptiste
13:17
created

StrTest::testSplit()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 53
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 36
nc 8
nop 0
dl 0
loc 53
rs 9.344
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types = 1);
3
4
namespace Tests\Innmind\Immutable;
5
6
use Innmind\Immutable\{
7
    Str as S,
8
    PrimitiveInterface,
0 ignored issues
show
Bug introduced by
The type Innmind\Immutable\PrimitiveInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
    StringableInterface,
0 ignored issues
show
Bug introduced by
The type Innmind\Immutable\StringableInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
    Sequence,
11
    Map,
12
    Exception\SubstringException,
13
    Exception\RegexException
14
};
15
use PHPUnit\Framework\{
16
    TestCase,
17
    ExpectationFailedException,
18
};
19
20
class StrTest extends TestCase
21
{
22
    public function testInterfaces()
23
    {
24
        $str = S::of('foo');
25
26
        $this->assertSame('foo', $str->toString());
27
    }
28
29
    public function testOf()
30
    {
31
        $str = S::of('foo', 'ASCII');
32
33
        $this->assertInstanceOf(S::class, $str);
34
        $this->assertSame('foo', $str->toString());
35
        $this->assertSame('ASCII', $str->encoding()->toString());
36
    }
37
38
    public function testThrowWhenInvalidType()
39
    {
40
        $this->expectException(\TypeError::class);
41
        $this->expectExceptionMessage('must be of the type string, int given');
42
43
        S::of(42);
44
    }
45
46
    public function testEncoding()
47
    {
48
        $this->assertInstanceOf(S::class, S::of('')->encoding());
49
        $this->assertSame('UTF-8', S::of('')->encoding()->toString());
50
    }
51
52
    public function testToEncoding()
53
    {
54
        $str = S::of('foo🙏bar');
55
        $str2 = $str->toEncoding('ASCII');
56
57
        $this->assertInstanceOf(S::class, $str2);
58
        $this->assertNotSame($str, $str2);
59
        $this->assertSame('UTF-8', $str->encoding()->toString());
60
        $this->assertSame('ASCII', $str2->encoding()->toString());
61
        $this->assertSame(7, $str->length());
62
        $this->assertSame(10, $str2->length());
63
    }
64
65
    public function testSplit()
66
    {
67
        $str = S::of('foo');
68
69
        $sequence = $str->split();
70
        $this->assertInstanceOf(Sequence::class, $sequence);
71
        $this->assertSame(S::class, $sequence->type());
72
        $this->assertCount(3, $sequence);
73
74
        foreach ($sequence as $part) {
75
            $this->assertInstanceOf(S::class, $part);
76
        }
77
78
        $this->assertSame('f', $sequence->get(0)->toString());
79
        $this->assertSame('o', $sequence->get(1)->toString());
80
        $this->assertSame('o', $sequence->get(2)->toString());
81
82
        $parts = S::of('🤩👍🤔', 'UTF-8')->split();
83
84
        $this->assertSame('🤩', $parts->get(0)->toString());
85
        $this->assertSame('👍', $parts->get(1)->toString());
86
        $this->assertSame('🤔', $parts->get(2)->toString());
87
        $this->assertNotSame(
88
            '🤩',
89
            S::of('🤩👍🤔', 'ASCII')->split()->get(0)->toString()
90
        );
91
92
        $sequence = $str->split('');
93
        $this->assertInstanceOf(Sequence::class, $sequence);
94
        $this->assertSame(S::class, $sequence->type());
95
        $this->assertCount(3, $sequence);
96
97
        foreach ($sequence as $part) {
98
            $this->assertInstanceOf(S::class, $part);
99
        }
100
101
        $this->assertSame('f', $sequence->get(0)->toString());
102
        $this->assertSame('o', $sequence->get(1)->toString());
103
        $this->assertSame('o', $sequence->get(2)->toString());
104
105
        $str = S::of('f|o|o');
106
        $sequence = $str->split('|');
107
        $this->assertInstanceOf(Sequence::class, $sequence);
108
        $this->assertSame(S::class, $sequence->type());
109
        $this->assertCount(3, $sequence);
110
111
        foreach ($sequence as $part) {
112
            $this->assertInstanceOf(S::class, $part);
113
        }
114
115
        $this->assertSame('f', $sequence->get(0)->toString());
116
        $this->assertSame('o', $sequence->get(1)->toString());
117
        $this->assertSame('o', $sequence->get(2)->toString());
118
    }
119
120
    public function testSplitOnZeroString()
121
    {
122
        $parts = S::of('10101')->split('0');
123
124
        $this->assertCount(3, $parts);
125
        $this->assertSame('1', $parts->get(0)->toString());
126
        $this->assertSame('1', $parts->get(1)->toString());
127
        $this->assertSame('1', $parts->get(2)->toString());
128
    }
129
130
    public function testSplitUtf8ManipulatedAsAscii()
131
    {
132
        $str = S::of('foo🙏bar');
133
        $splits = $str->split();
134
135
        $this->assertSame('f', $splits->get(0)->toString());
136
        $this->assertSame('o', $splits->get(1)->toString());
137
        $this->assertSame('o', $splits->get(2)->toString());
138
        $this->assertSame('🙏', $splits->get(3)->toString());
139
        $this->assertSame('b', $splits->get(4)->toString());
140
        $this->assertSame('a', $splits->get(5)->toString());
141
        $this->assertSame('r', $splits->get(6)->toString());
142
143
        $splits = $str->toEncoding('ASCII')->split();
144
145
        $this->assertSame('f', $splits->get(0)->toString());
146
        $this->assertSame('o', $splits->get(1)->toString());
147
        $this->assertSame('o', $splits->get(2)->toString());
148
        $this->assertSame(
149
            '🙏',
150
            $splits->get(3)->toString().$splits->get(4)->toString().$splits->get(5)->toString().$splits->get(6)->toString()
151
        );
152
        $this->assertSame('b', $splits->get(7)->toString());
153
        $this->assertSame('a', $splits->get(8)->toString());
154
        $this->assertSame('r', $splits->get(9)->toString());
155
    }
156
157
    public function testSplitUtf8ManipulatedAsAsciiWithDelimiter()
158
    {
159
        $str = S::of('foo🙏bar');
160
        $splits = $str->split('🙏');
161
162
        $this->assertSame('foo', $splits->get(0)->toString());
163
        $this->assertSame('bar', $splits->get(1)->toString());
164
165
        $splits = $str->toEncoding('ASCII')->split('🙏');
166
167
        $this->assertSame('foo', $splits->get(0)->toString());
168
        $this->assertSame('bar', $splits->get(1)->toString());
169
170
        $splits = $str->toEncoding('ASCII')->split(
171
            mb_substr('🙏', 0, 1, 'ASCII')
172
        );
173
174
        $this->assertSame('foo', $splits->get(0)->toString());
175
        $this->assertSame(
176
            mb_substr('🙏', 1, null, 'ASCII').'bar',
177
            $splits->get(1)->toString()
178
        );
179
    }
180
181
    public function testChunk()
182
    {
183
        $str = S::of('foobarbaz');
184
185
        $sequence = $str->chunk(4);
186
        $this->assertInstanceOf(Sequence::class, $sequence);
187
        $this->assertSame(S::class, $sequence->type());
188
        $this->assertInstanceOf(S::class, $sequence->get(0));
189
        $this->assertInstanceOf(S::class, $sequence->get(1));
190
        $this->assertInstanceOf(S::class, $sequence->get(2));
191
        $this->assertSame('foob', $sequence->get(0)->toString());
192
        $this->assertSame('arba', $sequence->get(1)->toString());
193
        $this->assertSame('z', $sequence->get(2)->toString());
194
    }
195
196
    public function testChunkUtf8ManipulatedAsAscii()
197
    {
198
        $splits = S::of('foo🙏bar')
199
            ->toEncoding('ASCII')
200
            ->chunk();
201
202
        $this->assertSame('f', $splits->get(0)->toString());
203
        $this->assertSame('o', $splits->get(1)->toString());
204
        $this->assertSame('o', $splits->get(2)->toString());
205
        $this->assertSame(
206
            '🙏',
207
            $splits->get(3)->toString().$splits->get(4)->toString().$splits->get(5)->toString().$splits->get(6)->toString()
208
        );
209
        $this->assertSame('b', $splits->get(7)->toString());
210
        $this->assertSame('a', $splits->get(8)->toString());
211
        $this->assertSame('r', $splits->get(9)->toString());
212
213
        $splits = S::of('foo🙏bar')
214
            ->toEncoding('ASCII')
215
            ->chunk(3);
216
217
        $this->assertSame('foo', $splits->get(0)->toString());
218
        $this->assertSame(
219
            mb_substr('🙏', 0, 3, 'ASCII'),
220
            $splits->get(1)->toString()
221
        );
222
        $this->assertSame(
223
            mb_substr('🙏', 3, 4, 'ASCII').'ba',
224
            $splits->get(2)->toString()
225
        );
226
        $this->assertSame('r', $splits->get(3)->toString());
227
    }
228
229
    public function testPosition()
230
    {
231
        $str = S::of('foo');
232
233
        $this->assertSame(1, $str->position('o'));
234
        $this->assertSame(2, $str->position('o', 2));
235
236
        $emoji = S::of('foo🙏bar');
237
238
        $this->assertSame(4, $emoji->position('bar'));
239
        $this->assertSame(7, $emoji->toEncoding('ASCII')->position('bar'));
240
    }
241
242
    public function testThrowWhenPositionNotFound()
243
    {
244
        $this->expectException(SubstringException::class);
245
        $this->expectExceptionMessage('Substring "o" not found');
246
247
        S::of('bar')->position('o');
248
    }
249
250
    public function testReplace()
251
    {
252
        $str = S::of('<body text="%body%">');
253
254
        $str2 = $str->replace('%body%', 'black');
255
        $this->assertInstanceOf(S::class, $str2);
256
        $this->assertNotSame($str, $str2);
257
        $this->assertSame('<body text="black">', $str2->toString());
258
        $this->assertSame('<body text="%body%">', $str->toString());
259
260
        $this->assertSame('foo', S::of('foo')->replace('.', '/')->toString());
261
        $this->assertSame('foo/bar', S::of('foo.bar')->replace('.', '/')->toString());
262
    }
263
264
    public function testReplaceWithDifferentEncoding()
265
    {
266
        $str = S::of('foo🙏🙏🙏bar');
267
268
        $str2 = $str->replace(
269
            mb_substr('🙏', 0, 1, 'ASCII'),
270
            'baz'
271
        );
272
        $remaining = mb_substr('🙏', 1, null, 'ASCII');
273
        $this->assertSame('foo🙏🙏🙏bar', $str->toString());
274
        $this->assertSame(
275
            'foobaz'.$remaining.'baz'.$remaining.'baz'.$remaining.'bar',
276
            $str2->toString()
277
        );
278
279
        $str3 = $str->toEncoding('ASCII')->replace(
280
            mb_substr('🙏', 0, 1, 'ASCII'),
281
            'baz'
282
        );
283
        $this->assertSame('foo🙏🙏🙏bar', $str->toString());
284
        $subPray = mb_substr('🙏', 1, null, 'ASCII');
285
        $this->assertSame(
286
            'foobaz'.$subPray.'baz'.$subPray.'baz'.$subPray.'bar',
287
            $str3->toString()
288
        );
289
    }
290
291
    public function testStr()
292
    {
293
        $str = S::of('[email protected]');
294
295
        $str2 = $str->str('@');
296
        $this->assertInstanceOf(S::class, $str2);
297
        $this->assertNotSame($str, $str2);
298
        $this->assertSame('@example.com', $str2->toString());
299
        $this->assertSame('[email protected]', $str->toString());
300
    }
301
302
    public function testStrUtf8ManipulatedAsAscii()
303
    {
304
        $str = S::of('foo🙏bar');
305
306
        $str2 = $str->toEncoding('ASCII')->str(mb_substr('🙏', 0, 1, 'ASCII'));
307
        $this->assertSame('foo🙏bar', $str->toString());
308
        $this->assertSame('🙏bar', $str2->toString());
309
    }
310
311
    public function testThrowWhenStrDelimiterNotFound()
312
    {
313
        $this->expectException(SubstringException::class);
314
        $this->expectExceptionMessage('Substring "foo" not found');
315
316
        S::of('[email protected]')->str('foo');
317
    }
318
319
    public function testToUpper()
320
    {
321
        $str = S::of('foo🙏');
322
323
        $str2 = $str->toUpper();
324
        $this->assertInstanceOf(S::class, $str2);
325
        $this->assertNotSame($str, $str2);
326
        $this->assertSame('FOO🙏', $str2->toString());
327
        $this->assertSame('foo🙏', $str->toString());
328
        $this->assertSame('ÉGÉRIE', S::of('égérie')->toUpper()->toString());
329
    }
330
331
    public function testToLower()
332
    {
333
        $str = S::of('FOO🙏');
334
335
        $str2 = $str->toLower();
336
        $this->assertInstanceOf(S::class, $str2);
337
        $this->assertNotSame($str, $str2);
338
        $this->assertSame('foo🙏', $str2->toString());
339
        $this->assertSame('FOO🙏', $str->toString());
340
        $this->assertSame('égérie', S::of('ÉGÉRIE')->toLower()->toString());
341
    }
342
343
    public function testLength()
344
    {
345
        $this->assertSame(4, S::of('foo🙏')->length());
346
        $this->assertSame(7, S::of('foo🙏')->toEncoding('ASCII')->length());
347
    }
348
349
    public function testEmpty()
350
    {
351
        $this->assertTrue(S::of('')->empty());
352
        $this->assertFalse(S::of('🙏')->empty());
353
        $this->assertFalse(S::of('🙏', 'ASCII')->substring(0, 1)->empty());
354
    }
355
356
    public function testReverse()
357
    {
358
        $str = S::of('foo🙏');
359
360
        $str2 = $str->reverse();
361
        $this->assertInstanceOf(S::class, $str2);
362
        $this->assertNotSame($str, $str2);
363
        $this->assertSame('🙏oof', $str2->toString());
364
        $this->assertSame('foo🙏', $str->toString());
365
        $this->assertSame(
366
            strrev('🙏').'oof',
367
            $str->toEncoding('ASCII')->reverse()->toString()
368
        );
369
    }
370
371
    public function testReverseKeepTheGivenEncoding()
372
    {
373
        $this->assertSame(
374
            'UTF-8',
375
            S::of('foo')->reverse()->encoding()->toString(),
376
        );
377
        $this->assertSame(
378
            'ASCII',
379
            S::of('foo', 'ASCII')->reverse()->encoding()->toString(),
380
        );
381
    }
382
383
    public function testPad()
384
    {
385
        $str = S::of('foo');
386
387
        $str2 = $str->rightPad(6, '0');
388
        $this->assertInstanceOf(S::class, $str2);
389
        $this->assertNotSame($str, $str2);
390
        $this->assertSame('foo000', $str2->toString());
391
        $this->assertSame('foo', $str->toString());
392
393
        $str2 = $str->leftPad(6, '0');
394
        $this->assertInstanceOf(S::class, $str2);
395
        $this->assertNotSame($str, $str2);
396
        $this->assertSame('000foo', $str2->toString());
397
        $this->assertSame('foo', $str->toString());
398
399
        $str2 = $str->uniPad(6, '0');
400
        $this->assertInstanceOf(S::class, $str2);
401
        $this->assertNotSame($str, $str2);
402
        $this->assertSame('0foo00', $str2->toString());
403
        $this->assertSame('foo', $str->toString());
404
    }
405
406
    public function testCspn()
407
    {
408
        $str = S::of('abcdhelloabcd');
409
410
        $this->assertSame(0, $str->cspn('abcd'));
411
        $this->assertSame(5, $str->cspn('abcd', -9));
412
        $this->assertSame(4, $str->cspn('abcd', -9, -5));
413
414
        $str = S::of('foo🙏bar');
415
416
        $this->assertSame(3, $str->cspn('🙏'));
417
        $this->assertSame(0, $str->cspn('🙏', 4));
418
        $this->assertSame(3, $str->cspn('🙏', 0, 4));
419
        $this->assertSame(3, $str->cspn(mb_substr('🙏', 0, 1, 'ASCII'), 0, 4));
420
        $this->assertSame(3, $str->toEncoding('ASCII')->cspn(mb_substr('🙏', 0, 1, 'ASCII'), 0, 4));
421
    }
422
423
    public function testRepeat()
424
    {
425
        $str = S::of('foo');
426
427
        $str2 = $str->repeat(3);
428
        $this->assertInstanceOf(S::class, $str2);
429
        $this->assertNotSame($str, $str2);
430
        $this->assertSame('foofoofoo', $str2->toString());
431
        $this->assertSame('foo', $str->toString());
432
        $this->assertSame('🙏🙏', S::of('🙏')->repeat(2)->toString());
433
        $this->assertSame('🙏🙏', S::of('🙏')->toEncoding('ASCII')->repeat(2)->toString());
434
    }
435
436
    public function testShuffle()
437
    {
438
        $str = S::of('shuffle🙏');
439
440
        $str2 = $str->shuffle();
441
        $this->assertInstanceOf(S::class, $str2);
442
        $this->assertNotSame($str, $str2);
443
        $this->assertSame('shuffle🙏', $str->toString());
444
        $this->assertSame(8, $str2->length());
445
446
        try {
447
            foreach ($str2->split() as $char) {
448
                $str->position($char->toString());
449
            }
450
        } catch (\Exception $e) {
451
            $this->fail('every character should be in the original string');
452
        }
453
    }
454
455
    public function testShuffleEmoji()
456
    {
457
        $str = S::of('🙏');
458
459
        try {
460
            $this->assertSame('🙏 ', $str->shuffle()->toString());
461
        } catch (ExpectationFailedException $e) {
462
            // sometimes it shuffles to the same order so the tests fails
463
            $this->assertSame('🙏', $str->shuffle()->toString());
464
        }
465
        $this->assertNotSame(
466
            '🙏',
467
            $str->toEncoding('ASCII')->shuffle()->toString()
468
        );
469
    }
470
471
    public function testStripSlashes()
472
    {
473
        $str = S::of("Is your name O\'reilly?");
474
475
        $str2 = $str->stripSlashes();
476
        $this->assertInstanceOf(S::class, $str2);
477
        $this->assertNotSame($str, $str2);
478
        $this->assertSame("Is your name O\'reilly?", $str->toString());
479
        $this->assertSame("Is your name O'reilly?", $str2->toString());
480
    }
481
482
    public function testStripCSlahes()
483
    {
484
        $str = S::of('He\xallo');
485
486
        $str2 = $str->stripCSlashes();
487
        $this->assertInstanceOf(S::class, $str2);
488
        $this->assertNotSame($str, $str2);
489
        $this->assertSame('He\xallo', $str->toString());
490
        $this->assertSame('He' . "\n" . 'llo', $str2->toString());
491
    }
492
493
    public function testWordCount()
494
    {
495
        $str = S::of("Hello fri3nd, you're
496
                    looking          good today!");
497
498
        $this->assertSame(7, $str->wordCount());
499
        $this->assertSame(6, $str->wordCount('àáãç3'));
500
    }
501
502
    public function testWords()
503
    {
504
        $str = S::of("Hello fri3nd, you're
505
        looking          good today!");
506
507
        $map = $str->words();
508
        $this->assertInstanceOf(Map::class, $map);
509
        $this->assertSame('int', $map->keyType());
510
        $this->assertSame(S::class, $map->valueType());
511
        $words = [
512
            0 => 'Hello',
513
            6 => 'fri',
514
            10 => 'nd',
515
            14 => 'you\'re',
516
            29 => 'looking',
517
            46 => 'good',
518
            51 => 'today',
519
        ];
520
521
        foreach ($words as $pos => $word) {
522
            $this->assertInstanceOf(S::class, $map->get($pos));
523
            $this->assertSame($word, $map->get($pos)->toString());
524
        }
525
526
        $map = $str->words('àáãç3');
527
        $this->assertInstanceOf(Map::class, $map);
528
        $this->assertSame('int', $map->keyType());
529
        $this->assertSame(S::class, $map->valueType());
530
        $words = [
531
            0 => 'Hello',
532
            6 => 'fri3nd',
533
            14 => 'you\'re',
534
            29 => 'looking',
535
            46 => 'good',
536
            51 => 'today',
537
        ];
538
539
        foreach ($words as $pos => $word) {
540
            $this->assertInstanceOf(S::class, $map->get($pos));
541
            $this->assertSame($word, $map->get($pos)->toString());
542
        }
543
    }
544
545
    public function testPregSplit()
546
    {
547
        $str = S::of('hypertext language, programming');
548
549
        $c = $str->pregSplit('/[\s,]+/');
550
        $this->assertInstanceOf(Sequence::class, $c);
551
        $this->assertSame(S::class, $c->type());
552
        $this->assertSame('hypertext', $c->get(0)->toString());
553
        $this->assertSame('language', $c->get(1)->toString());
554
        $this->assertSame('programming', $c->get(2)->toString());
555
    }
556
557
    public function testMatches()
558
    {
559
        $str = S::of('abcdef');
560
561
        $this->assertFalse($str->matches('/^def/'));
562
        $this->assertTrue($str->matches('/^abc/'));
563
564
        $this->assertTrue(S::of('foo🙏bar')->matches('/🙏/'));
565
        $this->assertTrue(S::of('foo🙏bar')->toEncoding('ASCII')->matches('/🙏/'));
566
    }
567
568
    public function testThrowWhenMatchInvalidRegex()
569
    {
570
        $this->expectException(RegexException::class);
571
        $this->expectExceptionMessage('Backtrack limit error');
572
573
        S::of(str_repeat("x", 1000000))->matches('/x+x+y/');
574
    }
575
576
    public function testCapture()
577
    {
578
        $str = S::of('http://www.php.net/index.html');
579
580
        $map = $str->capture('@^(?:http://)?(?P<host>[^/]+)@i');
581
        $this->assertInstanceOf(Map::class, $map);
582
        $this->assertSame('scalar', $map->keyType());
583
        $this->assertSame(S::class, $map->valueType());
584
        $this->assertCount(3, $map);
585
        $this->assertSame('http://www.php.net', $map->get(0)->toString());
586
        $this->assertSame('www.php.net', $map->get(1)->toString());
587
        $this->assertSame('www.php.net', $map->get('host')->toString());
588
    }
589
590
    public function testCastNullValuesWhenCapturing()
591
    {
592
        $str = S::of('en;q=0.7');
593
594
        $matches = $str->capture('~(?<lang>([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*|\*))(; ?q=(?<quality>\d+(\.\d+)?))?~');
595
        $this->assertInstanceOf(Map::class, $matches);
596
        $this->assertSame('scalar', $matches->keyType());
597
        $this->assertSame(S::class, $matches->valueType());
598
        $this->assertCount(9, $matches);
599
        $this->assertSame('en;q=0.7', $matches->get(0)->toString());
600
        $this->assertSame('en', $matches->get(1)->toString());
601
        $this->assertSame('en', $matches->get(2)->toString());
602
        $this->assertSame('', $matches->get(3)->toString());
603
        $this->assertSame('en', $matches->get('lang')->toString());
604
        $this->assertSame(';q=0.7', $matches->get(4)->toString());
605
        $this->assertSame('0.7', $matches->get(5)->toString());
606
        $this->assertSame('0.7', $matches->get('quality')->toString());
607
        $this->assertSame('.7', $matches->get(6)->toString());
608
    }
609
610
    public function testThrowWhenGettingMatchesInvalidRegex()
611
    {
612
        $this->expectException(RegexException::class);
613
        $this->expectExceptionMessage('Backtrack limit error');
614
615
        S::of(str_repeat("x", 1000000))->capture('/x+x+y/');
616
    }
617
618
    public function testPregReplace()
619
    {
620
        $str = S::of('April 15, 2003');
621
622
        $str2 = $str->pregReplace('/(\w+) (\d+), (\d+)/i', '${1}1,$3');
623
        $this->assertInstanceOf(S::class, $str2);
624
        $this->assertNotSame($str, $str2);
625
        $this->assertSame('April1,2003', $str2->toString());
626
        $this->assertSame('April 15, 2003', $str->toString());
627
    }
628
629
    public function testSubstring()
630
    {
631
        $str = S::of('foobarbaz');
632
633
        $str2 = $str->substring(3);
634
        $this->assertInstanceOf(S::class, $str2);
635
        $this->assertNotSame($str, $str2);
636
        $this->assertSame('barbaz', $str2->toString());
637
        $this->assertSame('foobarbaz', $str->toString());
638
639
        $str3 = $str->substring(3, 3);
640
        $this->assertInstanceOf(S::class, $str3);
641
        $this->assertNotSame($str, $str3);
642
        $this->assertSame('bar', $str3->toString());
643
        $this->assertSame('foobarbaz', $str->toString());
644
645
        $str4 = ($str = S::of(''))->substring(0, -1);
646
647
        $this->assertSame($str, $str4);
648
    }
649
650
    public function testTake()
651
    {
652
        $str = S::of('foobarbaz');
653
654
        $str2 = $str->take(3);
655
656
        $this->assertInstanceOf(S::class, $str2);
657
        $this->assertNotSame($str, $str2);
658
        $this->assertSame('foo', $str2->toString());
659
        $this->assertSame('foobarbaz', $str->toString());
660
    }
661
662
    public function testTakeEnd()
663
    {
664
        $str = S::of('foobarbaz');
665
666
        $str2 = $str->takeEnd(3);
667
668
        $this->assertInstanceOf(S::class, $str2);
669
        $this->assertNotSame($str, $str2);
670
        $this->assertSame('baz', $str2->toString());
671
        $this->assertSame('foobarbaz', $str->toString());
672
    }
673
674
    public function testDrop()
675
    {
676
        $str = S::of('foobarbaz');
677
678
        $str2 = $str->drop(3);
679
680
        $this->assertInstanceOf(S::class, $str2);
681
        $this->assertNotSame($str, $str2);
682
        $this->assertSame('barbaz', $str2->toString());
683
        $this->assertSame('foobarbaz', $str->toString());
684
    }
685
686
    public function testDropEnd()
687
    {
688
        $str = S::of('foobarbaz');
689
690
        $str2 = $str->dropEnd(3);
691
692
        $this->assertInstanceOf(S::class, $str2);
693
        $this->assertNotSame($str, $str2);
694
        $this->assertSame('foobar', $str2->toString());
695
        $this->assertSame('foobarbaz', $str->toString());
696
    }
697
698
    public function testSubstringUtf8ManipulatedAsAscii()
699
    {
700
        $str = S::of('foo🙏bar')->toEncoding('ASCII');
701
702
        $this->assertSame('🙏bar', $str->substring(3)->toString());
703
        $this->assertSame('🙏', $str->substring(3, 4)->toString());
704
        $this->assertSame(
705
            mb_substr('🙏', 0, 1, 'ASCII'),
706
            $str->substring(3, 1)->toString()
707
        );
708
    }
709
710
    public function testSprintf()
711
    {
712
        $str = S::of('foo %s baz');
713
714
        $str2 = $str->sprintf('bar');
715
        $this->assertInstanceOf(S::class, $str2);
716
        $this->assertNotSame($str, $str2);
717
        $this->assertSame('foo bar baz', $str2->toString());
718
        $this->assertSame('foo %s baz', $str->toString());
719
    }
720
721
    public function testUcfirst()
722
    {
723
        $str = S::of('foo');
724
725
        $str2 = $str->ucfirst();
726
        $this->assertInstanceOf(S::class, $str2);
727
        $this->assertNotSame($str, $str2);
728
        $this->assertSame('foo', $str->toString());
729
        $this->assertSame('Foo', $str2->toString());
730
        $this->assertSame('🙏', S::of('🙏')->ucfirst()->toString());
731
        $this->assertSame('Égérie', S::of('égérie')->ucfirst()->toString());
732
    }
733
734
    public function testLcfirst()
735
    {
736
        $str = S::of('FOO');
737
738
        $str2 = $str->lcfirst();
739
        $this->assertInstanceOf(S::class, $str2);
740
        $this->assertNotSame($str, $str2);
741
        $this->assertSame('FOO', $str->toString());
742
        $this->assertSame('fOO', $str2->toString());
743
        $this->assertSame('🙏', S::of('🙏')->lcfirst()->toString());
744
        $this->assertSame('éGÉRIE', S::of('ÉGÉRIE')->lcfirst()->toString());
745
    }
746
747
    public function testCamelize()
748
    {
749
        $str = S::of('foo_bar baz');
750
751
        $str2 = $str->camelize();
752
        $this->assertInstanceOf(S::class, $str2);
753
        $this->assertNotSame($str, $str2);
754
        $this->assertSame('foo_bar baz', $str->toString());
755
        $this->assertSame('fooBarBaz', $str2->toString());
756
    }
757
758
    public function testAppend()
759
    {
760
        $str = S::of('foo');
761
762
        $str2 = $str->append(' bar');
763
        $this->assertNotSame($str, $str2);
764
        $this->assertSame('foo', $str->toString());
765
        $this->assertSame('foo bar', $str2->toString());
766
    }
767
768
    public function testPrepend()
769
    {
770
        $str = S::of('foo');
771
772
        $str2 = $str->prepend('baz ');
773
        $this->assertNotSame($str, $str2);
774
        $this->assertSame('foo', $str->toString());
775
        $this->assertSame('baz foo', $str2->toString());
776
    }
777
778
    public function testEquals()
779
    {
780
        $this->assertTrue(S::of('foo')->equals(S::of('foo')));
781
        $this->assertFalse(S::of('foo')->equals(S::of('fo')));
782
    }
783
784
    public function testTrim()
785
    {
786
        $str = S::of(' foo ');
787
        $str2 = $str->trim();
788
789
        $this->assertInstanceOf(S::class, $str2);
790
        $this->assertNotSame($str, $str2);
791
        $this->assertSame(' foo ', $str->toString());
792
        $this->assertSame('foo', $str2->toString());
793
        $this->assertSame('f', $str2->trim('o')->toString());
794
    }
795
796
    public function testRightTrim()
797
    {
798
        $str = S::of(' foo ');
799
        $str2 = $str->rightTrim();
800
801
        $this->assertInstanceOf(S::class, $str2);
802
        $this->assertNotSame($str, $str2);
803
        $this->assertSame(' foo ', $str->toString());
804
        $this->assertSame(' foo', $str2->toString());
805
        $this->assertSame(' f', $str2->rightTrim('o')->toString());
806
    }
807
808
    public function testLeftTrim()
809
    {
810
        $str = S::of(' foo ');
811
        $str2 = $str->leftTrim();
812
813
        $this->assertInstanceOf(S::class, $str2);
814
        $this->assertNotSame($str, $str2);
815
        $this->assertSame(' foo ', $str->toString());
816
        $this->assertSame('foo ', $str2->toString());
817
        $this->assertSame('oo ', $str2->leftTrim('f')->toString());
818
    }
819
820
    public function testContains()
821
    {
822
        $str = S::of('foobar');
823
824
        $this->assertTrue($str->contains('foo'));
825
        $this->assertTrue($str->contains('bar'));
826
        $this->assertFalse($str->contains('baz'));
827
    }
828
829
    public function testStartsWith()
830
    {
831
        $str = S::of('foobar');
832
833
        $this->assertTrue($str->startsWith(''));
834
        $this->assertTrue($str->startsWith('foo'));
835
        $this->assertTrue($str->startsWith('foob'));
836
        $this->assertTrue($str->startsWith('foobar'));
837
        $this->assertFalse($str->startsWith('bar'));
838
        $this->assertFalse($str->startsWith('oobar'));
839
        $this->assertFalse($str->startsWith('foobar '));
840
    }
841
842
    public function testEndsWith()
843
    {
844
        $str = S::of('foobar');
845
846
        $this->assertTrue($str->endsWith(''));
847
        $this->assertTrue($str->endsWith('bar'));
848
        $this->assertTrue($str->endsWith('obar'));
849
        $this->assertTrue($str->endsWith('foobar'));
850
        $this->assertFalse($str->endsWith('foo'));
851
        $this->assertFalse($str->endsWith('fooba'));
852
        $this->assertFalse($str->endsWith('xfoobar'));
853
    }
854
855
    public function testPregQuote()
856
    {
857
        $a = S::of('foo#bar.*');
858
        $b = $a->pregQuote();
859
        $c = $a->pregQuote('o');
860
861
        $this->assertInstanceOf(S::class, $b);
862
        $this->assertInstanceOf(S::class, $c);
863
        $this->assertSame('foo#bar.*', $a->toString());
864
        $this->assertSame('foo\#bar\.\*', $b->toString());
865
        $this->assertSame('f\o\o\#bar\.\*', $c->toString());
866
    }
867
}
868