diff --git a/eth-rpc/server/servertypes.nim b/eth-rpc/server/servertypes.nim index d68f244..063304a 100644 --- a/eth-rpc/server/servertypes.nim +++ b/eth-rpc/server/servertypes.nim @@ -19,38 +19,6 @@ proc register*(server: RpcServer, name: string, rpc: RpcProc) = proc unRegisterAll*(server: RpcServer) = server.procs.clear -macro rpc*(prc: untyped): untyped = - ## Converts a procedure into the following format: - ## *(params: JsonNode): Future[JsonNode] {.async.} - ## This procedure is then added into a compile-time list - ## so that it is automatically registered for every server that - ## calls registerRpcs(server) - prc.expectKind nnkProcDef - result = prc - let - params = prc.params - procName = prc.name - - procName.expectKind(nnkIdent) - - # check there isn't already a result type - assert params[0].kind == nnkEmpty - - # add parameter - params.add nnkIdentDefs.newTree( - newIdentNode("params"), - newIdentNode("JsonNode"), - newEmptyNode() - ) - # set result type - params[0] = nnkBracketExpr.newTree( - newIdentNode("Future"), - newIdentNode("JsonNode") - ) - # add async pragma; we can assume there isn't an existing .async. - # as this would mean there's a return type and fail the result check above. - prc.addPragma(newIdentNode("async")) - proc newRpcServer*(address = "localhost", port: Port = Port(8545)): RpcServer = result = RpcServer( socket: newAsyncSocket(), @@ -168,77 +136,3 @@ macro on*(server: var RpcServer, path: string, body: untyped): untyped = `server`.register(`path`, `procName`) when defined(nimDumpRpcs): echo "\n", pathStr, ": ", result.repr - -when isMainModule: - import unittest - var s = newRpcServer("localhost") - s.on("rpc.simplepath"): - result = %1 - s.on("rpc.returnint") do() -> int: - result = %2 - s.on("rpc.differentparams") do(a: int, b: string): - var node = %"test" - result = node - s.on("rpc.arrayparam") do(arr: array[0..5, byte], b: string): - var res = newJArray() - for item in arr: - res.add %int(item) - res.add %b - result = %res - s.on("rpc.seqparam") do(a: string, s: seq[int]): - var res = newJArray() - res.add %a - for item in s: - res.add %int(item) - result = res - - type - Test2 = object - x: array[0..2, int] - y: string - - Test = object - a: array[0..1, int] - b: Test2 - - MyObject* = object - a: int - b: Test - c: float - let - testObj = %*{ - "a": %1, - "b": %*{ - "a": %[5, 0], - "b": %*{ - "x": %[1, 2, 3], - "y": %"test" - } - }, - "c": %1.23} - - s.on("rpc.objparam") do(a: string, obj: MyObject): - result = %obj - suite "Server types": - test "On macro registration": - check s.procs.hasKey("rpc.simplepath") - check s.procs.hasKey("rpc.returnint") - check s.procs.hasKey("rpc.returnint") - test "Array/seq parameters": - let r1 = waitfor rpcArrayParam(%[%[1, 2, 3], %"hello"]) - var ckR1 = %[1, 2, 3, 0, 0, 0] - ckR1.elems.add %"hello" - check r1 == ckR1 - - let r2 = waitfor rpcSeqParam(%[%"abc", %[1, 2, 3, 4, 5]]) - var ckR2 = %["abc"] - for i in 0..4: ckR2.add %(i + 1) - check r2 == ckR2 - test "Object parameters": - let r = waitfor rpcObjParam(%[%"abc", testObj]) - check r == testObj - test "Runtime errors": - expect ValueError: - echo waitfor rpcArrayParam(%[%[0, 1, 2, 3, 4, 5, 6], %"hello"]) - - diff --git a/tests/testrpcmacro.nim b/tests/testrpcmacro.nim index c537eb9..5d8d1f5 100644 --- a/tests/testrpcmacro.nim +++ b/tests/testrpcmacro.nim @@ -1,53 +1,86 @@ import ../ eth-rpc / server / servertypes, unittest, asyncdispatch, json, tables +type + # some nested types to check object parsing + Test2 = object + x: array[0..2, int] + y: string + + Test = object + a: array[0..1, int] + b: Test2 + + MyObject* = object + a: int + b: Test + c: float +let + testObj = %*{ + "a": %1, + "b": %*{ + "a": %[5, 0], + "b": %*{ + "x": %[1, 2, 3], + "y": %"test" + } + }, + "c": %1.23} + var s = newRpcServer("localhost") + +# RPC definitions s.on("rpc.simplepath"): echo "hello3" result = %1 + s.on("rpc.returnint") do() -> int: echo "hello2" + s.on("rpc.differentparams") do(a: int, b: string): var node = %"test" result = node + s.on("rpc.arrayparam") do(arr: array[0..5, byte], b: string): var res = newJArray() for item in arr: res.add %int(item) res.add %b result = %res -s.on("rpc.seqparam") do(b: string, s: seq[int]): + +s.on("rpc.seqparam") do(a: string, s: seq[int]): var res = newJArray() - res.add %b + res.add %a for item in s: res.add %int(item) result = res -type MyObject* = object - a: int - b: string - c: float -s.on("rpc.objparam") do(b: string, obj: MyObject): + +s.on("rpc.objparam") do(a: string, obj: MyObject): result = %obj + +# Tests suite "Server types": + test "On macro registration": check s.procs.hasKey("rpc.simplepath") check s.procs.hasKey("rpc.returnint") check s.procs.hasKey("rpc.returnint") - test "Array/seq parameters": + + test "Array parameters": let r1 = waitfor rpcArrayParam(%[%[1, 2, 3], %"hello"]) var ckR1 = %[1, 2, 3, 0, 0, 0] ckR1.elems.add %"hello" check r1 == ckR1 + test "Seq parameters": let r2 = waitfor rpcSeqParam(%[%"abc", %[1, 2, 3, 4, 5]]) var ckR2 = %["abc"] for i in 0..4: ckR2.add %(i + 1) check r2 == ckR2 + test "Object parameters": - let - obj = %*{"a": %1, "b": %"hello", "c": %1.23} - r = waitfor rpcObjParam(%[%"abc", obj]) - check r == obj + let r = waitfor rpcObjParam(%[%"abc", testObj]) + check r == testObj + test "Runtime errors": expect ValueError: discard waitfor rpcArrayParam(%[%[0, 1, 2, 3, 4, 5, 6], %"hello"]) - # TODO: Add other errors \ No newline at end of file diff --git a/tests/testserverclient.nim b/tests/testserverclient.nim index fd32548..1a8da47 100644 --- a/tests/testserverclient.nim +++ b/tests/testserverclient.nim @@ -7,7 +7,6 @@ srv.address = "localhost" srv.port = Port(8545) srv.on("myProc") do(input: string, data: array[0..3, int]): - # Custom async RPC call result = %("Hello " & input & " data: " & $data) asyncCheck srv.serve @@ -25,6 +24,7 @@ suite "RPC": response = waitFor client.web3_sha3(%["abc"]) check response.result.getStr == "3A985DA74FE225B2045C172D6BD390BD855F086E3E9D525B46BFE24511431532" test "Custom RPC": + # Custom async RPC call response = waitFor client.call("myProc", %[%"abc", %[1, 2, 3, 4]]) check response.result.getStr == "Hello abc data: [1, 2, 3, 4]"