1// Copyright 2020 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 pkgpath 6 7import ( 8 "internal/testenv" 9 "os" 10 "testing" 11) 12 13const testEnvName = "GO_PKGPATH_TEST_COMPILER" 14 15// This init function supports TestToSymbolFunc. For simplicity, 16// we use the test binary itself as a sample gccgo driver. 17// We set an environment variable to specify how it should behave. 18func init() { 19 switch os.Getenv(testEnvName) { 20 case "": 21 return 22 case "v1": 23 os.Stdout.WriteString(`.string "go.l__ufer.Run"`) 24 os.Exit(0) 25 case "v2": 26 os.Stdout.WriteString(`.string "go.l..u00e4ufer.Run"`) 27 os.Exit(0) 28 case "v3": 29 os.Stdout.WriteString(`.string "go_0l_u00e4ufer.Run"`) 30 os.Exit(0) 31 case "error": 32 os.Stdout.WriteString(`unknown string`) 33 os.Exit(0) 34 } 35} 36 37func TestToSymbolFunc(t *testing.T) { 38 testenv.MustHaveExec(t) 39 40 const input = "pä世" 41 tests := []struct { 42 env string 43 fail bool 44 mangled string 45 }{ 46 { 47 env: "v1", 48 mangled: "p___", 49 }, 50 { 51 env: "v2", 52 mangled: "p..u00e4..u4e16..U0001f703", 53 }, 54 { 55 env: "v3", 56 mangled: "p_u00e4_u4e16_U0001f703", 57 }, 58 { 59 env: "error", 60 fail: true, 61 }, 62 } 63 64 cmd := os.Args[0] 65 tmpdir := t.TempDir() 66 67 defer os.Unsetenv(testEnvName) 68 69 for _, test := range tests { 70 t.Run(test.env, func(t *testing.T) { 71 os.Setenv(testEnvName, test.env) 72 73 fn, err := ToSymbolFunc(cmd, tmpdir) 74 if err != nil { 75 if !test.fail { 76 t.Errorf("ToSymbolFunc(%q, %q): unexpected error %v", cmd, tmpdir, err) 77 } 78 } else if test.fail { 79 t.Errorf("ToSymbolFunc(%q, %q) succeeded but expected to fail", cmd, tmpdir) 80 } else if got, want := fn(input), test.mangled; got != want { 81 t.Errorf("ToSymbolFunc(%q, %q)(%q) = %q, want %q", cmd, tmpdir, input, got, want) 82 } 83 }) 84 } 85} 86 87var symbolTests = []struct { 88 input, v1, v2, v3 string 89}{ 90 { 91 "", 92 "", 93 "", 94 "", 95 }, 96 { 97 "bytes", 98 "bytes", 99 "bytes", 100 "bytes", 101 }, 102 { 103 "net/http", 104 "net_http", 105 "net..z2fhttp", 106 "net_1http", 107 }, 108 { 109 "golang.org/x/net/http", 110 "golang_org_x_net_http", 111 "golang.x2eorg..z2fx..z2fnet..z2fhttp", 112 "golang_0org_1x_1net_1http", 113 }, 114 { 115 "pä世.", 116 "p____", 117 "p..u00e4..u4e16.x2e..U0001f703", 118 "p_u00e4_u4e16_0_U0001f703", 119 }, 120} 121 122func TestV1(t *testing.T) { 123 for _, test := range symbolTests { 124 if got, want := toSymbolV1(test.input), test.v1; got != want { 125 t.Errorf("toSymbolV1(%q) = %q, want %q", test.input, got, want) 126 } 127 } 128} 129 130func TestV2(t *testing.T) { 131 for _, test := range symbolTests { 132 if got, want := toSymbolV2(test.input), test.v2; got != want { 133 t.Errorf("toSymbolV2(%q) = %q, want %q", test.input, got, want) 134 } 135 } 136} 137 138func TestV3(t *testing.T) { 139 for _, test := range symbolTests { 140 if got, want := toSymbolV3(test.input), test.v3; got != want { 141 t.Errorf("toSymbolV3(%q) = %q, want %q", test.input, got, want) 142 } 143 } 144} 145