discard """ output: ''' 3 2 12 Event { name: 'click: test' } Event { name: 'reloaded: test' } Event { name: 'updates: test' } ''' """ import jsffi, jsconsole # Tests for JsObject block: # Test JsObject []= and [] let obj = newJsObject() obj["a"] = 11 obj["b"] = "test" obj["c"] = "test".cstring doAssert obj["a"].to(int) == 11 doAssert obj["c"].to(cstring) == "test".cstring block: # Test JsObject .= and . let obj = newJsObject() obj.a = 11 obj.b = "test" obj.c = "test".cstring obj.`$!&` = 42 obj.`while` = 99 doAssert obj.a.to(int) == 11 doAssert obj.b.to(string) == "test" doAssert obj.c.to(cstring) == "test".cstring doAssert obj.`$!&`.to(int) == 42 doAssert obj.`while`.to(int) == 99 block: # Test JsObject .() let obj = newJsObject() obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z) doAssert obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == cstring"Result is: 6" block: # Test JsObject []() 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) doAssert call(1, 2, 3, "Result is: ") == "Result is: 6" # Test JsObject Iterators block: # testPairs let obj = newJsObject() obj.a = 10 obj.b = 20 obj.c = 30 for k, v in obj.pairs: case $k of "a": doAssert v.to(int) == 10 of "b": doAssert v.to(int) == 20 of "c": doAssert v.to(int) == 30 else: doAssert false block: # testItems let obj = newJsObject() obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.items: doAssert v.to(int) in [10, 20, 30] block: # testKeys let obj = newJsObject() obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.keys: doAssert $v in ["a", "b", "c"] block: # Test JsObject equality {. emit: "var comparison = {a: 22, b: 'test'};" .} var comparison {. importjs, nodecl .}: JsObject let obj = newJsObject() obj.a = 22 obj.b = "test".cstring doAssert obj.a == comparison.a and obj.b == comparison.b block: # Test JsObject literal {. emit: "var comparison = {a: 22, b: 'test'};" .} var comparison {. importjs, nodecl .}: JsObject let obj = JsObject{ a: 22, b: "test".cstring } doAssert obj.a == comparison.a and obj.b == comparison.b # Tests for JsAssoc block: # Test JsAssoc []= and [] let obj = newJsAssoc[int, int]() obj[1] = 11 doAssert not compiles(obj["a"] = 11) doAssert not compiles(obj["a"]) doAssert not compiles(obj[2] = "test") doAssert not compiles(obj[3] = "test".cstring) doAssert obj[1] == 11 block: # Test JsAssoc .= and . let obj = newJsAssoc[cstring, int]() var working = true obj.a = 11 obj.`$!&` = 42 doAssert not compiles(obj.b = "test") doAssert not compiles(obj.c = "test".cstring) doAssert obj.a == 11 doAssert obj.`$!&` == 42 block: # Test JsAssoc .() let obj = newJsAssoc[cstring, proc(e: int): int]() obj.a = proc(e: int): int = e * e doAssert obj.a(10) == 100 block: # Test JsAssoc []() let obj = newJsAssoc[cstring, proc(e: int): int]() obj.a = proc(e: int): int = e * e let call = obj["a"] doAssert call(10) == 100 # Test JsAssoc Iterators block: # testPairs let obj = newJsAssoc[cstring, int]() obj.a = 10 obj.b = 20 obj.c = 30 for k, v in obj.pairs: case $k of "a": doAssert v == 10 of "b": doAssert v == 20 of "c": doAssert v == 30 else: doAssert false block: # testItems let obj = newJsAssoc[cstring, int]() obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.items: doAssert v in [10, 20, 30] block: # testKeys let obj = newJsAssoc[cstring, int]() obj.a = 10 obj.b = 20 obj.c = 30 for v in obj.keys: doAssert v in [cstring"a", cstring"b", cstring"c"] block: # Test JsAssoc equality {. emit: "var comparison = {a: 22, b: 55};" .} var comparison {. importjs, nodecl .}: JsAssoc[cstring, int] let obj = newJsAssoc[cstring, int]() obj.a = 22 obj.b = 55 doAssert obj.a == comparison.a and obj.b == comparison.b block: # Test JsAssoc literal {. emit: "var comparison = {a: 22, b: 55};" .} var comparison {. importjs, nodecl .}: JsAssoc[cstring, int] let obj = JsAssoc[cstring, int]{ a: 22, b: 55 } doAssert compiles(JsAssoc[int, int]{ 1: 22, 2: 55 }) doAssert comparison.a == obj.a and comparison.b == obj.b doAssert not compiles(JsAssoc[cstring, int]{ a: "test" }) # Tests for macros on non-JsRoot objects block: # Test lit type TestObject = object a: int b: cstring {. emit: "var comparison = {a: 1};" .} var comparison {. importjs, nodecl .}: TestObject let obj = TestObject{ a: 1 } doAssert obj == comparison block: # Test bindMethod type TestObject = object a: int onWhatever: proc(e: int): int proc handleWhatever(this: TestObject, e: int): int = e + this.a block: let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever)) doAssert obj.onWhatever(1) == 10 block: {.emit: "function jsProc(n) { return n; }" .} proc jsProc(x: int32): JsObject {.importjs: "jsProc(#)".} block: var x = jsProc(1) var y = jsProc(2) console.log x + y console.log ++x x += jsProc(10) console.log x 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) {.importjs: "on(#,#)".} var jslib {.importjs: "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: doAssert jsUndefined == jsNull doAssert jsUndefined == nil doAssert jsNull == nil doAssert jsUndefined.isNil doAssert jsNull.isNil doAssert jsNull.isNull doAssert jsUndefined.isUndefined block: # test ** var a = toJs(0) var b = toJs(0) doAssert to(a ** b, int) == 1 a = toJs(1) b = toJs(1) doAssert to(a ** b, int) == 1 a = toJs(-1) b = toJs(-1) doAssert to(a ** b, int) == -1 a = toJs(6) b = toJs(6) doAssert to(a ** b, int) == 46656 a = toJs(5.5) b = toJs(3) doAssert to(a ** b, float) == 166.375 a = toJs(5) b = toJs(3.0) doAssert to(a ** b, float) == 125.0 a = toJs(7.0) b = toJS(6.0) doAssert to(a ** b, float) == 117649.0 a = toJs(8) b = toJS(-2) doAssert to(a ** b, float) == 0.015625 a = toJs(1) b = toJs(1) doAssert to(`**`(a + a, b), int) == 2 doAssert to(`**`(toJs(1) + toJs(1), toJs(2)), int) == 4