require("plenary.async").tests.add_to_env() local Semaphore = a.control.Semaphore local eq = assert.are.same describe("semaphore", function() a.it("should validate arguments", function() local status = pcall(Semaphore.new, -1) eq(status, false) local status = pcall(Semaphore.new) eq(status, false) end) a.it("should acquire a permit if available", function() local sem = Semaphore.new(1) local permit = sem:acquire() assert(permit ~= nil) end) a.it("should block if no permit is available", function() local sem = Semaphore.new(1) sem:acquire() local completed = false local blocking = function() sem:acquire() completed = true end a.run(blocking) eq(completed, false) end) a.it("should give another permit when an acquired permit is released", function() local sem = Semaphore.new(1) local permit = sem:acquire() permit:forget() local next_permit = sem:acquire() assert(next_permit ~= nil) end) a.it("should permit the next waiting client when a permit is released", function() local sem = Semaphore.new(1) local permit = sem:acquire() local completed = false local blocking = function() sem:acquire() completed = true end a.run(blocking) permit:forget() eq(completed, true) end) end)