Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .gitignore
Binary file not shown.
39 changes: 38 additions & 1 deletion Sprint-3/2-practice-tdd/count.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
function countChar(stringOfCharacters, findCharacter) {
return 5
// stringOfCharacters and findCharacter both should be string.
if (
typeof stringOfCharacters !== "string" ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If either or both arguments are not strings, does it really make sense to return 0? Think of it this way, you call the countChar(2, 3), what would you expect your function to return? I would suggest you to check this link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error

typeof findCharacter !== "string"
) {
return "Values Can not be Numbers";
}

// stringOfCharacters should be longer than findCharacter.
if (
stringOfCharacters.length !== 0 &&
findCharacter.length > stringOfCharacters.length
) {
return "the stringOfCharacters MUST be lonegr than findingcharacter";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in longer and findingcharacter

}

//stringOfCharacters shoud not be empty
if (stringOfCharacters.length === 0) {
return "stringOfCharacters can not be empty";
}

//findCharacter should not be empty
if (findCharacter.length === 0) {
return "findCharacter can not be empty";
}
Comment on lines +18 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These could be combined.


// finscharatcter should be single character.
if (findCharacter.length !== 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good check! As an extension, what if stringOfCharacters.length is 0 and findCharacter.length is 1? I see you now return just 0 but would it perhaps make more sense to throw an error because there is nothing to search character in?

return "findCharacter must be a single character";
}

let count = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice use of for loop!

for (let i = 0; i < stringOfCharacters.length; i++) {
if (stringOfCharacters[i] === findCharacter) {
count++;
}
}
return count;
}

module.exports = countChar;
85 changes: 85 additions & 0 deletions Sprint-3/2-practice-tdd/count.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,93 @@ test("should count multiple occurrences of a character", () => {
expect(count).toEqual(5);
});

test("should count multiple occurrences of a character", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, this is a good improvement on the previous iteration. Can you think of corner cases? What if length of stringOfCharacters is shorter than length of findCharacter? What either of them is an empty string or some other data type?

const str = "bbb";
const char = "b";
const count = countChar(str, char);
expect(count).toEqual(3);
});

test("should count mutiple of character 'coco can have coconut'", () => {
const str = "coco can have coconut";
const char = "c";
const count = countChar(str, char);
expect(count).toEqual(5);
});

test("should count multiple occurrences of a character 'a' in 'I have an apple'", () => {
const str = "I have an apple";
const char = "a";
const count = countChar(str, char);
expect(count).toEqual(3);
});

// Scenario: No Occurrences
// Given the input string str,
// And a character char that does not exist within the case-sensitive str,
// When the function is called with these inputs,
// Then it should return 0, indicating that no occurrences of the char were found in the case-sensitive str.

test("should return 0 when the character does not exist in the string", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test suite is very slim, can you think of more test cases? You should try to cover as many scenarios as possible to test whether your function behaves right if something expected or unexpected passed to your function.

const str = "hello";
const char = "z";
const count = countChar(str, char);
expect(count).toEqual(0);
});

test("should return 0 when the 'c' does not exist in string 'I dont have an apple'", () => {
const str = "I dont have an apple";
const char = "c";
const count = countChar(str, char);
expect(count).toEqual(0);
});

// Scenario: Find character is longer than the input string
// Given a string shorter than the findCharacter (e.g., 'a' vs 'abc'),
// When the function is called,
// Then it should return 0 because a multi-character string cannot match a single character position.

test("should return a message when findCharacter is longer than the input string", () => {
const str = "a";
const char = "abc";
const count = countChar(str, char);
expect(count).toEqual(
"the stringOfCharacters MUST be lonegr than findingcharacter"
);
});

// Scenario: Empty string input
// Given an empty input string and a valid character,
// When the function is called,
// Then it should return 0 because there are no characters to search.

test("should return a Message when input stringOfCharacters is empty", () => {
const str = "";
const char = "a";
const count = countChar(str, char);
expect(count).toEqual("stringOfCharacters can not be empty");
});

// Scenario: Empty findCharacter
// Given a valid string but an empty findCharacter,
// When the function is called,
// Then it should return 0 because an empty search target is not valid.

