From a66637bda46a62972a4cca2afc3c49b71c7222c2 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 4 Mar 2021 05:00:04 -0800 Subject: followup #16871 asyncjs.then: allow pipelining procs returning futures (#17189) * followup #16871 asyncjs.then: allow pipelining procs returning futures * rename test files where they belong * fix tests * tests for then with `onReject` callback * rename test file containing fail to avoid messing with grep * address comments * cleanup * un-disable 1 test --- tests/js/tasync.nim | 77 ----------------------------------- tests/js/tasync_pragma.nim | 27 ------------ tests/js/tasyncjs.nim | 97 ++++++++++++++++++++++++++++++++++++++++++++ tests/js/tasyncjs_bad.nim | 22 ++++++++++ tests/js/tasyncjs_fail.nim | 22 ---------- tests/js/tasyncjs_pragma.nim | 29 +++++++++++++ 6 files changed, 148 insertions(+), 126 deletions(-) delete mode 100644 tests/js/tasync.nim delete mode 100644 tests/js/tasync_pragma.nim create mode 100644 tests/js/tasyncjs.nim create mode 100644 tests/js/tasyncjs_bad.nim delete mode 100644 tests/js/tasyncjs_fail.nim create mode 100644 tests/js/tasyncjs_pragma.nim (limited to 'tests') diff --git a/tests/js/tasync.nim b/tests/js/tasync.nim deleted file mode 100644 index e676ba14b..000000000 --- a/tests/js/tasync.nim +++ /dev/null @@ -1,77 +0,0 @@ -discard """ - output: ''' -x -e -done -''' -""" - -#[ -xxx move this to tests/stdlib/tasyncjs.nim -]# - -import std/asyncjs - -block: - # demonstrate forward definition for js - proc y(e: int): Future[string] {.async.} - - proc e: int {.discardable.} = - echo "e" - return 2 - - proc x(e: int): Future[void] {.async.} = - var s = await y(e) - if e > 2: - return - echo s - e() - - proc y(e: int): Future[string] {.async.} = - if e > 0: - return await y(0) - else: - return "x" - - discard x(2) - -import std/sugar -from std/strutils import contains - -var witness: seq[string] - -proc fn(n: int): Future[int] {.async.} = - if n >= 7: - raise newException(ValueError, "foobar: " & $n) - if n > 0: - var ret = 1 + await fn(n-1) - witness.add $(n, ret) - return ret - else: - return 10 - -proc main() {.async.} = - block: # then - let x = await fn(4) - .then((a: int) => a.float) - .then((a: float) => $a) - doAssert x == "14.0" - doAssert witness == @["(1, 11)", "(2, 12)", "(3, 13)", "(4, 14)"] - - doAssert (await fn(2)) == 12 - - let x2 = await fn(4).then((a: int) => (discard)).then(() => 13) - doAssert x2 == 13 - - block: # catch - var reason: Error - await fn(6).then((a: int) => (witness.add $a)).catch((r: Error) => (reason = r)) - doAssert reason == nil - - await fn(7).then((a: int) => (discard)).catch((r: Error) => (reason = r)) - doAssert reason != nil - doAssert reason.name == "Error" - doAssert "foobar: 7" in $reason.message - echo "done" # justified here to make sure we're running this, since it's inside `async` - -discard main() diff --git a/tests/js/tasync_pragma.nim b/tests/js/tasync_pragma.nim deleted file mode 100644 index 916769fad..000000000 --- a/tests/js/tasync_pragma.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - output: ''' -0 -t -''' -""" - -import asyncjs, macros - -macro f*(a: untyped): untyped = - assert a.kind == nnkProcDef - result = nnkProcDef.newTree(a.name, a[1], a[2], a.params, a.pragma, a[5], nnkStmtList.newTree()) - let call = quote: - echo 0 - result.body.add(call) - for child in a.body: - result.body.add(child) - #echo result.body.repr - -proc t* {.async, f.} = - echo "t" - -proc t0* {.async.} = - await t() - -discard t0() - diff --git a/tests/js/tasyncjs.nim b/tests/js/tasyncjs.nim new file mode 100644 index 000000000..00753a16c --- /dev/null +++ b/tests/js/tasyncjs.nim @@ -0,0 +1,97 @@ +discard """ + output: ''' +x +e +done +''' +""" + +#[ +xxx move this to tests/stdlib/tasyncjs.nim +]# + +import std/asyncjs + +block: + # demonstrate forward definition for js + proc y(e: int): Future[string] {.async.} + + proc e: int {.discardable.} = + echo "e" + return 2 + + proc x(e: int): Future[void] {.async.} = + var s = await y(e) + if e > 2: + return + echo s + e() + + proc y(e: int): Future[string] {.async.} = + if e > 0: + return await y(0) + else: + return "x" + + discard x(2) + +import std/sugar +from std/strutils import contains + +var witness: seq[string] + +proc fn(n: int): Future[int] {.async.} = + if n >= 7: + raise newException(ValueError, "foobar: " & $n) + if n > 0: + var ret = 1 + await fn(n-1) + witness.add $(n, ret) + return ret + else: + return 10 + +proc asyncFact(n: int): Future[int] {.async.} = + if n > 0: result = n * await asyncFact(n-1) + else: result = 1 + +proc asyncIdentity(n: int): Future[int] {.async.} = + if n > 0: result = 1 + await asyncIdentity(n-1) + else: result = 0 + +proc main() {.async.} = + block: # then + let x = await fn(4) + .then((a: int) => a.float) + .then((a: float) => $a) + doAssert x == "14.0" + doAssert witness == @["(1, 11)", "(2, 12)", "(3, 13)", "(4, 14)"] + + doAssert (await fn(2)) == 12 + + let x2 = await fn(4).then((a: int) => (discard)).then(() => 13) + doAssert x2 == 13 + + let x4 = await asyncFact(3).then(asyncIdentity).then(asyncIdentity).then((a:int) => a * 7).then(asyncIdentity) + doAssert x4 == 3 * 2 * 7 + + block: # bug #17177 + proc asyncIdentityNested(n: int): Future[int] {.async.} = return n + let x5 = await asyncFact(3).then(asyncIdentityNested) + doAssert x5 == 3 * 2 + + when false: # xxx pending bug #17254 + let x6 = await asyncFact(3).then((a:int) {.async.} => a * 11) + doAssert x6 == 3 * 2 * 11 + + block: # catch + var reason: Error + await fn(6).then((a: int) => (witness.add $a)).catch((r: Error) => (reason = r)) + doAssert reason == nil + + await fn(7).then((a: int) => (discard)).catch((r: Error) => (reason = r)) + doAssert reason != nil + doAssert reason.name == "Error" + doAssert "foobar: 7" in $reason.message + echo "done" # justified here to make sure we're running this, since it's inside `async` + +discard main() diff --git a/tests/js/tasyncjs_bad.nim b/tests/js/tasyncjs_bad.nim new file mode 100644 index 000000000..b1e5a7bc3 --- /dev/null +++ b/tests/js/tasyncjs_bad.nim @@ -0,0 +1,22 @@ +discard """ + exitCode: 1 + outputsub: "Error: unhandled exception: foobar: 13" +""" + +# note: this needs `--unhandled-rejections=strict`, see D20210217T215950 + +import std/asyncjs +from std/sugar import `=>` + +proc fn(n: int): Future[int] {.async.} = + if n >= 7: raise newException(ValueError, "foobar: " & $n) + else: result = n + +proc main() {.async.} = + let x1 = await fn(6) + doAssert x1 == 6 + await fn(7).catch((a: Error) => (discard)) + let x3 = await fn(13) + doAssert false # shouldn't go here, should fail before + +discard main() diff --git a/tests/js/tasyncjs_fail.nim b/tests/js/tasyncjs_fail.nim deleted file mode 100644 index b1e5a7bc3..000000000 --- a/tests/js/tasyncjs_fail.nim +++ /dev/null @@ -1,22 +0,0 @@ -discard """ - exitCode: 1 - outputsub: "Error: unhandled exception: foobar: 13" -""" - -# note: this needs `--unhandled-rejections=strict`, see D20210217T215950 - -import std/asyncjs -from std/sugar import `=>` - -proc fn(n: int): Future[int] {.async.} = - if n >= 7: raise newException(ValueError, "foobar: " & $n) - else: result = n - -proc main() {.async.} = - let x1 = await fn(6) - doAssert x1 == 6 - await fn(7).catch((a: Error) => (discard)) - let x3 = await fn(13) - doAssert false # shouldn't go here, should fail before - -discard main() diff --git a/tests/js/tasyncjs_pragma.nim b/tests/js/tasyncjs_pragma.nim new file mode 100644 index 000000000..2b6f32e92 --- /dev/null +++ b/tests/js/tasyncjs_pragma.nim @@ -0,0 +1,29 @@ +discard """ + output: ''' +0 +t +''' +""" + +# xxx merge into tasyncjs.nim + +import asyncjs, macros + +macro f*(a: untyped): untyped = + assert a.kind == nnkProcDef + result = nnkProcDef.newTree(a.name, a[1], a[2], a.params, a.pragma, a[5], nnkStmtList.newTree()) + let call = quote: + echo 0 + result.body.add(call) + for child in a.body: + result.body.add(child) + #echo result.body.repr + +proc t* {.async, f.} = + echo "t" + +proc t0* {.async.} = + await t() + +discard t0() + -- cgit 1.4.1-2-gfad0