Skip to content

Feature request: support async custom matchers in expect #3

@christopher-buss

Description

@christopher-buss

Description

It would be great to support custom matchers that return a Promise! Currently the throwingMatcher in src/expect/src/init.lua (lines 337-344) casts the result straight to SyncExpectationResult:

local ok, result = pcall(function(...)
	local potentialResult = matcher(matcherContext, actual, ...)
	local syncResult = potentialResult :: SyncExpectationResult
	processResult(syncResult)
end, ...)

Upstream Jest handles this by checking for a promise before processing the result
(jest/packages/expect/src/index.ts#L380).

A similar approach could look like:

local ok, result = pcall(function(...)
	local potentialResult = matcher(matcherContext, actual, ...)

	if isPromise(potentialResult) then
		local asyncError = JestAssertionError.new()
		if Error.captureStackTrace then
			Error.captureStackTrace(asyncError, throwingMatcher)
		end

		return potentialResult
			:andThen(function(aResult)
				return processResult(aResult, asyncError)
			end)
			:catch(handleError)
	else
		return processResult(potentialResult)
	end
end, ...)

Use case

I ran into this while porting jest-extended matchers — some upstream matchers return promises from custom matchers, and those don't resolve properly today.

Would love to be able to support these!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions