Skip to content

Commit e396395

Browse files
committed
Refactor countChar function for improved input validation and enhance test cases for clarity and coverage
1 parent 1092e07 commit e396395

File tree

2 files changed

+102
-64
lines changed

2 files changed

+102
-64
lines changed

Sprint-3/2-practice-tdd/count.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,36 @@
11
function countChar(stringOfCharacters, findCharacter) {
2-
if (stringOfCharacters == null) {
3-
return "Error: The input string cannot be null or undefined.";
2+
// 1. Validate 'stringOfCharacters' input
3+
if (stringOfCharacters === null || stringOfCharacters === undefined) {
4+
throw new Error("The input string cannot be null or undefined.");
45
}
5-
6-
if (stringOfCharacters.length === 0) {
7-
return "Error: The string cannot be empty.";
6+
if (typeof stringOfCharacters !== "string") {
7+
throw new Error("The input string must be a string type.");
88
}
99

10-
if (findCharacter == null) {
11-
return "Error: The character to count must be a single character.";
10+
// 2. Validate 'findCharacter' input
11+
if (typeof findCharacter !== "string" || findCharacter.length !== 1) {
12+
// This handles null, undefined, and strings that aren't a single character (including empty string "")
13+
throw new Error(
14+
"The character to count must be a single character string."
15+
);
1216
}
1317

14-
const findChars = [...findCharacter];
15-
if (findChars.length !== 1) {
16-
return "Error: The character to count must be a single character.";
18+
// 3. Handle the empty string case (returns 0)
19+
if (stringOfCharacters.length === 0) {
20+
return 0;
1721
}
1822

23+
// 4. Perform the count
1924
let count = 0;
2025
for (let ch of stringOfCharacters) {
21-
if (ch === findCharacter) count++;
26+
if (ch === findCharacter) {
27+
count++;
28+
}
2229
}
2330

2431
return count;
2532
}
2633

2734
module.exports = countChar;
2835

29-
// implement a function countChar that counts the number of times a character occurs in a string
36+
// implement a function countChar that counts the number of times a character occurs in a string
Lines changed: 83 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,101 @@
11
// implement a function countChar that counts the number of times a character occurs in a string
2-
const countChar = require("./count");
2+
// const countChar = require("./count");
33
// Given a string str and a single character char to search for,
44
// When the countChar function is called with these inputs,
55
// Then it should:
66

77
const countChar = require("./count");
88

9-
// Grouped tests for standard character counting
10-
test.each([
11-
["a", "aaaaa", 5],
12-
["l", "hello", 2],
13-
["a", "javascript", 2],
14-
["z", "hello", 0],
15-
["h", "hello", 1],
16-
["o", "hipopotamos' make wonderful pets", 3],
17-
["p", "hipopotamos", 1],
18-
["t", "hipopotamos' are a friendly animal", 1],
19-
["x", "hipopotamos", 0],
20-
["i", "Pneumonoultramicroscopicsilicovolcanoconiosis", 6],
21-
])("should count occurrences of character '%s' in string '%s'", (char, str, expected) => {
22-
expect(countChar(str, char)).toEqual(expected);
9+
describe("countChar - Standard character counting", () => {
10+
test.each([
11+
["aaaaa", "a", 5],
12+
["hello", "l", 2],
13+
["javascript", "a", 2],
14+
["hello", "z", 0],
15+
["hello", "h", 1],
16+
["hipopotamos' make wonderful pets", "o", 4],
17+
["hipopotamos", "p", 2],
18+
["hipopotamos' are friendly animals", "t", 1],
19+
["hipopotamos", "x", 0],
20+
["Pneumonoultramicroscopicsilicovolcanoconiosis", "i", 6],
21+
])("should count occurrences of '%s' in '%s'", (input, char, expected) => {
22+
expect(countChar(input, char)).toBe(expected);
23+
});
2324
});
2425

25-
// Edge case: empty string
26-
test("should return error if the string is empty", () => {
27-
expect(countChar("", "a")).toEqual("Error: The string cannot be empty.");
28-
});
26+
describe("countChar - Edge cases", () => {
27+
test("should return 0 for empty string", () => {
28+
expect(countChar("", "a")).toBe(0);
29+
});
2930

30-
// Edge case: null or undefined string
31-
test("should return error if the string is null or undefined", () => {
32-
expect(countChar(null, "a")).toEqual("Error: The input string cannot be null or undefined.");
33-
expect(countChar(undefined, "a")).toEqual("Error: The input string cannot be null or undefined.");
34-
});
31+
test("should return 0 when character is not found", () => {
32+
expect(countChar("abcdef", "z")).toBe(0);
33+
});
3534

36-
// Edge case: invalid character input
37-
test("should return error if the character to count is not a single character", () => {
38-
expect(countChar("hello", "")).toEqual("Error: The character to count must be a single character.");
39-
expect(countChar("hello", "ll")).toEqual("Error: The character to count must be a single character.");
40-
expect(countChar("hello", null)).toEqual("Error: The character to count must be a single character.");
41-
expect(countChar("hello", undefined)).toEqual("Error: The character to count must be a single character.");
42-
});
35+
test("should handle special characters", () => {
36+
expect(countChar("!@#$%^&*", "&")).toBe(1);
37+
});
4338

44-
// Case sensitivity
45-
test("should count only characters that match the exact case", () => {
46-
const str = "AaAaA";
47-
expect(countChar(str, "a")).toEqual(2); // lowercase only
48-
expect(countChar(str, "A")).toEqual(3); // uppercase only
49-
});
39+
test("should be case-sensitive", () => {
40+
expect(countChar("AaAaA", "a")).toBe(2);
41+
expect(countChar("AaAaA", "A")).toBe(3);
42+
});
5043

51-
// Special characters
52-
test("should count special characters", () => {
53-
expect(countChar("!?!?", "?")).toEqual(2);
54-
});
44+
test("should handle numeric characters", () => {
45+
expect(countChar("123123123", "2")).toBe(3);
46+
});
5547

56-
// Spaces
57-
test("should count spaces correctly", () => {
58-
expect(countChar("a b c", " ")).toEqual(2);
48+
test("should handle whitespace characters", () => {
49+
expect(countChar("a b c d e", " ")).toBe(4);
50+
});
5951
});
6052

61-
// Unicode characters
62-
test("should count unicode characters correctly", () => {
63-
expect(countChar("😀😃😀😄", "😀")).toEqual(2);
64-
});
53+
describe("countChar - Input validation", () => {
54+
test("should throw error if input string is null", () => {
55+
expect(() => countChar(null, "a")).toThrow(
56+
"The input string cannot be null or undefined."
57+
);
58+
});
59+
60+
test("should throw error if input string is undefined", () => {
61+
expect(() => countChar(undefined, "a")).toThrow(
62+
"The input string cannot be null or undefined."
63+
);
64+
});
65+
66+
test("should throw error if input string is not a string", () => {
67+
expect(() => countChar(12345, "a")).toThrow(
68+
"The input string must be a string type."
69+
);
70+
});
71+
72+
test("should throw error if findCharacter is null", () => {
73+
expect(() => countChar("abc", null)).toThrow(
74+
"The character to count must be a single character string."
75+
);
76+
});
77+
78+
test("should throw error if findCharacter is undefined", () => {
79+
expect(() => countChar("abc", undefined)).toThrow(
80+
"The character to count must be a single character string."
81+
);
82+
});
83+
84+
test("should throw error if findCharacter is not a string", () => {
85+
expect(() => countChar("abc", 1)).toThrow(
86+
"The character to count must be a single character string."
87+
);
88+
});
89+
90+
test("should throw error if findCharacter is an empty string", () => {
91+
expect(() => countChar("abc", "")).toThrow(
92+
"The character to count must be a single character string."
93+
);
94+
});
6595

66-
// Long strings
67-
test("should handle long strings efficiently", () => {
68-
const longString = "a".repeat(10000) + "b".repeat(5000) + "a".repeat(3000);
69-
expect(countChar(longString, "a")).toEqual(13000);
96+
test("should throw error if findCharacter is more than one character", () => {
97+
expect(() => countChar("abc", "ab")).toThrow(
98+
"The character to count must be a single character string."
99+
);
100+
});
70101
});

0 commit comments

Comments
 (0)