Search code examples
node.jstestingjestjsnest

Jest issue very strange case : compare numbers


export class AppService {
  calculatePrice(books: Book[]): number {
    // The idea is to group a sets of books together
    if (books.length === 0) return 0;
    if (books.length === 1) return PRICE;

    const flatBooks = books.flat(2);
    const setOfBooks = [...new Set(flatBooks)];

    const cumulate = PRICE * setOfBooks.length * DISCOUNT[setOfBooks.length];
    // remove elements
    for (const book of setOfBooks) {
      const index = flatBooks.indexOf(book);
      flatBooks.splice(index, 1);
    }

    console.log(cumulate);

    return cumulate + this.calculatePrice(flatBooks);
  }
}

Well, I made a tests for a recursive function, but I got a strange case.
Instead of having 184.4€ for a test of a group of books, I got 184.39999999999999998
I used an addition and a multiplication, so it's impossible to get this price All details are below

https://github.com/wajdibenabdallah/liberation-kata

Just make clone then pnpm i then pnpm t


Solution

  • Since floating point math is inaccurate, you'll want to use the toBeCloseTo Jest matcher.

    IOW, in your tests where you're currently doing e.g.

    expect(appController.calculatePrice(booksExample1)).toBe(PRICE);
    

    you can do

    expect(appController.calculatePrice(booksExample1)).toBeCloseTo(PRICE);
    

    if you don't want to switch to precise decimals (e.g. with decimal.js).