npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

goobs-testing

v0.2.2

Published

A robust testing toolkit for JavaScript and TypeScript projects, offering custom assertions, advanced mocking utilities, performance profiling, benchmarking tools, flexible logging options, and seamless integration with Jest and Husky for enhanced test-dr

Downloads

252

Readme

goobs-testing

A comprehensive collection of testing utilities for JavaScript and TypeScript projects.

Description

goobs-testing is a package that provides a set of utilities to enhance your testing workflow. It includes custom assertions, mocking utilities, performance measurement tools, benchmarking, and logging helpers. This package is designed to work seamlessly with Jest and TypeScript projects, and includes integration with Husky for pre-commit hooks.

Installation

To install the package, run:

npm install goobs-testing

or if you're using Yarn:

yarn add goobs-testing

To set up Husky for pre-commit hooks, run:

npx goobs-testing setup-husky

This will install Husky and set up a pre-commit hook to run your tests.

Modules and Usage

Assertions (assertions/index.ts)

Custom assertion functions to make your tests more readable and maintainable.

import {
  expectToBeWithinRange,
  expectToBeCloseToNow,
  expectToHaveBeenCalledOnceWith,
  expectToBeValidEmail,
  expectToBeNonEmptyString,
  expectToBePositiveNumber,
  expectToBeValidUUID,
  expectToHaveProperty,
  expectToBeEmptyArray,
  expectToBeNonEmptyArray,
  expectToBeTrue,
  expectToBeFalse,
  expectToBeNull,
  expectToBeUndefined,
  expectToBeNullOrUndefined,
  expectToThrowError,
  expectToBePromise,
  expectToBeDate,
  expectToBeSorted,
} from 'goobs-testing';

describe('Assertion Tests', () => {
  it('should be within range', () => {
    expectToBeWithinRange(5, 1, 10);
  });

  it('should be close to now', () => {
    expectToBeCloseToNow(new Date());
  });

  it('should have been called once with specific arguments', () => {
    const mock = jest.fn();
    mock('test');
    expectToHaveBeenCalledOnceWith(mock, 'test');
  });

  it('should be a valid email', () => {
    expectToBeValidEmail('[email protected]');
  });

  it('should be a non-empty string', () => {
    expectToBeNonEmptyString('test');
  });

  it('should be a positive number', () => {
    expectToBePositiveNumber(5);
  });

  it('should be a valid UUID', () => {
    expectToBeValidUUID('123e4567-e89b-12d3-a456-426614174000');
  });

  it('should have property', () => {
    expectToHaveProperty({ test: 'value' }, 'test');
  });

  it('should be an empty array', () => {
    expectToBeEmptyArray([]);
  });

  it('should be a non-empty array', () => {
    expectToBeNonEmptyArray([1, 2, 3]);
  });

  it('should be true', () => {
    expectToBeTrue(true);
  });

  it('should be false', () => {
    expectToBeFalse(false);
  });

  it('should be null', () => {
    expectToBeNull(null);
  });

  it('should be undefined', () => {
    expectToBeUndefined(undefined);
  });

  it('should be null or undefined', () => {
    expectToBeNullOrUndefined(null);
    expectToBeNullOrUndefined(undefined);
  });

  it('should throw error', () => {
    expectToThrowError(() => {
      throw new Error('Test error');
    });
  });

  it('should be a promise', () => {
    expectToBePromise(Promise.resolve());
  });

  it('should be a date', () => {
    expectToBeDate(new Date());
  });

  it('should be sorted', () => {
    expectToBeSorted([1, 2, 3, 4, 5]);
  });
});

Error Handling (error/index.ts)

Utilities for setting up global error handling in your tests.

import { setupErrorHandling, restoreConsoleError } from 'goobs-testing';

