import { tap } from '@push.rocks/tapbundle'; import * as smartexpect from '../ts/index.js'; tap.test('basic type assertions', async () => { // String type checks smartexpect.expect('hello').toBeTypeofString(); smartexpect.expect(1).not.toBeTypeofString(); // Boolean type checks smartexpect.expect(true).toBeTypeofBoolean(); smartexpect.expect(false).toBeTypeofBoolean(); smartexpect.expect(1).not.toBeTypeofBoolean(); // Number type checks smartexpect.expect(42).toBeTypeofNumber(); smartexpect.expect(true).not.toBeTypeofNumber(); // Generic type checks with new method smartexpect.expect(() => {}).toBeTypeOf('function'); smartexpect.expect(class Test {}).toBeTypeOf('function'); smartexpect.expect({}).toBeTypeOf('object'); smartexpect.expect(Symbol('test')).toBeTypeOf('symbol'); }); tap.test('async tests', async (toolsArg) => { const deferred = toolsArg.defer(); toolsArg.delayFor(1000).then(() => { deferred.resolve('hello'); }); await smartexpect.expectAsync(deferred.promise).timeout(2000).toBeTypeofString(); await smartexpect.expectAsync(deferred.promise).not.toBeTypeofBoolean(); // Test async timeout handling const longOperation = toolsArg.defer(); toolsArg.delayFor(3000).then(() => { longOperation.resolve('completed'); }); try { await smartexpect.expectAsync(longOperation.promise).timeout(1000).toBeDefined(); throw new Error('Should have timed out'); } catch (err) { // Expected timeout error console.log('Successfully caught timeout:', err.message); } }); tap.test('equality and matching assertions', async () => { // Basic equality smartexpect.expect('hithere').toEqual('hithere'); smartexpect.expect('hithere').not.toEqual('hithere2'); // Object equality const obj1 = { a: 1, b: { c: true } }; const obj2 = { a: 1, b: { c: true } }; const obj3 = { a: 1, b: { c: false } }; smartexpect.expect(obj1).toEqual(obj2); smartexpect.expect(obj1).not.toEqual(obj3); // RegExp matching smartexpect.expect('hithere').toMatch(/hi/); smartexpect.expect('hithere').toMatch(/^hithere$/); smartexpect.expect('hithere').not.toMatch(/ho/); // String inclusion smartexpect.expect('hithere').toInclude('hit'); smartexpect.expect('hithere').not.toInclude('missing'); // String start/end smartexpect.expect('hithere').toStartWith('hi'); smartexpect.expect('hithere').toEndWith('ere'); }); tap.test('object property assertions', async () => { const testObject = { topLevel: 'hello', nested: { prop: 42, deeplyNested: { array: [1, 2, 3], }, }, }; // Basic property checks smartexpect.expect(testObject).toHaveProperty('topLevel'); smartexpect.expect(testObject).toHaveProperty('topLevel', 'hello'); smartexpect.expect(testObject).not.toHaveProperty('missing'); // Drill-down property navigation smartexpect.expect(testObject).property('nested').toHaveProperty('prop', 42); smartexpect .expect(testObject) .property('nested') .property('deeplyNested') .property('array') .toBeArray(); // Deep property checks smartexpect.expect(testObject).toHaveDeepProperty(['nested', 'deeplyNested', 'array']); // Array item navigation smartexpect .expect(testObject) .property('nested') .property('deeplyNested') .property('array') .arrayItem(0) .toEqual(1); }); tap.test('numeric comparison assertions', async () => { // Greater/less than smartexpect.expect(4).toBeGreaterThan(3); smartexpect.expect(4).toBeLessThan(5); smartexpect.expect(4).toBeGreaterThanOrEqual(4); smartexpect.expect(4).toBeLessThanOrEqual(4); // Approximate equality smartexpect.expect(0.1 + 0.2).toBeCloseTo(0.3, 10); }); tap.test('array assertions', async () => { const obj1 = { id: 1 }; const obj2 = { id: 2 }; const testArray = [1, 'two', obj1, true]; // Basic array checks smartexpect.expect(testArray).toBeArray(); smartexpect.expect(testArray).toHaveLength(4); // Content checks smartexpect.expect(testArray).toContain('two'); smartexpect.expect(testArray).toContain(obj1); smartexpect.expect(testArray).not.toContain(obj2); // Array with equal items (not same reference) smartexpect.expect([{ a: 1 }, { b: 2 }]).toContainEqual({ a: 1 }); // Multiple values smartexpect.expect(testArray).toContainAll([1, 'two']); smartexpect.expect(testArray).toExclude('missing'); // Empty array smartexpect.expect([]).toBeEmptyArray(); // Length comparisons smartexpect.expect(testArray).toHaveLengthGreaterThan(3); smartexpect.expect(testArray).toHaveLengthLessThan(5); }); tap.test('boolean assertions', async () => { // True/False smartexpect.expect(true).toBeTrue(); smartexpect.expect(false).toBeFalse(); // Truthy/Falsy smartexpect.expect('something').toBeTruthy(); smartexpect.expect(0).toBeFalsy(); // Null/Undefined smartexpect.expect(null).toBeNull(); smartexpect.expect(undefined).toBeUndefined(); smartexpect.expect(null).toBeNullOrUndefined(); smartexpect.expect(undefined).toBeNullOrUndefined(); }); tap.test('function assertions', async () => { // Function that throws const throwingFn = () => { throw new Error('test error'); }; smartexpect.expect(throwingFn).toThrow(); smartexpect.expect(throwingFn).toThrow(Error); // Function that doesn't throw const nonThrowingFn = () => 'safe'; smartexpect.expect(nonThrowingFn).not.toThrow(); }); tap.test('date assertions', async () => { const now = new Date(); const past = new Date(Date.now() - 10000); const future = new Date(Date.now() + 10000); smartexpect.expect(now).toBeDate(); smartexpect.expect(now).toBeAfterDate(past); smartexpect.expect(now).toBeBeforeDate(future); }); tap.test('custom assertions', async () => { // Custom validation logic smartexpect.expect(42).customAssertion((value) => value % 2 === 0, 'Expected number to be even'); // With fail message smartexpect.expect('test').setFailMessage('Custom fail message for assertion').toHaveLength(4); }); tap.test('logging and debugging', async () => { // Using log() for debugging const complexObject = { level1: { level2: { value: 'nested value', }, }, }; // This logs the current value in the chain for debugging smartexpect .expect(complexObject) .property('level1') .property('level2') .log() .property('value') .toEqual('nested value'); }); export default tap.start();