Mixed Juices possible incorrect test

In the Mixed Juices exercise, one of the conditions of the second exercise is that the loop should end once the array of limes ends. There is also a test for this. But it seems that the test isn’t catching all cases?

One of my mentees wrote the following solution:

export function limesToCut(wedgesNeeded, limes) {
  let wedges = 0
  let limesCut = 0;
  
  while (wedges < wedgesNeeded) {
    let wedgesToAdd;
    
    switch (limes[0]) {
      case 'small':
        wedgesToAdd = 6;
        break;
      case 'medium':
        wedgesToAdd = 8;
        break;
      case 'large':
        wedgesToAdd = 10
        break;
    }
    wedges += wedgesToAdd
    if (limes.length > 0) {
      limesCut++
    }
    limes.shift();    
  }
  return limesCut
}

which shouldn’t work if the amount of limes is not enough to reach the wedgesNeeded amount? Yet the test passes. Or am I missing something?

Without running it, that looks to me like an infinite loop if there are not enough limes. It seems the loop should be

while (wedges < wedgesNeeded && limesCut < limes.length)

There are tests testing the case when there aren’t enough limes to reach the wedges needed. However, this solution passes the tests because the loop does finish when there are not enough limes! Not in an intended way of course, but it does finish:

This happens because limes.shift() always works, even on an empty array. It does return undefined when the array is empty and can’t remove more elements, but doesn’t throw any errors.

Doing something like limes[0] is always valid, and returns undefined if there are no elements in limes. In this solution it just means that no case on the switch will be triggered.

When the code reaches wedges += wedgesToAdd, wedgesToAdd wasn’t initialized by any cases on the switch, so it’s undefined. So, the whole operation wedges += wedgesToAdd becomes wedges += undefined, which will make wedges be NaN.

Then when checking the loop condition, wedges < wedgesNeeded becomes NaN < wedgesNeeded, which is always false, and the function quits the loop.

While there’s of course a lot wrong with this solution, the quirks of Javascript actually make this work! Sounds like a good mentoring discussion to have about this.

The bit that actually saves this solution and makes it produce the right result, is the fact that the increments to the result variable limesCut are protected by limes.length > 0, which is the right thing to protect against! But maybe this condition should also be part of the loop condition.

3 Likes

Thanks for the thorough explanation. I will discuss this with my mentee.

2 Likes