diff options
Diffstat (limited to 'src/time/tzdata_test.go')
-rw-r--r-- | src/time/tzdata_test.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/time/tzdata_test.go b/src/time/tzdata_test.go new file mode 100644 index 0000000..33c6589 --- /dev/null +++ b/src/time/tzdata_test.go @@ -0,0 +1,99 @@ +// 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) { + undo := time.DisablePlatformSources() + defer undo() + + 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 + } +} |