Skip to content

NW | ITP-May-25 | Geraldine Edwards | Module-Structuring-and-Testing-Data | Sprint-3#541

Closed
Geraldine-Edwards wants to merge 14 commits intoCodeYourFuture:mainfrom
Geraldine-Edwards:coursework/sprint3
Closed

NW | ITP-May-25 | Geraldine Edwards | Module-Structuring-and-Testing-Data | Sprint-3#541
Geraldine-Edwards wants to merge 14 commits intoCodeYourFuture:mainfrom
Geraldine-Edwards:coursework/sprint3

Conversation

@Geraldine-Edwards
Copy link

Learners, PR Template

Self checklist

  • I have committed my files one by one, on purpose, and for a reason
  • I have titled my PR with REGION | COHORT_NAME | FIRST_NAME LAST_NAME | PROJ_NAME
  • I have tested my changes
  • My changes follow the style guide
  • My changes meet the requirements of this task

Changelist

This PR includes my responses and code to questions in the Key Implement, Mandatory Rewrite, Mandatory Practice and the Stretch Investigate files.

Questions

Ask any questions you have for your reviewer.

@Geraldine-Edwards Geraldine-Edwards added Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. labels Jun 13, 2025
Copy link

@CameronDowner CameronDowner left a comment

Choose a reason for hiding this comment

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

Really strong coursework - you are using some advanced practises here (e.g. parameterised tests, breaking down functions, throwing & testing for errors)

I have left some more advanced questions, but will mark as Complete because you've met all the criteria already

Comment on lines 12 to 13
if (Math.abs(numerator) < Math.abs(denominator)) return true;
return false; //if the inputs don't satisfy the expression it returns false

Choose a reason for hiding this comment

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

Do we need an if statement here?

Math.abs(numerator) < Math.abs(denominator) evaluates to true or false already

Copy link
Author

Choose a reason for hiding this comment

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

Ah yes, I can see now that I can just return the expression instead of using the if statement - I'll fix this now. :)

function getCardValue(card) {
if (rank === "A") return 11;
// use an array to hold the values of the face cards.
const faceCards = ["10", "J", "Q", "K"];

Choose a reason for hiding this comment

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

This will work as expected - but is 10 a face card?

If I wanted to extend this functionality & used this array in another method isFaceCard, this would start giving me the wrong answer

Copy link
Author

Choose a reason for hiding this comment

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

oh gosh of course! I think I got confused as I was just thinking about the values of the cards being 10. I've removed 10 from the array and adjusted the following if statement to cover numbers 2-10.


// Case 2: Identify Improper Fractions:
test("should return true for a improper fraction", () => {
expect(isProperFraction(5, 2)).toEqual(false);

Choose a reason for hiding this comment

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

Jest also has .toBeTruthy(): https://jestjs.io/docs/expect#tobetruthy

Why might that not be a good thing to use here?

Copy link
Author

Choose a reason for hiding this comment

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

I imagine it's not great to use at this test probably because if something is "truthy" it is less strict.. or something to that effect? I would need to make sure that an improper fraction was handled strictly to get the exact correct values.

Choose a reason for hiding this comment

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

That is exactly it - truthy values are a lot more than true which means it is less strict than .toEqual(true). It's any value that would be coerced into true when in a boolean context

https://developer.mozilla.org/en-US/docs/Glossary/Truthy

Boolean("hello") // true
Boolean([]) // true
Boolean({}) // true

expect(aceCard).toEqual(11);
});
// Case 5: Handle Invalid Cards - using an array for the inputs :
test("should throw an error for invalid card ranks", () => {

Choose a reason for hiding this comment

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

Great parameterised tests - Jest actually has functionality built-in to support this

https://jestjs.io/docs/api#testeachtablename-fn-timeout

Choose a reason for hiding this comment

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

Why might we use Jest's version over 'hand-rolling' our own parameterised test like?

Copy link
Author

Choose a reason for hiding this comment

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

I now understand that we can use Jest's .each() for clearer test output, better reporting, and less boilerplate code. In the description of the test we can use placeholders such as %s (string value) and %d (number , or digit, value), etc, as placeholders for the actual test cases inputs, meaning that when the error message appears we can immediately know which case it refers to. E.g if the current input is "G♥", the test name will be "should throw an error for invalid card rank: G♥" which makes for more readable tests.

Choose a reason for hiding this comment

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

That's exactly it - it avoids boilerplate & it's super easy to see which case has failed

Comment on lines 8 to 21
if (n % 100 === 11 || n % 100 === 12 || n % 100 === 13) {
return n + "th";
}
if (n % 10 === 1) {
return n + "st";
}
if (n % 10 === 2) {
return n + "nd";
}
if (n % 10 === 3) {
return n + "rd";
}
return n + "th"; //everything else in numbers
}

Choose a reason for hiding this comment

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

We have a lot of common values here - could we extract common variables?

Naming variables can give a value meaning which make it easier to read

Copy link
Author

Choose a reason for hiding this comment

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

Ah, yes of course I could use variable names called lastDigit and lastTwoDigits, so that :
const lastDigit = n & 10;
const lastTwoDigits = n % 100;
and then adjust each if statement, for example, if (lastDigit === 1){}, etc

Comment on lines +49 to +51
for (const input of invalidInputs) {
expect(() => getOrdinalNumber(input)).toThrow("Invalid ordinal number");
}

Choose a reason for hiding this comment

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

This is a really great test & something you'd expect to see in industry when reviewing tests

Comment on lines 8 to 10
if (count === 0) {
return "";
}

Choose a reason for hiding this comment

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

What happens if we pass 0 into str.repeat?

Copy link
Author

@Geraldine-Edwards Geraldine-Edwards Jun 18, 2025

Choose a reason for hiding this comment

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

Oh I see, yes of course ,it will return " " and empty string anyway so i don't need to account for if an input is exactly 0. oops! :)

test("should return the message 'Count is an invalid input'", () => {
const str = "hello";
const count = "three";
expect(() => repeat(str, count)).toThrow("Count is an invalid input");

Choose a reason for hiding this comment

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

Why do we pass a function here instead of just calling repeat(str, count)?

Copy link
Author

Choose a reason for hiding this comment

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

When I was looking at this I read about how if we didn't pass the arrow function to "expect", then Jest won't be able to catch the error to check it, if it was just calling repeat(str, count) it would run immediately before Jest can even check it and likely crash the program.

@@ -0,0 +1,90 @@
/*
Helper function to check if the card number is a string using the typeof operator.
Because credit card numbers can start with zero, using a "number" type would mean dropping any leading zeros which would result in loss of information.
Copy link

@CameronDowner CameronDowner Jun 14, 2025

Choose a reason for hiding this comment

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

Breaking down functions like this is amazing to see

It makes the code really easy to read and reason about. You can forget the specifics of the function and trust it does what the function is called.

function isValidCardNumber(cardNumber) {
//if the card number input is not a "string" type.
if (!isString(cardNumber)) {
return "Card number must be a string";

Choose a reason for hiding this comment

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

Could these be errors instead of strings?

Copy link
Author

Choose a reason for hiding this comment

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

Yes I understand, throwing an JS error is more standard procedure for invalid inputs rather than relying on a bespoke message, I'll change these. :)

@CameronDowner CameronDowner added Complete Volunteer to add when work is complete and all review comments have been addressed. and removed Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. labels Jun 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Complete Volunteer to add when work is complete and all review comments have been addressed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants