rt_general_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. void.Validate()
  50. if res, err := void.Eval(nil, nil, 0); err != nil || res != nil {
  51. t.Error("Unexpected result:", res, err)
  52. return
  53. }
  54. }
  55. func TestImporting(t *testing.T) {
  56. vs := scope.NewScope(scope.GlobalScope)
  57. il := &util.MemoryImportLocator{Files: make(map[string]string)}
  58. il.Files["foo/bar"] = `
  59. b := 123
  60. `
  61. res, err := UnitTestEvalAndASTAndImport(
  62. `
  63. import "foo/bar" as foobar
  64. a := foobar.b`, vs,
  65. `
  66. statements
  67. import
  68. string: 'foo/bar'
  69. identifier: foobar
  70. :=
  71. identifier: a
  72. identifier: foobar
  73. identifier: b
  74. `[1:], il)
  75. if vsRes := vs.String(); err != nil || res != nil || vsRes != `GlobalScope {
  76. a (float64) : 123
  77. foobar (map[interface {}]interface {}) : {"b":123}
  78. }` {
  79. t.Error("Unexpected result: ", vsRes, res, err)
  80. return
  81. }
  82. n, _ := parser.Parse("a", "a")
  83. imp := &importRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
  84. n.Runtime = imp
  85. imp.erp = NewECALRuntimeProvider("ECALTestRuntime", nil, nil)
  86. imp.erp.ImportLocator = nil
  87. imp.Validate()
  88. 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)" {
  89. t.Error("Unexpected result:", res, err)
  90. return
  91. }
  92. }
  93. func TestLogging(t *testing.T) {
  94. vs := scope.NewScope(scope.GlobalScope)
  95. _, err := UnitTestEvalAndAST(
  96. `
  97. log("Hello")
  98. debug("foo")
  99. error("bar")
  100. `, vs,
  101. `
  102. statements
  103. identifier: log
  104. funccall
  105. string: 'Hello'
  106. identifier: debug
  107. funccall
  108. string: 'foo'
  109. identifier: error
  110. funccall
  111. string: 'bar'
  112. `[1:])
  113. if err != nil {
  114. t.Error("Unexpected result: ", err)
  115. return
  116. }
  117. if testlogger.String() != `Hello
  118. debug: foo
  119. error: bar` {
  120. t.Error("Unexpected result: ", testlogger.String())
  121. return
  122. }
  123. }
  124. func TestOperatorRuntimeErrors(t *testing.T) {
  125. n, _ := parser.Parse("a", "a")
  126. op := &operatorRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
  127. if res := op.errorDetailString(n.Token, "foo"); res != "a=foo" {
  128. t.Error("Unexpected result:", res)
  129. }
  130. n.Token.Identifier = false
  131. if res := op.errorDetailString(n.Token, "foo"); res != "a" {
  132. t.Error("Unexpected result:", res)
  133. }
  134. n.Token.Identifier = true
  135. res, err := UnitTestEval(
  136. `+ "a"`, nil)
  137. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a number (a) (Line:1 Pos:3)" {
  138. t.Error("Unexpected result: ", res, err)
  139. return
  140. }
  141. res, err = UnitTestEval(
  142. `x := "a"; + x`, nil)
  143. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a number (x=a) (Line:1 Pos:13)" {
  144. t.Error("Unexpected result: ", res, err)
  145. return
  146. }
  147. res, err = UnitTestEval(
  148. `not "a"`, nil)
  149. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (a) (Line:1 Pos:5)" {
  150. t.Error("Unexpected result: ", res, err)
  151. return
  152. }
  153. res, err = UnitTestEval(
  154. `a:= 5; a or 6`, nil)
  155. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (a=5) (Line:1 Pos:8)" {
  156. t.Error("Unexpected result: ", res, err)
  157. return
  158. }
  159. res, err = UnitTestEval(
  160. `true or 2`, nil)
  161. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (2) (Line:1 Pos:1)" {
  162. t.Error("Unexpected result: ", res, err)
  163. return
  164. }
  165. res, err = UnitTestEval(
  166. `a := "foo"; x in a`, nil)
  167. if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a list (a=foo) (Line:1 Pos:13)" {
  168. t.Error("Unexpected result: ", res, err)
  169. return
  170. }
  171. }