tzdata_test.go 2.5 KB

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