Roblox / testez

BDD-style test and assertion library for Roblox Lua
https://roblox.github.io/testez/
Apache License 2.0
183 stars 58 forks source link

Add expect.extend #142

Closed benbrimeyer closed 3 years ago

benbrimeyer commented 3 years ago

Heavily influenced by https://jestjs.io/docs/en/expect#expectextendmatchers

Adds expect.extend which allow projects to add their own matchers to TestEZ. Matchers are functions that should return an object with with two keys: boolean pass and a string message

-- spec.lua
describe("...", function()
  beforeAll(function()
    expect.extend({
      divisibleBy = function(receivedValue, expectedValue)
        local pass = receivedValue % expectedValue == 0
        if pass then
          return {
            pass = true,
            message = ("Expected %s to be divisible by %s"):format(receivedValue, expectedValue)
          }
        else
          return {
            pass = false,
            message = ("Expected %s not to be divisible by %s"):format(receivedValue, expectedValue)
          }
        end
      end,
    })
  end)

  it("should be an even number", function()
    expect(10).to.be.divisibleBy(2)
  end)
end)

This allows use cases to register their own, opinionated expectations that integrates into expect.

Cavets:

Since describe blocks are outside the usual test execution environment and exist primarily for planning, we do not have easy access to the test session's context, making supporting extend from describe blocks non-trival. Realistically we may want to consider throwing a helpful error when users attempt to call expect from describe blocks, since these assertions should not occur during planning.

If a custom matcher is over written, we will throw. This is to help catch collisions in larger projects which would otherwise lead to subtle, confusing errors.

If a custom matcher tries to overwrite a default matcher or protected field of Expectation, it will throw.