summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/publicsuffix/list_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/publicsuffix/list_test.go')
-rw-r--r--vendor/golang.org/x/net/publicsuffix/list_test.go416
1 files changed, 416 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/publicsuffix/list_test.go b/vendor/golang.org/x/net/publicsuffix/list_test.go
new file mode 100644
index 0000000..42d79cc
--- /dev/null
+++ b/vendor/golang.org/x/net/publicsuffix/list_test.go
@@ -0,0 +1,416 @@
+// Copyright 2012 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 publicsuffix
+
+import (
+ "sort"
+ "strings"
+ "testing"
+)
+
+func TestNodeLabel(t *testing.T) {
+ for i, want := range nodeLabels {
+ got := nodeLabel(uint32(i))
+ if got != want {
+ t.Errorf("%d: got %q, want %q", i, got, want)
+ }
+ }
+}
+
+func TestFind(t *testing.T) {
+ testCases := []string{
+ "",
+ "a",
+ "a0",
+ "aaaa",
+ "ao",
+ "ap",
+ "ar",
+ "aro",
+ "arp",
+ "arpa",
+ "arpaa",
+ "arpb",
+ "az",
+ "b",
+ "b0",
+ "ba",
+ "z",
+ "zu",
+ "zv",
+ "zw",
+ "zx",
+ "zy",
+ "zz",
+ "zzzz",
+ }
+ for _, tc := range testCases {
+ got := find(tc, 0, numTLD)
+ want := notFound
+ for i := uint32(0); i < numTLD; i++ {
+ if tc == nodeLabel(i) {
+ want = i
+ break
+ }
+ }
+ if got != want {
+ t.Errorf("%q: got %d, want %d", tc, got, want)
+ }
+ }
+}
+
+func TestICANN(t *testing.T) {
+ testCases := map[string]bool{
+ "foo.org": true,
+ "foo.co.uk": true,
+ "foo.dyndns.org": false,
+ "foo.go.dyndns.org": false,
+ "foo.blogspot.co.uk": false,
+ "foo.intranet": false,
+ }
+ for domain, want := range testCases {
+ _, got := PublicSuffix(domain)
+ if got != want {
+ t.Errorf("%q: got %v, want %v", domain, got, want)
+ }
+ }
+}
+
+var publicSuffixTestCases = []struct {
+ domain, want string
+}{
+ // Empty string.
+ {"", ""},
+
+ // The .ao rules are:
+ // ao
+ // ed.ao
+ // gv.ao
+ // og.ao
+ // co.ao
+ // pb.ao
+ // it.ao
+ {"ao", "ao"},
+ {"www.ao", "ao"},
+ {"pb.ao", "pb.ao"},
+ {"www.pb.ao", "pb.ao"},
+ {"www.xxx.yyy.zzz.pb.ao", "pb.ao"},
+
+ // The .ar rules are:
+ // ar
+ // com.ar
+ // edu.ar
+ // gob.ar
+ // gov.ar
+ // int.ar
+ // mil.ar
+ // net.ar
+ // org.ar
+ // tur.ar
+ // blogspot.com.ar
+ {"ar", "ar"},
+ {"www.ar", "ar"},
+ {"nic.ar", "ar"},
+ {"www.nic.ar", "ar"},
+ {"com.ar", "com.ar"},
+ {"www.com.ar", "com.ar"},
+ {"blogspot.com.ar", "blogspot.com.ar"},
+ {"www.blogspot.com.ar", "blogspot.com.ar"},
+ {"www.xxx.yyy.zzz.blogspot.com.ar", "blogspot.com.ar"},
+ {"logspot.com.ar", "com.ar"},
+ {"zlogspot.com.ar", "com.ar"},
+ {"zblogspot.com.ar", "com.ar"},
+
+ // The .arpa rules are:
+ // arpa
+ // e164.arpa
+ // in-addr.arpa
+ // ip6.arpa
+ // iris.arpa
+ // uri.arpa
+ // urn.arpa
+ {"arpa", "arpa"},
+ {"www.arpa", "arpa"},
+ {"urn.arpa", "urn.arpa"},
+ {"www.urn.arpa", "urn.arpa"},
+ {"www.xxx.yyy.zzz.urn.arpa", "urn.arpa"},
+
+ // The relevant {kobe,kyoto}.jp rules are:
+ // jp
+ // *.kobe.jp
+ // !city.kobe.jp
+ // kyoto.jp
+ // ide.kyoto.jp
+ {"jp", "jp"},
+ {"kobe.jp", "jp"},
+ {"c.kobe.jp", "c.kobe.jp"},
+ {"b.c.kobe.jp", "c.kobe.jp"},
+ {"a.b.c.kobe.jp", "c.kobe.jp"},
+ {"city.kobe.jp", "kobe.jp"},
+ {"www.city.kobe.jp", "kobe.jp"},
+ {"kyoto.jp", "kyoto.jp"},
+ {"test.kyoto.jp", "kyoto.jp"},
+ {"ide.kyoto.jp", "ide.kyoto.jp"},
+ {"b.ide.kyoto.jp", "ide.kyoto.jp"},
+ {"a.b.ide.kyoto.jp", "ide.kyoto.jp"},
+
+ // The .tw rules are:
+ // tw
+ // edu.tw
+ // gov.tw
+ // mil.tw
+ // com.tw
+ // net.tw
+ // org.tw
+ // idv.tw
+ // game.tw
+ // ebiz.tw
+ // club.tw
+ // 網路.tw (xn--zf0ao64a.tw)
+ // 組織.tw (xn--uc0atv.tw)
+ // 商業.tw (xn--czrw28b.tw)
+ // blogspot.tw
+ {"tw", "tw"},
+ {"aaa.tw", "tw"},
+ {"www.aaa.tw", "tw"},
+ {"xn--czrw28b.aaa.tw", "tw"},
+ {"edu.tw", "edu.tw"},
+ {"www.edu.tw", "edu.tw"},
+ {"xn--czrw28b.edu.tw", "edu.tw"},
+ {"xn--czrw28b.tw", "xn--czrw28b.tw"},
+ {"www.xn--czrw28b.tw", "xn--czrw28b.tw"},
+ {"xn--uc0atv.xn--czrw28b.tw", "xn--czrw28b.tw"},
+ {"xn--kpry57d.tw", "tw"},
+
+ // The .uk rules are:
+ // uk
+ // ac.uk
+ // co.uk
+ // gov.uk
+ // ltd.uk
+ // me.uk
+ // net.uk
+ // nhs.uk
+ // org.uk
+ // plc.uk
+ // police.uk
+ // *.sch.uk
+ // blogspot.co.uk
+ {"uk", "uk"},
+ {"aaa.uk", "uk"},
+ {"www.aaa.uk", "uk"},
+ {"mod.uk", "uk"},
+ {"www.mod.uk", "uk"},
+ {"sch.uk", "uk"},
+ {"mod.sch.uk", "mod.sch.uk"},
+ {"www.sch.uk", "www.sch.uk"},
+ {"blogspot.co.uk", "blogspot.co.uk"},
+ {"blogspot.nic.uk", "uk"},
+ {"blogspot.sch.uk", "blogspot.sch.uk"},
+
+ // The .рф rules are
+ // рф (xn--p1ai)
+ {"xn--p1ai", "xn--p1ai"},
+ {"aaa.xn--p1ai", "xn--p1ai"},
+ {"www.xxx.yyy.xn--p1ai", "xn--p1ai"},
+
+ // The .bd rules are:
+ // *.bd
+ {"bd", "bd"},
+ {"www.bd", "www.bd"},
+ {"zzz.bd", "zzz.bd"},
+ {"www.zzz.bd", "zzz.bd"},
+ {"www.xxx.yyy.zzz.bd", "zzz.bd"},
+
+ // There are no .nosuchtld rules.
+ {"nosuchtld", "nosuchtld"},
+ {"foo.nosuchtld", "nosuchtld"},
+ {"bar.foo.nosuchtld", "nosuchtld"},
+}
+
+func BenchmarkPublicSuffix(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, tc := range publicSuffixTestCases {
+ List.PublicSuffix(tc.domain)
+ }
+ }
+}
+
+func TestPublicSuffix(t *testing.T) {
+ for _, tc := range publicSuffixTestCases {
+ got := List.PublicSuffix(tc.domain)
+ if got != tc.want {
+ t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want)
+ }
+ }
+}
+
+func TestSlowPublicSuffix(t *testing.T) {
+ for _, tc := range publicSuffixTestCases {
+ got := slowPublicSuffix(tc.domain)
+ if got != tc.want {
+ t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want)
+ }
+ }
+}
+
+// slowPublicSuffix implements the canonical (but O(number of rules)) public
+// suffix algorithm described at http://publicsuffix.org/list/.
+//
+// 1. Match domain against all rules and take note of the matching ones.
+// 2. If no rules match, the prevailing rule is "*".
+// 3. If more than one rule matches, the prevailing rule is the one which is an exception rule.
+// 4. If there is no matching exception rule, the prevailing rule is the one with the most labels.
+// 5. If the prevailing rule is a exception rule, modify it by removing the leftmost label.
+// 6. The public suffix is the set of labels from the domain which directly match the labels of the prevailing rule (joined by dots).
+// 7. The registered or registrable domain is the public suffix plus one additional label.
+//
+// This function returns the public suffix, not the registrable domain, and so
+// it stops after step 6.
+func slowPublicSuffix(domain string) string {
+ match := func(rulePart, domainPart string) bool {
+ switch rulePart[0] {
+ case '*':
+ return true
+ case '!':
+ return rulePart[1:] == domainPart
+ }
+ return rulePart == domainPart
+ }
+
+ domainParts := strings.Split(domain, ".")
+ var matchingRules [][]string
+
+loop:
+ for _, rule := range rules {
+ ruleParts := strings.Split(rule, ".")
+ if len(domainParts) < len(ruleParts) {
+ continue
+ }
+ for i := range ruleParts {
+ rulePart := ruleParts[len(ruleParts)-1-i]
+ domainPart := domainParts[len(domainParts)-1-i]
+ if !match(rulePart, domainPart) {
+ continue loop
+ }
+ }
+ matchingRules = append(matchingRules, ruleParts)
+ }
+ if len(matchingRules) == 0 {
+ matchingRules = append(matchingRules, []string{"*"})
+ } else {
+ sort.Sort(byPriority(matchingRules))
+ }
+ prevailing := matchingRules[0]
+ if prevailing[0][0] == '!' {
+ prevailing = prevailing[1:]
+ }
+ if prevailing[0][0] == '*' {
+ replaced := domainParts[len(domainParts)-len(prevailing)]
+ prevailing = append([]string{replaced}, prevailing[1:]...)
+ }
+ return strings.Join(prevailing, ".")
+}
+
+type byPriority [][]string
+
+func (b byPriority) Len() int { return len(b) }
+func (b byPriority) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+func (b byPriority) Less(i, j int) bool {
+ if b[i][0][0] == '!' {
+ return true
+ }
+ if b[j][0][0] == '!' {
+ return false
+ }
+ return len(b[i]) > len(b[j])
+}
+
+// eTLDPlusOneTestCases come from
+// https://github.com/publicsuffix/list/blob/master/tests/test_psl.txt
+var eTLDPlusOneTestCases = []struct {
+ domain, want string
+}{
+ // Empty input.
+ {"", ""},
+ // Unlisted TLD.
+ {"example", ""},
+ {"example.example", "example.example"},
+ {"b.example.example", "example.example"},
+ {"a.b.example.example", "example.example"},
+ // TLD with only 1 rule.
+ {"biz", ""},
+ {"domain.biz", "domain.biz"},
+ {"b.domain.biz", "domain.biz"},
+ {"a.b.domain.biz", "domain.biz"},
+ // TLD with some 2-level rules.
+ {"com", ""},
+ {"example.com", "example.com"},
+ {"b.example.com", "example.com"},
+ {"a.b.example.com", "example.com"},
+ {"uk.com", ""},
+ {"example.uk.com", "example.uk.com"},
+ {"b.example.uk.com", "example.uk.com"},
+ {"a.b.example.uk.com", "example.uk.com"},
+ {"test.ac", "test.ac"},
+ // TLD with only 1 (wildcard) rule.
+ {"mm", ""},
+ {"c.mm", ""},
+ {"b.c.mm", "b.c.mm"},
+ {"a.b.c.mm", "b.c.mm"},
+ // More complex TLD.
+ {"jp", ""},
+ {"test.jp", "test.jp"},
+ {"www.test.jp", "test.jp"},
+ {"ac.jp", ""},
+ {"test.ac.jp", "test.ac.jp"},
+ {"www.test.ac.jp", "test.ac.jp"},
+ {"kyoto.jp", ""},
+ {"test.kyoto.jp", "test.kyoto.jp"},
+ {"ide.kyoto.jp", ""},
+ {"b.ide.kyoto.jp", "b.ide.kyoto.jp"},
+ {"a.b.ide.kyoto.jp", "b.ide.kyoto.jp"},
+ {"c.kobe.jp", ""},
+ {"b.c.kobe.jp", "b.c.kobe.jp"},
+ {"a.b.c.kobe.jp", "b.c.kobe.jp"},
+ {"city.kobe.jp", "city.kobe.jp"},
+ {"www.city.kobe.jp", "city.kobe.jp"},
+ // TLD with a wildcard rule and exceptions.
+ {"ck", ""},
+ {"test.ck", ""},
+ {"b.test.ck", "b.test.ck"},
+ {"a.b.test.ck", "b.test.ck"},
+ {"www.ck", "www.ck"},
+ {"www.www.ck", "www.ck"},
+ // US K12.
+ {"us", ""},
+ {"test.us", "test.us"},
+ {"www.test.us", "test.us"},
+ {"ak.us", ""},
+ {"test.ak.us", "test.ak.us"},
+ {"www.test.ak.us", "test.ak.us"},
+ {"k12.ak.us", ""},
+ {"test.k12.ak.us", "test.k12.ak.us"},
+ {"www.test.k12.ak.us", "test.k12.ak.us"},
+ // Punycoded IDN labels
+ {"xn--85x722f.com.cn", "xn--85x722f.com.cn"},
+ {"xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"},
+ {"www.xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"},
+ {"shishi.xn--55qx5d.cn", "shishi.xn--55qx5d.cn"},
+ {"xn--55qx5d.cn", ""},
+ {"xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"},
+ {"www.xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"},
+ {"shishi.xn--fiqs8s", "shishi.xn--fiqs8s"},
+ {"xn--fiqs8s", ""},
+}
+
+func TestEffectiveTLDPlusOne(t *testing.T) {
+ for _, tc := range eTLDPlusOneTestCases {
+ got, _ := EffectiveTLDPlusOne(tc.domain)
+ if got != tc.want {
+ t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want)
+ }
+ }
+}