224 lines
5.1 KiB
Go
224 lines
5.1 KiB
Go
package xsd
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
P2Y6M5DT12H35M30S = 2*Yearish + 6*Monthish + 5*Day + 12*time.Hour + 35*time.Minute + 30*time.Second
|
|
P1DT2H = Day + 2*time.Hour
|
|
P20M = 20 * Monthish
|
|
PT20M = 20 * time.Minute
|
|
P0Y = time.Duration(0)
|
|
NegP60D = -1 * (60 * Day)
|
|
PT1M30_5S = time.Minute + time.Duration(30.5*float64(time.Second))
|
|
)
|
|
|
|
func TestMarshal(t *testing.T) {
|
|
type args struct {
|
|
d time.Duration
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []byte
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "2 years, 6 months, 5 days, 12 hours, 35 minutes, 30 seconds",
|
|
args: args{P2Y6M5DT12H35M30S},
|
|
wantErr: false,
|
|
want: []byte("P2Y6M5DT12H35M30S"),
|
|
},
|
|
{
|
|
name: "1 day, 2 hours",
|
|
args: args{P1DT2H},
|
|
wantErr: false,
|
|
want: []byte("P1DT2H"),
|
|
},
|
|
{
|
|
name: "20 months (the number of months can be more than 12)",
|
|
args: args{P20M},
|
|
want: []byte("P1Y8M4D"),
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "20 minutes",
|
|
args: args{PT20M},
|
|
want: []byte("PT20M"),
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "0 years",
|
|
args: args{P0Y},
|
|
want: []byte("PT0S"),
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "minus 60 days",
|
|
args: args{NegP60D},
|
|
want: []byte("-P2M"),
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 minute, 30.5 seconds",
|
|
args: args{PT1M30_5S},
|
|
want: []byte("PT1M30.5S"),
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := Marshal(tt.args.d)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("Marshal() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if !bytes.Equal(got, tt.want) {
|
|
t.Errorf("Marshal() got = %s, want %s", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUnmarshal(t *testing.T) {
|
|
type args struct {
|
|
data []byte
|
|
d *time.Duration
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want time.Duration
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "an empty value should not be valid",
|
|
args: args{[]byte{}, nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "at least one number and designator are required",
|
|
args: args{[]byte("P"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "missing type",
|
|
args: args{[]byte("PT"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "minus sign must appear first",
|
|
args: args{[]byte("P-20M"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no time items are present, so \"T\" must not be present",
|
|
args: args{[]byte("P20MT"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no value is specified for months, so \"M\" must not be present",
|
|
args: args{[]byte("P1YM5D"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "only the seconds can be expressed as a decimal",
|
|
args: args{[]byte("P15.5Y"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "\"T\" must be present to separate days and hours",
|
|
args: args{[]byte("P1D2H"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "\"P\" must always be present",
|
|
args: args{[]byte("1Y2M"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "years must appear before months",
|
|
args: args{[]byte("P2M1Y"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "at least one digit must follow the decimal point if it appears",
|
|
args: args{[]byte("PT15.S"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "invalid data at the end",
|
|
args: args{[]byte("P2Y6M5DT12H35M30Stest"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "invalid data at the start",
|
|
args: args{[]byte("testP2Y6M5DT12H35M30S"), nil},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "2 years, 6 months, 5 days, 12 hours, 35 minutes, 30 seconds",
|
|
args: args{[]byte("P2Y6M5DT12H35M30S"), new(time.Duration)},
|
|
want: P2Y6M5DT12H35M30S,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 day, 2 hours",
|
|
args: args{[]byte("P1DT2H"), new(time.Duration)},
|
|
want: P1DT2H,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "20 months (the number of months can be more than 12)",
|
|
args: args{[]byte("P20M"), new(time.Duration)},
|
|
want: P20M,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "20 minutes",
|
|
args: args{[]byte("PT20M"), new(time.Duration)},
|
|
want: PT20M,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "20 months (0 is permitted as a number, but is not required)",
|
|
args: args{[]byte("P0Y20M0D"), new(time.Duration)},
|
|
want: P20M,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "0 years",
|
|
args: args{[]byte("P0Y"), new(time.Duration)},
|
|
want: P0Y,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "minus 60 days",
|
|
args: args{[]byte("-P60D"), new(time.Duration)},
|
|
want: NegP60D,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "1 minute, 30.5 seconds",
|
|
args: args{[]byte("PT1M30.5S"), new(time.Duration)},
|
|
want: PT1M30_5S,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if err := Unmarshal(tt.args.data, tt.args.d); (err != nil) != tt.wantErr {
|
|
t.Errorf("Unmarshal() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
if tt.want == 0 {
|
|
return
|
|
}
|
|
if *tt.args.d != tt.want {
|
|
t.Errorf("Marshal() got = %s, want %s", tt.args.d, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|