]> Cypherpunks.ru repositories - gostls13.git/blob - src/time/tzdata/tzdata_test.go
time/tzdata: new package
[gostls13.git] / src / time / tzdata / tzdata_test.go
1 // Copyright 2020 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package tzdata
6
7 import (
8         "reflect"
9         "testing"
10         "time"
11 )
12
13 var zones = []string{
14         "Asia/Jerusalem",
15         "America/Los_Angeles",
16 }
17
18 func TestEmbeddedTZData(t *testing.T) {
19         for _, zone := range zones {
20                 ref, err := time.LoadLocation(zone)
21                 if err != nil {
22                         t.Errorf("LoadLocation(%q): %v", zone, err)
23                         continue
24                 }
25
26                 embedded, err := loadFromEmbeddedTZData(zone)
27                 if err != nil {
28                         t.Errorf("loadFromEmbeddedTZData(%q): %v", zone, err)
29                         continue
30                 }
31                 sample, err := time.LoadLocationFromTZData(zone, []byte(embedded))
32                 if err != nil {
33                         t.Errorf("LoadLocationFromTZData failed for %q: %v", zone, err)
34                         continue
35                 }
36
37                 // Compare the name and zone fields of ref and sample.
38                 // The tx field changes faster as tzdata is updated.
39                 // The cache fields are expected to differ.
40                 v1 := reflect.ValueOf(ref).Elem()
41                 v2 := reflect.ValueOf(sample).Elem()
42                 typ := v1.Type()
43                 nf := typ.NumField()
44                 found := 0
45                 for i := 0; i < nf; i++ {
46                         ft := typ.Field(i)
47                         if ft.Name != "name" && ft.Name != "zone" {
48                                 continue
49                         }
50                         found++
51                         if !equal(t, v1.Field(i), v2.Field(i)) {
52                                 t.Errorf("zone %s: system and embedded tzdata field %s differs", zone, ft.Name)
53                         }
54                 }
55                 if found != 2 {
56                         t.Errorf("test must be updated for change to time.Location struct")
57                 }
58         }
59 }
60
61 // equal is a small version of reflect.DeepEqual that we use to
62 // compare the values of zoneinfo unexported fields.
63 func equal(t *testing.T, f1, f2 reflect.Value) bool {
64         switch f1.Type().Kind() {
65         case reflect.Slice:
66                 if f1.Len() != f2.Len() {
67                         return false
68                 }
69                 for i := 0; i < f1.Len(); i++ {
70                         if !equal(t, f1.Index(i), f2.Index(i)) {
71                                 return false
72                         }
73                 }
74                 return true
75         case reflect.Struct:
76                 nf := f1.Type().NumField()
77                 for i := 0; i < nf; i++ {
78                         if !equal(t, f1.Field(i), f2.Field(i)) {
79                                 return false
80                         }
81                 }
82                 return true
83         case reflect.String:
84                 return f1.String() == f2.String()
85         case reflect.Bool:
86                 return f1.Bool() == f2.Bool()
87         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
88                 return f1.Int() == f2.Int()
89         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
90                 return f1.Uint() == f2.Uint()
91         default:
92                 t.Errorf("test internal error: unsupported kind %v", f1.Type().Kind())
93                 return true
94         }
95 }