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, "latin 5", "", errInvalidName},
78		{MIME, "latin-5", "", errInvalidName},
79
80		{IANA, "utf-8", "UTF-8", nil},
81		{IANA, "  utf-8  ", "UTF-8", nil},
82		{IANA, "  l5  ", "ISO_8859-9:1989", nil},
83		{IANA, "latin5 ", "ISO_8859-9:1989", nil},
84		{IANA, "LATIN5 ", "ISO_8859-9:1989", nil},
85		{IANA, "latin 5", "", errInvalidName},
86		{IANA, "latin-5", "", errInvalidName},
87
88		{MIB, "utf-8", "UTF8", nil},
89		{MIB, "  utf-8  ", "UTF8", nil},
90		{MIB, "  l5  ", "ISOLatin5", nil},
91		{MIB, "latin5 ", "ISOLatin5", nil},
92		{MIB, "LATIN5 ", "ISOLatin5", nil},
93		{MIB, "latin 5", "", errInvalidName},
94		{MIB, "latin-5", "", errInvalidName},
95	}
96	for i, tc := range testCases {
97		enc, err := tc.index.Encoding(tc.name)
98		if err != tc.err {
99			t.Errorf("%d: error was %v; want %v", i, err, tc.err)
100		}
101		if err != nil {
102			continue
103		}
104		if got, err := tc.index.Name(enc); got != tc.canonical {
105			t.Errorf("%d: Name(Encoding(%q)) = %q; want %q (%v)", i, tc.name, got, tc.canonical, err)
106		}
107	}
108}
109
110func TestTables(t *testing.T) {
111	for i, x := range []*Index{MIME, IANA} {
112		for name, index := range x.alias {
113			got, err := x.Encoding(name)
114			if err != nil {
115				t.Errorf("%d%s:err: unexpected error %v", i, name, err)
116			}
117			if want := x.enc[index]; got != want {
118				t.Errorf("%d%s:encoding: got %v; want %v", i, name, got, want)
119			}
120			if got != nil {
121				mib, _ := got.(identifier.Interface).ID()
122				if i := findMIB(x.toMIB, mib); i != index {
123					t.Errorf("%d%s:mib: got %d; want %d", i, name, i, index)
124				}
125			}
126		}
127	}
128}
129
130type unsupported struct {
131	encoding.Encoding
132}
133
134func (unsupported) ID() (identifier.MIB, string) { return 9999, "" }
135
136func TestName(t *testing.T) {
137	testCases := []struct {
138		desc string
139		enc  encoding.Encoding
140		f    func(e encoding.Encoding) (string, error)
141		name string
142		err  error
143	}{{
144		"defined encoding",
145		charmap.ISO8859_2,
146		MIME.Name,
147		"ISO-8859-2",
148		nil,
149	}, {
150		"defined Unicode encoding",
151		unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM),
152		IANA.Name,
153		"UTF-16BE",
154		nil,
155	}, {
156		"another defined Unicode encoding",
157		unicode.UTF16(unicode.BigEndian, unicode.UseBOM),
158		MIME.Name,
159		"UTF-16",
160		nil,
161	}, {
162		"unknown Unicode encoding",
163		unicode.UTF16(unicode.BigEndian, unicode.ExpectBOM),
164		MIME.Name,
165		"",
166		errUnknown,
167	}, {
168		"undefined encoding",
169		unsupported{},
170		MIME.Name,
171		"",
172		errUnsupported,
173	}, {
174		"undefined other encoding in HTML standard",
175		charmap.CodePage437,
176		IANA.Name,
177		"IBM437",
178		nil,
179	}, {
180		"unknown encoding",
181		encoding.Nop,
182		IANA.Name,
183		"",
184		errUnknown,
185	}}
186	for i, tc := range testCases {
187		name, err := tc.f(tc.enc)
188		if name != tc.name || err != tc.err {
189			t.Errorf("%d:%s: got %q, %v; want %q, %v", i, tc.desc, name, err, tc.name, tc.err)
190		}
191	}
192}
193