| // Copyright 2020 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. | |
| //go:build goexperiment.jsonv2 | |
| package json | |
| import ( | |
| "fmt" | |
| "reflect" | |
| "testing" | |
| "unicode" | |
| ) | |
| var equalFoldTestdata = []struct { | |
| in1, in2 string | |
| want bool | |
| }{ | |
| {"", "", true}, | |
| {"abc", "abc", true}, | |
| {"ABcd", "ABcd", true}, | |
| {"123abc", "123ABC", true}, | |
| {"_1_2_-_3__--a-_-b-c-", "123ABC", true}, | |
| {"αβδ", "ΑΒΔ", true}, | |
| {"abc", "xyz", false}, | |
| {"abc", "XYZ", false}, | |
| {"abcdefghijk", "abcdefghijX", false}, | |
| {"abcdefghijk", "abcdefghij\u212A", true}, | |
| {"abcdefghijK", "abcdefghij\u212A", true}, | |
| {"abcdefghijkz", "abcdefghij\u212Ay", false}, | |
| {"abcdefghijKz", "abcdefghij\u212Ay", false}, | |
| {"1", "2", false}, | |
| {"utf-8", "US-ASCII", false}, | |
| {"hello, world!", "hello, world!", true}, | |
| {"hello, world!", "Hello, World!", true}, | |
| {"hello, world!", "HELLO, WORLD!", true}, | |
| {"hello, world!", "jello, world!", false}, | |
| {"γειά, κόσμε!", "γειά, κόσμε!", true}, | |
| {"γειά, κόσμε!", "Γειά, Κόσμε!", true}, | |
| {"γειά, κόσμε!", "ΓΕΙΆ, ΚΌΣΜΕ!", true}, | |
| {"γειά, κόσμε!", "ΛΕΙΆ, ΚΌΣΜΕ!", false}, | |
| {"AESKey", "aesKey", true}, | |
| {"γειά, κόσμε!", "Γ\xce_\xb5ιά, Κόσμε!", false}, | |
| {"aeskey", "AESKEY", true}, | |
| {"AESKEY", "aes_key", true}, | |
| {"aes_key", "AES_KEY", true}, | |
| {"AES_KEY", "aes-key", true}, | |
| {"aes-key", "AES-KEY", true}, | |
| {"AES-KEY", "aesKey", true}, | |
| {"aesKey", "AesKey", true}, | |
| {"AesKey", "AESKey", true}, | |
| {"AESKey", "aeskey", true}, | |
| {"DESKey", "aeskey", false}, | |
| {"AES Key", "aeskey", false}, | |
| {"aes﹏key", "aeskey", false}, // Unicode underscore not handled | |
| {"aes〰key", "aeskey", false}, // Unicode dash not handled | |
| } | |
| func TestEqualFold(t *testing.T) { | |
| for _, tt := range equalFoldTestdata { | |
| got := equalFold([]byte(tt.in1), []byte(tt.in2)) | |
| if got != tt.want { | |
| t.Errorf("equalFold(%q, %q) = %v, want %v", tt.in1, tt.in2, got, tt.want) | |
| } | |
| } | |
| } | |
| func equalFold(x, y []byte) bool { | |
| return string(foldName(x)) == string(foldName(y)) | |
| } | |
| func TestFoldRune(t *testing.T) { | |
| if testing.Short() { | |
| t.Skip() | |
| } | |
| var foldSet []rune | |
| for r := range rune(unicode.MaxRune + 1) { | |
| // Derive all runes that are all part of the same fold set. | |
| foldSet = foldSet[:0] | |
| for r0 := r; r != r0 || len(foldSet) == 0; r = unicode.SimpleFold(r) { | |
| foldSet = append(foldSet, r) | |
| } | |
| // Normalized form of each rune in a foldset must be the same and | |
| // also be within the set itself. | |
| var withinSet bool | |
| rr0 := foldRune(foldSet[0]) | |
| for _, r := range foldSet { | |
| withinSet = withinSet || rr0 == r | |
| rr := foldRune(r) | |
| if rr0 != rr { | |
| t.Errorf("foldRune(%q) = %q, want %q", r, rr, rr0) | |
| } | |
| } | |
| if !withinSet { | |
| t.Errorf("foldRune(%q) = %q not in fold set %q", foldSet[0], rr0, string(foldSet)) | |
| } | |
| } | |
| } | |
| // TestBenchmarkUnmarshalUnknown unmarshals an unknown field into a struct with | |
| // varying number of fields. Since the unknown field does not directly match | |
| // any known field by name, it must fall back on case-insensitive matching. | |
| func TestBenchmarkUnmarshalUnknown(t *testing.T) { | |
| in := []byte(`{"NameUnknown":null}`) | |
| for _, n := range []int{1, 2, 5, 10, 20, 50, 100} { | |
| unmarshal := Unmarshal | |
| var fields []reflect.StructField | |
| for i := range n { | |
| fields = append(fields, reflect.StructField{ | |
| Name: fmt.Sprintf("Name%d", i), | |
| Type: T[int](), | |
| Tag: `json:",case:ignore"`, | |
| }) | |
| } | |
| out := reflect.New(reflect.StructOf(fields)).Interface() | |
| t.Run(fmt.Sprintf("N%d", n), func(t *testing.T) { | |
| if err := unmarshal(in, out); err != nil { | |
| t.Fatalf("Unmarshal error: %v", err) | |
| } | |
| }) | |
| } | |
| } |