1// Copyright 2017 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
5package ianaindex
6
7import (
8	"testing"
9
10	"golang.org/x/text/encoding"
11	"golang.org/x/text/encoding/charmap"
12	"golang.org/x/text/encoding/internal/identifier"
13	"golang.org/x/text/encoding/japanese"
14	"golang.org/x/text/encoding/korean"
15	"golang.org/x/text/encoding/simplifiedchinese"
16	"golang.org/x/text/encoding/traditionalchinese"
17	"golang.org/x/text/encoding/unicode"
18)
19
20var All = [][]encoding.Encoding{
21	unicode.All,
22	charmap.All,
23	japanese.All,
24	korean.All,
25	simplifiedchinese.All,
26	traditionalchinese.All,
27}
28
29// TestAllIANA tests whether an Encoding supported in x/text is defined by IANA but
30// not supported by this package.
31func TestAllIANA(t *testing.T) {
32	for _, ea := range All {
33		for _, e := range ea {
34			mib, _ := e.(identifier.Interface).ID()
35			if x := findMIB(ianaToMIB, mib); x != -1 && encodings[x] == nil {
36				t.Errorf("supported MIB %v (%v) not in index", mib, e)
37			}
38		}
39	}
40}
41
42// TestNotSupported reports the encodings in IANA, but not by x/text.
43func TestNotSupported(t *testing.T) {
44	mibs := map[identifier.MIB]bool{}
45	for _, ea := range All {
46		for _, e := range ea {
47			mib, _ := e.(identifier.Interface).ID()
48			mibs[mib] = true
49		}
50	}
51
52	// Many encodings in the IANA index will likely not be suppored by the
53	// Go encodings. That is fine.
54	// TODO: consider wheter we should add this test.
55	// for code, mib := range ianaToMIB {
56	// 	t.Run(fmt.Sprint("IANA:", mib), func(t *testing.T) {
57	// 		if !mibs[mib] {
58	// 			t.Skipf("IANA encoding %s (MIB %v) not supported",
59	// 				ianaNames[code], mib)
60	// 		}
61	// 	})
62	// }
63}
64
65func TestEncoding(t *testing.T) {
66	testCases := []struct {
67		index     *Index
68		name      string
69		canonical string
70		err       error
71	}{
72		{MIME, "utf-8", "UTF-8", nil},
73		{MIME, "  utf-8  ", "UTF-8", nil},
74		{MIME, "  l5  ", "ISO-8859-9", nil},
75		{MIME, "latin5 ", "ISO-8859-9", nil},
76		{MIME, "LATIN5 ", "ISO-8859-9", nil},
77		{MIME, "us-ascii", "US-ASCII", nil},
78		{MIME, "latin 5", "", errInvalidName},
79		{MIME, "latin-5", "", errInvalidName},
80
81		{IANA, "utf-8", "UTF-8", nil},
82		{IANA, "  utf-8  ", "UTF-8", nil},
83		{IANA, "  l5  ", "ISO_8859-9:1989", nil},
84		{IANA, "latin5 ", "ISO_8859-9:1989", nil},
85		{IANA, "LATIN5 ", "ISO_8859-9:1989", nil},
86		{IANA, "latin 5", "", errInvalidName},
87		{IANA, "latin-5", "", errInvalidName},
88
89		{MIB, "utf-8", "UTF8", nil},
90		{MIB, "  utf-8  ", "UTF8", nil},
91		{MIB, "  l5  ", "ISOLatin5", nil},
92		{MIB, "latin5 ", "ISOLatin5", nil},
93		{MIB, "LATIN5 ", "ISOLatin5", nil},
94		{MIB, "latin 5", "", errInvalidName},
95		{MIB, "latin-5", "", errInvalidName},
96	}
97	for i, tc := range testCases {
98		enc, err := tc.index.Encoding(tc.name)
99		if err != tc.err {
100			t.Errorf("%d: error was %v; want %v", i, err, tc.err)
101		}
102		if err != nil {
103			continue
104		}
105		if got, err := tc.index.Name(enc); got != tc.canonical {
106			t.Errorf("%d: Name(Encoding(%q)) = %q; want %q (%v)", i, tc.name, got, tc.canonical, err)
107		}
108	}
109}
110
111func TestTables(t *testing.T) {
112	for i, x := range []*Index{MIME, IANA} {
113		for name, index := range x.alias {
114			got, err := x.Encoding(name)
115			if err != nil {
116				t.Errorf("%d%s:err: unexpected error %v", i, name, err)
117			}
118			if want := x.enc[index]; got != want {
119				t.Errorf("%d%s:encoding: got %v; want %v", i, name, got, want)
120			}
121			if got != nil {
122				mib, _ := got.(identifier.Interface).ID()
123				if i := findMIB(x.toMIB, mib); i != index {
124					t.Errorf("%d%s:mib: got %d; want %d", i, name, i, index)
125				}
126			}
127		}
128	}
129}
130
131type unsupported struct {
132	encoding.Encoding
133}
134
135func (unsupported) ID() (identifier.MIB, string) { return 9999, "" }
136
137func TestName(t *testing.T) {
138	testCases := []struct {
139		desc string
140		enc  encoding.Encoding
141		f    func(e encoding.Encoding) (string, error)
142		name string
143		err  error
144	}{{
145		"defined encoding",
146		charmap.ISO8859_2,
147		MIME.Name,
148		"ISO-8859-2",
149		nil,
150	}, {
151		"defined Unicode encoding",
152		unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM),
153		IANA.Name,
154		"UTF-16BE",
155		nil,
156	}, {
157		"another defined Unicode encoding",
158		unicode.UTF16(unicode.BigEndian, unicode.UseBOM),
159		MIME.Name,
160		"UTF-16",
161		nil,
162	}, {
163		"unknown Unicode encoding",
164		unicode.UTF16(unicode.BigEndian, unicode.ExpectBOM),
165		MIME.Name,
166		"",
167		errUnknown,
168	}, {
169		"undefined encoding",
170		unsupported{},
171		MIME.Name,
172		"",
173		errUnsupported,
174	}, {
175		"undefined other encoding in HTML standard",
176		charmap.CodePage437,
177		IANA.Name,
178		"IBM437",
179		nil,
180	}, {
181		"unknown encoding",
182		encoding.Nop,
183		IANA.Name,
184		"",
185		errUnknown,
186	}}
187	for i, tc := range testCases {
188		name, err := tc.f(tc.enc)
189		if name != tc.name || err != tc.err {
190			t.Errorf("%d:%s: got %q, %v; want %q, %v", i, tc.desc, name, err, tc.name, tc.err)
191		}
192	}
193}
194