stack_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package errors
  2. import (
  3. "fmt"
  4. "runtime"
  5. "testing"
  6. )
  7. var initpc, _, _, _ = runtime.Caller(0)
  8. func TestFrameLine(t *testing.T) {
  9. var tests = []struct {
  10. Frame
  11. want int
  12. }{{
  13. Frame(initpc),
  14. 9,
  15. }, {
  16. func() Frame {
  17. var pc, _, _, _ = runtime.Caller(0)
  18. return Frame(pc)
  19. }(),
  20. 20,
  21. }, {
  22. func() Frame {
  23. var pc, _, _, _ = runtime.Caller(1)
  24. return Frame(pc)
  25. }(),
  26. 28,
  27. }, {
  28. Frame(0), // invalid PC
  29. 0,
  30. }}
  31. for _, tt := range tests {
  32. got := tt.Frame.line()
  33. want := tt.want
  34. if want != got {
  35. t.Errorf("Frame(%v): want: %v, got: %v", uintptr(tt.Frame), want, got)
  36. }
  37. }
  38. }
  39. func TestStackLocation(t *testing.T) {
  40. st := func() *stack {
  41. var pcs [32]uintptr
  42. n := runtime.Callers(1, pcs[:])
  43. var st stack = pcs[0:n]
  44. return &st
  45. }()
  46. file, line := st.Location()
  47. wfile, wline := "github.com/pkg/errors/stack_test.go", 47
  48. if file != wfile || line != wline {
  49. t.Errorf("stack.Location(): want %q %d, got %q %d", wfile, wline, file, line)
  50. }
  51. }
  52. type X struct{}
  53. func (x X) val() Frame {
  54. var pc, _, _, _ = runtime.Caller(0)
  55. return Frame(pc)
  56. }
  57. func (x *X) ptr() Frame {
  58. var pc, _, _, _ = runtime.Caller(0)
  59. return Frame(pc)
  60. }
  61. func TestFrameFormat(t *testing.T) {
  62. var tests = []struct {
  63. Frame
  64. format string
  65. want string
  66. }{{
  67. Frame(initpc),
  68. "%s",
  69. "stack_test.go",
  70. }, {
  71. Frame(initpc),
  72. "%+s",
  73. "github.com/pkg/errors/stack_test.go",
  74. }, {
  75. Frame(0),
  76. "%s",
  77. "unknown",
  78. }, {
  79. Frame(0),
  80. "%+s",
  81. "unknown",
  82. }, {
  83. Frame(initpc),
  84. "%d",
  85. "9",
  86. }, {
  87. Frame(0),
  88. "%d",
  89. "0",
  90. }, {
  91. Frame(initpc),
  92. "%n",
  93. "init",
  94. }, {
  95. func() Frame {
  96. var x X
  97. return x.ptr()
  98. }(),
  99. "%n",
  100. "(*X).ptr",
  101. }, {
  102. func() Frame {
  103. var x X
  104. return x.val()
  105. }(),
  106. "%n",
  107. "X.val",
  108. }, {
  109. Frame(0),
  110. "%n",
  111. "",
  112. }, {
  113. Frame(initpc),
  114. "%v",
  115. "stack_test.go:9",
  116. }, {
  117. Frame(initpc),
  118. "%+v",
  119. "github.com/pkg/errors/stack_test.go:9",
  120. }, {
  121. Frame(0),
  122. "%v",
  123. "unknown:0",
  124. }}
  125. for _, tt := range tests {
  126. got := fmt.Sprintf(tt.format, tt.Frame)
  127. want := tt.want
  128. if want != got {
  129. t.Errorf("%v %q: want: %q, got: %q", tt.Frame, tt.format, want, got)
  130. }
  131. }
  132. }
  133. func TestTrimGOPATH(t *testing.T) {
  134. var tests = []struct {
  135. Frame
  136. want string
  137. }{{
  138. Frame(initpc),
  139. "github.com/pkg/errors/stack_test.go",
  140. }}
  141. for _, tt := range tests {
  142. pc := tt.Frame.pc()
  143. fn := runtime.FuncForPC(pc)
  144. file, _ := fn.FileLine(pc)
  145. got := trimGOPATH(fn.Name(), file)
  146. want := tt.want
  147. if want != got {
  148. t.Errorf("%v: want %q, got %q", tt.Frame, want, got)
  149. }
  150. }
  151. }