100 lines
2.5 KiB
Go
100 lines
2.5 KiB
Go
// Copyright 2020 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package time_test
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
_ "time/tzdata"
|
|
)
|
|
|
|
var zones = []string{
|
|
"Asia/Jerusalem",
|
|
"America/Los_Angeles",
|
|
}
|
|
|
|
func TestEmbeddedTZData(t *testing.T) {
|
|
time.ForceZipFileForTesting(true)
|
|
defer time.ForceZipFileForTesting(false)
|
|
|
|
for _, zone := range zones {
|
|
ref, err := time.LoadLocation(zone)
|
|
if err != nil {
|
|
t.Errorf("LoadLocation(%q): %v", zone, err)
|
|
continue
|
|
}
|
|
|
|
embedded, err := time.LoadFromEmbeddedTZData(zone)
|
|
if err != nil {
|
|
t.Errorf("LoadFromEmbeddedTZData(%q): %v", zone, err)
|
|
continue
|
|
}
|
|
sample, err := time.LoadLocationFromTZData(zone, []byte(embedded))
|
|
if err != nil {
|
|
t.Errorf("LoadLocationFromTZData failed for %q: %v", zone, err)
|
|
continue
|
|
}
|
|
|
|
// Compare the name and zone fields of ref and sample.
|
|
// The tx field changes faster as tzdata is updated.
|
|
// The cache fields are expected to differ.
|
|
v1 := reflect.ValueOf(ref).Elem()
|
|
v2 := reflect.ValueOf(sample).Elem()
|
|
typ := v1.Type()
|
|
nf := typ.NumField()
|
|
found := 0
|
|
for i := 0; i < nf; i++ {
|
|
ft := typ.Field(i)
|
|
if ft.Name != "name" && ft.Name != "zone" {
|
|
continue
|
|
}
|
|
found++
|
|
if !equal(t, v1.Field(i), v2.Field(i)) {
|
|
t.Errorf("zone %s: system and embedded tzdata field %s differs", zone, ft.Name)
|
|
}
|
|
}
|
|
if found != 2 {
|
|
t.Errorf("test must be updated for change to time.Location struct")
|
|
}
|
|
}
|
|
}
|
|
|
|
// equal is a small version of reflect.DeepEqual that we use to
|
|
// compare the values of zoneinfo unexported fields.
|
|
func equal(t *testing.T, f1, f2 reflect.Value) bool {
|
|
switch f1.Type().Kind() {
|
|
case reflect.Slice:
|
|
if f1.Len() != f2.Len() {
|
|
return false
|
|
}
|
|
for i := 0; i < f1.Len(); i++ {
|
|
if !equal(t, f1.Index(i), f2.Index(i)) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
case reflect.Struct:
|
|
nf := f1.Type().NumField()
|
|
for i := 0; i < nf; i++ {
|
|
if !equal(t, f1.Field(i), f2.Field(i)) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
case reflect.String:
|
|
return f1.String() == f2.String()
|
|
case reflect.Bool:
|
|
return f1.Bool() == f2.Bool()
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return f1.Int() == f2.Int()
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return f1.Uint() == f2.Uint()
|
|
default:
|
|
t.Errorf("test internal error: unsupported kind %v", f1.Type().Kind())
|
|
return true
|
|
}
|
|
}
|