envExternalLookup_test.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package env
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strings"
  6. "testing"
  7. )
  8. type TestExternalLookup struct {
  9. values map[string]reflect.Value
  10. types map[string]reflect.Type
  11. }
  12. func NewTestExternalLookup() *TestExternalLookup {
  13. return &TestExternalLookup{
  14. values: make(map[string]reflect.Value),
  15. types: make(map[string]reflect.Type),
  16. }
  17. }
  18. func (testExternalLookup *TestExternalLookup) SetValue(symbol string, value interface{}) error {
  19. if strings.Contains(symbol, ".") {
  20. return ErrSymbolContainsDot
  21. }
  22. if value == nil {
  23. testExternalLookup.values[symbol] = NilValue
  24. } else {
  25. testExternalLookup.values[symbol] = reflect.ValueOf(value)
  26. }
  27. return nil
  28. }
  29. func (testExternalLookup *TestExternalLookup) Get(symbol string) (reflect.Value, error) {
  30. if value, ok := testExternalLookup.values[symbol]; ok {
  31. return value, nil
  32. }
  33. return NilValue, fmt.Errorf("undefined symbol '%s'", symbol)
  34. }
  35. func (testExternalLookup *TestExternalLookup) DefineType(symbol string, aType interface{}) error {
  36. if strings.Contains(symbol, ".") {
  37. return ErrSymbolContainsDot
  38. }
  39. var reflectType reflect.Type
  40. if aType == nil {
  41. reflectType = NilType
  42. } else {
  43. var ok bool
  44. reflectType, ok = reflectType.(reflect.Type)
  45. if !ok {
  46. reflectType = reflect.TypeOf(aType)
  47. }
  48. }
  49. testExternalLookup.types[symbol] = reflectType
  50. return nil
  51. }
  52. func (testExternalLookup *TestExternalLookup) Type(symbol string) (reflect.Type, error) {
  53. if value, ok := testExternalLookup.types[symbol]; ok {
  54. return value, nil
  55. }
  56. return NilType, fmt.Errorf("undefined symbol '%s'", symbol)
  57. }
  58. func TestExternalLookupValueAndGet(t *testing.T) {
  59. var err error
  60. var value interface{}
  61. tests := []struct {
  62. testInfo string
  63. varName string
  64. varDefineValue interface{}
  65. varGetValue interface{}
  66. varKind reflect.Kind
  67. defineError error
  68. getError error
  69. }{
  70. {testInfo: "nil", varName: "a", varDefineValue: nil, varGetValue: nil, varKind: reflect.Interface},
  71. {testInfo: "bool", varName: "a", varDefineValue: true, varGetValue: true, varKind: reflect.Bool},
  72. {testInfo: "int16", varName: "a", varDefineValue: int16(1), varGetValue: int16(1), varKind: reflect.Int16},
  73. {testInfo: "int32", varName: "a", varDefineValue: int32(1), varGetValue: int32(1), varKind: reflect.Int32},
  74. {testInfo: "int64", varName: "a", varDefineValue: int64(1), varGetValue: int64(1), varKind: reflect.Int64},
  75. {testInfo: "uint32", varName: "a", varDefineValue: uint32(1), varGetValue: uint32(1), varKind: reflect.Uint32},
  76. {testInfo: "uint64", varName: "a", varDefineValue: uint64(1), varGetValue: uint64(1), varKind: reflect.Uint64},
  77. {testInfo: "float32", varName: "a", varDefineValue: float32(1), varGetValue: float32(1), varKind: reflect.Float32},
  78. {testInfo: "float64", varName: "a", varDefineValue: float64(1), varGetValue: float64(1), varKind: reflect.Float64},
  79. {testInfo: "string", varName: "a", varDefineValue: "a", varGetValue: "a", varKind: reflect.String},
  80. {testInfo: "string with dot", varName: "a.a", varDefineValue: "a", varGetValue: nil, varKind: reflect.String, defineError: ErrSymbolContainsDot, getError: fmt.Errorf("undefined symbol 'a.a'")},
  81. {testInfo: "string with quotes", varName: "a", varDefineValue: `"a"`, varGetValue: `"a"`, varKind: reflect.String},
  82. }
  83. // ExternalLookup set And get
  84. for _, test := range tests {
  85. testExternalLookup := NewTestExternalLookup()
  86. env := NewEnv()
  87. env.SetExternalLookup(testExternalLookup)
  88. err = testExternalLookup.SetValue(test.varName, test.varDefineValue)
  89. if err != nil && test.defineError != nil {
  90. if err.Error() != test.defineError.Error() {
  91. t.Errorf("TestExternalLookupValueAndGet %v - SetValue error - received: %v - expected: %v", test.testInfo, err, test.defineError)
  92. continue
  93. }
  94. } else if err != test.defineError {
  95. t.Errorf("TestExternalLookupValueAndGet %v - SetValue error - received: %v - expected: %v", test.testInfo, err, test.defineError)
  96. continue
  97. }
  98. value, err = env.Get(test.varName)
  99. if err != nil && test.getError != nil {
  100. if err.Error() != test.getError.Error() {
  101. t.Errorf("TestExternalLookupValueAndGet %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
  102. continue
  103. }
  104. } else if err != test.getError {
  105. t.Errorf("TestExternalLookupValueAndGet %v - Get error - received: %v - expected: %v", test.testInfo, err, test.getError)
  106. continue
  107. }
  108. if value != test.varGetValue {
  109. t.Errorf("TestExternalLookupValueAndGet %v - value check - received %#v expected: %#v", test.testInfo, value, test.varGetValue)
  110. }
  111. }
  112. }
  113. func TestExternalLookupTypeAndGet(t *testing.T) {
  114. var err error
  115. var valueType reflect.Type
  116. tests := []struct {
  117. testInfo string
  118. varName string
  119. varDefineValue interface{}
  120. defineError error
  121. typeError error
  122. }{
  123. {testInfo: "nil", varName: "a", varDefineValue: nil},
  124. {testInfo: "bool", varName: "a", varDefineValue: true},
  125. {testInfo: "int16", varName: "a", varDefineValue: int16(1)},
  126. {testInfo: "int32", varName: "a", varDefineValue: int32(1)},
  127. {testInfo: "int64", varName: "a", varDefineValue: int64(1)},
  128. {testInfo: "uint32", varName: "a", varDefineValue: uint32(1)},
  129. {testInfo: "uint64", varName: "a", varDefineValue: uint64(1)},
  130. {testInfo: "float32", varName: "a", varDefineValue: float32(1)},
  131. {testInfo: "float64", varName: "a", varDefineValue: float64(1)},
  132. {testInfo: "string", varName: "a", varDefineValue: "a"},
  133. {testInfo: "string with dot", varName: "a.a", varDefineValue: nil, defineError: ErrSymbolContainsDot, typeError: fmt.Errorf("undefined type 'a.a'")},
  134. }
  135. // DefineType
  136. for _, test := range tests {
  137. testExternalLookup := NewTestExternalLookup()
  138. env := NewEnv()
  139. env.SetExternalLookup(testExternalLookup)
  140. err = testExternalLookup.DefineType(test.varName, test.varDefineValue)
  141. if err != nil && test.defineError != nil {
  142. if err.Error() != test.defineError.Error() {
  143. t.Errorf("TestExternalLookupTypeAndGet %v - DefineType error - received: %v - expected: %v", test.testInfo, err, test.defineError)
  144. continue
  145. }
  146. } else if err != test.defineError {
  147. t.Errorf("TestExternalLookupTypeAndGet %v - DefineType error - received: %v - expected: %v", test.testInfo, err, test.defineError)
  148. continue
  149. }
  150. valueType, err = env.Type(test.varName)
  151. if err != nil && test.typeError != nil {
  152. if err.Error() != test.typeError.Error() {
  153. t.Errorf("TestExternalLookupTypeAndGet %v - Type error - received: %v - expected: %v", test.testInfo, err, test.typeError)
  154. continue
  155. }
  156. } else if err != test.typeError {
  157. t.Errorf("TestExternalLookupTypeAndGet %v - Type error - received: %v - expected: %v", test.testInfo, err, test.typeError)
  158. continue
  159. }
  160. if valueType == nil || test.varDefineValue == nil {
  161. if valueType != reflect.TypeOf(test.varDefineValue) {
  162. t.Errorf("TestExternalLookupTypeAndGet %v - Type check - received: %v - expected: %v", test.testInfo, valueType, reflect.TypeOf(test.varDefineValue))
  163. }
  164. } else if valueType.String() != reflect.TypeOf(test.varDefineValue).String() {
  165. t.Errorf("TestExternalLookupTypeAndGet %v - Type check - received: %v - expected: %v", test.testInfo, valueType, reflect.TypeOf(test.varDefineValue))
  166. }
  167. }
  168. }
  169. func TestExternalLookupAddr(t *testing.T) {
  170. var err error
  171. tests := []struct {
  172. testInfo string
  173. varName string
  174. varDefineValue interface{}
  175. defineError error
  176. addrError error
  177. }{
  178. {testInfo: "nil", varName: "a", varDefineValue: nil, addrError: nil},
  179. {testInfo: "bool", varName: "a", varDefineValue: true, addrError: fmt.Errorf("unaddressable")},
  180. {testInfo: "int64", varName: "a", varDefineValue: int64(1), addrError: fmt.Errorf("unaddressable")},
  181. {testInfo: "float64", varName: "a", varDefineValue: float64(1), addrError: fmt.Errorf("unaddressable")},
  182. {testInfo: "string", varName: "a", varDefineValue: "a", addrError: fmt.Errorf("unaddressable")},
  183. }
  184. for _, test := range tests {
  185. envParent := NewEnv()
  186. testExternalLookup := NewTestExternalLookup()
  187. envParent.SetExternalLookup(testExternalLookup)
  188. envChild := envParent.NewEnv()
  189. err = testExternalLookup.SetValue(test.varName, test.varDefineValue)
  190. if err != nil && test.defineError != nil {
  191. if err.Error() != test.defineError.Error() {
  192. t.Errorf("TestExternalLookupAddr %v - SetValue error - received: %v - expected: %v", test.testInfo, err, test.defineError)
  193. continue
  194. }
  195. } else if err != test.defineError {
  196. t.Errorf("TestExternalLookupAddr %v - SetValue error - received: %v - expected: %v", test.testInfo, err, test.defineError)
  197. continue
  198. }
  199. _, err = envChild.Addr(test.varName)
  200. if err != nil && test.addrError != nil {
  201. if err.Error() != test.addrError.Error() {
  202. t.Errorf("TestExternalLookupAddr %v - Addr error - received: %v - expected: %v", test.testInfo, err, test.addrError)
  203. continue
  204. }
  205. } else if err != test.addrError {
  206. t.Errorf("TestExternalLookupAddr %v - Addr error - received: %v - expected: %v", test.testInfo, err, test.addrError)
  207. continue
  208. }
  209. }
  210. }