test("should return message when findCharacter is an empty string", () => {
const str = "hello";
const char = "";
const count = countChar(str, char);
expect(count).toEqual("findCharacter can not be empty");
});

// Scenario: Non-string input type
// Given that one or both inputs are not strings (e.g., number, array),
// When the function is called,
// Then it should return 0 or handle the input gracefully without throwing an error.

test("should return message when inputs are numbers", () => {
const str = 12345;
const char = 1;
const count = countChar(str, char);
expect(count).toEqual("Values Can not be Numbers");
});
25 changes: 23 additions & 2 deletions Sprint-3/2-practice-tdd/get-ordinal-number.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
function getOrdinalNumber(num) {
return "1st";
function getOrdinalNumber(number) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this function is not passing the acceptance criteria. What if I pass, for example, 23 to it?

// Handle invalid inputs
if (typeof number !== "number" || !Number.isFinite(number)) {
return "Invalid input : Expected a infinit number";
}

// Handle zero or negative numbers (optional)
if (number <= 0) {
return number + "th";
}

// Handle special 11–13 endings
if (number % 100 >= 11 && number % 100 <= 13) {
return number + "th";
}

// Get last digit to determine suffix
const lastDigit = number % 10;

if (lastDigit === 1) return number + "st";
if (lastDigit === 2) return number + "nd";
if (lastDigit === 3) return number + "rd";
return number + "th";
}

module.exports = getOrdinalNumber;
96 changes: 95 additions & 1 deletion Sprint-3/2-practice-tdd/get-ordinal-number.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// get-ordinal-number.test.js
const getOrdinalNumber = require("./get-ordinal-number");
// In this week's prep, we started implementing getOrdinalNumber

Expand All @@ -7,7 +8,100 @@ const getOrdinalNumber = require("./get-ordinal-number");
// Case 1: Identify the ordinal number for 1
// When the number is 1,
// Then the function should return "1st"

test("should return '1st' for 1", () => {
expect(getOrdinalNumber(1)).toEqual("1st");
});

// Case 2: Identify the ordinal number for 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good illustration why you need to write more versatile unit tests. Before fixing your function, add more unit tests (for different numbers) and see if they pass. You will see that they do not and this is a good sign that your function implementation is incorrect.

// When the number is 2,
// Then the function should return "2nd"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the comment for countChar function's tests. If I pass undefined, I think your function will output undefinedth, is this a behaviour you expect? Can you think of other corner cases and how you can guard your function against them?

test("should return '2nd' for 2", () => {
expect(getOrdinalNumber(2)).toEqual("2nd");
});

// Case 3: Identify the ordinal number for 3
// When the number is 3,
// Then the function should return "3rd"
test("should return '3rd' for 3", () => {
expect(getOrdinalNumber(3)).toEqual("3rd");
});

// Case 4: Identify the ordinal number for 4
// When the number is 4,
// Then the function should return "4th"
test("should return '4th' for 4", () => {
expect(getOrdinalNumber(4)).toEqual("4th");
});

// Case 9: Identify the ordinal number for 9
// When the number is 9,
// Then the function should return "4th"
test("should return '9th' for 9", () => {
expect(getOrdinalNumber(9)).toEqual("9th");
});

// Case 10: Identify the ordinal number for 10
// When the number is 10,
// Then the function should return "4th"
test("should return '10th' for 10", () => {
expect(getOrdinalNumber(10)).toEqual("10th");
});

// Case 11: Identify the ordinal number for 11
// When the number is 11,
// Then the function should return "4th"
test("should return '11th' for 11", () => {
expect(getOrdinalNumber(11)).toEqual("11th");
});

// Case 20: Identify the ordinal number for 20
// When the number is 20,
// Then the function should return "20rd"
test("should return '20th' for 20", () => {
expect(getOrdinalNumber(20)).toEqual("20th");
});

// Case 23: Identify the ordinal number for 23
// When the number is 23,
// Then the function should return "33rd"
test("should return '23rd' for 23", () => {
expect(getOrdinalNumber(23)).toEqual("23rd");
});

// Case Undefind :
// When the nymber is Undefind ,
// Then the function should return "Invalid input"

test("should return 'Invalid input' when input is undefined", () => {
expect(getOrdinalNumber(undefined)).toEqual(
"Invalid input : Expected a infinit number"
);
});

