--- /dev/null
+// 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 stack_test
+
+import (
+ "bytes"
+ "strings"
+ "testing"
+
+ "golang.org/x/tools/internal/stack"
+)
+
+func TestProcess(t *testing.T) {
+ for _, test := range []struct{ name, input, expect string }{{
+ name: `empty`,
+ input: ``,
+ expect: ``,
+ }, {
+ name: `no_frame`,
+ input: `goroutine 1 [running]:`,
+ expect: `
+[running]: $1
+
+1 goroutines, 1 unique
+`,
+ }, {
+ name: `one_frame`,
+ input: `
+goroutine 1 [running]:
+package.function(args)
+ file.go:10
+`,
+ expect: `
+[running]: $1
+file.go:10: function
+
+1 goroutines, 1 unique
+`,
+ }, {
+ name: `one_call`,
+ input: `
+goroutine 1 [running]:
+package1.functionA(args)
+ file1.go:10
+package2.functionB(args)
+ file2.go:20
+package3.functionC(args)
+ file3.go:30
+`,
+ expect: `
+[running]: $1
+file1.go:10: functionA
+file2.go:20: functionB
+file3.go:30: functionC
+
+1 goroutines, 1 unique
+`,
+ }, {
+ name: `two_call`,
+ input: `
+goroutine 1 [running]:
+package1.functionA(args)
+ file1.go:10
+goroutine 2 [running]:
+package2.functionB(args)
+ file2.go:20
+`,
+ expect: `
+[running]: $1
+file1.go:10: functionA
+
+[running]: $2
+file2.go:20: functionB
+
+2 goroutines, 2 unique
+`,
+ }, {
+ name: `merge_call`,
+ input: `
+goroutine 1 [running]:
+package1.functionA(args)
+ file1.go:10
+goroutine 2 [running]:
+package1.functionA(args)
+ file1.go:10
+`,
+ expect: `
+[running]: $1, $2
+file1.go:10: functionA
+
+2 goroutines, 1 unique
+`,
+ }, {
+ name: `alternating_call`,
+ input: `
+goroutine 1 [running]:
+package1.functionA(args)
+ file1.go:10
+goroutine 2 [running]:
+package2.functionB(args)
+ file2.go:20
+goroutine 3 [running]:
+package1.functionA(args)
+ file1.go:10
+goroutine 4 [running]:
+package2.functionB(args)
+ file2.go:20
+goroutine 5 [running]:
+package1.functionA(args)
+ file1.go:10
+goroutine 6 [running]:
+package2.functionB(args)
+ file2.go:20
+`,
+ expect: `
+[running]: $1, $3, $5
+file1.go:10: functionA
+
+[running]: $2, $4, $6
+file2.go:20: functionB
+
+6 goroutines, 2 unique
+`,
+ }, {
+ name: `sort_calls`,
+ input: `
+goroutine 1 [running]:
+package3.functionC(args)
+ file3.go:30
+goroutine 2 [running]:
+package2.functionB(args)
+ file2.go:20
+goroutine 3 [running]:
+package1.functionA(args)
+ file1.go:10
+`,
+ expect: `
+[running]: $3
+file1.go:10: functionA
+
+[running]: $2
+file2.go:20: functionB
+
+[running]: $1
+file3.go:30: functionC
+
+3 goroutines, 3 unique
+`,
+ }, {
+ name: `real_single`,
+ input: `
+panic: oops
+
+goroutine 53 [running]:
+golang.org/x/tools/internal/jsonrpc2_test.testHandler.func1(0x1240c20, 0xc000013350, 0xc0000133b0, 0x1240ca0, 0xc00002ab00, 0x3, 0x3)
+ /work/tools/internal/jsonrpc2/jsonrpc2_test.go:160 +0x74c
+golang.org/x/tools/internal/jsonrpc2.(*Conn).Run(0xc000204330, 0x1240c20, 0xc000204270, 0x1209570, 0xc000212120, 0x1242700)
+ /work/tools/internal/jsonrpc2/jsonrpc2.go:187 +0x777
+golang.org/x/tools/internal/jsonrpc2_test.run.func1(0x123ebe0, 0xc000206018, 0x123ec20, 0xc000206010, 0xc0002080a0, 0xc000204330, 0x1240c20, 0xc000204270, 0xc000212120)
+ /work/tools/internal/jsonrpc2/jsonrpc2_test.go:131 +0xe2
+created by golang.org/x/tools/internal/jsonrpc2_test.run
+ /work/tools/internal/jsonrpc2/jsonrpc2_test.go:121 +0x263
+FAIL golang.org/x/tools/internal/jsonrpc2 0.252s
+FAIL
+`,
+ expect: `
+panic: oops
+
+[running]: $53
+/work/tools/internal/jsonrpc2/jsonrpc2_test.go:160: testHandler.func1
+/work/tools/internal/jsonrpc2/jsonrpc2.go:187: (*Conn).Run
+/work/tools/internal/jsonrpc2/jsonrpc2_test.go:131: run.func1
+/work/tools/internal/jsonrpc2/jsonrpc2_test.go:121: run
+
+1 goroutines, 1 unique
+
+FAIL golang.org/x/tools/internal/jsonrpc2 0.252s
+FAIL
+`,
+ }} {
+ t.Run(test.name, func(t *testing.T) {
+ buf := &bytes.Buffer{}
+ stack.Process(buf, strings.NewReader(test.input))
+ expect := strings.TrimSpace(test.expect)
+ got := strings.TrimSpace(buf.String())
+ if got != expect {
+ t.Errorf("got:\n%s\nexpect:\n%s", got, expect)
+ }
+ })
+ }
+}