diff --git a/String/CountWords.js b/String/CountWords.js new file mode 100644 index 0000000000..5c04a36e59 --- /dev/null +++ b/String/CountWords.js @@ -0,0 +1,19 @@ +/** + * @function countWords + * @description Counts the number of words in a given string. + * Words are separated by whitespace. + * @param {string} str - The input string + * @returns {number} - The number of words in the string + * @see https://en.wikipedia.org/wiki/Word_count + * @example countWords("Hello World") => 2 + * @example countWords(" Hello World ") => 2 + * @example countWords("") => 0 + */ +const countWords = (str) => { + if (typeof str !== 'string') { + throw new TypeError('Input must be a string') + } + return str.trim() === '' ? 0 : str.trim().split(/\s+/).length +} + +export { countWords } diff --git a/String/test/CountWords.test.js b/String/test/CountWords.test.js new file mode 100644 index 0000000000..9defd7976d --- /dev/null +++ b/String/test/CountWords.test.js @@ -0,0 +1,39 @@ +import { countWords } from '../CountWords.js' + +describe('countWords', () => { + test("countWords('Hello World') returns 2", () => { + expect(countWords('Hello World')).toBe(2) + }) + + test("countWords('') returns 0", () => { + expect(countWords('')).toBe(0) + }) + + test("countWords(' Hello World ') returns 2", () => { + expect(countWords(' Hello World ')).toBe(2) + }) + + test('countWords single word returns 1', () => { + expect(countWords('JavaScript')).toBe(1) + }) + + test("countWords('The quick brown fox') returns 4", () => { + expect(countWords('The quick brown fox')).toBe(4) + }) + + test('countWords with tabs and newlines', () => { + expect(countWords('hello\tworld\nfoo')).toBe(3) + }) + + test('countWords with only spaces returns 0', () => { + expect(countWords(' ')).toBe(0) + }) + + test('throws TypeError for non-string input', () => { + expect(() => countWords(123)).toThrow(TypeError) + }) + + test('throws TypeError for null input', () => { + expect(() => countWords(null)).toThrow(TypeError) + }) +})