Skip to content

Commit 34c18b8

Browse files
authored
Merge pull request #23 from ymt2/feat/implement-TextUnmarshaler
2 parents 279d3bc + 2f240f5 commit 34c18b8

File tree

2 files changed

+77
-5
lines changed

2 files changed

+77
-5
lines changed

bps/serial.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ package bps
33
import (
44
"database/sql"
55
"database/sql/driver"
6+
"encoding"
67
"errors"
78
)
89

9-
// make sure a *BPS implements the sql.Scanner interface.
10-
var _ sql.Scanner = (*BPS)(nil)
10+
// make sure that the *BPS implements some interfaces.
11+
var _ interface {
12+
sql.Scanner
13+
driver.Valuer
14+
encoding.TextUnmarshaler
15+
} = (*BPS)(nil)
1116

1217
// Scan implements the sql.Scanner interface for database deserialization.
1318
func (b *BPS) Scan(value interface{}) error {
@@ -52,10 +57,23 @@ func (b *BPS) Scan(value interface{}) error {
5257
return errors.New("BPS.Scan: invalid type, supporting only integer or string")
5358
}
5459

55-
// make sure a *BPS implements the driver.Valuer interface.
56-
var _ driver.Valuer = (*BPS)(nil)
57-
5860
// Value implements the driver.Valuer interface for database serialization.
5961
func (b *BPS) Value() (driver.Value, error) {
6062
return b.String(), nil
6163
}
64+
65+
// UnmarshalText implements the encoding.TextUnmarshaler interface.
66+
func (b *BPS) UnmarshalText(text []byte) error {
67+
v := string(text)
68+
if v == "" {
69+
return errors.New("BPS.UnmarshalText: no data")
70+
}
71+
72+
n, err := NewFromString(v)
73+
if err != nil {
74+
return err
75+
}
76+
b.value = n.value
77+
78+
return nil
79+
}

bps/serial_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,57 @@ func TestBPS_Scan(t *testing.T) {
118118
})
119119
}
120120
}
121+
122+
func TestBPS_UnmarshalText(t *testing.T) {
123+
t.Parallel()
124+
tests := map[string]struct {
125+
value string
126+
want *bps.BPS
127+
wantErr bool
128+
}{
129+
"If value is valid string with the integer part abbreviating, it should set value via NewFromString": {
130+
".15",
131+
bps.NewFromPercentage(15),
132+
false,
133+
},
134+
"If value is valid string, it should set value via NewFromString": {
135+
"1.15",
136+
bps.NewFromPercentage(115),
137+
false,
138+
},
139+
"If value is negative, it should set value via NewFromString": {
140+
"-123.456",
141+
bps.NewFromBasisPoint(-1234560),
142+
false,
143+
},
144+
"If value is zero, it should set value via NewFromString": {
145+
"0",
146+
bps.NewFromAmount(0),
147+
false,
148+
},
149+
"If value is invalid string, it should return an error": {
150+
"a15",
151+
&bps.BPS{},
152+
true,
153+
},
154+
"If value is empty, it should return an error": {
155+
"",
156+
&bps.BPS{},
157+
true,
158+
},
159+
}
160+
for name, tt := range tests {
161+
name := name
162+
tt := tt
163+
t.Run(name, func(t *testing.T) {
164+
t.Parallel()
165+
b := &bps.BPS{}
166+
if err := b.UnmarshalText([]byte(tt.value)); (err != nil) != tt.wantErr {
167+
t.Errorf("BPS.UnmarshalText() error = %v, wantErr %v", err, tt.wantErr)
168+
}
169+
if !reflect.DeepEqual(b, tt.want) {
170+
t.Errorf("BPS.Value() = %v, want %v", b, tt.want)
171+
}
172+
})
173+
}
174+
}

0 commit comments

Comments
 (0)