quote.test.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /**
  2. * test/quote.test.js —— core 单测:node --test test/
  3. * 不依赖浏览器、不依赖 jsdom;所有不确定输入经参数注入。
  4. */
  5. import { test } from 'node:test';
  6. import assert from 'node:assert/strict';
  7. import { quote, round2, formatMoney } from '../core/index.js';
  8. const fixed = { now: () => 0, id: () => 'q-test' };
  9. test('合计与税:四舍五入到分', () => {
  10. const r = quote([{ sku: 'A', price: 19.99, qty: 3 }], { taxRate: 0.06, ...fixed });
  11. assert.equal(r.subtotal, 59.97);
  12. assert.equal(r.tax, 3.6); // 59.97 * 0.06 = 3.5982 → 3.60
  13. assert.equal(r.total, 63.57);
  14. assert.equal(r.id, 'q-test');
  15. assert.equal(r.at, 0);
  16. });
  17. test('折扣先减后计税', () => {
  18. const r = quote([{ sku: 'A', price: 100, qty: 2 }], { discount: 0.1, taxRate: 0.1, ...fixed });
  19. assert.equal(r.subtotal, 200);
  20. assert.equal(r.discount, 20);
  21. assert.equal(r.net, 180);
  22. assert.equal(r.tax, 18);
  23. assert.equal(r.total, 198);
  24. });
  25. test('行小计等于单价 × 数量', () => {
  26. const r = quote([{ sku: 'A', price: 0.1, qty: 3 }], fixed);
  27. assert.deepEqual(r.lines, [{ sku: 'A', qty: 3, amount: 0.3 }]); // 0.1*3 浮点尾巴被抹平
  28. });
  29. test('非法输入抛带 code 的错误', () => {
  30. assert.throws(() => quote('x'), (e) => e.code === 'E_ITEMS');
  31. assert.throws(() => quote([{ sku: 'A', price: -1, qty: 1 }]), (e) => e.code === 'E_ITEM');
  32. assert.throws(() => quote([{ sku: 'A', price: 1, qty: 1.5 }]), (e) => e.code === 'E_ITEM');
  33. assert.throws(() => quote([], { discount: 2 }), (e) => e.code === 'E_DISCOUNT');
  34. });
  35. test('缺省 id / now 也能跑(未注入时用默认实现)', () => {
  36. const r = quote([{ sku: 'A', price: 1, qty: 1 }]);
  37. assert.match(r.id, /^q-/);
  38. assert.equal(typeof r.at, 'number');
  39. });
  40. test('工具函数', () => {
  41. assert.equal(round2(1.005), 1.01);
  42. assert.equal(formatMoney(12.5), '¥12.50');
  43. assert.equal(formatMoney(12.5, '$'), '$12.50');
  44. });