-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
106 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require "./spec_helper" | ||
|
||
describe Marten::Core::Sluggable do | ||
describe ".generate_slug" do | ||
value = "Test Title 123" | ||
max_size = 20 | ||
slug = Marten::Core::Sluggable.generate_slug(value, max_size) | ||
|
||
it "removes non-alphanumeric characters" do | ||
value_with_special_chars = "Test@Title#123!" | ||
slug = Marten::Core::Sluggable.generate_slug(value_with_special_chars, max_size) | ||
slug.starts_with?("testtitle12-").should be_true | ||
end | ||
|
||
it "converts the string to lowercase" do | ||
slug.starts_with?("testtitle12-").should be_true | ||
end | ||
|
||
it "replaces whitespace and hyphens with a single hyphen" do | ||
value_with_spaces_and_hyphens = "Test - Title 123" | ||
slug = Marten::Core::Sluggable.generate_slug(value_with_spaces_and_hyphens, max_size) | ||
slug.starts_with?("test-title-").should be_true | ||
end | ||
|
||
it "strips leading and trailing hyphens and underscores" do | ||
value_with_hyphens = "-Test Title 123-" | ||
slug = Marten::Core::Sluggable.generate_slug(value_with_hyphens, max_size) | ||
slug.starts_with?("test-title-").should be_true | ||
end | ||
|
||
it "removes non-ASCII characters" do | ||
value_with_non_ascii = "Test Títle 123" | ||
slug = Marten::Core::Sluggable.generate_slug(value_with_non_ascii, max_size) | ||
slug.starts_with?("test-ttle-1-").should be_true | ||
end | ||
|
||
it "limits the slug length to max_size" do | ||
slug.size.should eq(max_size) | ||
end | ||
|
||
it "does not exceed max_size even with long input" do | ||
long_value = "This is a very long title that should be truncated" | ||
slug = Marten::Core::Sluggable.generate_slug(long_value, max_size) | ||
slug.size.should eq(max_size) | ||
end | ||
|
||
it "does not truncate the slug when max_size is large enough" do | ||
long_value = "This is a very long title that should not be truncated" | ||
slug = Marten::Core::Sluggable.generate_slug(long_value, 100) | ||
|
||
slug.starts_with?("this-is-a-very-long-title-that-should-not-be-truncated").should be_true | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 0 additions & 12 deletions
12
spec/marten/db/field/slug_spec/models/article_with_custom_slug_generator.cr
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
module Marten | ||
module Core | ||
# The Sluggable module provides functionality for generating URL-friendly slugs from strings. | ||
module Sluggable | ||
extend self | ||
|
||
NON_ALPHANUMERIC_RE = /[^\w\s-]/ | ||
WHITESPACE_HYPHEN_RE = /[-\s]+/ | ||
NON_ASCII_RE = /[^\x00-\x7F]/ | ||
|
||
# Generates a slug from the given value, ensuring the resulting slug does not exceed the specified max_size. | ||
# | ||
# The slug is created by: | ||
# 1. Removing non-alphanumeric characters (except whitespace and hyphens). | ||
# 2. Converting the string to lowercase. | ||
# 3. Replacing sequences of whitespace and hyphens with a single hyphen. | ||
# 4. Removing non-ASCII characters. | ||
# 5. Truncating the slug to fit within the max_size, minus the size of a randomly generated suffix. | ||
# 6. Stripping trailing hyphens and underscores of the slug without suffix, and appending the suffix. | ||
def generate_slug(value, max_size) | ||
suffix = "-#{Random::Secure.hex(4)}" | ||
|
||
slug = value.gsub(NON_ALPHANUMERIC_RE, "").downcase | ||
slug = slug.gsub(WHITESPACE_HYPHEN_RE, "-") | ||
slug = slug.gsub(NON_ASCII_RE, "") | ||
|
||
slug[...(max_size - suffix.size)].strip("-_") + suffix | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters