parent
66666617e1
commit
504f581182
@ -1,16 +1,18 @@ |
|||||||
import { describe, expect, it } from '@jest/globals'; |
import { describe, expect, it } from '@jest/globals'; |
||||||
import { _, cnst, fromNative, id, toNative } from '../src/core'; |
import { _, cnst, fromNative, id, toNative, undef } from '../src/core'; |
||||||
|
|
||||||
describe('id', () => { |
describe('id', () => { |
||||||
it('returns first argument', () => { |
it('returns first argument', () => { |
||||||
expect(id).toDeferEvaluationOf('first'); |
|
||||||
expect(toNative(id._(fromNative('first')))).toBe('first'); |
expect(toNative(id._(fromNative('first')))).toBe('first'); |
||||||
}); |
}); |
||||||
}); |
}); |
||||||
|
|
||||||
describe('cnst', () => { |
describe('cnst', () => { |
||||||
it('returns first argument after receiving second', () => { |
it('returns first argument after receiving second', () => { |
||||||
expect(cnst).toDeferEvaluationOf('first', expect.skipped(fromNative('second'))); |
|
||||||
expect(toNative(cnst._(fromNative('first'))._(fromNative('second')))).toBe('first'); |
expect(toNative(cnst._(fromNative('first'))._(fromNative('second')))).toBe('first'); |
||||||
}); |
}); |
||||||
|
|
||||||
|
it('ignores second argument', () => { |
||||||
|
expect(toNative(cnst._(fromNative('first'))._(undef))).toBe('first'); |
||||||
|
}); |
||||||
}); |
}); |
||||||
|
|||||||
@ -1,99 +0,0 @@ |
|||||||
import { expect } from '@jest/globals'; |
|
||||||
import type { MatcherFunction } from 'expect'; |
|
||||||
import { L, P, _, fromNative } from '../src/core'; |
|
||||||
|
|
||||||
class Deferrable<T extends P> { |
|
||||||
constructor( |
|
||||||
public readonly when: 'always' | 'deferred' | 'never', |
|
||||||
public readonly what: T) { } |
|
||||||
} |
|
||||||
|
|
||||||
const toEvaluateTo: MatcherFunction<[expected: unknown]> = |
|
||||||
function (actual, expected) { |
|
||||||
if (!(actual instanceof L)) { |
|
||||||
throw new TypeError('Actual must be of type Lazy!'); |
|
||||||
} |
|
||||||
if (this.equals(fromNative(actual), expected)) { |
|
||||||
return { |
|
||||||
message: () => `expected ${this.utils.printReceived(fromNative(actual))} not to evaluate to ${this.utils.printExpected(expected)}`, |
|
||||||
pass: true, |
|
||||||
}; |
|
||||||
} else { |
|
||||||
return { |
|
||||||
message: () => `expected ${this.utils.printReceived(fromNative(actual))} to evaluate to ${this.utils.printExpected(expected)}`, |
|
||||||
pass: false, |
|
||||||
}; |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
const toDeferEvaluationOf: MatcherFunction<(unknown | Deferrable<P>)[]> = |
|
||||||
function (actual, ...args) { |
|
||||||
while (actual instanceof L) { |
|
||||||
actual = actual.value; |
|
||||||
} |
|
||||||
if (typeof actual !== 'function') { |
|
||||||
throw new TypeError('Actual must be of type function!'); |
|
||||||
} |
|
||||||
if (this.isNot) { |
|
||||||
throw new TypeError('`toDeferEvaluationOf` can not be `not`ted, use `always`/`deferred`/`never` on arguments!'); |
|
||||||
} |
|
||||||
const largs: Deferrable<P>[] = args.map(v => |
|
||||||
v instanceof Deferrable ? v |
|
||||||
: v instanceof L ? new Deferrable('deferred', _(v.value)) |
|
||||||
: new Deferrable('deferred', _(v as any))); |
|
||||||
const cargs: Deferrable<P>[] = []; |
|
||||||
let result = actual; |
|
||||||
for (const la of largs) { |
|
||||||
result = result instanceof L ? result._(la.what) : result(la.what); |
|
||||||
cargs.push(la); |
|
||||||
const mismatchingArg: Deferrable<P> | undefined = cargs.find(v => v.when === 'always' ? !v.what.evaluated : v.what.evaluated); |
|
||||||
if (mismatchingArg) { |
|
||||||
return { |
|
||||||
message: () => |
|
||||||
mismatchingArg.when === 'always' |
|
||||||
? `expected ${this.utils.printExpected(actual.name)} to evaluate ${this.utils.printReceived(`${largs.indexOf(mismatchingArg) + 1}th argument`)} immediately` |
|
||||||
: `expected ${this.utils.printExpected(actual.name)} not to evaluate ${this.utils.printReceived(`${largs.indexOf(mismatchingArg) + 1}th argument`)} immediately`, |
|
||||||
pass: false, |
|
||||||
}; |
|
||||||
} |
|
||||||
} |
|
||||||
if (!(result instanceof L)) { |
|
||||||
throw new TypeError('Actual did not resolve to value, more arguments expected.'); |
|
||||||
} |
|
||||||
(() => result.value)(); |
|
||||||
const mismatchingArg: Deferrable<P> | undefined = cargs.find(v => v.when === 'never' && v.what.evaluated); |
|
||||||
if (mismatchingArg) { |
|
||||||
return { |
|
||||||
message: () => `expected ${this.utils.printExpected(actual.name)} not to evaluate ${this.utils.printReceived(`${largs.indexOf(mismatchingArg) + 1}th argument`)}`, |
|
||||||
pass: false, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
return { |
|
||||||
message: () => `expected ${this.utils.printExpected('toDeferEvaluationOf')} to ${this.utils.printReceived('fail')}`, |
|
||||||
pass: true, |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
expect.extend({ |
|
||||||
toEvaluateTo, |
|
||||||
toDeferEvaluationOf, |
|
||||||
}); |
|
||||||
|
|
||||||
expect.evaluated = (v) => new Deferrable('always', _(v.value) as any); |
|
||||||
expect.deferred = (v) => new Deferrable('deferred', _(v.value) as any); |
|
||||||
expect.skipped = (v) => new Deferrable('never', _(v.value) as any); |
|
||||||
|
|
||||||
declare module 'expect' { |
|
||||||
interface AsymmetricMatchers { |
|
||||||
evaluated<T extends P>(value: T): Deferrable<T>; |
|
||||||
deferred<T extends P>(value: T): Deferrable<T>; |
|
||||||
skipped<T extends P>(value: T): Deferrable<T>; |
|
||||||
toEvaluateTo(value: any): void; |
|
||||||
toDeferEvaluationOf(...args: any[]): void; |
|
||||||
} |
|
||||||
interface Matchers<R> { |
|
||||||
toEvaluateTo(value: any): R; |
|
||||||
toDeferEvaluationOf(...args: any[]): R; |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue