1
|
|
|
<?php |
2
|
|
|
declare(strict_types = 1); |
3
|
|
|
|
4
|
|
|
namespace Tests\Innmind\Immutable; |
5
|
|
|
|
6
|
|
|
use Innmind\Immutable\{ |
7
|
|
|
Str as S, |
8
|
|
|
PrimitiveInterface, |
|
|
|
|
9
|
|
|
StringableInterface, |
|
|
|
|
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
|
|
|
|
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:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths