Build a Cash Register Project

When I test something by changing the values of cid it says that it passes the test, but when I switch the cid values to test for another set of values, the previous test that was just passing is now failing. All I changed was the cid values, price, and input to test like the tests they run would so I don’t understand how that should change how another test passes or fails when it was just passing.

Normally I can debug a program because there are errors and I am not getting the expected result, but it’s incredibly hard for me to debug something that’s appearing to work as intended as the test asks.

I have all of the tests passing except the last two. When I switch cid to the values of the last test it is now passing and another test is now failing. This is the main problem I have and why I am struggling so much to find the solution since the tests pass when I pass in the correct cid values to test my code.

Please if anyone has any insight into this problem I could really use an idea of what could be going wrong. Thank you.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Cash Register</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <div id="container">
      <h1>Cash Register</h1>
      <div id="change-due"></div>
      <input id="cash">
      <button id="purchase-btn">Purchase</button>
      <div id="register">
        <p id="total"></p>
        <h4>Change in Drawer</h4>
        <p id="pennies"></p>
        <p id="nickels"></p>
        <p id="dimes"></p>
        <p id="quarters"></p>
        <p id="ones"></p>
        <p id="fives"></p>
        <p id="tens"></p>
        <p id="twenties"></p>
        <p id="hundreds"></p>
      </div>
    </div>
	  <script src="script.js"></script>
  </body>
</html>
* {
  overflow: hidden;
  margin: 0;
  padding: 0;
}
#container {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: rgb(76, 100, 130);
}
h1 {
  margin-top: 2em;
}
#change-due {
  width: 200px;
  height: 500px;
  position: absolute;
  margin-left: 400px;
  margin-top: 300px;
}
input {
  margin-top : 1em;
  width: 35%;
  height: 30px;
  font-size: 18px;
}
button {
  margin-top: 1em;
  width: 20%;
  height: 30px;
  font-size: 18px;
}
#register {
  margin-top: 3rem;
  font-size: 20px;
}
h4 {
  margin: 20px 0px;
}
#register p {
  margin: 4px 0px;
}
const input = document.getElementById("cash");
const button = document.getElementById("purchase-btn");
const changeDueDiv = document.getElementById("change-due");
const total = document.getElementById("total");
const pennies = document.getElementById("pennies");
const nickels = document.getElementById("nickels");
const dimes = document.getElementById("dimes");
const quarters = document.getElementById("quarters");
const ones = document.getElementById("ones");
const fives = document.getElementById("fives");
const tens = document.getElementById("tens");
const twenties = document.getElementById("twenties");
const hundreds = document.getElementById("hundreds");

let price = 3.26;
let cid = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]];
let allCashInDrawer = cid.map(total => total[1]).reduce((total, arg) => total + arg, 0).toFixed(2) * 100;
let cidNumbers = [pennies, nickels, dimes, quarters, ones, fives, tens, twenties, hundreds];
let cidWords = ["Pennies: $", "Nickels: $", "Dimes: $", "Quarters: $", "Ones: $", "Fives: $", "Tens: $", "Twenties: $", "Hundreds: $"];
function updateCid() {
  total.innerText = `Total: $${price}`;
  for (let i = 0; i < cidNumbers.length; i++) {
    cidNumbers[i].innerText = `${cidWords[i]}${cid[i][1]}`;
  }
}
updateCid();
function getChange(inputValue) {
  inputValue = Number(inputValue) * 100;
  price *= 100;
  let changeDue = Number(inputValue) - price;
  if (changeDue < allCashInDrawer) {
      changeDueDiv.innerText = "Status: OPEN\n"
  }
  if (changeDue === allCashInDrawer) {
      changeDueDiv.innerText = "Status: CLOSED\n";
  }
  if (allCashInDrawer < changeDue) {
      changeDueDiv.innerText = "Status: INSUFFICIENT_FUNDS";
  }
  let cashValues = [10000, 2000, 1000, 500, 100, 25, 10, 5, 1];
  let newValues = [0, 0, 0, 0, 0, 0, 0, 0, 0];
  let reverseCid = [...cid].reverse();
  for (let i = 0; i < reverseCid.length; i++) {
    reverseCid[i][1] *= 100;
  }
  // REDUCE CHANGEDUE TO 0 FROM LARGEST TO SMALLEST BILL AND STORE VALUE IN NEWVALUES[]
  for (let i = 0; i < newValues.length; i++) {
    while (changeDue >= cashValues[i] && reverseCid[i][1] >= cashValues[i]) {
    reverseCid[i][1] = reverseCid[i][1] - cashValues[i];
    changeDue = changeDue - cashValues[i];
    newValues[i] += cashValues[i];
    //console.log(reverseCid[i][1]);
    } 
  }
  if (changeDue > 0) {
      changeDueDiv.innerText = "Status: INSUFFICIENT_FUNDS";
  }
  // ADD TEXT TO SCREEN BASED ON WHICH VALUES WERE ADDED TO NEWVALUES[]
  function addText () {
    console.log(changeDue);
    if ((Number(inputValue) - price < allCashInDrawer || Number(inputValue) - price === allCashInDrawer) && !changeDue > 0) {
      for (let i = 0; i < newValues.length; i++) {
        if (newValues[i] > 0) {
          newValues[i] *= .01;
          changeDueDiv.innerText += `${reverseCid[i][0]}: $${newValues[i]}\n`
        }
      }
    }
  }
  addText();
  for (let i = 0; i < reverseCid.length; i++) {
    reverseCid[i][1] *= .01;
  }
  if (allCashInDrawer > Number(inputValue) - price) {
    allCashInDrawer -= Number(inputValue) - price;
  }
  price /= 100;
  console.log("Change Due: ", changeDue, "All Cash :", allCashInDrawer);
  inputValue = "";
}

