|  | package regsrc | 
|  |  | 
|  | import ( | 
|  | "strings" | 
|  | "testing" | 
|  | ) | 
|  |  | 
|  | func TestFriendlyHost(t *testing.T) { | 
|  | tests := []struct { | 
|  | name        string | 
|  | source      string | 
|  | wantHost    string | 
|  | wantDisplay string | 
|  | wantNorm    string | 
|  | wantValid   bool | 
|  | }{ | 
|  | { | 
|  | name:        "simple ascii", | 
|  | source:      "registry.terraform.io", | 
|  | wantHost:    "registry.terraform.io", | 
|  | wantDisplay: "registry.terraform.io", | 
|  | wantNorm:    "registry.terraform.io", | 
|  | wantValid:   true, | 
|  | }, | 
|  | { | 
|  | name:        "mixed-case ascii", | 
|  | source:      "Registry.TerraForm.io", | 
|  | wantHost:    "Registry.TerraForm.io", | 
|  | wantDisplay: "registry.terraform.io", // Display case folded | 
|  | wantNorm:    "registry.terraform.io", | 
|  | wantValid:   true, | 
|  | }, | 
|  | { | 
|  | name:        "IDN", | 
|  | source:      "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io", | 
|  | wantHost:    "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io", | 
|  | wantDisplay: "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io", | 
|  | wantNorm:    "xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io", | 
|  | wantValid:   true, | 
|  | }, | 
|  | { | 
|  | name:        "IDN TLD", | 
|  | source:      "zhongwen.中国", | 
|  | wantHost:    "zhongwen.中国", | 
|  | wantDisplay: "zhongwen.中国", | 
|  | wantNorm:    "zhongwen.xn--fiqs8s", | 
|  | wantValid:   true, | 
|  | }, | 
|  | { | 
|  | name:        "IDN Case Folding", | 
|  | source:      "Испытание.com", | 
|  | wantHost:    "Испытание.com", // Raw input retains case | 
|  | wantDisplay: "испытание.com", // Display form is unicode but case-folded | 
|  | wantNorm:    "xn--80akhbyknj4f.com", | 
|  | wantValid:   true, | 
|  | }, | 
|  | { | 
|  | name:        "Punycode is invalid as an input format", | 
|  | source:      "xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io", | 
|  | wantHost:    "xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io", | 
|  | wantDisplay: "ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io", | 
|  | wantNorm:    InvalidHostString, | 
|  | wantValid:   false, | 
|  | }, | 
|  | { | 
|  | name:        "non-host prefix is left alone", | 
|  | source:      "foo/bar/baz", | 
|  | wantHost:    "", | 
|  | wantDisplay: "", | 
|  | wantNorm:    "", | 
|  | wantValid:   false, | 
|  | }, | 
|  | } | 
|  | for _, tt := range tests { | 
|  | // Matrix each test with prefix and total match variants | 
|  | for _, sfx := range []string{"", "/", "/foo/bar/baz"} { | 
|  | t.Run(tt.name+" suffix:"+sfx, func(t *testing.T) { | 
|  | gotHost, gotRest := ParseFriendlyHost(tt.source + sfx) | 
|  |  | 
|  | if gotHost == nil { | 
|  | if tt.wantHost != "" { | 
|  | t.Fatalf("ParseFriendlyHost() gotHost = nil, want %v", tt.wantHost) | 
|  | } | 
|  | // If we return nil host, the whole input string should be in rest | 
|  | if gotRest != (tt.source + sfx) { | 
|  | t.Fatalf("ParseFriendlyHost() was nil rest = %s, want %v", gotRest, tt.source+sfx) | 
|  | } | 
|  | return | 
|  | } | 
|  |  | 
|  | if tt.wantHost == "" { | 
|  | t.Fatalf("ParseFriendlyHost() gotHost.Raw = %v, want nil", gotHost.Raw) | 
|  | } | 
|  |  | 
|  | if v := gotHost.String(); v != tt.wantHost { | 
|  | t.Fatalf("String() = %v, want %v", v, tt.wantHost) | 
|  | } | 
|  | if v := gotHost.Display(); v != tt.wantDisplay { | 
|  | t.Fatalf("Display() = %v, want %v", v, tt.wantDisplay) | 
|  | } | 
|  | if v := gotHost.Normalized(); v != tt.wantNorm { | 
|  | t.Fatalf("Normalized() = %v, want %v", v, tt.wantNorm) | 
|  | } | 
|  | if v := gotHost.Valid(); v != tt.wantValid { | 
|  | t.Fatalf("Valid() = %v, want %v", v, tt.wantValid) | 
|  | } | 
|  | if gotRest != strings.TrimLeft(sfx, "/") { | 
|  | t.Fatalf("ParseFriendlyHost() rest = %v, want %v", gotRest, strings.TrimLeft(sfx, "/")) | 
|  | } | 
|  |  | 
|  | // Also verify that host compares equal with all the variants. | 
|  | if gotHost.Valid() && !gotHost.Equal(&FriendlyHost{Raw: tt.wantDisplay}) { | 
|  | t.Fatalf("Equal() should be true for %s and %s", tt.wantHost, tt.wantDisplay) | 
|  | } | 
|  | }) | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestInvalidHostEquals(t *testing.T) { | 
|  | invalid := NewFriendlyHost("NOT_A_HOST_NAME") | 
|  | valid := PublicRegistryHost | 
|  |  | 
|  | // invalid hosts are not comparable | 
|  | if invalid.Equal(invalid) { | 
|  | t.Fatal("invalid host names are not comparable") | 
|  | } | 
|  |  | 
|  | if valid.Equal(invalid) { | 
|  | t.Fatalf("%q is not equal to %q", valid, invalid) | 
|  | } | 
|  |  | 
|  | puny := NewFriendlyHost("xn--s-fka0wmm0zea7g8b.xn--o-8ta85a3b1dwcda1k.io") | 
|  | display := NewFriendlyHost("ʎɹʇsıƃǝɹ.ɯɹoɟɐɹɹǝʇ.io") | 
|  |  | 
|  | // The pre-normalized host is not a valid source, and therefore not | 
|  | // comparable to the display version. | 
|  | if display.Equal(puny) { | 
|  | t.Fatalf("invalid host %q should not be comparable", puny) | 
|  | } | 
|  | } |