Skip to content

Commit ebae878

Browse files
committed
is_slug now allows multiple consecutive separator signs between words
1 parent bb8cef6 commit ebae878

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ importable as before (`from string_utils import xxx`). Similarly `tests.py` has
6767
with a module for each test case
6868
- `is_snake_case()` now considers as "snake case" strings with mixed upper and lower case characters, strings with
6969
leading or trailing underscores and string containing multiple underscores in sequence
70+
- `is_slug()` now allows multiple consecutive separator signs between words
7071

7172
### Improvements:
7273

string_utils/validation.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ def is_isogram(input_string: Any) -> bool:
543543
return is_full_string(input_string) and len(set(input_string)) == len(input_string)
544544

545545

546-
def is_slug(input_string: Any, sign: str = '-') -> bool:
546+
def is_slug(input_string: Any, separator: str = '-') -> bool:
547547
"""
548548
Checks if a given string is a slug (as created by `slugify()`).
549549
@@ -554,14 +554,14 @@ def is_slug(input_string: Any, sign: str = '-') -> bool:
554554
555555
:param input_string: String to check.
556556
:type input_string: str
557-
:param sign: Join sign used by the slug.
558-
:type sign: str
557+
:param separator: Join sign used by the slug.
558+
:type separator: str
559559
:return: True if slug, false otherwise.
560560
"""
561561
if not is_full_string(input_string):
562562
return False
563563

564-
rex = r'^([a-z\d]+' + re.escape(sign) + r'?)*[a-z\d]$'
564+
rex = r'^([a-z\d]+' + re.escape(separator) + r'*?)*[a-z\d]$'
565565

566566
return re.match(rex, input_string) is not None
567567

tests/test_is_slug.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ def test_recognizes_slugs(self):
2929
self.assertTrue(is_slug('yep.i.am.a.slug', '.'))
3030
self.assertTrue(is_slug('yep_i_am_a_slug', '_'))
3131

32+
def test_slug_can_have_multiple_consecutive_separator_signs(self):
33+
self.assertTrue(is_slug('oh-----yeah'))
34+
self.assertTrue(is_slug('oh_____yeah', '_'))
35+
self.assertTrue(is_slug('1----2'))
36+
3237
def test_slug_cannot_contain_spaces(self):
3338
self.assertFalse(is_slug('not - a - slug'))
3439
self.assertFalse(is_slug('not- a - slug'))
@@ -37,6 +42,18 @@ def test_slug_cannot_contain_spaces(self):
3742
self.assertFalse(is_slug('not-a-slug '))
3843
self.assertFalse(is_slug(' not-a-slug'))
3944

45+
def test_slug_cannot_contain_non_ascii_chars(self):
46+
self.assertFalse(is_slug('foò-bär'))
47+
48+
def test_slug_cannot_contain_punctuation(self):
49+
self.assertFalse(is_slug('foo.-bar'))
50+
self.assertFalse(is_slug('foo-bar.'))
51+
self.assertFalse(is_slug('foo-bar,'))
52+
self.assertFalse(is_slug('!foo-bar'))
53+
self.assertFalse(is_slug('foo-bar?'))
54+
self.assertFalse(is_slug('foo-bar:'))
55+
self.assertFalse(is_slug('foo-bar;'))
56+
4057
def test_exclude_invalid_slugs(self):
4158
self.assertFalse(is_slug(' nope'))
4259
self.assertFalse(is_slug('nope '))
@@ -46,3 +63,12 @@ def test_exclude_invalid_slugs(self):
4663
self.assertFalse(is_slug('-no-no-no-'))
4764
self.assertFalse(is_slug('100%no-slug!'))
4865
self.assertFalse(is_slug('NOT-AS-UPPERCASE'))
66+
67+
def test_slug_can_be_single_word(self):
68+
self.assertTrue(is_slug('hello'))
69+
self.assertTrue(is_slug('x'))
70+
self.assertTrue(is_slug('42'))
71+
self.assertTrue(is_slug('5'))
72+
73+
def test_slug_must_have_at_least_one_non_separator_char(self):
74+
self.assertFalse(is_slug('-'))

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy