package main import ( "errors" "testing" ) func TestLocalTimezone(t *testing.T) { noLink := func(string) (string, error) { return "", errors.New("no") } noFile := func(string) ([]byte, error) { return nil, errors.New("no") } env := func(v string) func(string) string { return func(k string) string { if k == "TZ" { return v } return "" } } link := func(target string) func(string) (string, error) { return func(string) (string, error) { return target, nil } } file := func(body string) func(string) ([]byte, error) { return func(string) ([]byte, error) { return []byte(body), nil } } cases := []struct { name string getenv func(string) string readlink func(string) (string, error) readFile func(string) ([]byte, error) want string }{ {"TZ plain", env("Europe/London"), noLink, noFile, "Europe/London"}, {"TZ colon", env(":Europe/London"), noLink, noFile, "Europe/London"}, {"TZ path", env("/usr/share/zoneinfo/Asia/Kolkata"), noLink, noFile, "Asia/Kolkata"}, {"localtime link (linux)", env(""), func(string) (string, error) { return "/usr/share/zoneinfo/Europe/Dublin", nil }, noFile, "Europe/Dublin"}, {"localtime link (macOS)", env(""), func(string) (string, error) { return "/var/db/timezone/zoneinfo/Australia/Sydney", nil }, noFile, "Australia/Sydney"}, {"etc/timezone", env(""), noLink, func(string) ([]byte, error) { return []byte("Europe/Paris\n"), nil }, "Europe/Paris"}, // Review Focus 1: real-machine noise is a clean name or nothing. {"etc/timezone padded", env(""), noLink, func(string) ([]byte, error) { return []byte(" America/New_York \r\n# trailing\n"), nil }, "America/New_York"}, {"TZ bare colon", env(":"), noLink, noFile, ""}, {"TZ localtime", env("localtime"), noLink, noFile, ""}, {"TZ posixrules path", env("/usr/share/zoneinfo/posixrules"), noLink, noFile, ""}, {"TZ POSIX rule string", env("EST5EDT,M3.2.0,M11.1.0"), noLink, noFile, ""}, {"nothing", env(""), noLink, noFile, ""}, // Source order and fall-through: more than one source is live. {"TZ beats link", env("Europe/London"), link("/usr/share/zoneinfo/Asia/Tokyo"), noFile, "Europe/London"}, {"invalid TZ falls through to link", env("EST5EDT,M3.2.0,M11.1.0"), link("/usr/share/zoneinfo/Asia/Tokyo"), noFile, "Asia/Tokyo"}, {"link beats etc/timezone", env(""), link("/usr/share/zoneinfo/Asia/Tokyo"), file("Europe/Paris\n"), "Asia/Tokyo"}, {"invalid link falls through to etc/timezone", env(""), link("/usr/share/zoneinfo/posixrules"), file("Europe/Paris\n"), "Europe/Paris"}, } for _, c := range cases { if got := localTimezone(c.getenv, c.readlink, c.readFile); got != c.want { t.Errorf("%s: %q, want %q", c.name, got, c.want) } } }