rt_general_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package interpreter
  11. import (
  12. "testing"
  13. "devt.de/krotik/ecal/parser"
  14. "devt.de/krotik/ecal/scope"
  15. "devt.de/krotik/ecal/util"
  16. )
  17. func TestGeneralCases(t *testing.T) {
  18. rt := NewECALRuntimeProvider("a", nil, nil)
  19. id1 := rt.NewThreadID()
  20. id2 := rt.NewThreadID()
  21. if id1 == id2 {
  22. t.Error("Thread ids should not be the same:", id1)
  23. return
  24. }
  25. n, _ := parser.Parse("a", "a")
  26. inv := &invalidRuntime{newBaseRuntime(rt, n)}
  27. if err := inv.Validate().Error(); err != "ECAL error in a: Invalid construct (Unknown node: identifier) (Line:1 Pos:1)" {
  28. t.Error("Unexpected result:", err)
  29. return
  30. }
  31. if _, err := inv.Eval(nil, nil, 0); err.Error() != "ECAL error in a: Invalid construct (Unknown node: identifier) (Line:1 Pos:1)" {
  32. t.Error("Unexpected result:", err)
  33. return
  34. }
  35. n, _ = parser.Parse("a", "a")
  36. inv = &invalidRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
  37. n.Runtime = inv
  38. n2, _ := parser.Parse("a", "a")
  39. inv2 := &invalidRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n2)}
  40. n2.Runtime = inv2
  41. n.Children = append(n.Children, n2)
  42. if err := inv.Validate().Error(); err != "ECAL error in a: Invalid construct (Unknown node: identifier) (Line:1 Pos:1)" {
  43. t.Error("Unexpected result:", err)
  44. return
  45. }
  46. n, _ = parser.Parse("a", "a")
  47. void := &voidRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
  48. n.Runtime = void
  49. if res, err := void.Eval(nil, nil, 0); err != nil || res != nil {
  50. t.Error("Unexpected result:", res, err)
  51. return
  52. }
  53. }
  54. func TestImporting(t *testing.T) {
  55. vs := scope.NewScope(scope.GlobalScope)
  56. il := &util.MemoryImportLocator{Files: make(map[string]string)}
  57. il.Files["foo/bar"] = `
  58. b := 123
  59. `
  60. res, err := UnitTestEvalAndASTAndImport(
  61. `
  62. import "foo/bar" as foobar
  63. a := foobar.b`, vs,
  64. `
  65. statements
  66. import
  67. string: 'foo/bar'
  68. identifier: foobar
  69. :=
  70. identifier: a
  71. identifier: foobar
  72. identifier: b
  73. `[1:], il)
  74. if vsRes := vs.String(); err != nil || res != nil || vsRes != `GlobalScope {
  75. a (float64) : 123
  76. foobar (map[interface {}]interface {}) : {"b":123}
  77. }` {
  78. t.Error("Unexpected result: ", vsRes, res, err)
  79. return
  80. }
  81. n, _ := parser.Parse("a", "a")
  82. imp := &importRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
  83. n.Runtime = imp
  84. imp.erp = NewECALRuntimeProvider("ECALTestRuntime", nil, nil)
  85. imp.erp.ImportLocator = nil
  86. if res, err := imp.Eval(nil, nil, 0); err == nil || err.Error() != "ECAL error in ECALTestRuntime: Runtime error (No import locator was specified) (Line:1 Pos:1)" {
  87. t.Error("Unexpected result:", res, err)
  88. return
  89. }
  90. }
  91. func TestLogging(t *testing.T) {
  92. vs := scope.NewScope(scope.GlobalScope)
  93. _, err := UnitTestEvalAndAST(
  94. `
  95. log("Hello")
  96. debug("foo")
  97. error("bar")
  98. `, vs,
  99. `
  100. statements
  101. identifier: log
  102. funccall
  103. string: 'Hello'
  104. identifier: debug
  105. funccall
  106. string: 'foo'
  107. identifier: error
  108. funccall
  109. string: 'bar'
  110. `[1:])
  111. if err != nil {
  112. t.Error("Unexpected result: ", err)
  113. return
  114. }
  115. if testlogger.String() != `Hello
  116. debug: foo
  117. error: bar` {
  118. t.Error("Unexpected result: ", testlogger.String())
  119. return
  120. }
  121. }
  122. func TestOperatorRuntimeErrors(t *testing.T) {
  123. n, _ := parser.Parse("a", "a")
  124. op := &operatorRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
  125. if res := op.errorDetailString(n.Token, "foo"); res != "a=foo" {
  126. t.Error("Unexpected result:", res)
  127. }
  128. n.Token.Identifier = false
  129. if res := op.errorDetailString(n.Token, "foo"); res != "a" {
  130. t.Error("Unexpected result:", res)
  131. }
  132. n.Token.Identifier = true
  133. res, err := UnitTestEval(
  134. `+ "a"`, nil)
  135. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a number (a) (Line:1 Pos:3)" {
  136. t.Error("Unexpected result: ", res, err)
  137. return
  138. }
  139. res, err = UnitTestEval(
  140. `x := "a"; + x`, nil)
  141. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a number (x=a) (Line:1 Pos:13)" {
  142. t.Error("Unexpected result: ", res, err)
  143. return
  144. }
  145. res, err = UnitTestEval(
  146. `not "a"`, nil)
  147. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (a) (Line:1 Pos:5)" {
  148. t.Error("Unexpected result: ", res, err)
  149. return
  150. }
  151. res, err = UnitTestEval(
  152. `a:= 5; a or 6`, nil)
  153. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (a=5) (Line:1 Pos:8)" {
  154. t.Error("Unexpected result: ", res, err)
  155. return
  156. }
  157. res, err = UnitTestEval(
  158. `true or 2`, nil)
  159. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (2) (Line:1 Pos:1)" {
  160. t.Error("Unexpected result: ", res, err)
  161. return
  162. }
  163. res, err = UnitTestEval(
  164. `a := "foo"; x in a`, nil)
  165. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a list (a=foo) (Line:1 Pos:13)" {
  166. t.Error("Unexpected result: ", res, err)
  167. return
  168. }
  169. }