tjsffi.nim 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. discard """
  2. matrix: "--legacy:jsnolambdalifting;"
  3. output: '''
  4. 3
  5. 2
  6. 12
  7. Event { name: 'click: test' }
  8. Event { name: 'reloaded: test' }
  9. Event { name: 'updates: test' }
  10. '''
  11. """
  12. import jsffi, jsconsole
  13. # Tests for JsObject
  14. block: # Test JsObject []= and []
  15. let obj = newJsObject()
  16. obj["a"] = 11
  17. obj["b"] = "test"
  18. obj["c"] = "test".cstring
  19. doAssert obj["a"].to(int) == 11
  20. doAssert obj["c"].to(cstring) == "test".cstring
  21. block: # Test JsObject .= and .
  22. let obj = newJsObject()
  23. obj.a = 11
  24. obj.b = "test"
  25. obj.c = "test".cstring
  26. obj.`$!&` = 42
  27. obj.`while` = 99
  28. doAssert obj.a.to(int) == 11
  29. doAssert obj.b.to(string) == "test"
  30. doAssert obj.c.to(cstring) == "test".cstring
  31. doAssert obj.`$!&`.to(int) == 42
  32. doAssert obj.`while`.to(int) == 99
  33. block: # Test JsObject .()
  34. let obj = newJsObject()
  35. obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z)
  36. doAssert obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == cstring"Result is: 6"
  37. block: # Test JsObject []()
  38. let obj = newJsObject()
  39. obj.a = proc(x, y, z: int, t: string): string = t & $(x + y + z)
  40. let call = obj["a"].to(proc(x, y, z: int, t: string): string)
  41. doAssert call(1, 2, 3, "Result is: ") == "Result is: 6"
  42. # Test JsObject Iterators
  43. block: # testPairs
  44. let obj = newJsObject()
  45. obj.a = 10
  46. obj.b = 20
  47. obj.c = 30
  48. for k, v in obj.pairs:
  49. case $k
  50. of "a":
  51. doAssert v.to(int) == 10
  52. of "b":
  53. doAssert v.to(int) == 20
  54. of "c":
  55. doAssert v.to(int) == 30
  56. else:
  57. doAssert false
  58. block: # testItems
  59. let obj = newJsObject()
  60. obj.a = 10
  61. obj.b = 20
  62. obj.c = 30
  63. for v in obj.items:
  64. doAssert v.to(int) in [10, 20, 30]
  65. block: # testKeys
  66. let obj = newJsObject()
  67. obj.a = 10
  68. obj.b = 20
  69. obj.c = 30
  70. for v in obj.keys:
  71. doAssert $v in ["a", "b", "c"]
  72. block: # Test JsObject equality
  73. {. emit: "var comparison = {a: 22, b: 'test'};" .}
  74. var comparison {. importjs, nodecl .}: JsObject
  75. let obj = newJsObject()
  76. obj.a = 22
  77. obj.b = "test".cstring
  78. doAssert obj.a == comparison.a and obj.b == comparison.b
  79. block: # Test JsObject literal
  80. {. emit: "var comparison = {a: 22, b: 'test'};" .}
  81. var comparison {. importjs, nodecl .}: JsObject
  82. let obj = JsObject{ a: 22, b: "test".cstring }
  83. doAssert obj.a == comparison.a and obj.b == comparison.b
  84. # Tests for JsAssoc
  85. block: # Test JsAssoc []= and []
  86. let obj = newJsAssoc[int, int]()
  87. obj[1] = 11
  88. doAssert not compiles(obj["a"] = 11)
  89. doAssert not compiles(obj["a"])
  90. doAssert not compiles(obj[2] = "test")
  91. doAssert not compiles(obj[3] = "test".cstring)
  92. doAssert obj[1] == 11
  93. block: # Test JsAssoc .= and .
  94. let obj = newJsAssoc[cstring, int]()
  95. var working = true
  96. obj.a = 11
  97. obj.`$!&` = 42
  98. doAssert not compiles(obj.b = "test")
  99. doAssert not compiles(obj.c = "test".cstring)
  100. doAssert obj.a == 11
  101. doAssert obj.`$!&` == 42
  102. block: # Test JsAssoc .()
  103. let obj = newJsAssoc[cstring, proc(e: int): int]()
  104. obj.a = proc(e: int): int = e * e
  105. doAssert obj.a(10) == 100
  106. block: # Test JsAssoc []()
  107. let obj = newJsAssoc[cstring, proc(e: int): int]()
  108. obj.a = proc(e: int): int = e * e
  109. let call = obj["a"]
  110. doAssert call(10) == 100
  111. # Test JsAssoc Iterators
  112. block: # testPairs
  113. let obj = newJsAssoc[cstring, int]()
  114. obj.a = 10
  115. obj.b = 20
  116. obj.c = 30
  117. for k, v in obj.pairs:
  118. case $k
  119. of "a":
  120. doAssert v == 10
  121. of "b":
  122. doAssert v == 20
  123. of "c":
  124. doAssert v == 30
  125. else:
  126. doAssert false
  127. block: # testItems
  128. let obj = newJsAssoc[cstring, int]()
  129. obj.a = 10
  130. obj.b = 20
  131. obj.c = 30
  132. for v in obj.items:
  133. doAssert v in [10, 20, 30]
  134. block: # testKeys
  135. let obj = newJsAssoc[cstring, int]()
  136. obj.a = 10
  137. obj.b = 20
  138. obj.c = 30
  139. for v in obj.keys:
  140. doAssert v in [cstring"a", cstring"b", cstring"c"]
  141. block: # Test JsAssoc equality
  142. {. emit: "var comparison = {a: 22, b: 55};" .}
  143. var comparison {. importjs, nodecl .}: JsAssoc[cstring, int]
  144. let obj = newJsAssoc[cstring, int]()
  145. obj.a = 22
  146. obj.b = 55
  147. doAssert obj.a == comparison.a and obj.b == comparison.b
  148. block: # Test JsAssoc literal
  149. {. emit: "var comparison = {a: 22, b: 55};" .}
  150. var comparison {. importjs, nodecl .}: JsAssoc[cstring, int]
  151. let obj = JsAssoc[cstring, int]{ a: 22, b: 55 }
  152. doAssert compiles(JsAssoc[int, int]{ 1: 22, 2: 55 })
  153. doAssert comparison.a == obj.a and comparison.b == obj.b
  154. doAssert not compiles(JsAssoc[cstring, int]{ a: "test" })
  155. # Tests for macros on non-JsRoot objects
  156. block: # Test lit
  157. type TestObject = object
  158. a: int
  159. b: cstring
  160. {. emit: "var comparison = {a: 1};" .}
  161. var comparison {. importjs, nodecl .}: TestObject
  162. let obj = TestObject{ a: 1 }
  163. doAssert obj == comparison
  164. block: # Test bindMethod
  165. type TestObject = object
  166. a: int
  167. onWhatever: proc(e: int): int {.nimcall.}
  168. proc handleWhatever(this: TestObject, e: int): int =
  169. e + this.a
  170. block:
  171. let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever))
  172. doAssert obj.onWhatever(1) == 10
  173. block:
  174. {.emit: "function jsProc(n) { return n; }" .}
  175. proc jsProc(x: int32): JsObject {.importjs: "jsProc(#)".}
  176. block:
  177. var x = jsProc(1)
  178. var y = jsProc(2)
  179. console.log x + y
  180. console.log ++x
  181. x += jsProc(10)
  182. console.log x
  183. block:
  184. {.emit:
  185. """
  186. function Event(name) { this.name = name; }
  187. function on(eventName, eventHandler) { eventHandler(new Event(eventName + ": test")); }
  188. var jslib = { "on": on, "subscribe": on };
  189. """
  190. .}
  191. type Event = object
  192. name: cstring
  193. proc on(event: cstring, handler: proc) {.importjs: "on(#,#)".}
  194. var jslib {.importjs: "jslib", nodecl.}: JsObject
  195. on("click") do (e: Event):
  196. console.log e
  197. jslib.on("reloaded") do ():
  198. console.log jsarguments[0]
  199. # this test case is different from the above, because
  200. # `subscribe` is not overloaded in the current scope
  201. jslib.subscribe("updates"):
  202. console.log jsarguments[0]
  203. block:
  204. doAssert jsUndefined == jsNull
  205. doAssert jsUndefined == nil
  206. doAssert jsNull == nil
  207. doAssert jsUndefined.isNil
  208. doAssert jsNull.isNil
  209. doAssert jsNull.isNull
  210. doAssert jsUndefined.isUndefined
  211. block: # test **
  212. var a = toJs(0)
  213. var b = toJs(0)
  214. doAssert to(a ** b, int) == 1
  215. a = toJs(1)
  216. b = toJs(1)
  217. doAssert to(a ** b, int) == 1
  218. a = toJs(-1)
  219. b = toJs(-1)
  220. doAssert to(a ** b, int) == -1
  221. a = toJs(6)
  222. b = toJs(6)
  223. doAssert to(a ** b, int) == 46656
  224. a = toJs(5.5)
  225. b = toJs(3)
  226. doAssert to(a ** b, float) == 166.375
  227. a = toJs(5)
  228. b = toJs(3.0)
  229. doAssert to(a ** b, float) == 125.0
  230. a = toJs(7.0)
  231. b = toJS(6.0)
  232. doAssert to(a ** b, float) == 117649.0
  233. a = toJs(8)
  234. b = toJS(-2)
  235. doAssert to(a ** b, float) == 0.015625
  236. a = toJs(1)
  237. b = toJs(1)
  238. doAssert to(`**`(a + a, b), int) == 2
  239. doAssert to(`**`(toJs(1) + toJs(1), toJs(2)), int) == 4
  240. block: # issue #21208
  241. type MyEnum = enum baz
  242. var obj: JsObject
  243. {.emit: "`obj` = {bar: {baz: 123}};".}
  244. discard obj.bar.baz