reflect_test.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright (c) 2019 Uber Technologies, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package xreflect
  21. import (
  22. "errors"
  23. "log"
  24. "sync"
  25. "testing"
  26. "github.com/stretchr/testify/assert"
  27. "go.uber.org/dig"
  28. )
  29. type hollerer interface {
  30. Holler()
  31. }
  32. type impl struct{}
  33. func (impl) Holler() {}
  34. type result struct {
  35. dig.Out // referencing di introduces import cycles
  36. mu sync.Mutex // unexported
  37. Logger *log.Logger
  38. }
  39. func TestReturnTypes(t *testing.T) {
  40. t.Run("non-function", func(t *testing.T) {
  41. assert.Empty(t, ReturnTypes(42))
  42. })
  43. t.Run("primitive", func(t *testing.T) {
  44. fn := func() (int, string) {
  45. return 0, ""
  46. }
  47. assert.Equal(t, []string{"int", "string"}, ReturnTypes(fn))
  48. })
  49. t.Run("pointer", func(t *testing.T) {
  50. type s struct{}
  51. fn := func() *s {
  52. return &s{}
  53. }
  54. assert.Equal(t, []string{"*xreflect.s"}, ReturnTypes(fn))
  55. })
  56. t.Run("interface", func(t *testing.T) {
  57. fn := func() hollerer {
  58. return impl{}
  59. }
  60. assert.Equal(t, []string{"xreflect.hollerer"}, ReturnTypes(fn))
  61. })
  62. t.Run("result struct", func(t *testing.T) {
  63. fn := func() result {
  64. return result{}
  65. }
  66. assert.Equal(t, []string{"*log.Logger"}, ReturnTypes(fn))
  67. })
  68. t.Run("skips errors", func(t *testing.T) {
  69. fn := func() (string, error) {
  70. return "", errors.New("err")
  71. }
  72. assert.Equal(t, []string{"string"}, ReturnTypes(fn))
  73. })
  74. }
  75. func TestCaller(t *testing.T) {
  76. assert.Equal(t, "git.llsapp.com/zhenghe/pkg/di/xreflect.TestCaller", Caller())
  77. }
  78. func someFunc() {}
  79. func TestFuncName(t *testing.T) {
  80. tests := []struct {
  81. desc string
  82. give interface{}
  83. want string
  84. }{
  85. {
  86. desc: "function",
  87. give: someFunc,
  88. want: "git.llsapp.com/zhenghe/pkg/di/xreflect.someFunc()",
  89. },
  90. {
  91. desc: "not a function",
  92. give: 42,
  93. want: "42",
  94. },
  95. }
  96. for _, tt := range tests {
  97. t.Run(tt.desc, func(t *testing.T) {
  98. assert.Equal(t, tt.want, FuncName(tt.give))
  99. })
  100. }
  101. }
  102. func TestSanitizeFuncNames(t *testing.T) {
  103. cases := []struct {
  104. name string
  105. input string
  106. expected string
  107. }{
  108. {
  109. "url encoding",
  110. "go.uber.org/di/sample%2egit/someFunc",
  111. "go.uber.org/di/sample.git/someFunc",
  112. },
  113. {
  114. "vendor removal",
  115. "go.uber.org/di/vendor/github.com/some/lib.SomeFunc",
  116. "vendor/github.com/some/lib.SomeFunc",
  117. },
  118. {
  119. "package happens to be named vendor is untouched",
  120. "go.uber.org/di/foovendor/someFunc",
  121. "go.uber.org/di/foovendor/someFunc",
  122. },
  123. }
  124. for _, c := range cases {
  125. t.Run(c.name, func(t *testing.T) {
  126. assert.Equal(t, c.expected, sanitize(c.input))
  127. })
  128. }
  129. }