| 21 | ) |
| 22 | |
| 23 | func TestUnescape(t *testing.T) { |
| 24 | tests := []struct { |
| 25 | in string |
| 26 | out interface{} |
| 27 | isBytes bool |
| 28 | }{ |
| 29 | // Simple string unescaping tests. |
| 30 | {in: `'hello'`, out: `hello`}, |
| 31 | {in: `r'hello'`, out: `hello`}, |
| 32 | {in: `""`, out: ``}, |
| 33 | {in: `"\\\""`, out: `\"`}, |
| 34 | {in: `"\\"`, out: `\`}, |
| 35 | {in: `'''x''x'''`, out: `x''x`}, |
| 36 | {in: `"""x""x"""`, out: `x""x`}, |
| 37 | {in: `"\303\277"`, out: `ÿ`}, |
| 38 | {in: `"\377"`, out: `ÿ`}, |
| 39 | {in: `"\u263A\u263A"`, out: `☺☺`}, |
| 40 | {in: `"\a\b\f\n\r\t\v\'\"\\\? Legal escapes"`, out: "\a\b\f\n\r\t\v'\"\\? Legal escapes"}, |
| 41 | // Byte unescaping tests. |
| 42 | {in: `"abc"`, out: "\x61\x62\x63", isBytes: true}, |
| 43 | {in: `"ÿ"`, out: "\xc3\xbf", isBytes: true}, |
| 44 | {in: `"\303\277"`, out: "\xc3\xbf", isBytes: true}, |
| 45 | {in: `"\377"`, out: "\xff", isBytes: true}, |
| 46 | {in: `"\xff"`, out: "\xff", isBytes: true}, |
| 47 | {in: `"\xc3\xbf"`, out: "\xc3\xbf", isBytes: true}, |
| 48 | {in: `'''"Kim\t"'''`, out: "\x22\x4b\x69\x6d\x09\x22", isBytes: true}, |
| 49 | // Escaping errors. |
| 50 | {in: `"\a\b\f\n\r\t\v\'\"\\\? Illegal escape \>"`, out: errors.New("unable to unescape string")}, |
| 51 | {in: `"\u00f"`, out: errors.New("unable to unescape string")}, |
| 52 | {in: `"\u00fÿ"`, out: errors.New("unable to unescape string")}, |
| 53 | {in: `"\u00ff"`, out: errors.New("unable to unescape string"), isBytes: true}, |
| 54 | {in: `"\U00ff"`, out: errors.New("unable to unescape string"), isBytes: true}, |
| 55 | {in: `"\26"`, out: errors.New("unable to unescape octal sequence")}, |
| 56 | {in: `"\268"`, out: errors.New("unable to unescape octal sequence")}, |
| 57 | {in: `"\267\"`, out: errors.New(`found '\' as last character`)}, |
| 58 | {in: `'`, out: errors.New("unable to unescape string")}, |
| 59 | {in: `*hello*`, out: errors.New("unable to unescape string")}, |
| 60 | {in: `r'''hello'`, out: errors.New("unable to unescape string")}, |
| 61 | {in: `r"""hello"`, out: errors.New("unable to unescape string")}, |
| 62 | {in: `r"""hello"`, out: errors.New("unable to unescape string")}, |
| 63 | } |
| 64 | |
| 65 | for _, tst := range tests { |
| 66 | tc := tst |
| 67 | t.Run(tc.in, func(t *testing.T) { |
| 68 | got, err := unescape(tc.in, tc.isBytes) |
| 69 | if err != nil { |
| 70 | expect, isErr := tc.out.(error) |
| 71 | if isErr { |
| 72 | if !strings.Contains(err.Error(), expect.Error()) { |
| 73 | t.Errorf("unescape(%s, %v) errored with %v, wanted %v", tc.in, tc.isBytes, err, expect) |
| 74 | } |
| 75 | } else { |
| 76 | t.Fatalf("unescape(%s, %v) failed: %v", tc.in, tc.isBytes, err) |
| 77 | } |
| 78 | } else if got != tc.out { |
| 79 | t.Errorf("unescape(%s, %v) got %v, wanted %v", tc.in, tc.isBytes, got, tc.out) |
| 80 | } |