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
21 changes: 17 additions & 4 deletions format-clock-edge-cases/timeConverter.js

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not all statements are terminated by a semicolon and spacing around { and '}` is not fully consistent.

Suggestion:

  • Look up the benefits of using a code formatter.
  • Install the Prettier extension for VS Code, then:
    • Use VS Code's Format Document feature to format your code.
    • Optionally, enable Format On Save and Format On Paste to keep your code consistently formatted.

Resource: Visual Studio Code - Formatting

Note: The formatter may not work correctly if your code contains syntax errors.

Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
function formatAs12HourClock(time) {

const [hoursStr, minutesStr] = time.split(':');
const hours = Number(hoursStr);
const minutes = minutesStr;

const hours = Number(time.slice(0, 2));
if (hours === 0 || hours === 24) {
return `12:${minutes} am`;
}

if (hours === 12) {
return `12:${minutes} pm`;
}

if (hours > 12) {
return `${hours - 12}:00 pm`;
const formattedHours = String(hours - 12).padStart(2, '0');
return `${formattedHours}:${minutes} pm`;
}
return `${time} am`;

const formattedHours = String(hours).padStart(2, '0');
return `${formattedHours}:${minutes} am`;
}

export {formatAs12HourClock};
export {formatAs12HourClock};
88 changes: 86 additions & 2 deletions format-clock-edge-cases/timeConverter.test.js
Comment thread
cjyuan marked this conversation as resolved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you check whether the expected return values specified in the tests use a consistent format?

When a function's return values are not consistently formatted, it can lead to unintended side effects. For examples:

  1. When the formatted strings are displayed, they may not align nicely:
01:00 am
1:00 pm
12:00 am
01:00 pm
02:00pm
  1. When the formatted strings are compared in a program, they may produce unexpected results:
  • "1:00 pm" < "11:00 pm" evaluates to false
  • "01:00 am" < "11:00 am" evaluates to true

For this reason, it would be better to ensure that the function always returns values in a consistent format.

Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,94 @@ import {formatAs12HourClock} from "./timeConverter.js";
import assert from "node:assert";
import test from "node:test";

test("correctly convert time after 12:00", function(){
test("correctly convert hours after 12:00", () => {
assert.equal(formatAs12HourClock("23:00"), "11:00 pm");
});

test("can correctly convert morning time", function() {
test("correctly convert minutes after 12:00", () => {
assert.equal(formatAs12HourClock("23:53"), "11:53 pm");
});

test("can correctly convert morning time", () => {
assert.equal(formatAs12HourClock("08:00"), "08:00 am");
});

test("can correctly convert morning time minutes", () => {
assert.equal(formatAs12HourClock("08:30"), "08:30 am");
});

test("can correctly convert morning time minutes", () => {
assert.equal(formatAs12HourClock("08:34"), "08:34 am");
});

test("can successfully convert midnight time", () =>
assert.equal(formatAs12HourClock("24:00"), "12:00 am"));
Comment thread
cjyuan marked this conversation as resolved.

test("correctly convert midnight 00:00", () => {
assert.equal(formatAs12HourClock("00:00"), "12:00 am");
});

test("correctly convert noon 12:00", () => {
assert.equal(formatAs12HourClock("12:00"), "12:00 pm");
});

test("correctly convert boundary time around noon", () => {
assert.equal(formatAs12HourClock("11:59"), "11:59 am");
assert.equal(formatAs12HourClock("12:01"), "12:01 pm");
});

test("correctly convert early afternoon hours", () => {
assert.equal(formatAs12HourClock("13:00"), "01:00 pm");
});

test("correctly convert single-digit morning hours if supported", () => {
assert(formatAs12HourClock("08:30"), "08:30am");
});

/*
Edge cases:
Correctly convert hours after 12:00
Input | Expected
23:00 11:00 pm

Correctly convert afternoon hours and minutes
Input | Expected
23:00 11:53 pm

Correctly convert morning time and minutes
Input | Expected
08:00 08:00 am

Correctly convert morning time and minutes
Input | Expected
08:30 08:30 am

Correctly convert morning time and minutes
Input | Expected
08:34 08:34 am

Correctly convert midnight time
Input | Expected
24:00 12:00 am

Correctly convert midnight
Input | Expected
00:00 12:00 am

Correctly convert noon
Input | Expected
12:00 12:00 pm

Correctly convert boundary time around noon
Input | Expected
11:59 11:59 am
12:01 12:01 pm

Correctly convert early afternoon hours
Input | Expected
13:00 1:00 pm

Correctly convert single-digit morning hours if supported
Input | Expected
08:30 8:30 am
*/
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,41 @@ test("Classifies right angles", () => {
const right = getAngleType(90);
assert.equal(right, "Right angle");
});

test("classifies acute angles", () => {
assert.equal(getAngleType(1), "Acute angle");
assert.equal(getAngleType(45), "Acute angle");
assert.equal(getAngleType(89), "Acute angle");
assert.equal(getAngleType(36), "Acute angle");
assert.equal(getAngleType(20), "Acute angle");

});

test("classifies obtuse angles", () => {
assert.equal(getAngleType(91), "Obtuse angle");
assert.equal(getAngleType(105), "Obtuse angle");
assert.equal(getAngleType(179), "Obtuse angle");
assert.equal(getAngleType(125), "Obtuse angle");
assert.equal(getAngleType(110), "Obtuse angle");
});

test("classifies straight angles", () => {
const straight = getAngleType(180);
assert.equal(straight, "Straight angle");
});

test("classifies reflex angles", () => {
assert.equal(getAngleType(181), "Reflex angle");
assert.equal(getAngleType(220), "Reflex angle");
assert.equal(getAngleType(289), "Reflex angle");
assert.equal(getAngleType(300), "Reflex angle");
assert.equal(getAngleType(349), "Reflex angle");
});

test("classifies invalid angles", () => {
assert.equal(getAngleType(-5), "Invalid angle");
assert.equal(getAngleType(0), "Invalid angle");
assert.equal(getAngleType(360), "Invalid angle");
assert.equal(getAngleType(400), "Invalid angle");
assert.equal(getAngleType(420), "Invalid angle");
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,75 @@ import { isProperFraction } from "../implement/2-is-proper-fraction.js";
// TODO: Write tests to cover all cases.
// What combinations of numerators and denominators should you test?

test("Basic proper fraction", () => {
test("Returns true for a basic proper fraction", () => {
// Example: 1/2 is a proper fraction
assert.equal(isProperFraction(1, 2), true);
});

test("Returns true for 2/8", () => {
assert.equal(isProperFraction(2, 8), true);
});

test("Returns true when the numerator is zero and denominator is positive", () => {
assert.equal(isProperFraction(0, 1), true);
});

test("Returns true for 5/8", () => {
assert.equal(isProperFraction(5, 8), true);
});

test("Returns true for 8/9", () => {
assert.equal(isProperFraction(8, 9), true);
});

test("Returns true for another proper fraction with a smaller numerator", () => {
assert.equal(isProperFraction(2, 4), true);
});

test("Returns true when both numerator and denominator is negative", () => {
assert.equal(isProperFraction(-1, -2), true);
});

test("Returns true when the numerator is positive denominator is negative", () => {
assert.equal(isProperFraction(1, -2), true);
});

test("Returns true when the numerator is negative and the denominator is positive", () => {
assert.equal(isProperFraction(-1, 2), true);
});

test("Returns false when the numerator is greater than the denominator", () => {
assert.equal(isProperFraction(9, 8), false);
});

test("Returns false when numerator is negative and denominator is zero", () => {
assert.equal(isProperFraction(-1, 0), false);
});

test("Returns false for 4/2", () => {
assert.equal(isProperFraction(4, 2), false);
});

test("Returns false for 5/3", () => {
assert.equal(isProperFraction(5, 3), false);
});

test("Returns false for 6/4", () => {
assert.equal(isProperFraction(6, 4), false);
});

test("Returns false for 7/1", () => {
assert.equal(isProperFraction(7, 1), false);
});

test("Returns false for 15/14", () => {
assert.equal(isProperFraction(15, 14), false);
});

test("Returns false when numerator equals denominator", () => {
assert.equal(isProperFraction(4, 4), false);
});

test("Returns false when numerator is positive and denominator is zero", () => {
assert.equal(isProperFraction(1,0), false);
})
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,53 @@ test("Valid single-digit card", () => {
assert.equal(getCardValue("9♠"), 9);
});

test("Ace has a value of 11", () => {
assert.equal(getCardValue("A♠"), 11);
});

test("Two has a value of 2", () => {
assert.equal(getCardValue("2♥"), 2);
});

test("Ten has a value of 10", () => {
assert.equal(getCardValue("10♥"), 10);
});

test("Jack has a value of 10", () => {
assert.equal(getCardValue("J♣"), 10);
});

test("Queen has a value of 10", () => {
assert.equal(getCardValue("Q♦"), 10);
});

test("King has a value of 10", () => {
assert.equal(getCardValue("K♦"), 10);
});

test("Arbitrary non-card string", () => {
assert.throws(() => getCardValue("invalid"), /Expected a number followed by a suit, but got "invalid"/, "Expected clear error");
});

// TODO: What other invalid card cases can you think of?
test("Invalid rank throws an error", () => {
assert.throws(() => getCardValue("Z♠"), /Expected a number followed by a suit, but got "Z♠"/, "Expected clear error");
});

test("Invalid suit throws an error", () => {
assert.throws(() => getCardValue("9X"), /Expected a number followed by a suit, but got "9X"/, "Expected clear error");
});

test("Card without a suit throws an error", () => {
assert.throws(() => getCardValue("9"), /Expected a number followed by a suit, but got "9"/, "Expected clear error");
});

test("Card without a rank throws an error", () => {
assert.throws(() => getCardValue("♠"), /Expected a number followed by a suit, but got "♠"/, "Expected clear error");
});

test("Card without a number greater than 10 throws an error", () => {
assert.throws(() => getCardValue("15♠"), /Expected a number followed by a suit, but got "15♠"/, "Expected clear error");
});


// TODO: What other invalid card cases can you think of?
21 changes: 20 additions & 1 deletion implement-and-rewrite-tests/implement/1-get-angle-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,24 @@
// execute the code to ensure all tests pass.

export function getAngleType(angle) {
// TODO: Implement this function
if (angle === 90) {
return "Right angle";
}

if (angle > 0 && angle < 90) {
return "Acute angle";
}

if (angle > 90 && angle < 180) {
return "Obtuse angle";
}

if (angle === 180) {
return "Straight angle";
}
if (angle > 180 && angle < 360) {
return "Reflex angle";
}

return "Invalid angle";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
// execute the code to ensure all tests pass.

export function isProperFraction(numerator, denominator) {
// TODO: Implement this function
return Math.abs(numerator) < Math.abs(denominator)
}
26 changes: 24 additions & 2 deletions implement-and-rewrite-tests/implement/3-get-card-value.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,28 @@
// After you have implemented the function, write tests to cover all the cases, and
// execute the code to ensure all tests pass.


export function getCardValue(card) {
// TODO: Implement this function
}
const rank = card.slice(0, -1);
const suit = card.slice(-1);
const validSuits = ["♠", "♥", "♦", "♣"];
const validRanks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];

if (!validSuits.includes(suit)) {
throw new Error (`Expected a number followed by a suit, but got "${card}"`);
}

if (!validRanks.includes(rank)) {
throw new Error(`Expected a number followed by a suit, but got "${card}"`);
}

if (rank === "A") {
return 11;
}

if (rank === "J" || rank === "Q" || rank === "K") {
return 10;
}

return Number(rank);
}
Loading