describe('Error Handling', () => {
  let teardown: () => void;

  beforeAll(() => {
    teardown = setupErrorHandling((message) => console.log(message));
  });

  afterAll(() => {
    teardown();
    restoreConsoleError();
  });

  it('should handle uncaught exception', () => {
    // This will be caught by the global error handler
    throw new Error('Uncaught exception');
  });

  it('should handle unhandled rejection', async () => {
    // This will be caught by the global error handler
    await Promise.reject(new Error('Unhandled rejection'));
  });
});

Logging (logging/index.ts)

Functions to assist with logging during test execution, including support for local logging and GitHub pre-commit logging.

import { setupLogging, logTestResults, closeLogStreams } from 'goobs-testing';

describe('Logging Tests', () => {
  let log: (message: string) => void;

  beforeAll(() => {
    log = setupLogging('test-log.txt', 'TestSuite');
  });

  afterAll(() => {
    closeLogStreams();
  });

  it('should log test results', () => {
    log('Test passed');
    // Assertions would go here
  });

  it('should log failed tests', () => {
    log('Test failed');
    // Assertions would go here
  });

  afterAll(() => {
    logTestResults(log, 1, 1, 2, 'TestSuite');
  });
});

Mocking (mock/index.ts)

Helper functions for mocking various JavaScript/TypeScript features.

import {
  mockPerformanceNow,
  realPerformanceNow,
  mockConsole,
  mockFetch,
  mockAsyncFunction,
  createMockEvent,
  mockLocalStorage,
  mockTimer,
  mockModule,
  mockEnvironment,
} from 'goobs-testing';

describe('Mocking Tests', () => {
  it('should mock performance.now', () => {
    const mockNow = mockPerformanceNow();
    expect(mockNow()).toBe(0);
    mockNow.advanceTime(100);
    expect(mockNow()).toBe(100);
  });

  it('should use real performance.now', () => {
    const now = realPerformanceNow();
    expect(typeof now).toBe('number');
  });

  it('should mock console', () => {
    const { mockLog, mockError, mockWarn, mockInfo } = mockConsole();
    console.log('test');
    expect(mockLog).toHaveBeenCalledWith('test');
  });

  it('should mock fetch', async () => {
    const mockFetchFn = mockFetch({ data: 'mocked data' });
    const response = await mockFetchFn('https://api.example.com');
    const data = await response.json();
    expect(data).toEqual({ data: 'mocked data' });
  });

  it('should mock async function', async () => {
    const mockAsync = mockAsyncFunction('result', 100);
    const result = await mockAsync();
    expect(result).toBe('result');
  });

  it('should create mock event', () => {
    const mockEvent = createMockEvent({ target: { value: 'test' } });
    expect(mockEvent.preventDefault).toBeDefined();
    expect(mockEvent.target.value).toBe('test');
  });

  it('should mock localStorage', () => {
    const mockStorage = mockLocalStorage();
    mockStorage.setItem('key', 'value');
    expect(mockStorage.getItem('key')).toBe('value');
  });

  it('should mock timer', () => {
    const { advanceTimersByTime, runAllTimers, clearAllTimers } = mockTimer();
    const callback = jest.fn();
    setTimeout(callback, 1000);
    advanceTimersByTime(1000);
    expect(callback).toHaveBeenCalled();
  });

  it('should mock module', () => {
    mockModule('fake-module', { fakeFunction: jest.fn() });
    const fakeModule = require('fake-module');
    fakeModule.fakeFunction();
    expect(fakeModule.fakeFunction).toHaveBeenCalled();
  });

  it('should mock environment', () => {
    mockEnvironment({ NODE_ENV: 'test' });
    expect(process.env.NODE_ENV).toBe('test');
  });
});

Performance Measurement (performance/index.ts)

Tools for measuring the performance of asynchronous functions.

import { measureAsyncExecutionTime, measureMultipleAsyncExecutionTimes } from 'goobs-testing';