button.addEventListener("click", () => {
  if (Number(input.value).toFixed(2) < price) {
    alert("Customer does not have enough money to purchase the item");
    input.value = '';
  } else if (input.value == price) {
    changeDueDiv.innerHTML = "No change due - customer paid with exact cash";
  } else {
    getChange(input.value);
  }
  updateCid();
});

Also somebody in the last forum post told me to convert everything into the value of a penny which is why everything multiplied by 100

The way I tested other test cases was to add code to reassign the price and cid similar to below

let price = 1.87;
let cid = [
  ['PENNY', 1.01],
  ['NICKEL', 2.05],
  ['DIME', 3.1],
  ['QUARTER', 4.25],
  ['ONE', 90],
  ['FIVE', 55],
  ['TEN', 20],
  ['TWENTY', 60],
  ['ONE HUNDRED', 100]
];


price = 187; 
cid = [
  ['PENNY', 2.33],
  ['NICKEL', 1.55],
  ['DIME', 1.70],
  ['QUARTER', 5.25],
  ['ONE', 43],
  ['FIVE', 10],
  ['TEN', 40],
  ['TWENTY', 120],
  ['ONE HUNDRED', 200]
];

That is a great way to test the other cases, however the problem isn’t that I can’t test the cases. The problem is that WHEN I test a case it passes and then when I test another case the one that just passed now fails. As far as I’m aware, this makes no sense since I am just changing the testing variables and nothing else. I tried testing with this method instead of copy pasting and I got the same results. Thank you for trying to help though.

Can you provide details like: give us the exact js that was used and tell us which testcase was passing. Then tell us what you changed in that code so we can try it and then show us which testcase stopped passing?

Yeah of course. So when I first launch the project my code is set to test for:

When price is 3.26 , the value in the #cash element is 100 , cid is [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]] , and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN TWENTY: $60 TEN: $20 FIVE: $15 ONE: $1 QUARTER: $0.5 DIME: $0.2 PENNY: $0.04"

so my cid is set to all of those values, price to 3.26 and cash input 100. When I run the tests, this test fails:

" When price is less than the value in the #cash element, total cash in drawer cid is greater than the change due, individual denomination amounts allows for returning change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN" with required change due in coins and bills sorted in highest to lowest order."

Then if I just click on the “script.js” file at the top to look at my javascript then run the tests again it passes even though I changed nothing in my code at all, I just clicked to view the js in addition to the html that was already showing.

Now at this point only the last two tests are failing. When I change my cid values, price, and cash input to this tests values:

When price is 19.5 , the value in the #cash element is 20 , cid is [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]] , and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: CLOSED PENNY: $0.5"

This test is now passing instead of failing. However, now these three tests are failing:

  • When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN QUARTER: $0.5".

  • Failed:When price is 3.26, the value in the #cash element is 100, cid is [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN TWENTY: $60 TEN: $20 FIVE: $15 ONE: $1 QUARTER: $0.5 DIME: $0.2 PENNY: $0.04".

  • Failed:When price is less than the value in the #cash element, total cash in drawer cid is greater than the change due, individual denomination amounts allows for returning change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN" with required change due in coins and bills sorted in highest to lowest order.

All I am changing is the cid values, price, and cash input to match what the test is asking for and nothing else just like in your example. This is where I am at a loss because I don’t know how to test anything anymore because every time I test something it passes and shows the exact correct thing on screen that it is asking for.

can you move this and any global code other than price and cid into the functions that run when a button is clicked?
The tests change the cid and price by re-assigning them between each test run and your allCashInDrawer will not get reset when that happens.

this is another one that needs to move from the global scope

Thank you SO MUCH! You have no idea how long I’ve been working on a solution to this project and all it took was moving it into the function instead of the global scope so it could also update each time I ran the function. Thank you so much for taking the time to help out a stranger in need, you are my hero!

1 Like