require.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. package require
  2. import (
  3. "bytes"
  4. "fmt"
  5. "reflect"
  6. "runtime"
  7. "strings"
  8. "testing"
  9. "unicode"
  10. "unicode/utf8"
  11. "github.com/d5/tengo/v2"
  12. "github.com/d5/tengo/v2/parser"
  13. "github.com/d5/tengo/v2/token"
  14. )
  15. // NoError asserts err is not an error.
  16. func NoError(t *testing.T, err error, msg ...interface{}) {
  17. if err != nil {
  18. failExpectedActual(t, "no error", err, msg...)
  19. }
  20. }
  21. // Error asserts err is an error.
  22. func Error(t *testing.T, err error, msg ...interface{}) {
  23. if err == nil {
  24. failExpectedActual(t, "error", err, msg...)
  25. }
  26. }
  27. // Nil asserts v is nil.
  28. func Nil(t *testing.T, v interface{}, msg ...interface{}) {
  29. if !isNil(v) {
  30. failExpectedActual(t, "nil", v, msg...)
  31. }
  32. }
  33. // True asserts v is true.
  34. func True(t *testing.T, v bool, msg ...interface{}) {
  35. if !v {
  36. failExpectedActual(t, "true", v, msg...)
  37. }
  38. }
  39. // False asserts vis false.
  40. func False(t *testing.T, v bool, msg ...interface{}) {
  41. if v {
  42. failExpectedActual(t, "false", v, msg...)
  43. }
  44. }
  45. // NotNil asserts v is not nil.
  46. func NotNil(t *testing.T, v interface{}, msg ...interface{}) {
  47. if isNil(v) {
  48. failExpectedActual(t, "not nil", v, msg...)
  49. }
  50. }
  51. // IsType asserts expected and actual are of the same type.
  52. func IsType(
  53. t *testing.T,
  54. expected, actual interface{},
  55. msg ...interface{},
  56. ) {
  57. if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
  58. failExpectedActual(t, reflect.TypeOf(expected),
  59. reflect.TypeOf(actual), msg...)
  60. }
  61. }
  62. // Equal asserts expected and actual are equal.
  63. func Equal(
  64. t *testing.T,
  65. expected, actual interface{},
  66. msg ...interface{},
  67. ) {
  68. if isNil(expected) {
  69. Nil(t, actual, "expected nil, but got not nil")
  70. return
  71. }
  72. NotNil(t, actual, "expected not nil, but got nil")
  73. IsType(t, expected, actual, msg...)
  74. switch expected := expected.(type) {
  75. case int:
  76. if expected != actual.(int) {
  77. failExpectedActual(t, expected, actual, msg...)
  78. }
  79. case int64:
  80. if expected != actual.(int64) {
  81. failExpectedActual(t, expected, actual, msg...)
  82. }
  83. case float64:
  84. if expected != actual.(float64) {
  85. failExpectedActual(t, expected, actual, msg...)
  86. }
  87. case string:
  88. if expected != actual.(string) {
  89. failExpectedActual(t, expected, actual, msg...)
  90. }
  91. case []byte:
  92. if !bytes.Equal(expected, actual.([]byte)) {
  93. failExpectedActual(t, string(expected),
  94. string(actual.([]byte)), msg...)
  95. }
  96. case []string:
  97. if !equalStringSlice(expected, actual.([]string)) {
  98. failExpectedActual(t, expected, actual, msg...)
  99. }
  100. case []int:
  101. if !equalIntSlice(expected, actual.([]int)) {
  102. failExpectedActual(t, expected, actual, msg...)
  103. }
  104. case bool:
  105. if expected != actual.(bool) {
  106. failExpectedActual(t, expected, actual, msg...)
  107. }
  108. case rune:
  109. if expected != actual.(rune) {
  110. failExpectedActual(t, expected, actual, msg...)
  111. }
  112. case *tengo.Symbol:
  113. if !equalSymbol(expected, actual.(*tengo.Symbol)) {
  114. failExpectedActual(t, expected, actual, msg...)
  115. }
  116. case parser.Pos:
  117. if expected != actual.(parser.Pos) {
  118. failExpectedActual(t, expected, actual, msg...)
  119. }
  120. case token.Token:
  121. if expected != actual.(token.Token) {
  122. failExpectedActual(t, expected, actual, msg...)
  123. }
  124. case []tengo.Object:
  125. equalObjectSlice(t, expected, actual.([]tengo.Object), msg...)
  126. case *tengo.Int:
  127. Equal(t, expected.Value, actual.(*tengo.Int).Value, msg...)
  128. case *tengo.Float:
  129. Equal(t, expected.Value, actual.(*tengo.Float).Value, msg...)
  130. case *tengo.String:
  131. Equal(t, expected.Value, actual.(*tengo.String).Value, msg...)
  132. case *tengo.Char:
  133. Equal(t, expected.Value, actual.(*tengo.Char).Value, msg...)
  134. case *tengo.Bool:
  135. if expected != actual {
  136. failExpectedActual(t, expected, actual, msg...)
  137. }
  138. case *tengo.Array:
  139. equalObjectSlice(t, expected.Value,
  140. actual.(*tengo.Array).Value, msg...)
  141. case *tengo.ImmutableArray:
  142. equalObjectSlice(t, expected.Value,
  143. actual.(*tengo.ImmutableArray).Value, msg...)
  144. case *tengo.Bytes:
  145. if !bytes.Equal(expected.Value, actual.(*tengo.Bytes).Value) {
  146. failExpectedActual(t, string(expected.Value),
  147. string(actual.(*tengo.Bytes).Value), msg...)
  148. }
  149. case *tengo.Map:
  150. equalObjectMap(t, expected.Value,
  151. actual.(*tengo.Map).Value, msg...)
  152. case *tengo.ImmutableMap:
  153. equalObjectMap(t, expected.Value,
  154. actual.(*tengo.ImmutableMap).Value, msg...)
  155. case *tengo.CompiledFunction:
  156. equalCompiledFunction(t, expected,
  157. actual.(*tengo.CompiledFunction), msg...)
  158. case *tengo.Undefined:
  159. if expected != actual {
  160. failExpectedActual(t, expected, actual, msg...)
  161. }
  162. case *tengo.Error:
  163. Equal(t, expected.Value, actual.(*tengo.Error).Value, msg...)
  164. case tengo.Object:
  165. if !expected.Equals(actual.(tengo.Object)) {
  166. failExpectedActual(t, expected, actual, msg...)
  167. }
  168. case *parser.SourceFileSet:
  169. equalFileSet(t, expected, actual.(*parser.SourceFileSet), msg...)
  170. case *parser.SourceFile:
  171. Equal(t, expected.Name, actual.(*parser.SourceFile).Name, msg...)
  172. Equal(t, expected.Base, actual.(*parser.SourceFile).Base, msg...)
  173. Equal(t, expected.Size, actual.(*parser.SourceFile).Size, msg...)
  174. True(t, equalIntSlice(expected.Lines,
  175. actual.(*parser.SourceFile).Lines), msg...)
  176. case error:
  177. if expected != actual.(error) {
  178. failExpectedActual(t, expected, actual, msg...)
  179. }
  180. default:
  181. panic(fmt.Errorf("type not implemented: %T", expected))
  182. }
  183. }
  184. // Fail marks the function as having failed but continues execution.
  185. func Fail(t *testing.T, msg ...interface{}) {
  186. t.Logf("\nError trace:\n\t%s\n%s", strings.Join(errorTrace(), "\n\t"),
  187. message(msg...))
  188. t.Fail()
  189. }
  190. func failExpectedActual(
  191. t *testing.T,
  192. expected, actual interface{},
  193. msg ...interface{},
  194. ) {
  195. var addMsg string
  196. if len(msg) > 0 {
  197. addMsg = "\nMessage: " + message(msg...)
  198. }
  199. t.Logf("\nError trace:\n\t%s\nExpected: %v\nActual: %v%s",
  200. strings.Join(errorTrace(), "\n\t"),
  201. expected, actual,
  202. addMsg)
  203. t.FailNow()
  204. }
  205. func message(formatArgs ...interface{}) string {
  206. var format string
  207. var args []interface{}
  208. if len(formatArgs) > 0 {
  209. format = formatArgs[0].(string)
  210. }
  211. if len(formatArgs) > 1 {
  212. args = formatArgs[1:]
  213. }
  214. return fmt.Sprintf(format, args...)
  215. }
  216. func equalIntSlice(a, b []int) bool {
  217. if len(a) != len(b) {
  218. return false
  219. }
  220. for i := 0; i < len(a); i++ {
  221. if a[i] != b[i] {
  222. return false
  223. }
  224. }
  225. return true
  226. }
  227. func equalStringSlice(a, b []string) bool {
  228. if len(a) != len(b) {
  229. return false
  230. }
  231. for i := 0; i < len(a); i++ {
  232. if a[i] != b[i] {
  233. return false
  234. }
  235. }
  236. return true
  237. }
  238. func equalSymbol(a, b *tengo.Symbol) bool {
  239. return a.Name == b.Name &&
  240. a.Index == b.Index &&
  241. a.Scope == b.Scope
  242. }
  243. func equalObjectSlice(
  244. t *testing.T,
  245. expected, actual []tengo.Object,
  246. msg ...interface{},
  247. ) {
  248. Equal(t, len(expected), len(actual), msg...)
  249. for i := 0; i < len(expected); i++ {
  250. Equal(t, expected[i], actual[i], msg...)
  251. }
  252. }
  253. func equalFileSet(
  254. t *testing.T,
  255. expected, actual *parser.SourceFileSet,
  256. msg ...interface{},
  257. ) {
  258. Equal(t, len(expected.Files), len(actual.Files), msg...)
  259. for i, f := range expected.Files {
  260. Equal(t, f, actual.Files[i], msg...)
  261. }
  262. Equal(t, expected.Base, actual.Base)
  263. Equal(t, expected.LastFile, actual.LastFile)
  264. }
  265. func equalObjectMap(
  266. t *testing.T,
  267. expected, actual map[string]tengo.Object,
  268. msg ...interface{},
  269. ) {
  270. Equal(t, len(expected), len(actual), msg...)
  271. for key, expectedVal := range expected {
  272. actualVal := actual[key]
  273. Equal(t, expectedVal, actualVal, msg...)
  274. }
  275. }
  276. func equalCompiledFunction(
  277. t *testing.T,
  278. expected, actual tengo.Object,
  279. msg ...interface{},
  280. ) {
  281. expectedT := expected.(*tengo.CompiledFunction)
  282. actualT := actual.(*tengo.CompiledFunction)
  283. Equal(t,
  284. tengo.FormatInstructions(expectedT.Instructions, 0),
  285. tengo.FormatInstructions(actualT.Instructions, 0), msg...)
  286. }
  287. func isNil(v interface{}) bool {
  288. if v == nil {
  289. return true
  290. }
  291. value := reflect.ValueOf(v)
  292. kind := value.Kind()
  293. return kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil()
  294. }
  295. func errorTrace() []string {
  296. var pc uintptr
  297. file := ""
  298. line := 0
  299. var ok bool
  300. name := ""
  301. var callers []string
  302. for i := 0; ; i++ {
  303. pc, file, line, ok = runtime.Caller(i)
  304. if !ok {
  305. break
  306. }
  307. if file == "<autogenerated>" {
  308. break
  309. }
  310. f := runtime.FuncForPC(pc)
  311. if f == nil {
  312. break
  313. }
  314. name = f.Name()
  315. if name == "testing.tRunner" {
  316. break
  317. }
  318. parts := strings.Split(file, "/")
  319. file = parts[len(parts)-1]
  320. if len(parts) > 1 {
  321. dir := parts[len(parts)-2]
  322. if dir != "require" ||
  323. file == "mock_test.go" {
  324. callers = append(callers, fmt.Sprintf("%s:%d", file, line))
  325. }
  326. }
  327. // Drop the package
  328. segments := strings.Split(name, ".")
  329. name = segments[len(segments)-1]
  330. if isTest(name, "Test") ||
  331. isTest(name, "Benchmark") ||
  332. isTest(name, "Example") {
  333. break
  334. }
  335. }
  336. return callers
  337. }
  338. func isTest(name, prefix string) bool {
  339. if !strings.HasPrefix(name, prefix) {
  340. return false
  341. }
  342. if len(name) == len(prefix) { // "Test" is ok
  343. return true
  344. }
  345. r, _ := utf8.DecodeRuneInString(name[len(prefix):])
  346. return !unicode.IsLower(r)
  347. }