Problem: Tests failing due to truncation with Math.floor
If your unit tests are failing with mismatches like 67.872 vs 67.87 or 2.3 vs 2.29, the culprit is likely a truncation helper that uses Math.floor (or any floor-based truncation). Flooring removes digits instead of rounding, producing systematically smaller values and different numbers of decimals.
Root cause
- Truncation (Math.floor) discards fractional digits — it does NOT round to nearest.
- Tests expect either the exact multiplication result or normal rounding behavior — not truncated values.
- So a helper called
strictDecimalthat callsMath.floor(value * 100) / 100will produce wrong assertions.
Fix strategy (high level)
- Stop truncating values in
cartTotal. Return the raw product (exact multiplication) unless tests explicitly require a fixed decimal format. - If you need fixed decimals, round using
Math.round(or a small rounding helper). - Keep your
filterEntries,mapEntries,reduceEntriesutilities — they are fine.
Drop-in replacement code (no truncation)
// Utilities: filter/map/reduce for objects
function filterEntries(obj, callback) {
return Object.fromEntries(
Object.entries(obj).filter(([k, v]) => callback([k, v]))
);
}
function mapEntries(obj, callback) {
return Object.fromEntries(
Object.entries(obj).map(([k, v]) => callback([k, v]))
);
}
function reduceEntries(obj, callback, initial) {
const entries = Object.entries(obj);
let acc = initial;
if (acc === undefined) {
if (entries.length === 0) throw new TypeError("Reduce of empty object with no initial value");
acc = entries[0];
for (let i = 1; i < entries.length; i++) acc = callback(acc, entries[i]);
} else {
for (let i = 0; i < entries.length; i++) acc = callback(acc, entries[i]);
}
return acc;
}
// Proper rounding helper: rounds to d decimals (nearest)
function roundDecimal(num, d) {
const p = Math.pow(10, d);
return Math.round(num * p) / p;
}
// Example: totalCalories (keeps one-decimal rounding like sample)
function totalCalories(cart) {
return Math.round(
reduceEntries(
cart,
(acc, [k, amount]) => acc + (nutritionDB[k].calories * amount) / 100,
0
) * 10
) / 10;
}
function lowCarbs(cart) {
return filterEntries(
cart,
([k, amount]) => (nutritionDB[k].carbs * amount) / 100 < 50
);
}
// Fixed cartTotal: no truncation — exact multiplication results
function cartTotal(cart) {
return mapEntries(cart, ([k, amount]) => {
const nut = nutritionDB[k];
const factor = amount / 100;
const result = {};
for (const key in nut) {
if (Object.prototype.hasOwnProperty.call(nut, key)) {
// Return the exact product. If you want 2-decimal rounding, use:
// result[key] = roundDecimal(nut[key] * factor, 2);
result[key] = nut[key] * factor;
}
}
return [k, result];
});
}
When to round vs return raw values
- Return raw product when tests expect precise multiplication results or when further aggregation is required (safest).
- Round to N decimals only when the UI or test explicitly requires formatted numbers. Use
roundDecimalabove to round to nearest. - Avoid truncation (floor) unless you deliberately want to always keep the lower bound (rare).
Example: sample inputs & expected outputs
Given nutritionDB entry:
nutritionDB["itemA"] = { calories: 200, carbs: 34.5, protein: 7.2 };
cart = { itemA: 33 }; // amount = 33 (meaning 33%)
Raw product for calories = 200 * 0.33 = 66
Raw product for carbs = 34.5 * 0.33 = 11.385
If you had truncated to 2 decimals using Math.floor you'd get 11.38, but if test expects 11.385 or 11.39 (rounded), floor will break.
Testing tips (quick unit test examples)
// Node.js assert example
const assert = require('assert');
const nutritionDB = {
a: { calories: 100, carbs: 20.5 },
b: { calories: 50, carbs: 10.2 }
};
const cart = { a: 50, b: 25 }; // 50% and 25%
const totals = cartTotal(cart);
// exact products:
assert.strictEqual(totals.a.calories, 50); // 100 * 0.5
assert.strictEqual(totals.a.carbs, 20.5 * 0.5); // 10.25
// If tests expect rounding to 2 decimals:
assert.strictEqual(roundDecimal(totals.a.carbs, 2), 10.25);
Summary
- Truncation with
Math.floorremoves digits and breaks equality tests. - Fix
cartTotalby returning raw multiplication results or by rounding withMath.roundwhen required. - Use a
roundDecimalhelper to get consistent, nearest-value rounding.