describe('Performance Tests', () => {
  it('should measure async execution time', async () => {
    const time = await measureAsyncExecutionTime(async () => {
      await new Promise((resolve) => setTimeout(resolve, 100));
    });
    expect(time).toBeGreaterThanOrEqual(100);
  });

  it('should measure multiple async execution times', async () => {
    const times = await measureMultipleAsyncExecutionTimes(async () => {
      await new Promise((resolve) => setTimeout(resolve, 100));
    }, 3);
    expect(times.length).toBe(3);
    times.forEach((time) => {
      expect(time).toBeGreaterThanOrEqual(100);
    });
  });
});

Benchmarking (benchmark/index.ts)

Utilities for benchmarking functions and comparing their performance.

import { benchmark, compareBenchmarks, formatBenchmarkResults, runBenchmarks } from 'goobs-testing';

describe('Benchmark Tests', () => {
  it('should benchmark a function', async () => {
    const result = await benchmark(() => {
      for (let i = 0; i < 1000000; i++) {}
    });
    expect(typeof result).toBe('number');
  });

  it('should compare benchmarks', async () => {
    const results = await compareBenchmarks({
      slowFunction: () => {
        for (let i = 0; i < 1000000; i++) {}
      },
      fastFunction: () => {
        for (let i = 0; i < 100000; i++) {}
      },
    });
    expect(results.slowFunction).toBeGreaterThan(results.fastFunction);
  });

  it('should format benchmark results', () => {
    const results = {
      slowFunction: 10.5,
      fastFunction: 1.2,
    };
    const formatted = formatBenchmarkResults(results);
    expect(formatted).toContain('slowFunction: 10.5000 ms');
    expect(formatted).toContain('fastFunction: 1.2000 ms');
  });

  it('should run benchmarks and return formatted results', async () => {
    const results = await runBenchmarks({
      slowFunction: () => {
        for (let i = 0; i < 1000000; i++) {}
      },
      fastFunction: () => {
        for (let i = 0; i < 100000; i++) {}
      },
    });
    expect(results).toContain('Benchmark Results:');
    expect(results).toContain('slowFunction:');
    expect(results).toContain('fastFunction:');
  });
});

Full Example

Here's an example of how you might use multiple utilities from goobs-testing in a single test suite:

import {
  expectToBeWithinRange,
  mockFetch,
  measureAsyncExecutionTime,
  setupErrorHandling,
  setupLogging,
  logTestResults,
  closeLogStreams,
  benchmark,
} from 'goobs-testing';

describe('Comprehensive Test Suite', () => {
  let log: (message: string) => void;
  let teardown: () => void;

  beforeAll(() => {
    // Set up error handling
    teardown = setupErrorHandling((message) => console.error(message));

    // Set up logging
    log = setupLogging('comprehensive-test.log', 'ComprehensiveTestSuite');
  });

  afterAll(() => {
    teardown();
    closeLogStreams();
  });

  it('should perform a complex test scenario', async () => {
    // Use custom assertion
    expectToBeWithinRange(5, 1, 10);

    // Use mocking
    const mockFetchFn = mockFetch({ data: 'mocked data' });
    const response = await mockFetchFn('https://api.example.com');
    const data = await response.json();
    expect(data).toEqual({ data: 'mocked data' });

    // Measure performance
    const time = await measureAsyncExecutionTime(async () => {
      await new Promise((resolve) => setTimeout(resolve, 100));
    });
    expect(time).toBeGreaterThanOrEqual(100);

    // Benchmark a function
    const benchmarkResult = await benchmark(() => {
      for (let i = 0; i < 1000000; i++) {}
    });

    // Log results
    log(`Test completed in ${time}ms`);
    log(`Benchmark result: ${benchmarkResult}ms`);
  });

  afterAll(() => {
    logTestResults(log, 0, 1, 1, 'ComprehensiveTestSuite');
  });
});

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License.

Author

Matthew Goluba

Repository

https://github.com/goobz22/goobs-testing