discard """ output: ''' true true true true true true true true true true true true true true true true 3 2 12 Event { name: 'click: test' } Event { name: 'reloaded: test' } Event { name: 'updates: test' } true true true true true true true ''' """ import macros, jsffi, jsconsole # Tests for JsObject # Test JsObject []= and [] block: proc test(): bool = let obj = newJsObject() var working = true obj["a"] = 11 obj["b"] = "test" obj["c"] = "test".cstring working = working and obj["a"].to(int) == 11 working = working and obj["c"].to(cstring) == "test".cstring working echo test() # Test JsObject .= and . block: proc test(): bool = let obj = newJsObject() var working = true obj.a = 11 obj.b = "test" obj.c = "test".cstring obj.`$!&` = 42 obj.`while` = 99 working = working and obj.a.to(int) == 11 working = working and obj.b.to(string) == "test" working = working and obj.c.to(cstring) == "test".cstring working = working and obj.`$!&`.to(int) == 42 working = working and obj.`while`.to(int) == 99 working echo test() # Test JsObject .() block: proc test(): bool = let obj = newJsObject() obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z) obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == cstring"Result is: 6" echo test() # Test JsObject []() block: proc test(): bool = let obj = newJsObject() obj.a = proc(x, y, z: int, t: string): string = t & $(x + y + z) let call = obj["a"].to(proc(x, y, z: int, t: string): string) call(1, 2, 3, "Result is: ") == "Result is: 6" echo test() # Test JsObject Iterators block: proc testPairs(): bool = let obj = newJsObject() var working = true obj.a = 10 obj.b = 20 obj.c = 30 for k, v in obj.pairs: case $k of "a": working = working and v.to(int) == 10 of "b": working = working and v.to(int) == 20 of "c": working = working and v.to(int) == 30 else: return false working proc testItems(): bool = let obj = newJsObject() var working = true obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.items: working = working and v.to(int) in [10, 20, 30] working proc testKeys(): bool = let obj = newJsObject() var working = true obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.keys: working = working and $v in ["a", "b", "c"] working proc test(): bool = testPairs() and testItems() and testKeys() echo test() # Test JsObject equality block: proc test(): bool = {. emit: "var comparison = {a: 22, b: 'test'};" .} var comparison {. importc, nodecl .}: JsObject let obj = newJsObject() obj.a = 22 obj.b = "test".cstring obj.a == comparison.a and obj.b == comparison.b echo test() # Test JsObject literal block: proc test(): bool = {. emit: "var comparison = {a: 22, b: 'test'};" .} var comparison {. importc, nodecl .}: JsObject let obj = JsObject{ a: 22, b: "test".cstring } obj.a == comparison.a and obj.b == comparison.b echo test() # Tests for JsAssoc # Test JsAssoc []= and [] block: proc test(): bool = let obj = newJsAssoc[int, int]() var working = true obj[1] = 11 working = working and not compiles(obj["a"] = 11) working = working and not compiles(obj["a"]) working = working and not compiles(obj[2] = "test") working = working and not compiles(obj[3] = "test".cstring) working = working and obj[1] == 11 working echo test() # Test JsAssoc .= and . block: proc test(): bool = let obj = newJsAssoc[cstring, int]() var working = true obj.a = 11 obj.`$!&` = 42 working = working and not compiles(obj.b = "test") working = working and not compiles(obj.c = "test".cstring) working = working and obj.a == 11 working = working and obj.`$!&` == 42 working echo test() # Test JsAssoc .() block: proc test(): bool = let obj = newJsAssoc[cstring, proc(e: int): int]() obj.a = proc(e: int): int = e * e obj.a(10) == 100 echo test() # Test JsAssoc []() block: proc test(): bool = let obj = newJsAssoc[cstring, proc(e: int): int]() obj.a = proc(e: int): int = e * e let call = obj["a"] call(10) == 100 echo test() # Test JsAssoc Iterators block: proc testPairs(): bool = let obj = newJsAssoc[cstring, int]() var working = true obj.a = 10 obj.b = 20 obj.c = 30 for k, v in obj.pairs: case $k of "a": working = working and v == 10 of "b": working = working and v == 20 of "c": working = working and v == 30 else: return false working proc testItems(): bool = let obj = newJsAssoc[cstring, int]() var working = true obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.items: working = working and v in [10, 20, 30] working proc testKeys(): bool = let obj = newJsAssoc[cstring, int]() var working = true obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.keys: working = working and v in [cstring"a", cstring"b", cstring"c"] working proc test(): bool = testPairs() and testItems() and testKeys() echo test() # Test JsAssoc equality block: proc test(): bool = {. emit: "var comparison = {a: 22, b: 55};" .} var comparison {. importcpp, nodecl .}: JsAssoc[cstring, int] let obj = newJsAssoc[cstring, int]() obj.a = 22 obj.b = 55 obj.a == comparison.a and obj.b == comparison.b echo test() # Test JsAssoc literal block: proc test(): bool = {. emit: "var comparison = {a: 22, b: 55};" .} var comparison {. importcpp, nodecl .}: JsAssoc[cstring, int] let obj = JsAssoc[cstring, int]{ a: 22, b: 55 } var working = true working = working and compiles(JsAssoc[int, int]{ 1: 22, 2: 55 }) working = working and comparison.a == obj.a and comparison.b == obj.b working = working and not compiles(JsAssoc[cstring, int]{ a: "test" }) working echo test() # Tests for macros on non-JsRoot objects # Test lit block: type TestObject = object a: int b: cstring proc test(): bool = {. emit: "var comparison = {a: 1};" .} var comparison {. importc, nodecl .}: TestObject let obj = TestObject{ a: 1 } obj == comparison echo test() # Test bindMethod block: type TestObject = object a: int onWhatever: proc(e: int): int proc handleWhatever(this: TestObject, e: int): int = e + this.a proc test(): bool = let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever)) obj.onWhatever(1) == 10 echo test() block: {.emit: "function jsProc(n) { return n; }" .} proc jsProc(x: int32): JsObject {.importc: "jsProc".} proc test() = var x = jsProc(1) var y = jsProc(2) console.log x + y console.log ++x x += jsProc(10) console.log x test() import macros block: {.emit: """ function Event(name) { this.name = name; } function on(eventName, eventHandler) { eventHandler(new Event(eventName + ": test")); } var jslib = { "on": on, "subscribe": on }; """ .} type Event = object name: cstring proc on(event: cstring, handler: proc) {.importc: "on".} var jslib {.importc: "jslib", nodecl.}: JsObject on("click") do (e: Event): console.log e jslib.on("reloaded") do: console.log jsarguments[0] # this test case is different from the above, because # `subscribe` is not overloaded in the current scope jslib.subscribe("updates"): console.log jsarguments[0] block: echo jsUndefined == jsNull echo jsUndefined == nil echo jsNull == nil echo jsUndefined.isNil echo jsNull.isNil echo jsNull.isNull echo jsUndefined.isUndefined