summaryrefslogtreecommitdiffstats
path: root/src/time/tzdata_test.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/time/tzdata_test.go99
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
+ }
+}