|
| 1 | +local Job = require "plenary.job" |
| 2 | + |
| 3 | +local Timing = {} |
| 4 | + |
| 5 | +function Timing:log(name) |
| 6 | + self[name] = vim.loop.uptime() |
| 7 | +end |
| 8 | + |
| 9 | +function Timing:check(from, to, min_elapsed) |
| 10 | + assert(self[from], "did not log " .. from) |
| 11 | + assert(self[to], "did not log " .. to) |
| 12 | + local elapsed = self[to] - self[from] |
| 13 | + assert( |
| 14 | + min_elapsed <= elapsed, |
| 15 | + string.format("only took %s to get from %s to %s - expected at least %s", elapsed, from, to, min_elapsed) |
| 16 | + ) |
| 17 | +end |
| 18 | + |
| 19 | +describe("Async test", function() |
| 20 | + it("can resume testing with vim.defer_fn", function() |
| 21 | + local co = coroutine.running() |
| 22 | + assert(co, "not running inside a coroutine") |
| 23 | + |
| 24 | + local timing = setmetatable({}, { __index = Timing }) |
| 25 | + |
| 26 | + vim.defer_fn(function() |
| 27 | + coroutine.resume(co) |
| 28 | + end, 200) |
| 29 | + timing:log "before" |
| 30 | + coroutine.yield() |
| 31 | + timing:log "after" |
| 32 | + timing:check("before", "after", 0.1) |
| 33 | + end) |
| 34 | + |
| 35 | + it("can resume testing from job callback", function() |
| 36 | + local co = coroutine.running() |
| 37 | + assert(co, "not running inside a coroutine") |
| 38 | + |
| 39 | + local timing = setmetatable({}, { __index = Timing }) |
| 40 | + |
| 41 | + Job:new({ |
| 42 | + command = "bash", |
| 43 | + args = { |
| 44 | + "-ce", |
| 45 | + [[ |
| 46 | + sleep 0.2 |
| 47 | + echo hello |
| 48 | + sleep 0.2 |
| 49 | + echo world |
| 50 | + sleep 0.2 |
| 51 | + exit 42 |
| 52 | + ]], |
| 53 | + }, |
| 54 | + on_stdout = function(_, data) |
| 55 | + timing:log(data) |
| 56 | + end, |
| 57 | + on_exit = function(_, exit_status) |
| 58 | + timing:log "exit" |
| 59 | + --This is required so that the rest of the test will run in a proper context |
| 60 | + vim.schedule(function() |
| 61 | + coroutine.resume(co, exit_status) |
| 62 | + end) |
| 63 | + end, |
| 64 | + }):start() |
| 65 | + timing:log "job started" |
| 66 | + local exit_status = coroutine.yield() |
| 67 | + timing:log "job finished" |
| 68 | + assert.are.equal(exit_status, 42) |
| 69 | + |
| 70 | + timing:check("job started", "job finished", 0.3) |
| 71 | + timing:check("job started", "hello", 0.1) |
| 72 | + timing:check("hello", "world", 0.1) |
| 73 | + timing:check("world", "job finished", 0.1) |
| 74 | + end) |
| 75 | +end) |
0 commit comments