Skip to content

Commit

Permalink
feat: deprecation warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
Tieske committed Oct 9, 2020
1 parent fb9fc09 commit 1405a0d
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 0 deletions.
74 changes: 74 additions & 0 deletions lua/pl/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ local function _string_lambda(f)
end
end


--- an anonymous function as a string. This string is either of the form
-- '|args| expression' or is a function of one argument, '_'
-- @param lf function as a string
Expand Down Expand Up @@ -587,6 +588,7 @@ function utils.bind1 (fn,p)
return function(...) return fn(p,...) end
end


--- bind the second argument of the function to a value.
-- @param fn a function of at least two values (may be an operator string)
-- @param p a value
Expand All @@ -605,6 +607,78 @@ function utils.bind2 (fn,p)
return function(x,...) return fn(x,p,...) end
end




--- Deprecation
-- @section deprecation


--- A deprecation warning function, to be overridden.
-- An application can override this function to support proper output of
-- deprecation warnings. The warnings can be generated from libraries or
-- functions by calling `utils.raise_deprecation`. By default this function
-- doesn't do anything.
--
-- Note: only applications should override this function, libraries should not.
-- @string msg the message to display/log
-- @string trace the traceback from where the deprecated element was invoked
-- @usage
-- function utils.deprecation_warning(msg, trace)
-- io.stderr:write(msg .. "\n" .. trace .."\n")
-- end
function utils.deprecation_warning(msg, trace)
-- this does nothing by default
end


--- raises a deprecation warning.
-- For options see the usage example below.
--
-- Note: the `opts.version_deprecated` field is the last version in which
-- a feature or option was NOT YET deprecated! Because when writing the code it
-- is quite often not known in what version the code will land. But the last
-- released version is usually known.
-- @param opts options table
-- @see utils.deprecation_warning
-- @usage
-- function stringx.islower(str)
-- deprecation_warning {
-- source = "Penlight " .. utils._VERSION, -- optional
-- message = "function 'islower' was renamed to 'is_lower'" -- required
-- version_removed = "2.0.0", -- optional
-- version_deprecated = "1.2.3", -- optional
-- }
-- return stringx.is_lower(str)
-- end
-- -- output: "[Penlight 1.9.2] function 'islower' was renamed to 'is_lower' (deprecated after 1.2.3, scheduled for removal in 2.0.0)"
function utils.raise_deprecation(opts)
utils.assert_arg(1, opts, "table")
if type(opts.message) ~= "string" then
error("field 'message' of the options table must be a string", 2)
end
local trace = debug.traceback("", 2):match("[\n%s]*(.-)$")
local msg
if opts.version_deprecated and opts.version_removed then
msg = (" (deprecated after %s, scheduled for removal in %s)"):format(
tostring(opts.version_deprecated), tostring(opts.version_removed))
elseif opts.version_deprecated then
msg = (" (deprecated after %s)"):format(tostring(opts.version_deprecated))
elseif opts.version_removed then
msg = (" (scheduled for removal in %s)"):format(tostring(opts.version_removed))
else
msg = ""
end

msg = opts.message .. msg

if opts.source then
msg = "[" .. opts.source .."] " .. msg
end

utils.deprecation_warning(msg, trace)
end

return utils


102 changes: 102 additions & 0 deletions spec/utils-deprecate_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
local utils = require("pl.utils")

describe("pl.utils", function ()

local old_fn, last_msg, last_trace

before_each(function()
old_fn = utils.deprecation_warning
last_msg = nil
last_trace = nil
utils.deprecation_warning = function(msg, trace)
last_msg = msg
last_trace = trace
end
end)


after_each(function()
utils.deprecation_warning = old_fn
end)



describe("raise_deprecation", function ()

it("requires the opts table", function()
assert.has.error(function() utils.raise_deprecation(nil) end,
"argument 1 expected a 'table', got a 'nil'")
end)


it("requires the opts.message field", function()
assert.has.error(function() utils.raise_deprecation({}) end,
"field 'message' of the options table must be a string")
end)


it("should output the message", function ()
utils.raise_deprecation {
message = "hello world"
}
assert.equal("hello world", last_msg)
end)


it("should output the deprecated version", function ()
utils.raise_deprecation {
message = "hello world",
version_deprecated = "2.0.0",
}
assert.equal("hello world (deprecated after 2.0.0)", last_msg)
end)


it("should output the removal version", function ()
utils.raise_deprecation {
message = "hello world",
version_removed = "3.0.0",
}
assert.equal("hello world (scheduled for removal in 3.0.0)", last_msg)
end)


it("should output the deprecated and removal versions", function ()
utils.raise_deprecation {
message = "hello world",
version_deprecated = "2.0.0",
version_removed = "3.0.0",
}
assert.equal("hello world (deprecated after 2.0.0, scheduled for removal in 3.0.0)", last_msg)
end)


it("should output the application/module name", function ()
utils.raise_deprecation {
source = "MyApp 1.2.3",
message = "hello world",
version_deprecated = "2.0.0",
version_removed = "3.0.0",
}
assert.equal("[MyApp 1.2.3] hello world (deprecated after 2.0.0, scheduled for removal in 3.0.0)", last_msg)
end)


it("should add a stracktrace", function ()
local function my_function_name()
utils.raise_deprecation {
source = "MyApp 1.2.3",
message = "hello world",
version_deprecated = "2.0.0",
version_removed = "3.0.0",
}
end
my_function_name()

assert.Not.match("raise_deprecation", last_trace)
assert.match("my_function_name", last_trace)
end)

end)

end)

0 comments on commit 1405a0d

Please sign in to comment.