// Case null :
// When the nymber is null ,
// Then the function should return "Invalid input"

test("should return 'Invalid input' when input is null", () => {
expect(getOrdinalNumber(null)).toEqual(
"Invalid input : Expected a infinit number"
);
});

// Case negetive number :
// When the number is negetive number ,
// Then the function should return "-1th"

test("should return '-1th' for -1", () => {
expect(getOrdinalNumber(-1)).toEqual("-1th");
});

// Case NaN input :
// When the nymber is NaN ,
// Then the function should return "Invalid input"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice test cases, very comprehensive!

test("should return 'Invalid input' when input is NaN", () => {
expect(getOrdinalNumber(NaN)).toEqual(
"Invalid input : Expected a infinit number"
);
});
28 changes: 26 additions & 2 deletions Sprint-3/2-practice-tdd/repeat.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
function repeat() {
return "hellohellohello";
function repeat(str, count) {
if (str === undefined) {
throw new Error("String must be defined");
}
if (str === null || typeof str !== "string") {
throw new Error("String must be a valid string");
}

if (count === undefined || typeof count !== "number") {
throw new Error("Count must be a number");
}

if (count < 0 || !Number.isInteger(count)) {
throw new Error("Count must be a non-negative integer");
}

if (str === "" || count === 0) {
return "";
}
Comment on lines +2 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is okay but it could be simplified by combining some of these if conditions and/or writing more general if condition that would catch most of the cases. You don't need to do anything, it's just something to think about and perhaps to implement on your spare time.


let result = "";
for (let i = 0; i < count; i++) {
result += str;
}

return result;
}

module.exports = repeat;
58 changes: 57 additions & 1 deletion Sprint-3/2-practice-tdd/repeat.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Implement a function repeat
const repeat = require("./repeat");
// Given a target string str and a positive integer count,
// When the repeat function is called with these inputs,
Expand All @@ -21,12 +20,69 @@ test("should repeat the string count times", () => {
// When the repeat function is called with these inputs,
// Then it should return the original str without repetition, ensuring that a count of 1 results in no repetition.

test("should return the original string when count is 1", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These unit tests are correct but they are a bit limited. What if I pass undefined as str and count 2? What if I pass empty string? You should try to guard your function against these scenarios and unit tests help to think of different scenarios.

const str = "hi";
const count = 1;
const repeatedStr = repeat(str, count);
expect(repeatedStr).toEqual("hi");
});

// case: Handle Count of 0:
// Given a target string str and a count equal to 0,
// When the repeat function is called with these inputs,
// Then it should return an empty string, ensuring that a count of 0 results in an empty output.

test("should return an empty string when count is 0", () => {
const str = "hi";
const count = 0;
const repeatedStr = repeat(str, count);
expect(repeatedStr).toEqual("");
});

// case: Negative Count:
// Given a target string str and a negative integer count,
// When the repeat function is called with these inputs,
// Then it should throw an error or return an appropriate error message, as negative counts are not valid.

test("should throw an error when count is negative", () => {
const str = "hi";
const count = -2;
expect(() => repeat(str, count)).toThrow(
"Count must be a non-negative integer"
);
});

// case: Undefined String
// Given that str is undefined and count is a positive integer,
// When the repeat function is called with these inputs,
// Then it should throw an error or return an appropriate message,
// since repeating an undefined value does not make sense.

test("should throw an error when string is undefined", () => {
const str = undefined;
const count = 2;
expect(() => repeat(str, count)).toThrow("String must be defined");
});

// case: Empty String
// Given an empty string str and a positive integer count,
// When the repeat function is called,
// Then it should return an empty string, since there is nothing to repeat.

test("should return an empty string when input string is empty", () => {
const str = "";
const count = 3;
const repeatedStr = repeat(str, count);
expect(repeatedStr).toEqual("");
});

// case: Null String
// Given that str is null and count is a positive integer,
// When the repeat function is called,
// Then it should throw an error, because null is not a valid string input.

test("should throw an error when string is null", () => {
const str = null;
const count = 2;
expect(() => repeat(str, count)).toThrow("String must be a valid string");
});
15 changes: 0 additions & 15 deletions package.json

This file was deleted.