From 9268f437559495b2dd4a0509db08b5b2e3dabb5c Mon Sep 17 00:00:00 2001 From: sarthakgupta1907-cell Date: Fri, 6 Nov 2026 11:18:58 +0530 Subject: [PATCH] feat: add string truncate algorithm --- String/Truncate.js | 23 ++++++++++++++++++ String/test/Truncate.test.js | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 String/Truncate.js create mode 100644 String/test/Truncate.test.js diff --git a/String/Truncate.js b/String/Truncate.js new file mode 100644 index 0000000000..f80a3507ae --- /dev/null +++ b/String/Truncate.js @@ -0,0 +1,23 @@ +/** + * @function truncate + * @description Truncates a string to a specified length and appends + * an ellipsis (...) if the string exceeds that length. + * @param {string} str - The input string + * @param {number} maxLength - The maximum length of the output string + * @returns {string} - The truncated string + * @see https://en.wikipedia.org/wiki/Ellipsis + * @example truncate("Hello World", 5) => "Hello..." + * @example truncate("Hi", 5) => "Hi" + * @example truncate("Hello World", 11) => "Hello World" + */ +const truncate = (str, maxLength) => { + if (typeof str !== 'string') { + throw new TypeError('First argument must be a string') + } + if (!Number.isInteger(maxLength) || maxLength < 1) { + throw new TypeError('Second argument must be a positive integer') + } + return str.length > maxLength ? str.slice(0, maxLength) + '...' : str +} + +export { truncate } diff --git a/String/test/Truncate.test.js b/String/test/Truncate.test.js new file mode 100644 index 0000000000..e809d345d8 --- /dev/null +++ b/String/test/Truncate.test.js @@ -0,0 +1,47 @@ +import { truncate } from '../Truncate.js' + +describe('truncate', () => { + test("truncate('Hello World', 5) returns 'Hello...'", () => { + expect(truncate('Hello World', 5)).toBe('Hello...') + }) + + test("truncate('Hi', 5) returns 'Hi'", () => { + expect(truncate('Hi', 5)).toBe('Hi') + }) + + test('truncate at exact length returns original', () => { + expect(truncate('Hello', 5)).toBe('Hello') + }) + + test("truncate('Hello World', 11) returns 'Hello World'", () => { + expect(truncate('Hello World', 11)).toBe('Hello World') + }) + + test('truncate empty string returns empty string', () => { + expect(truncate('', 5)).toBe('') + }) + + test('truncate with maxLength 1', () => { + expect(truncate('Hello', 1)).toBe('H...') + }) + + test('truncate long string', () => { + expect(truncate('The quick brown fox', 9)).toBe('The quick...') + }) + + test('throws TypeError for non-string input', () => { + expect(() => truncate(123, 5)).toThrow(TypeError) + }) + + test('throws TypeError for zero maxLength', () => { + expect(() => truncate('Hello', 0)).toThrow(TypeError) + }) + + test('throws TypeError for negative maxLength', () => { + expect(() => truncate('Hello', -1)).toThrow(TypeError) + }) + + test('throws TypeError for float maxLength', () => { + expect(() => truncate('Hello', 2.5)).toThrow(TypeError) + }) +})