()
| 147 | |
| 148 | |
| 149 | def test_promises(): |
| 150 | # should throw RuntimeError if Promises are created outside a coroutine |
| 151 | create_promise = pm.eval("() => Promise.resolve(1)") |
| 152 | with pytest.raises(RuntimeError, |
| 153 | match="PythonMonkey cannot find a running Python event-loop to make asynchronous calls."): |
| 154 | create_promise() |
| 155 | |
| 156 | async def async_fn(): |
| 157 | create_promise() # inside a coroutine, no error |
| 158 | |
| 159 | # Python awaitables to JS Promise coercion |
| 160 | # 1. Python asyncio.Future to JS promise |
| 161 | loop = asyncio.get_running_loop() |
| 162 | f0 = loop.create_future() |
| 163 | f0.set_result(2561) |
| 164 | |
| 165 | assert type(f0) is asyncio.Future |
| 166 | assert 2561 == await f0 |
| 167 | assert pm.eval("(p) => p instanceof Promise")(f0) is True |
| 168 | assert 2561 == await pm.eval("(p) => p")(f0) |
| 169 | del f0 |
| 170 | |
| 171 | # 2. Python asyncio.Task to JS promise |
| 172 | async def coro_fn(x): |
| 173 | await asyncio.sleep(0.01) |
| 174 | return x |
| 175 | task = loop.create_task(coro_fn("from a Task")) |
| 176 | assert type(task) is asyncio.Task |
| 177 | assert type(task) is not asyncio.Future |
| 178 | assert isinstance(task, asyncio.Future) |
| 179 | assert "from a Task" == await task |
| 180 | assert pm.eval("(p) => p instanceof Promise")(task) is True |
| 181 | assert "from a Task" == await pm.eval("(p) => p")(task) |
| 182 | del task |
| 183 | |
| 184 | # 3. Python coroutine to JS promise |
| 185 | coro = coro_fn("from a Coroutine") |
| 186 | assert asyncio.iscoroutine(coro) |
| 187 | # assert "a Coroutine" == await coro # coroutines cannot be awaited more than once |
| 188 | # assert pm.eval("(p) => p instanceof Promise")(coro) # RuntimeError: cannot reuse already awaited coroutine |
| 189 | assert "from a Coroutine" == await pm.eval("(p) => (p instanceof Promise) && p")(coro) |
| 190 | del coro |
| 191 | |
| 192 | # JS Promise to Python awaitable coercion |
| 193 | assert 100 == await pm.eval("new Promise((r)=>{ r(100) })") |
| 194 | assert 10010 == await pm.eval("Promise.resolve(10010)") |
| 195 | with pytest.raises(pm.SpiderMonkeyError, match="^TypeError: (.|\\n)+ is not a constructor$"): |
| 196 | await pm.eval("Promise.resolve")(10086) |
| 197 | assert 10086 == await pm.eval("Promise.resolve.bind(Promise)")(10086) |
| 198 | |
| 199 | assert "promise returning a function" == (await pm.eval(""" |
| 200 | Promise.resolve(() => { |
| 201 | return 'promise returning a function'; |
| 202 | }); |
| 203 | """))() |
| 204 | assert "function 2" == (await pm.eval("Promise.resolve(x=>x)"))("function 2") |
| 205 | |
| 206 | def aaa(n): |
nothing calls this directly
no test coverage detected