Skip to content

Commit e6245ae

Browse files
authored
Feature: doesntStartWith() and doesntEndWith() string methods (#56168)
* wip * wip
1 parent d3aa39c commit e6245ae

File tree

4 files changed

+248
-0
lines changed

4 files changed

+248
-0
lines changed

src/Illuminate/Support/Str.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,18 @@ public static function endsWith($haystack, $needles)
405405
return false;
406406
}
407407

408+
/**
409+
* Determine if a given string doesn't end with a given substring.
410+
*
411+
* @param string $haystack
412+
* @param string|iterable<string> $needles
413+
* @return bool
414+
*/
415+
public static function doesntEndWith($haystack, $needles)
416+
{
417+
return ! static::endsWith($haystack, $needles);
418+
}
419+
408420
/**
409421
* Extracts an excerpt from text that matches the first instance of a phrase.
410422
*
@@ -1659,6 +1671,18 @@ public static function startsWith($haystack, $needles)
16591671
return false;
16601672
}
16611673

1674+
/**
1675+
* Determine if a given string doesn't start with a given substring.
1676+
*
1677+
* @param string $haystack
1678+
* @param string|iterable<string> $needles
1679+
* @return bool
1680+
*/
1681+
public static function doesntStartWith($haystack, $needles)
1682+
{
1683+
return ! static::startsWith($haystack, $needles);
1684+
}
1685+
16621686
/**
16631687
* Convert a value to studly caps case.
16641688
*

src/Illuminate/Support/Stringable.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,17 @@ public function endsWith($needles)
267267
return Str::endsWith($this->value, $needles);
268268
}
269269

270+
/**
271+
* Determine if a given string doesn't end with a given substring.
272+
*
273+
* @param string|iterable<string> $needles
274+
* @return bool
275+
*/
276+
public function doesntEndWith($needles)
277+
{
278+
return Str::doesntEndWith($this->value, $needles);
279+
}
280+
270281
/**
271282
* Determine if the string is an exact match with the given value.
272283
*
@@ -932,6 +943,17 @@ public function startsWith($needles)
932943
return Str::startsWith($this->value, $needles);
933944
}
934945

946+
/**
947+
* Determine if a given string doesn't start with a given substring.
948+
*
949+
* @param string|iterable<string> $needles
950+
* @return bool
951+
*/
952+
public function doesntStartWith($needles)
953+
{
954+
return Str::doesntStartWith($this->value, $needles);
955+
}
956+
935957
/**
936958
* Convert a value to studly caps case.
937959
*
@@ -1143,6 +1165,19 @@ public function whenEndsWith($needles, $callback, $default = null)
11431165
return $this->when($this->endsWith($needles), $callback, $default);
11441166
}
11451167

1168+
/**
1169+
* Execute the given callback if the string doesn't end with a given substring.
1170+
*
1171+
* @param string|iterable<string> $needles
1172+
* @param callable $callback
1173+
* @param callable|null $default
1174+
* @return static
1175+
*/
1176+
public function whenDoesntEndWith($needles, $callback, $default = null)
1177+
{
1178+
return $this->when($this->doesntEndWith($needles), $callback, $default);
1179+
}
1180+
11461181
/**
11471182
* Execute the given callback if the string is an exact match with the given value.
11481183
*
@@ -1231,6 +1266,19 @@ public function whenStartsWith($needles, $callback, $default = null)
12311266
return $this->when($this->startsWith($needles), $callback, $default);
12321267
}
12331268

1269+
/**
1270+
* Execute the given callback if the string doesn't start with a given substring.
1271+
*
1272+
* @param string|iterable<string> $needles
1273+
* @param callable $callback
1274+
* @param callable|null $default
1275+
* @return static
1276+
*/
1277+
public function whenDoesntStartWith($needles, $callback, $default = null)
1278+
{
1279+
return $this->when($this->doesntStartWith($needles), $callback, $default);
1280+
}
1281+
12341282
/**
12351283
* Execute the given callback if the string matches the given pattern.
12361284
*

tests/Support/SupportStrTest.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,41 @@ public function testStartsWith()
186186
$this->assertFalse(Str::startsWith('你好', 'a'));
187187
}
188188

189+
public function testDoesntStartWith()
190+
{
191+
$this->assertFalse(Str::doesntStartWith('jason', 'jas'));
192+
$this->assertFalse(Str::doesntStartWith('jason', 'jason'));
193+
$this->assertFalse(Str::doesntStartWith('jason', ['jas']));
194+
$this->assertFalse(Str::doesntStartWith('jason', ['day', 'jas']));
195+
$this->assertFalse(Str::doesntStartWith('jason', collect(['day', 'jas'])));
196+
$this->assertTrue(Str::doesntStartWith('jason', 'day'));
197+
$this->assertTrue(Str::doesntStartWith('jason', ['day']));
198+
$this->assertTrue(Str::doesntStartWith('jason', null));
199+
$this->assertTrue(Str::doesntStartWith('jason', [null]));
200+
$this->assertTrue(Str::doesntStartWith('0123', [null]));
201+
$this->assertFalse(Str::doesntStartWith('0123', 0));
202+
$this->assertTrue(Str::doesntStartWith('jason', 'J'));
203+
$this->assertTrue(Str::doesntStartWith('jason', ''));
204+
$this->assertTrue(Str::doesntStartWith('', ''));
205+
$this->assertTrue(Str::doesntStartWith('7', ' 7'));
206+
$this->assertFalse(Str::doesntStartWith('7a', '7'));
207+
$this->assertFalse(Str::doesntStartWith('7a', 7));
208+
$this->assertFalse(Str::doesntStartWith('7.12a', 7.12));
209+
$this->assertTrue(Str::doesntStartWith('7.12a', 7.13));
210+
$this->assertFalse(Str::doesntStartWith(7.123, '7'));
211+
$this->assertFalse(Str::doesntStartWith(7.123, '7.12'));
212+
$this->assertTrue(Str::doesntStartWith(7.123, '7.13'));
213+
$this->assertTrue(Str::doesntStartWith(null, 'Marc'));
214+
// Test for multibyte string support
215+
$this->assertFalse(Str::doesntStartWith('Jönköping', ''));
216+
$this->assertFalse(Str::doesntStartWith('Malmö', 'Malmö'));
217+
$this->assertTrue(Str::doesntStartWith('Jönköping', 'Jonko'));
218+
$this->assertTrue(Str::doesntStartWith('Malmö', 'Malmo'));
219+
$this->assertFalse(Str::doesntStartWith('你好', ''));
220+
$this->assertTrue(Str::doesntStartWith('你好', ''));
221+
$this->assertTrue(Str::doesntStartWith('你好', 'a'));
222+
}
223+
189224
public function testEndsWith()
190225
{
191226
$this->assertTrue(Str::endsWith('jason', 'on'));
@@ -219,6 +254,39 @@ public function testEndsWith()
219254
$this->assertFalse(Str::endsWith('你好', 'a'));
220255
}
221256

257+
public function testDoesntEndWith()
258+
{
259+
$this->assertFalse(Str::doesntEndWith('jason', 'on'));
260+
$this->assertFalse(Str::doesntEndWith('jason', 'jason'));
261+
$this->assertFalse(Str::doesntEndWith('jason', ['on']));
262+
$this->assertFalse(Str::doesntEndWith('jason', ['no', 'on']));
263+
$this->assertFalse(Str::doesntEndWith('jason', collect(['no', 'on'])));
264+
$this->assertTrue(Str::doesntEndWith('jason', 'no'));
265+
$this->assertTrue(Str::doesntEndWith('jason', ['no']));
266+
$this->assertTrue(Str::doesntEndWith('jason', ''));
267+
$this->assertTrue(Str::doesntEndWith('', ''));
268+
$this->assertTrue(Str::doesntEndWith('jason', [null]));
269+
$this->assertTrue(Str::doesntEndWith('jason', null));
270+
$this->assertTrue(Str::doesntEndWith('jason', 'N'));
271+
$this->assertTrue(Str::doesntEndWith('7', ' 7'));
272+
$this->assertFalse(Str::doesntEndWith('a7', '7'));
273+
$this->assertFalse(Str::doesntEndWith('a7', 7));
274+
$this->assertFalse(Str::doesntEndWith('a7.12', 7.12));
275+
$this->assertTrue(Str::doesntEndWith('a7.12', 7.13));
276+
$this->assertFalse(Str::doesntEndWith(0.27, '7'));
277+
$this->assertFalse(Str::doesntEndWith(0.27, '0.27'));
278+
$this->assertTrue(Str::doesntEndWith(0.27, '8'));
279+
$this->assertTrue(Str::doesntEndWith(null, 'Marc'));
280+
// Test for multibyte string support
281+
$this->assertFalse(Str::doesntEndWith('Jönköping', 'öping'));
282+
$this->assertFalse(Str::doesntEndWith('Malmö', ''));
283+
$this->assertTrue(Str::doesntEndWith('Jönköping', 'oping'));
284+
$this->assertTrue(Str::doesntEndWith('Malmö', 'mo'));
285+
$this->assertFalse(Str::doesntEndWith('你好', ''));
286+
$this->assertTrue(Str::doesntEndWith('你好', ''));
287+
$this->assertTrue(Str::doesntEndWith('你好', 'a'));
288+
}
289+
222290
public function testStrExcerpt()
223291
{
224292
$this->assertSame('...is a beautiful morn...', Str::excerpt('This is a beautiful morning', 'beautiful', ['radius' => 5]));

tests/Support/SupportStringableTest.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,31 @@ public function testWhenEndsWith()
277277
}));
278278
}
279279

280+
public function testWhenDoesntEndWith()
281+
{
282+
$this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntEndWith('ark', function ($stringable) {
283+
return $stringable->studly();
284+
}, function ($stringable) {
285+
return $stringable->title();
286+
}));
287+
288+
$this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntEndWith(['kra', 'ark'], function ($stringable) {
289+
return $stringable->studly();
290+
}, function ($stringable) {
291+
return $stringable->title();
292+
}));
293+
294+
$this->assertSame('tony stark', (string) $this->stringable('tony stark')->whenDoesntEndWith(['xxx'], function ($stringable) {
295+
return $stringable;
296+
}));
297+
298+
$this->assertSame('TonyStark', (string) $this->stringable('tony stark')->whenDoesntEndWith(['tony', 'xxx'], function ($stringable) {
299+
return $stringable->studly();
300+
}, function ($stringable) {
301+
return $stringable->title();
302+
}));
303+
}
304+
280305
public function testWhenExactly()
281306
{
282307
$this->assertSame('Nailed it...!', (string) $this->stringable('Tony Stark')->whenExactly('Tony Stark', function ($stringable) {
@@ -437,6 +462,31 @@ public function testWhenStartsWith()
437462
}));
438463
}
439464

465+
public function testWhenDoesntStartWith()
466+
{
467+
$this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntStartWith('ton', function ($stringable) {
468+
return $stringable->studly();
469+
}, function ($stringable) {
470+
return $stringable->title();
471+
}));
472+
473+
$this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntStartWith(['ton', 'not'], function ($stringable) {
474+
return $stringable->studly();
475+
}, function ($stringable) {
476+
return $stringable->title();
477+
}));
478+
479+
$this->assertSame('tony stark', (string) $this->stringable('tony stark')->whenDoesntStartWith(['xxx'], function ($stringable) {
480+
return $stringable;
481+
}));
482+
483+
$this->assertSame('Tony Stark', (string) $this->stringable('tony stark')->whenDoesntStartWith(['tony', 'xxx'], function ($stringable) {
484+
return $stringable->studly();
485+
}, function ($stringable) {
486+
return $stringable->title();
487+
}));
488+
}
489+
440490
public function testWhenEmpty()
441491
{
442492
tap($this->stringable(), function ($stringable) {
@@ -598,6 +648,36 @@ public function testStartsWith()
598648
$this->assertFalse($this->stringable('Malmö')->startsWith('Malmo'));
599649
}
600650

651+
public function testDoesntStartWith()
652+
{
653+
$this->assertFalse($this->stringable('jason')->doesntStartWith('jas'));
654+
$this->assertFalse($this->stringable('jason')->doesntStartWith('jason'));
655+
$this->assertFalse($this->stringable('jason')->doesntStartWith(['jas']));
656+
$this->assertFalse($this->stringable('jason')->doesntStartWith(['day', 'jas']));
657+
$this->assertFalse($this->stringable('jason')->doesntStartWith(collect(['day', 'jas'])));
658+
$this->assertTrue($this->stringable('jason')->doesntStartWith('day'));
659+
$this->assertTrue($this->stringable('jason')->doesntStartWith(['day']));
660+
$this->assertTrue($this->stringable('jason')->doesntStartWith(null));
661+
$this->assertTrue($this->stringable('jason')->doesntStartWith([null]));
662+
$this->assertTrue($this->stringable('0123')->doesntStartWith([null]));
663+
$this->assertFalse($this->stringable('0123')->doesntStartWith(0));
664+
$this->assertTrue($this->stringable('jason')->doesntStartWith('J'));
665+
$this->assertTrue($this->stringable('jason')->doesntStartWith(''));
666+
$this->assertTrue($this->stringable('7')->doesntStartWith(' 7'));
667+
$this->assertFalse($this->stringable('7a')->doesntStartWith('7'));
668+
$this->assertFalse($this->stringable('7a')->doesntStartWith(7));
669+
$this->assertFalse($this->stringable('7.12a')->doesntStartWith(7.12));
670+
$this->assertTrue($this->stringable('7.12a')->doesntStartWith(7.13));
671+
$this->assertFalse($this->stringable(7.123)->doesntStartWith('7'));
672+
$this->assertFalse($this->stringable(7.123)->doesntStartWith('7.12'));
673+
$this->assertTrue($this->stringable(7.123)->doesntStartWith('7.13'));
674+
// Test for multibyte string support
675+
$this->assertFalse($this->stringable('Jönköping')->doesntStartWith(''));
676+
$this->assertFalse($this->stringable('Malmö')->doesntStartWith('Malmö'));
677+
$this->assertTrue($this->stringable('Jönköping')->doesntStartWith('Jonko'));
678+
$this->assertTrue($this->stringable('Malmö')->doesntStartWith('Malmo'));
679+
}
680+
601681
public function testEndsWith()
602682
{
603683
$this->assertTrue($this->stringable('jason')->endsWith('on'));
@@ -626,6 +706,34 @@ public function testEndsWith()
626706
$this->assertFalse($this->stringable('Malmö')->endsWith('mo'));
627707
}
628708

709+
public function testDoesntEndWith()
710+
{
711+
$this->assertFalse($this->stringable('jason')->doesntEndWith('on'));
712+
$this->assertFalse($this->stringable('jason')->doesntEndWith('jason'));
713+
$this->assertFalse($this->stringable('jason')->doesntEndWith(['on']));
714+
$this->assertFalse($this->stringable('jason')->doesntEndWith(['no', 'on']));
715+
$this->assertFalse($this->stringable('jason')->doesntEndWith(collect(['no', 'on'])));
716+
$this->assertTrue($this->stringable('jason')->doesntEndWith('no'));
717+
$this->assertTrue($this->stringable('jason')->doesntEndWith(['no']));
718+
$this->assertTrue($this->stringable('jason')->doesntEndWith(''));
719+
$this->assertTrue($this->stringable('jason')->doesntEndWith([null]));
720+
$this->assertTrue($this->stringable('jason')->doesntEndWith(null));
721+
$this->assertTrue($this->stringable('jason')->doesntEndWith('N'));
722+
$this->assertTrue($this->stringable('7')->doesntEndWith(' 7'));
723+
$this->assertFalse($this->stringable('a7')->doesntEndWith('7'));
724+
$this->assertFalse($this->stringable('a7')->doesntEndWith(7));
725+
$this->assertFalse($this->stringable('a7.12')->doesntEndWith(7.12));
726+
$this->assertTrue($this->stringable('a7.12')->doesntEndWith(7.13));
727+
$this->assertFalse($this->stringable(0.27)->doesntEndWith('7'));
728+
$this->assertFalse($this->stringable(0.27)->doesntEndWith('0.27'));
729+
$this->assertTrue($this->stringable(0.27)->doesntEndWith('8'));
730+
// Test for multibyte string support
731+
$this->assertFalse($this->stringable('Jönköping')->doesntEndWith('öping'));
732+
$this->assertFalse($this->stringable('Malmö')->doesntEndWith(''));
733+
$this->assertTrue($this->stringable('Jönköping')->doesntEndWith('oping'));
734+
$this->assertTrue($this->stringable('Malmö')->doesntEndWith('mo'));
735+
}
736+
629737
public function testExcerpt()
630738
{
631739
$this->assertSame('...is a beautiful morn...', (string) $this->stringable('This is a beautiful morning')->excerpt('beautiful', ['radius' => 5]));

0 commit comments

Comments
 (0)