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