| // 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. |
| |
| package pkgpath |
| |
| import ( |
| "internal/testenv" |
| "os" |
| "testing" |
| ) |
| |
| const testEnvName = "GO_PKGPATH_TEST_COMPILER" |
| |
| // This init function supports TestToSymbolFunc. For simplicity, |
| // we use the test binary itself as a sample gccgo driver. |
| // We set an environment variable to specify how it should behave. |
| func init() { |
| switch os.Getenv(testEnvName) { |
| case "": |
| return |
| case "v1": |
| os.Stdout.WriteString(`.string "go.l__ufer.Run"`) |
| os.Exit(0) |
| case "v2": |
| os.Stdout.WriteString(`.string "go.l..u00e4ufer.Run"`) |
| os.Exit(0) |
| case "v3": |
| os.Stdout.WriteString(`.string "go_0l_u00e4ufer.Run"`) |
| os.Exit(0) |
| case "error": |
| os.Stdout.WriteString(`unknown string`) |
| os.Exit(0) |
| } |
| } |
| |
| func TestToSymbolFunc(t *testing.T) { |
| testenv.MustHaveExec(t) |
| |
| const input = "pä世🜃" |
| tests := []struct { |
| env string |
| fail bool |
| mangled string |
| }{ |
| { |
| env: "v1", |
| mangled: "p___", |
| }, |
| { |
| env: "v2", |
| mangled: "p..u00e4..u4e16..U0001f703", |
| }, |
| { |
| env: "v3", |
| mangled: "p_u00e4_u4e16_U0001f703", |
| }, |
| { |
| env: "error", |
| fail: true, |
| }, |
| } |
| |
| cmd := os.Args[0] |
| tmpdir := t.TempDir() |
| |
| defer os.Unsetenv(testEnvName) |
| |
| for _, test := range tests { |
| t.Run(test.env, func(t *testing.T) { |
| os.Setenv(testEnvName, test.env) |
| |
| fn, err := ToSymbolFunc(cmd, tmpdir) |
| if err != nil { |
| if !test.fail { |
| t.Errorf("ToSymbolFunc(%q, %q): unexpected error %v", cmd, tmpdir, err) |
| } |
| } else if test.fail { |
| t.Errorf("ToSymbolFunc(%q, %q) succeeded but expected to fail", cmd, tmpdir) |
| } else if got, want := fn(input), test.mangled; got != want { |
| t.Errorf("ToSymbolFunc(%q, %q)(%q) = %q, want %q", cmd, tmpdir, input, got, want) |
| } |
| }) |
| } |
| } |
| |
| var symbolTests = []struct { |
| input, v1, v2, v3 string |
| }{ |
| { |
| "", |
| "", |
| "", |
| "", |
| }, |
| { |
| "bytes", |
| "bytes", |
| "bytes", |
| "bytes", |
| }, |
| { |
| "net/http", |
| "net_http", |
| "net..z2fhttp", |
| "net_1http", |
| }, |
| { |
| "golang.org/x/net/http", |
| "golang_org_x_net_http", |
| "golang.x2eorg..z2fx..z2fnet..z2fhttp", |
| "golang_0org_1x_1net_1http", |
| }, |
| { |
| "pä世.🜃", |
| "p____", |
| "p..u00e4..u4e16.x2e..U0001f703", |
| "p_u00e4_u4e16_0_U0001f703", |
| }, |
| } |
| |
| func TestV1(t *testing.T) { |
| for _, test := range symbolTests { |
| if got, want := toSymbolV1(test.input), test.v1; got != want { |
| t.Errorf("toSymbolV1(%q) = %q, want %q", test.input, got, want) |
| } |
| } |
| } |
| |
| func TestV2(t *testing.T) { |
| for _, test := range symbolTests { |
| if got, want := toSymbolV2(test.input), test.v2; got != want { |
| t.Errorf("toSymbolV2(%q) = %q, want %q", test.input, got, want) |
| } |
| } |
| } |
| |
| func TestV3(t *testing.T) { |
| for _, test := range symbolTests { |
| if got, want := toSymbolV3(test.input), test.v3; got != want { |
| t.Errorf("toSymbolV3(%q) = %q, want %q", test.input, got, want) |
| } |
| } |
| } |