import { Value, is, preserves } from '@preserves/core';

declare global {
    namespace jest {
        interface Matchers<R> {
            is<T>(expected: Value<T>): R;
            toThrowFilter(f: (e: Error) => boolean): R;
        }
    }
}

expect.extend({
    is(actual, expected) {
        return is(actual, expected)
            ? { message: () => preserves`expected ${actual} not to be Preserves.is to ${expected}`,
                pass: true }
            : { message: () => preserves`expected ${actual} to be Preserves.is to ${expected}`,
                pass: false };
    },

    toThrowFilter(thunk, f) {
        try {
            thunk();
            return { message: () => preserves`expected an exception`, pass: false };
        } catch (e) {
            if (f(e)) {
                return { message: () => preserves`expected an exception not matching the filter`,
                         pass: true };
            } else {
                return { message: () => preserves`expected an exception matching the filter: ${(e as any)?.constructor?.name}`,
                         pass: false };
            }
        }
    }
});
