1// Copyright 2011 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 json
6
7import (
8	"testing"
9)
10
11type basicLatin2xTag struct {
12	V string `json:"$%-/"`
13}
14
15type basicLatin3xTag struct {
16	V string `json:"0123456789"`
17}
18
19type basicLatin4xTag struct {
20	V string `json:"ABCDEFGHIJKLMO"`
21}
22
23type basicLatin5xTag struct {
24	V string `json:"PQRSTUVWXYZ_"`
25}
26
27type basicLatin6xTag struct {
28	V string `json:"abcdefghijklmno"`
29}
30
31type basicLatin7xTag struct {
32	V string `json:"pqrstuvwxyz"`
33}
34
35type miscPlaneTag struct {
36	V string `json:"色は匂へど"`
37}
38
39type percentSlashTag struct {
40	V string `json:"text/html%"` // https://golang.org/issue/2718
41}
42
43type punctuationTag struct {
44	V string `json:"!#$%&()*+-./:;<=>?@[]^_{|}~ "` // https://golang.org/issue/3546
45}
46
47type dashTag struct {
48	V string `json:"-,"`
49}
50
51type emptyTag struct {
52	W string
53}
54
55type misnamedTag struct {
56	X string `jsom:"Misnamed"`
57}
58
59type badFormatTag struct {
60	Y string `:"BadFormat"`
61}
62
63type badCodeTag struct {
64	Z string `json:" !\"#&'()*+,."`
65}
66
67type spaceTag struct {
68	Q string `json:"With space"`
69}
70
71type unicodeTag struct {
72	W string `json:"Ελλάδα"`
73}
74
75var structTagObjectKeyTests = []struct {
76	raw   interface{}
77	value string
78	key   string
79}{
80	{basicLatin2xTag{"2x"}, "2x", "$%-/"},
81	{basicLatin3xTag{"3x"}, "3x", "0123456789"},
82	{basicLatin4xTag{"4x"}, "4x", "ABCDEFGHIJKLMO"},
83	{basicLatin5xTag{"5x"}, "5x", "PQRSTUVWXYZ_"},
84	{basicLatin6xTag{"6x"}, "6x", "abcdefghijklmno"},
85	{basicLatin7xTag{"7x"}, "7x", "pqrstuvwxyz"},
86	{miscPlaneTag{"いろはにほへと"}, "いろはにほへと", "色は匂へど"},
87	{dashTag{"foo"}, "foo", "-"},
88	{emptyTag{"Pour Moi"}, "Pour Moi", "W"},
89	{misnamedTag{"Animal Kingdom"}, "Animal Kingdom", "X"},
90	{badFormatTag{"Orfevre"}, "Orfevre", "Y"},
91	{badCodeTag{"Reliable Man"}, "Reliable Man", "Z"},
92	{percentSlashTag{"brut"}, "brut", "text/html%"},
93	{punctuationTag{"Union Rags"}, "Union Rags", "!#$%&()*+-./:;<=>?@[]^_{|}~ "},
94	{spaceTag{"Perreddu"}, "Perreddu", "With space"},
95	{unicodeTag{"Loukanikos"}, "Loukanikos", "Ελλάδα"},
96}
97
98func TestStructTagObjectKey(t *testing.T) {
99	for _, tt := range structTagObjectKeyTests {
100		b, err := Marshal(tt.raw)
101		if err != nil {
102			t.Fatalf("Marshal(%#q) failed: %v", tt.raw, err)
103		}
104		var f interface{}
105		err = Unmarshal(b, &f)
106		if err != nil {
107			t.Fatalf("Unmarshal(%#q) failed: %v", b, err)
108		}
109		for i, v := range f.(map[string]interface{}) {
110			switch i {
111			case tt.key:
112				if s, ok := v.(string); !ok || s != tt.value {
113					t.Fatalf("Unexpected value: %#q, want %v", s, tt.value)
114				}
115			default:
116				t.Fatalf("Unexpected key: %#q, from %#q", i, b)
117			}
118		}
119	}
120}
121