lunarmodules / luassert

Assertion library for Lua
MIT License
202 stars 77 forks source link

Error checking with varargs #98

Closed AdamBuchweitz closed 9 years ago

AdamBuchweitz commented 9 years ago

In my projects I like to write multiple errors in functions, especially for validating arguments. Currently there's no way to pass arguments into a function called with assert.has.error so it is not possible to test each error message. I would have submitted a pull request, but after reviewing the Guidelines for Contributing I thought I should check with the direction of the project before assuming this is something you would want to include.

The feature is trivial to implement, and I'm already using it in my own projects: src/assertions.lua: local ok, err_actual = pcall(func, table.unpack(arguments,3,arguments.n))

screen shot 2015-05-12 at 9 12 51 am

Hope you agree with it, and thanks!

mpeterv commented 9 years ago

Of course you could pass a closure calling the tested function with necessary arguments:

assert.has.error(function() f(arg1, arg2, arg3) end, error_message)
assert.has.error(function() f(another_arg) end, another_error_message)

But your suggestion makes it much easier. :+1:

o-lim commented 9 years ago

I think it's better to pass a closure like @mpeterv mentioned.

assert.has.error(function() f(arg1, arg2, arg3) end, expected_error_message)

It's straight forward and easy to read, and it's even how xpcall works.

The problem with using

local ok, err_actual = pcall(func, table.unpack(arguments,3,arguments.n))

is that it makes the calling convention non-intuitive because error_message is not one of the arguments being passed to func. When one sees assert.has.error(func, arg1, arg2, arg3) for the first time, one would most likely think "Hey, this looks just like pcall, it must work the same way too", but it doesn't because arg1 is not an argument to func but an argument to assert.has.error, which can lead to a lot of confusion. This is probably why xpcall requires you to pass a closure when you need to pass arguments.

mpeterv commented 9 years ago

This is probably why xpcall requires you to pass a closure when you need to pass arguments.

Only in Lua 5.1, both Lua 5.2+ and LuaJIT 2.0 accept additional arguments after error handler: http://www.lua.org/manual/5.2/manual.html#pdf-xpcall