105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
package entities
|
|||
|
|
|
||
|
|
import "testing"
|
||
|
|
|
||
|
|
func weightPtr(v float64) *float64 { return &v }
|
||
|
|
|
||
|
|
func TestBillableQuantity(t *testing.T) {
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
item OrderItem
|
||
|
|
want float64
|
||
|
|
}{
|
||
|
|
{"unit line counts items", OrderItem{Quantity: 3}, 3},
|
||
|
|
{"weighed line uses the weight", OrderItem{Quantity: 1, Weight: weightPtr(4.2)}, 4.2},
|
||
|
|
{"weight of zero is still a weighed line", OrderItem{Quantity: 1, Weight: weightPtr(0)}, 0},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tt := range tests {
|
||
|
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
|
if got := tt.item.BillableQuantity(); got != tt.want {
|
||
|
|
t.Errorf("BillableQuantity() = %v, want %v", got, tt.want)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// A weighed line is voided or refunded whole, so the units asked for must not shrink
|
||
|
|
// the amount: refunding "1" of a 4.2 ons line refunds all 4.2 ons.
|
||
|
|
func TestBillableQuantityForIgnoresUnitsOnWeighedLines(t *testing.T) {
|
||
|
|
weighed := OrderItem{Quantity: 1, Weight: weightPtr(5.6)}
|
||
|
|
if got := weighed.BillableQuantityFor(1); got != 5.6 {
|
||
|
|
t.Errorf("weighed BillableQuantityFor(1) = %v, want 5.6", got)
|
||
|
|
}
|
||
|
|
|
||
|
|
counted := OrderItem{Quantity: 3}
|
||
|
|
if got := counted.BillableQuantityFor(2); got != 2 {
|
||
|
|
t.Errorf("unit BillableQuantityFor(2) = %v, want 2", got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// The regression this whole feature exists to prevent: a 4.2 ons fish priced per ons
|
||
|
|
// must not be billed as a single ons.
|
||
|
|
func TestCalculateTotalPriceForWeighedLine(t *testing.T) {
|
||
|
|
item := OrderItem{Quantity: 1, Weight: weightPtr(4.2), UnitPrice: 4500, UnitCost: 3000}
|
||
|
|
item.CalculateTotalPrice()
|
||
|
|
item.CalculateTotalCost()
|
||
|
|
|
||
|
|
if item.TotalPrice != 18900 {
|
||
|
|
t.Errorf("TotalPrice = %v, want 18900", item.TotalPrice)
|
||
|
|
}
|
||
|
|
if item.TotalCost != 12600 {
|
||
|
|
t.Errorf("TotalCost = %v, want 12600", item.TotalCost)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestCalculateTotalPriceForUnitLine(t *testing.T) {
|
||
|
|
item := OrderItem{Quantity: 3, UnitPrice: 25000, UnitCost: 10000}
|
||
|
|
item.CalculateTotalPrice()
|
||
|
|
item.CalculateTotalCost()
|
||
|
|
|
||
|
|
if item.TotalPrice != 75000 {
|
||
|
|
t.Errorf("TotalPrice = %v, want 75000", item.TotalPrice)
|
||
|
|
}
|
||
|
|
if item.TotalCost != 30000 {
|
||
|
|
t.Errorf("TotalCost = %v, want 30000", item.TotalCost)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Sub-rupiah residue must not survive into a decimal(10,2) column.
|
||
|
|
func TestCalculateTotalPriceRoundsToStoredPrecision(t *testing.T) {
|
||
|
|
item := OrderItem{Quantity: 1, Weight: weightPtr(4.237), UnitPrice: 4500}
|
||
|
|
item.CalculateTotalPrice()
|
||
|
|
|
||
|
|
if item.TotalPrice != 19066.5 {
|
||
|
|
t.Errorf("TotalPrice = %v, want 19066.5", item.TotalPrice)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestIsWeighed(t *testing.T) {
|
||
|
|
if (&OrderItem{Quantity: 1}).IsWeighed() {
|
||
|
|
t.Error("unit line reported as weighed")
|
||
|
|
}
|
||
|
|
if !(&OrderItem{Quantity: 1, Weight: weightPtr(1.5)}).IsWeighed() {
|
||
|
|
t.Error("weighed line reported as unit")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRoundWeight(t *testing.T) {
|
||
|
|
tests := []struct {
|
||
|
|
in float64
|
||
|
|
want float64
|
||
|
|
}{
|
||
|
|
{4.2, 4.2},
|
||
|
|
{4.2374, 4.237},
|
||
|
|
{4.2375, 4.238},
|
||
|
|
{0.0004, 0},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tt := range tests {
|
||
|
|
if got := RoundWeight(tt.in); got != tt.want {
|
||
|
|
t.Errorf("RoundWeight(%v) = %v, want %v", tt.in, got, tt.want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|