import std/unittest import monoucha/fromjs import monoucha/javascript import monoucha/jspropenumlist import monoucha/jstypes import monoucha/optshim import monoucha/quickjs import monoucha/tojs type TestEnum = enum teA = "a", teB = "b", teC = "c" type TestEnum2 = enum te2C = "c", te2B = "b", te2A = "a" test "enums": let rt = newJSRuntime() let ctx = rt.newJSContext() let val = ctx.toJS(teB) var e: TestEnum assert ctx.fromJS(val, e).isSome assert e == teB var e2: TestEnum2 let val2 = ctx.toJS(te2A) assert ctx.fromJS(val2, e2).isSome assert e2 == te2A ctx.free() rt.free() test "enums null": let rt = newJSRuntime() let ctx = rt.newJSContext() let val = ctx.toJS("b\0c") var e: TestEnum assert ctx.fromJS(val, e).isNone ctx.free() rt.free() type TestDict0 = object of JSDict a {.jsdefault: true.}: bool b: int c {.jsdefault.}: TestEnum d: TestDict1 e {.jsdefault.}: int32 f {.jsdefault.}: Option[JSValueConst] TestDict1 = object of JSDict a: Option[JSValueConst] TestDict2 = object of JSDict a {.jsdefault.}: Option[JSValueConst] b {.jsdefault: 2.}: int c {.jsdefault.}: string TestDict3 = object of TestDict2 proc default(e: typedesc[TestEnum]): TestEnum = return teB test "jsdict undefined missing fields": let rt = newJSRuntime() let ctx = rt.newJSContext() var res: TestDict0 assert ctx.fromJS(JS_UNDEFINED, res).isNone ctx.free() rt.free() test "optional jsdict undefined": let rt = newJSRuntime() let ctx = rt.newJSContext() var res: TestDict2 assert ctx.fromJS(JS_UNDEFINED, res).isSome, ctx.getExceptionMsg() ctx.free() rt.free() test "optional jsdict inherited": let rt = newJSRuntime() let ctx = rt.newJSContext() var res: TestDict3 assert ctx.fromJS(JS_UNDEFINED, res).isSome, ctx.getExceptionMsg() assert res.b == 2 ctx.free() rt.free() proc subroutine(ctx: JSContext; val: JSValueConst) = var res: TestDict0 assert ctx.fromJS(val, res).isSome, ctx.getExceptionMsg() discard ctx.eval("delete val.f", "") assert res.a assert res.b == 1 assert res.c == teB assert res.e == 0 assert res.d.a.isNone doAssert ctx.defineProperty(res.f.get, "x", JS_NewInt32(ctx, 9)) == dprSuccess test "jsdict transitive JSValue descendant": let rt = newJSRuntime() let ctx = rt.newJSContext() const code = """ const val = { b: 1, d: { a: null }, f: { x: 1 } } val""" let val = ctx.eval(code, "") ctx.subroutine(val) GC_fullCollect() JS_FreeValue(ctx, val) ctx.free() rt.free() test "jspropenumlist": let rt = newJSRuntime() let ctx = rt.newJSContext() var list = newJSPropertyEnumList(ctx, 0) list.add(1) list.add("hi") list.add(3) list.add(4) assert list.len == 4 js_free(ctx, list.buffer) ctx.free() rt.free() test "fromjs-seq": let rt = newJSRuntime() let ctx = rt.newJSContext() var test = @[1, 2, 3, 4] let jsTest = ctx.toJS(test) var test2: seq[int] assert ctx.fromJS(jsTest, test2).isSome assert test2 == test JS_FreeValue(ctx, jsTest) ctx.free() rt.free() test "fromjs-tuple": let rt = newJSRuntime() let ctx = rt.newJSContext() var test = (2, "hi") let jsTest = ctx.toJS(test) var test2: tuple[n: int; s: string] assert ctx.fromJS(jsTest, test2).isSome assert test2 == test JS_FreeValue(ctx, jsTest) ctx.free() rt.free() type X = ref object jsDestructor(X) proc foo(x: X; s: sink string) {.jsfunc.} = discard proc bar(x: X; s: sink(string)) {.jsfunc.} = discard test "sink": let rt = newJSRuntime() let ctx = rt.newJSContext() ctx.registerType(X) ctx.free() rt.free()