Make assert.has_error work with all kinds of errors

assert.has_error used to work by overriding the default error() function. Unfortunately this approach doesn't catch errors from assert(), internal Lua errors or any error thrown from C, which is very limiting.

This new implementation catches all errors and is almost always backwards compatible. It works exactly as before when the error is not of type string. In the common case when the error is a string, we can no longer make a direct equality comparison because the message will have been changed (augmented with filename/line/column, etc). The solution is to search if the expected message is contained in the actual message. This is more powerful than an equality comparison because it's possible to (optionally) test where the error occurred. It's very unlikely to break tests, and makes the assertion work with all kinds of errors.