Skip to content

Commit

Permalink
removed unnecessary string concats on assert
Browse files Browse the repository at this point in the history
  • Loading branch information
oberblastmeister committed Mar 22, 2021
1 parent 73c4c81 commit fbdf03f
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 46 deletions.
6 changes: 4 additions & 2 deletions lua/plenary/async_lib/async.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ local execute = function(future, callback)
local stat = res[1]
local ret = {select(2, unpack(res))}

assert(stat, string.format("The coroutine failed with this message: %s", ret[1]))
if not stat then
error(string.format("The coroutine failed with this message: %s", ret[1]))
end

if co.status(thread) == "dead" then
(callback or function() end)(unpack(ret))
Expand All @@ -32,7 +34,7 @@ end
-- use with CPS function, creates future factory
-- must have argc for arity checking
M.wrap = function(func, argc)
assert(type(func) == "function", "type error :: expected func, got " .. type(func))
assert(type(func) == "function", "type error :: expected func")
assert(type(argc) == "number" or argc == "vararg", "expected argc to be a number or string literal 'vararg'")

return function(...)
Expand Down
33 changes: 14 additions & 19 deletions lua/plenary/async_lib/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,6 @@ M.id = async(function(...)
return ...
end)

M.thread_loop = function(thread, callback)
local idle = uv.new_idle()
idle:start(function()
local success = co.resume(thread)
assert(success, "Coroutine failed")

if co.status(thread) == "dead" then
idle:stop()
callback()
end
end)
end

M.thread_loop_async = a.wrap(M.thread_loop, 2)

M.yield_now = async(function()
Expand Down Expand Up @@ -164,11 +151,16 @@ M.channel = {}
M.channel.oneshot = function()
local val = nil
local saved_callback = nil
local done = false
local sended = false
local received = false

--- sender is not async
--- sends a value
local sender = function(...)
if sended then
error('Can only send once')
end

local args = {...}

if #args == 0 then
Expand All @@ -182,7 +174,7 @@ M.channel.oneshot = function()

if saved_callback then
saved_callback(unpack(val or args))
done = true
sended = true
else
val = args
end
Expand All @@ -191,14 +183,17 @@ M.channel.oneshot = function()
--- receiver is async
--- blocks until a value is received
local receiver = a.wrap(function(callback)
if done then
error('Oneshot channel can only send one value!')
return
if received then
error('Oneshot channel can only receive one value!')
end

if saved_callback then
error('Can only receive once')
end

if val then
received = true
callback(unpack(val))
done = true
else
saved_callback = callback
end
Expand Down
15 changes: 15 additions & 0 deletions tests/plenary/async_lib/async_spec.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
local a = require('plenary.async_lib')
local async, await = a.async, a.await
local await_all = a.await_all
local channel = a.util.channel
local protected = a.util.protected

local eq = function(a, b)
assert.are.same(a, b)
Expand Down Expand Up @@ -77,5 +79,18 @@ describe('async await', function()

a.block_on(main())
end)

it('should be able to protect a oneshot channel that was called twice', function ()
local main = async(function()
local tx, rx = channel.oneshot()
tx(true)
await(rx())
local stat, ret = await(protected(rx()))
eq(stat, false)
assert(ret:match('Oneshot channel can only receive one value!'))
end)

a.block_on(main())
end)
end)
end)
69 changes: 44 additions & 25 deletions tests/plenary/async_lib/channel_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,62 @@ local async = a.async
local await = a.await
local channel = a.util.channel
local runned = a.util.runned
local protected = a.util.protected

local eq = function(a, b)
assert.are.same(a, b)
end

describe('oneshot channel', function()
it('should work when rx is used first', runned(a.future(function()
local tx, rx = channel.oneshot()
end)

describe('channel', function()
describe('oneshot', function()
it('should work when rx is used first', runned(a.future(function()
local tx, rx = channel.oneshot()

a.run(a.future(function()
local got = await(rx())
eq("sent value", got)
end))

tx("sent value")
end)))

a.run(a.future(function()
local got = await(rx())
eq("sent value", got)
end))
it('should work when tx is used first', runned(a.future(function()
local tx, rx = channel.oneshot()

tx("sent value")
end)))
tx("sent value")

it('should work when tx is used first', runned(a.future(function()
local tx, rx = channel.oneshot()
a.run(a.future(function()
local got = await(rx())
eq("sent value", got)
end))
end)))

tx("sent value")
it('should work with multiple returns', runned(a.future(function()
local tx, rx = channel.oneshot()

a.run(a.future(function()
local got = await(rx())
eq("sent value", got)
end))
end)))
a.run(a.future(function()
local got, got2 = await(rx())
eq("sent value", got)
eq("another sent value", got2)
end))

it('should work with multiple returns', runned(a.future(function()
local tx, rx = channel.oneshot()
tx("sent value", "another sent value")
end)))

a.run(a.future(function()
local got, got2 = await(rx())
eq("sent value", got)
eq("another sent value", got2)
end))
it('should be able to protect a oneshot channel that was called twice', function ()
local main = async(function()
local tx, rx = channel.oneshot()
tx(true)
await(rx())
local stat, ret = await(protected(rx()))
eq(stat, false)
assert(ret:match('Oneshot channel can only receive one value!'))
end)

tx("sent value", "another sent value")
end)))
a.block_on(main())
end)
end)
end)

0 comments on commit fbdf03f

Please sign in to comment.