summaryrefslogtreecommitdiff
path: root/src/checkout/money/money_test.go
diff options
context:
space:
mode:
authorSaumit <justsaumit@protonmail.com>2025-09-27 02:14:26 +0530
committerSaumit <justsaumit@protonmail.com>2025-09-27 02:14:26 +0530
commit82e03978b89938219958032efb1448cc76baa181 (patch)
tree626f3e54d52ecd49be0ed3bee30abacc0453d081 /src/checkout/money/money_test.go
Initial snapshot - OpenTelemetry demo 2.1.3 -f
Diffstat (limited to 'src/checkout/money/money_test.go')
-rw-r--r--src/checkout/money/money_test.go233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/checkout/money/money_test.go b/src/checkout/money/money_test.go
new file mode 100644
index 0000000..8c2c3d7
--- /dev/null
+++ b/src/checkout/money/money_test.go
@@ -0,0 +1,233 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+package money
+
+import (
+ "fmt"
+ "reflect"
+ "testing"
+
+ pb "github.com/open-telemetry/opentelemetry-demo/src/checkout/genproto/oteldemo"
+)
+
+func mmc(u int64, n int32, c string) *pb.Money { return &pb.Money{Units: u, Nanos: n, CurrencyCode: c} }
+func mm(u int64, n int32) *pb.Money { return mmc(u, n, "") }
+
+func TestIsValid(t *testing.T) {
+ tests := []struct {
+ name string
+ in *pb.Money
+ want bool
+ }{
+ {"valid -/-", mm(-981273891273, -999999999), true},
+ {"invalid -/+", mm(-981273891273, +999999999), false},
+ {"valid +/+", mm(981273891273, 999999999), true},
+ {"invalid +/-", mm(981273891273, -999999999), false},
+ {"invalid +/+overflow", mm(3, 1000000000), false},
+ {"invalid +/-overflow", mm(3, -1000000000), false},
+ {"invalid -/+overflow", mm(-3, 1000000000), false},
+ {"invalid -/-overflow", mm(-3, -1000000000), false},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := IsValid(tt.in); got != tt.want {
+ t.Errorf("IsValid(%v) = %v, want %v", tt.in, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestIsZero(t *testing.T) {
+ tests := []struct {
+ name string
+ in *pb.Money
+ want bool
+ }{
+ {"zero", mm(0, 0), true},
+ {"not-zero (-/+)", mm(-1, +1), false},
+ {"not-zero (-/-)", mm(-1, -1), false},
+ {"not-zero (+/+)", mm(+1, +1), false},
+ {"not-zero (+/-)", mm(+1, -1), false},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := IsZero(tt.in); got != tt.want {
+ t.Errorf("IsZero(%v) = %v, want %v", tt.in, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestIsPositive(t *testing.T) {
+ tests := []struct {
+ name string
+ in *pb.Money
+ want bool
+ }{
+ {"zero", mm(0, 0), false},
+ {"positive (+/+)", mm(+1, +1), true},
+ {"invalid (-/+)", mm(-1, +1), false},
+ {"negative (-/-)", mm(-1, -1), false},
+ {"invalid (+/-)", mm(+1, -1), false},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := IsPositive(tt.in); got != tt.want {
+ t.Errorf("IsPositive(%v) = %v, want %v", tt.in, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestIsNegative(t *testing.T) {
+ tests := []struct {
+ name string
+ in *pb.Money
+ want bool
+ }{
+ {"zero", mm(0, 0), false},
+ {"positive (+/+)", mm(+1, +1), false},
+ {"invalid (-/+)", mm(-1, +1), false},
+ {"negative (-/-)", mm(-1, -1), true},
+ {"invalid (+/-)", mm(+1, -1), false},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := IsNegative(tt.in); got != tt.want {
+ t.Errorf("IsNegative(%v) = %v, want %v", tt.in, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestAreSameCurrency(t *testing.T) {
+ type args struct {
+ l *pb.Money
+ r *pb.Money
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ }{
+ {"both empty currency", args{mmc(1, 0, ""), mmc(2, 0, "")}, false},
+ {"left empty currency", args{mmc(1, 0, ""), mmc(2, 0, "USD")}, false},
+ {"right empty currency", args{mmc(1, 0, "USD"), mmc(2, 0, "")}, false},
+ {"mismatching", args{mmc(1, 0, "USD"), mmc(2, 0, "CAD")}, false},
+ {"matching", args{mmc(1, 0, "USD"), mmc(2, 0, "USD")}, true},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := AreSameCurrency(tt.args.l, tt.args.r); got != tt.want {
+ t.Errorf("AreSameCurrency([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestAreEquals(t *testing.T) {
+ type args struct {
+ l *pb.Money
+ r *pb.Money
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ }{
+ {"equals", args{mmc(1, 2, "USD"), mmc(1, 2, "USD")}, true},
+ {"mismatching currency", args{mmc(1, 2, "USD"), mmc(1, 2, "CAD")}, false},
+ {"mismatching units", args{mmc(10, 20, "USD"), mmc(1, 20, "USD")}, false},
+ {"mismatching nanos", args{mmc(1, 2, "USD"), mmc(1, 20, "USD")}, false},
+ {"negated", args{mmc(1, 2, "USD"), mmc(-1, -2, "USD")}, false},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := AreEquals(tt.args.l, tt.args.r); got != tt.want {
+ t.Errorf("AreEquals([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestNegate(t *testing.T) {
+ tests := []struct {
+ name string
+ in *pb.Money
+ want *pb.Money
+ }{
+ {"zero", mm(0, 0), mm(0, 0)},
+ {"negative", mm(-1, -200), mm(1, 200)},
+ {"positive", mm(1, 200), mm(-1, -200)},
+ {"carries currency code", mmc(0, 0, "XXX"), mmc(0, 0, "XXX")},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := Negate(tt.in); !AreEquals(got, tt.want) {
+ t.Errorf("Negate([%v]) = %v, want %v", tt.in, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestMust_pass(t *testing.T) {
+ v := Must(mm(2, 3), nil)
+ if !AreEquals(v, mm(2, 3)) {
+ t.Errorf("returned the wrong value: %v", v)
+ }
+}
+
+func TestMust_panic(t *testing.T) {
+ defer func() {
+ if r := recover(); r != nil {
+ t.Logf("panic captured: %v", r)
+ }
+ }()
+ Must(mm(2, 3), fmt.Errorf("some error"))
+ t.Fatal("this should not have executed due to the panic above")
+}
+
+func TestSum(t *testing.T) {
+ type args struct {
+ l *pb.Money
+ r *pb.Money
+ }
+ tests := []struct {
+ name string
+ args args
+ want *pb.Money
+ wantErr error
+ }{
+ {"0+0=0", args{mm(0, 0), mm(0, 0)}, mm(0, 0), nil},
+ {"Error: currency code on left", args{mmc(0, 0, "XXX"), mm(0, 0)}, mm(0, 0), ErrMismatchingCurrency},
+ {"Error: currency code on right", args{mm(0, 0), mmc(0, 0, "YYY")}, mm(0, 0), ErrMismatchingCurrency},
+ {"Error: currency code mismatch", args{mmc(0, 0, "AAA"), mmc(0, 0, "BBB")}, mm(0, 0), ErrMismatchingCurrency},
+ {"Error: invalid +/-", args{mm(+1, -1), mm(0, 0)}, mm(0, 0), ErrInvalidValue},
+ {"Error: invalid -/+", args{mm(0, 0), mm(-1, +2)}, mm(0, 0), ErrInvalidValue},
+ {"Error: invalid nanos", args{mm(0, 1000000000), mm(1, 0)}, mm(0, 0), ErrInvalidValue},
+ {"both positive (no carry)", args{mm(2, 200000000), mm(2, 200000000)}, mm(4, 400000000), nil},
+ {"both positive (nanos=max)", args{mm(2, 111111111), mm(2, 888888888)}, mm(4, 999999999), nil},
+ {"both positive (carry)", args{mm(2, 200000000), mm(2, 900000000)}, mm(5, 100000000), nil},
+ {"both negative (no carry)", args{mm(-2, -200000000), mm(-2, -200000000)}, mm(-4, -400000000), nil},
+ {"both negative (carry)", args{mm(-2, -200000000), mm(-2, -900000000)}, mm(-5, -100000000), nil},
+ {"mixed (larger positive, just decimals)", args{mm(11, 0), mm(-2, 0)}, mm(9, 0), nil},
+ {"mixed (larger negative, just decimals)", args{mm(-11, 0), mm(2, 0)}, mm(-9, 0), nil},
+ {"mixed (larger positive, no borrow)", args{mm(11, 100000000), mm(-2, -100000000)}, mm(9, 0), nil},
+ {"mixed (larger positive, with borrow)", args{mm(11, 100000000), mm(-2, -9000000 /*.09*/)}, mm(9, 91000000 /*.091*/), nil},
+ {"mixed (larger negative, no borrow)", args{mm(-11, -100000000), mm(2, 100000000)}, mm(-9, 0), nil},
+ {"mixed (larger negative, with borrow)", args{mm(-11, -100000000), mm(2, 9000000 /*.09*/)}, mm(-9, -91000000 /*.091*/), nil},
+ {"0+negative", args{mm(0, 0), mm(-2, -100000000)}, mm(-2, -100000000), nil},
+ {"negative+0", args{mm(-2, -100000000), mm(0, 0)}, mm(-2, -100000000), nil},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := Sum(tt.args.l, tt.args.r)
+ if err != tt.wantErr {
+ t.Errorf("Sum([%v],[%v]): expected err=\"%v\" got=\"%v\"", tt.args.l, tt.args.r, tt.wantErr, err)
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("Sum([%v],[%v]) = %v, want %v", tt.args.l, tt.args.r, got, tt.want)
+ }
+ })
+ }
+}