mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			520 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			520 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) Meta Platforms, Inc. and affiliates.
 | |
|  *
 | |
|  * This source code is licensed under the MIT license found in the
 | |
|  * LICENSE file in the root directory of this source tree.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| import { test } from '../playwright-test/stable-test-runner';
 | |
| import { expect as expectUnderTest, asymmetricMatchers } from '../../packages/playwright/bundles/expect/src/expectBundleImpl';
 | |
| 
 | |
| const {
 | |
|   any,
 | |
|   anything,
 | |
|   arrayContaining,
 | |
|   arrayNotContaining,
 | |
|   closeTo,
 | |
|   notCloseTo,
 | |
|   objectContaining,
 | |
|   objectNotContaining,
 | |
|   stringContaining,
 | |
|   stringMatching,
 | |
|   stringNotContaining,
 | |
|   stringNotMatching,
 | |
| } = asymmetricMatchers;
 | |
| 
 | |
| test('Any.asymmetricMatch()', () => {
 | |
|   class Thing {}
 | |
| 
 | |
|   [
 | |
|     any(String).asymmetricMatch('jest'),
 | |
|     any(Number).asymmetricMatch(1),
 | |
|     any(Function).asymmetricMatch(() => {}),
 | |
|     any(Boolean).asymmetricMatch(true),
 | |
|     any(BigInt).asymmetricMatch(1n),
 | |
|     any(Symbol).asymmetricMatch(Symbol()),
 | |
|     any(Object).asymmetricMatch({}),
 | |
|     any(Object).asymmetricMatch(null),
 | |
|     any(Array).asymmetricMatch([]),
 | |
|     any(Thing).asymmetricMatch(new Thing()),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toBe(true);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('Any.asymmetricMatch() on primitive wrapper classes', () => {
 | |
|   [
 | |
| 
 | |
|     any(String).asymmetricMatch(new String('jest')),
 | |
| 
 | |
|     any(Number).asymmetricMatch(new Number(1)),
 | |
| 
 | |
|     any(Function).asymmetricMatch(new Function('() => {}')),
 | |
| 
 | |
|     any(Boolean).asymmetricMatch(new Boolean(true)),
 | |
|     any(BigInt).asymmetricMatch(Object(1n)),
 | |
|     any(Symbol).asymmetricMatch(Object(Symbol())),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toBe(true);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('Any.toAsymmetricMatcher()', () => {
 | |
|   expectUnderTest(any(Number).toAsymmetricMatcher()).toBe('Any<Number>');
 | |
| });
 | |
| 
 | |
| test('Any.toAsymmetricMatcher() with function name', () => {
 | |
|   [
 | |
|     ['someFunc', function someFunc() {}],
 | |
|     ['$someFunc', function $someFunc() {}],
 | |
|     [
 | |
|       '$someFunc2',
 | |
|       (function() {
 | |
|         function $someFunc2() {}
 | |
|         Object.defineProperty($someFunc2, 'name', { value: '' });
 | |
|         return $someFunc2;
 | |
|       })(),
 | |
|     ],
 | |
|     [
 | |
|       '$someAsyncFunc',
 | |
|       (function() {
 | |
|         async function $someAsyncFunc() {}
 | |
|         Object.defineProperty($someAsyncFunc, 'name', { value: '' });
 | |
|         return $someAsyncFunc;
 | |
|       })(),
 | |
|     ],
 | |
|     [
 | |
|       '$someGeneratorFunc',
 | |
|       (function() {
 | |
|         function* $someGeneratorFunc() {}
 | |
|         Object.defineProperty($someGeneratorFunc, 'name', { value: '' });
 | |
|         return $someGeneratorFunc;
 | |
|       })(),
 | |
|     ],
 | |
|     [
 | |
|       '$someFuncWithFakeToString',
 | |
|       (function() {
 | |
|         function $someFuncWithFakeToString() {}
 | |
|         $someFuncWithFakeToString.toString = () => 'Fake to string';
 | |
|         return $someFuncWithFakeToString;
 | |
|       })(),
 | |
|     ],
 | |
|   ].forEach(([name, fn]) => {
 | |
|     expectUnderTest(any(fn).toAsymmetricMatcher()).toBe(`Any<${name}>`);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('Any throws when called with empty constructor', () => {
 | |
|   // @ts-expect-error: Testing runtime error
 | |
|   expectUnderTest(() => any()).toThrow(
 | |
|       'any() expects to be passed a constructor function. Please pass one or use anything() to match any object.',
 | |
|   );
 | |
| });
 | |
| 
 | |
| test('Anything matches any type', () => {
 | |
|   [
 | |
|     anything().asymmetricMatch('jest'),
 | |
|     anything().asymmetricMatch(1),
 | |
|     anything().asymmetricMatch(() => {}),
 | |
|     anything().asymmetricMatch(true),
 | |
|     anything().asymmetricMatch({}),
 | |
|     anything().asymmetricMatch([]),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toBe(true);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('Anything does not match null and undefined', () => {
 | |
|   [
 | |
|     anything().asymmetricMatch(null),
 | |
|     anything().asymmetricMatch(undefined),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toBe(false);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('Anything.toAsymmetricMatcher()', () => {
 | |
|   expectUnderTest(anything().toAsymmetricMatcher()).toBe('Anything');
 | |
| });
 | |
| 
 | |
| test('ArrayContaining matches', () => {
 | |
|   [
 | |
|     arrayContaining([]).asymmetricMatch('jest'),
 | |
|     arrayContaining(['foo']).asymmetricMatch(['foo']),
 | |
|     arrayContaining(['foo']).asymmetricMatch(['foo', 'bar']),
 | |
|     arrayContaining([]).asymmetricMatch({}),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toEqual(true);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('ArrayContaining does not match', () => {
 | |
|   expectUnderTest(arrayContaining(['foo']).asymmetricMatch(['bar'])).toBe(false);
 | |
| });
 | |
| 
 | |
| test('ArrayContaining throws for non-arrays', () => {
 | |
|   expectUnderTest(() => {
 | |
|     // @ts-expect-error: Testing runtime error
 | |
|     arrayContaining('foo').asymmetricMatch([]);
 | |
|   }).toThrow("You must provide an array to ArrayContaining, not 'string'.");
 | |
| });
 | |
| 
 | |
| test('ArrayNotContaining matches', () => {
 | |
|   expectUnderTest(arrayNotContaining(['foo']).asymmetricMatch(['bar'])).toBe(true);
 | |
| });
 | |
| 
 | |
| test('ArrayNotContaining does not match', () => {
 | |
|   [
 | |
|     arrayNotContaining([]).asymmetricMatch('jest'),
 | |
|     arrayNotContaining(['foo']).asymmetricMatch(['foo']),
 | |
|     arrayNotContaining(['foo']).asymmetricMatch(['foo', 'bar']),
 | |
|     arrayNotContaining([]).asymmetricMatch({}),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toEqual(false);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('ArrayNotContaining throws for non-arrays', () => {
 | |
|   expectUnderTest(() => {
 | |
|     // @ts-expect-error: Testing runtime error
 | |
|     arrayNotContaining('foo').asymmetricMatch([]);
 | |
|   }).toThrow("You must provide an array to ArrayNotContaining, not 'string'.");
 | |
| });
 | |
| 
 | |
| test('ObjectContaining matches', () => {
 | |
|   const foo = Symbol('foo');
 | |
|   [
 | |
|     objectContaining({}).asymmetricMatch('jest'),
 | |
|     objectContaining({ foo: 'foo' }).asymmetricMatch({ foo: 'foo', jest: 'jest' }),
 | |
|     objectContaining({ foo: undefined }).asymmetricMatch({ foo: undefined }),
 | |
|     objectContaining({ first: objectContaining({ second: {} }) }).asymmetricMatch({
 | |
|       first: { second: {} },
 | |
|     }),
 | |
|     objectContaining({ foo: Buffer.from('foo') }).asymmetricMatch({
 | |
|       foo: Buffer.from('foo'),
 | |
|       jest: 'jest',
 | |
|     }),
 | |
|     objectContaining({ [foo]: 'foo' }).asymmetricMatch({ [foo]: 'foo' }),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toEqual(true);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('ObjectContaining does not match', () => {
 | |
|   const foo = Symbol('foo');
 | |
|   const bar = Symbol('bar');
 | |
|   [
 | |
|     objectContaining({ foo: 'foo' }).asymmetricMatch({ bar: 'bar' }),
 | |
|     objectContaining({ foo: 'foo' }).asymmetricMatch({ foo: 'foox' }),
 | |
|     objectContaining({ foo: undefined }).asymmetricMatch({}),
 | |
|     objectContaining({
 | |
|       answer: 42,
 | |
|       foo: { bar: 'baz', foobar: 'qux' },
 | |
|     }).asymmetricMatch({ foo: { bar: 'baz' } }),
 | |
|     objectContaining({ [foo]: 'foo' }).asymmetricMatch({ [bar]: 'bar' }),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toEqual(false);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('ObjectContaining matches defined properties', () => {
 | |
|   const definedPropertyObject = {};
 | |
|   Object.defineProperty(definedPropertyObject, 'foo', { get: () => 'bar' });
 | |
|   expectUnderTest(
 | |
|       objectContaining({ foo: 'bar' }).asymmetricMatch(definedPropertyObject),
 | |
|   ).toBe(true);
 | |
| });
 | |
| 
 | |
| test('ObjectContaining matches prototype properties', () => {
 | |
|   const prototypeObject = { foo: 'bar' };
 | |
|   let obj;
 | |
| 
 | |
|   if (Object.create) {
 | |
|     obj = Object.create(prototypeObject);
 | |
|   } else {
 | |
|     function Foo() {}
 | |
|     Foo.prototype = prototypeObject;
 | |
|     Foo.prototype.constructor = Foo;
 | |
|     obj = new (Foo as any)();
 | |
|   }
 | |
|   expectUnderTest(objectContaining({ foo: 'bar' }).asymmetricMatch(obj)).toBe(true);
 | |
| });
 | |
| 
 | |
| test('ObjectContaining throws for non-objects', () => {
 | |
|   // @ts-expect-error: Testing runtime error
 | |
|   expectUnderTest(() => objectContaining(1337).asymmetricMatch()).toThrow(
 | |
|       "You must provide an object to ObjectContaining, not 'number'.",
 | |
|   );
 | |
| });
 | |
| 
 | |
| test('ObjectContaining does not mutate the sample', () => {
 | |
|   const sample = { foo: { bar: {} } };
 | |
|   const sample_json = JSON.stringify(sample);
 | |
|   expectUnderTest({ foo: { bar: {} } }).toEqual(expectUnderTest.objectContaining(sample));
 | |
| 
 | |
|   expectUnderTest(JSON.stringify(sample)).toEqual(sample_json);
 | |
| });
 | |
| 
 | |
| test('ObjectNotContaining matches', () => {
 | |
|   const foo = Symbol('foo');
 | |
|   const bar = Symbol('bar');
 | |
|   [
 | |
|     objectContaining({}).asymmetricMatch(null),
 | |
|     objectContaining({}).asymmetricMatch(undefined),
 | |
|     objectNotContaining({ [foo]: 'foo' }).asymmetricMatch({ [bar]: 'bar' }),
 | |
|     objectNotContaining({ foo: 'foo' }).asymmetricMatch({ bar: 'bar' }),
 | |
|     objectNotContaining({ foo: 'foo' }).asymmetricMatch({ foo: 'foox' }),
 | |
|     objectNotContaining({ foo: undefined }).asymmetricMatch({}),
 | |
|     objectNotContaining({
 | |
|       first: objectNotContaining({ second: {} }),
 | |
|     }).asymmetricMatch({ first: { second: {} } }),
 | |
|     objectNotContaining({ first: { second: {}, third: {} } }).asymmetricMatch({
 | |
|       first: { second: {} },
 | |
|     }),
 | |
|     objectNotContaining({ first: { second: {} } }).asymmetricMatch({
 | |
|       first: { second: {}, third: {} },
 | |
|     }),
 | |
|     objectNotContaining({ foo: 'foo', jest: 'jest' }).asymmetricMatch({
 | |
|       foo: 'foo',
 | |
|     }),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toEqual(true);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('ObjectNotContaining does not match', () => {
 | |
|   [
 | |
|     objectNotContaining({}).asymmetricMatch('jest'),
 | |
|     objectNotContaining({ foo: 'foo' }).asymmetricMatch({
 | |
|       foo: 'foo',
 | |
|       jest: 'jest',
 | |
|     }),
 | |
|     objectNotContaining({ foo: undefined }).asymmetricMatch({ foo: undefined }),
 | |
|     objectNotContaining({ first: { second: {} } }).asymmetricMatch({
 | |
|       first: { second: {} },
 | |
|     }),
 | |
|     objectNotContaining({
 | |
|       first: objectContaining({ second: {} }),
 | |
|     }).asymmetricMatch({ first: { second: {} } }),
 | |
|     objectNotContaining({}).asymmetricMatch(null),
 | |
|     objectNotContaining({}).asymmetricMatch(undefined),
 | |
|     objectNotContaining({}).asymmetricMatch({}),
 | |
|   ].forEach(test => {
 | |
|     expectUnderTest(test).toEqual(false);
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('ObjectNotContaining inverts ObjectContaining', () => {
 | |
|   (
 | |
|     [
 | |
|       [{}, null],
 | |
|       [{ foo: 'foo' }, { foo: 'foo', jest: 'jest' }],
 | |
|       [{ foo: 'foo', jest: 'jest' }, { foo: 'foo' }],
 | |
|       [{ foo: undefined }, { foo: undefined }],
 | |
|       [{ foo: undefined }, {}],
 | |
|       [{ first: { second: {} } }, { first: { second: {} } }],
 | |
|       [{ first: objectContaining({ second: {} }) }, { first: { second: {} } }],
 | |
|       [{ first: objectNotContaining({ second: {} }) }, { first: { second: {} } }],
 | |
|       [{}, { foo: undefined }],
 | |
|     ] as const
 | |
|   ).forEach(([sample, received]) => {
 | |
|     expectUnderTest(objectNotContaining(sample).asymmetricMatch(received)).toEqual(
 | |
|         !objectContaining(sample).asymmetricMatch(received),
 | |
|     );
 | |
|   });
 | |
| });
 | |
| 
 | |
| test('ObjectNotContaining throws for non-objects', () => {
 | |
|   expectUnderTest(() => {
 | |
|     // @ts-expect-error: Testing runtime error
 | |
|     objectNotContaining(1337).asymmetricMatch();
 | |
|   }).toThrow(
 | |
|       "You must provide an object to ObjectNotContaining, not 'number'.",
 | |
|   );
 | |
| });
 | |
| 
 | |
| test('StringContaining matches string against string', () => {
 | |
|   expectUnderTest(stringContaining('en*').asymmetricMatch('queen*')).toBe(true);
 | |
|   expectUnderTest(stringContaining('en').asymmetricMatch('queue')).toBe(false);
 | |
| });
 | |
| 
 | |
| test('StringContaining throws if expected value is not string', () => {
 | |
|   expectUnderTest(() => {
 | |
|     // @ts-expect-error: Testing runtime error
 | |
|     stringContaining([1]).asymmetricMatch('queen');
 | |
|   }).toThrow('Expected is not a string');
 | |
| });
 | |
| 
 | |
| test('StringContaining returns false if received value is not string', () => {
 | |
|   expectUnderTest(stringContaining('en*').asymmetricMatch(1)).toBe(false);
 | |
| });
 | |
| 
 | |
| test('StringNotContaining matches string against string', () => {
 | |
|   expectUnderTest(stringNotContaining('en*').asymmetricMatch('queen*')).toBe(false);
 | |
|   expectUnderTest(stringNotContaining('en').asymmetricMatch('queue')).toBe(true);
 | |
| });
 | |
| 
 | |
| test('StringNotContaining throws if expected value is not string', () => {
 | |
|   expectUnderTest(() => {
 | |
|     // @ts-expect-error: Testing runtime error
 | |
|     stringNotContaining([1]).asymmetricMatch('queen');
 | |
|   }).toThrow('Expected is not a string');
 | |
| });
 | |
| 
 | |
| test('StringNotContaining returns true if received value is not string', () => {
 | |
|   expectUnderTest(stringNotContaining('en*').asymmetricMatch(1)).toBe(true);
 | |
| });
 | |
| 
 | |
| test('StringMatching matches string against regexp', () => {
 | |
|   expectUnderTest(stringMatching(/en/).asymmetricMatch('queen')).toBe(true);
 | |
|   expectUnderTest(stringMatching(/en/).asymmetricMatch('queue')).toBe(false);
 | |
| });
 | |
| 
 | |
| test('StringMatching matches string against string', () => {
 | |
|   expectUnderTest(stringMatching('en').asymmetricMatch('queen')).toBe(true);
 | |
|   expectUnderTest(stringMatching('en').asymmetricMatch('queue')).toBe(false);
 | |
| });
 | |
| 
 | |
| test('StringMatching throws if expected value is neither string nor regexp', () => {
 | |
|   expectUnderTest(() => {
 | |
|     // @ts-expect-error: Testing runtime error
 | |
|     stringMatching([1]).asymmetricMatch('queen');
 | |
|   }).toThrow('Expected is not a String or a RegExp');
 | |
| });
 | |
| 
 | |
| test('StringMatching returns false if received value is not string', () => {
 | |
|   expectUnderTest(stringMatching('en').asymmetricMatch(1)).toBe(false);
 | |
| });
 | |
| 
 | |
| test('StringMatching returns false even if coerced non-string received value matches pattern', () => {
 | |
|   expectUnderTest(stringMatching('null').asymmetricMatch(null)).toBe(false);
 | |
| });
 | |
| 
 | |
| test('StringNotMatching matches string against regexp', () => {
 | |
|   expectUnderTest(stringNotMatching(/en/).asymmetricMatch('queen')).toBe(false);
 | |
|   expectUnderTest(stringNotMatching(/en/).asymmetricMatch('queue')).toBe(true);
 | |
| });
 | |
| 
 | |
| test('StringNotMatching matches string against string', () => {
 | |
|   expectUnderTest(stringNotMatching('en').asymmetricMatch('queen')).toBe(false);
 | |
|   expectUnderTest(stringNotMatching('en').asymmetricMatch('queue')).toBe(true);
 | |
| });
 | |
| 
 | |
| test('StringNotMatching throws if expected value is neither string nor regexp', () => {
 | |
|   expectUnderTest(() => {
 | |
|     // @ts-expect-error: Testing runtime error
 | |
|     stringNotMatching([1]).asymmetricMatch('queen');
 | |
|   }).toThrow('Expected is not a String or a RegExp');
 | |
| });
 | |
| 
 | |
| test('StringNotMatching returns true if received value is not string', () => {
 | |
|   expectUnderTest(stringNotMatching('en').asymmetricMatch(1)).toBe(true);
 | |
| });
 | |
| 
 | |
| test.describe('closeTo', () => {
 | |
|   [
 | |
|     [0, 0],
 | |
|     [0, 0.001],
 | |
|     [1.23, 1.229],
 | |
|     [1.23, 1.226],
 | |
|     [1.23, 1.225],
 | |
|     [1.23, 1.234],
 | |
|     [Infinity, Infinity],
 | |
|     [-Infinity, -Infinity],
 | |
|   ].forEach(([expected, received]) => {
 | |
|     test(`${expected} closeTo ${received} return true`, () => {
 | |
|       expectUnderTest(closeTo(expected).asymmetricMatch(received)).toBe(true);
 | |
|     });
 | |
|     test(`${expected} notCloseTo ${received} return false`, () => {
 | |
|       expectUnderTest(notCloseTo(expected).asymmetricMatch(received)).toBe(false);
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   [
 | |
|     [0, 0.01],
 | |
|     [1, 1.23],
 | |
|     [1.23, 1.2249999],
 | |
|     [Infinity, -Infinity],
 | |
|     [Infinity, 1.23],
 | |
|     [-Infinity, -1.23],
 | |
|   ].forEach(([expected, received]) => {
 | |
|     test(`${expected} closeTo ${received} return false`, () => {
 | |
|       expectUnderTest(closeTo(expected).asymmetricMatch(received)).toBe(false);
 | |
|     });
 | |
|     test(`${expected} notCloseTo ${received} return true`, () => {
 | |
|       expectUnderTest(notCloseTo(expected).asymmetricMatch(received)).toBe(true);
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   [
 | |
|     [0, 0.1, 0],
 | |
|     [0, 0.0001, 3],
 | |
|     [0, 0.000004, 5],
 | |
|     [2.0000002, 2, 5],
 | |
|   ].forEach(([expected, received, precision]) => {
 | |
|     test(`${expected} closeTo ${received} with precision ${precision} return true`, () => {
 | |
|       expectUnderTest(closeTo(expected, precision).asymmetricMatch(received)).toBe(
 | |
|           true,
 | |
|       );
 | |
|     });
 | |
|     test(`${expected} notCloseTo ${received} with precision ${precision} return false`, () => {
 | |
|       expectUnderTest(
 | |
|           notCloseTo(expected, precision).asymmetricMatch(received),
 | |
|       ).toBe(false);
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   [
 | |
|     [3.141592e-7, 3e-7, 8],
 | |
|     [56789, 51234, -4],
 | |
|   ].forEach(([expected, received, precision]) => {
 | |
|     test(`${expected} closeTo ${received} with precision ${precision} return false`, () => {
 | |
|       expectUnderTest(closeTo(expected, precision).asymmetricMatch(received)).toBe(
 | |
|           false,
 | |
|       );
 | |
|     });
 | |
|     test(`${expected} notCloseTo ${received} with precision ${precision} return true`, () => {
 | |
|       expectUnderTest(
 | |
|           notCloseTo(expected, precision).asymmetricMatch(received),
 | |
|       ).toBe(true);
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   test('closeTo throw if expected is not number', () => {
 | |
|     expectUnderTest(() => {
 | |
|       // @ts-expect-error: Testing runtime error
 | |
|       closeTo('a');
 | |
|     }).toThrow('Expected is not a Number');
 | |
|   });
 | |
| 
 | |
|   test('notCloseTo throw if expected is not number', () => {
 | |
|     expectUnderTest(() => {
 | |
|       // @ts-expect-error: Testing runtime error
 | |
|       notCloseTo('a');
 | |
|     }).toThrow('Expected is not a Number');
 | |
|   });
 | |
| 
 | |
|   test('closeTo throw if precision is not number', () => {
 | |
|     expectUnderTest(() => {
 | |
|       // @ts-expect-error: Testing runtime error
 | |
|       closeTo(1, 'a');
 | |
|     }).toThrow('Precision is not a Number');
 | |
|   });
 | |
| 
 | |
|   test('notCloseTo throw if precision is not number', () => {
 | |
|     expectUnderTest(() => {
 | |
|       // @ts-expect-error: Testing runtime error
 | |
|       notCloseTo(1, 'a');
 | |
|     }).toThrow('Precision is not a Number');
 | |
|   });
 | |
| 
 | |
|   test('closeTo return false if received is not number', () => {
 | |
|     expectUnderTest(closeTo(1).asymmetricMatch('a')).toBe(false);
 | |
|   });
 | |
| 
 | |
|   test('notCloseTo return false if received is not number', () => {
 | |
|     expectUnderTest(notCloseTo(1).asymmetricMatch('a')).toBe(false);
 | |
|   });
 | |
| });
 | 
