tjsffi.nim 7.4 KB

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