detect-tab
Version:
A comprehensive tab detection and management library for web applications
132 lines (106 loc) • 3.6 kB
text/typescript
/**
* @jest-environment jsdom
*/
import {
isVisibilityAPISupported,
isBrowserSupported,
getVisibilityProperties,
debounce,
now,
formatDuration,
safeJSONParse,
isStorageAvailable
} from './utils';
describe('Utils', () => {
describe('isVisibilityAPISupported', () => {
it('should return true when document.visibilityState exists', () => {
expect(isVisibilityAPISupported()).toBe(true);
});
});
describe('isBrowserSupported', () => {
it('should return true in browser environment', () => {
expect(isBrowserSupported()).toBe(true);
});
});
describe('getVisibilityProperties', () => {
it('should return standard property names', () => {
const props = getVisibilityProperties();
expect(props.hidden).toBe('hidden');
expect(props.visibilityChange).toBe('visibilitychange');
});
});
describe('debounce', () => {
jest.useFakeTimers();
afterEach(() => {
jest.clearAllTimers();
});
it('should debounce function calls', () => {
const mockFn = jest.fn();
const debouncedFn = debounce(mockFn, 100);
debouncedFn();
debouncedFn();
debouncedFn();
expect(mockFn).not.toHaveBeenCalled();
jest.advanceTimersByTime(100);
expect(mockFn).toHaveBeenCalledTimes(1);
});
it('should pass arguments to debounced function', () => {
const mockFn = jest.fn();
const debouncedFn = debounce(mockFn, 100);
debouncedFn('arg1', 'arg2');
jest.advanceTimersByTime(100);
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');
});
});
describe('now', () => {
it('should return current timestamp', () => {
const timestamp = now();
expect(typeof timestamp).toBe('number');
expect(timestamp).toBeGreaterThan(0);
});
});
describe('formatDuration', () => {
it('should format seconds', () => {
expect(formatDuration(5000)).toBe('5s');
});
it('should format minutes and seconds', () => {
expect(formatDuration(65000)).toBe('1m 5s');
});
it('should format hours, minutes and seconds', () => {
expect(formatDuration(3665000)).toBe('1h 1m 5s');
});
it('should format days, hours, minutes and seconds', () => {
expect(formatDuration(90065000)).toBe('1d 1h 1m 5s');
});
});
describe('safeJSONParse', () => {
it('should parse valid JSON', () => {
const obj = { test: 'value' };
const result = safeJSONParse(JSON.stringify(obj), {});
expect(result).toEqual(obj);
});
it('should return fallback for invalid JSON', () => {
const fallback = { fallback: true };
const result = safeJSONParse('invalid json', fallback);
expect(result).toEqual(fallback);
});
it('should return fallback for null JSON', () => {
const fallback = { fallback: true };
const result = safeJSONParse('null', fallback);
expect(result).toEqual(fallback);
});
});
describe('isStorageAvailable', () => {
it('should return true when localStorage is available', () => {
expect(isStorageAvailable()).toBe(true);
});
it('should handle storage errors gracefully', () => {
const originalSetItem = Storage.prototype.setItem;
Storage.prototype.setItem = jest.fn(() => {
throw new Error('Storage error');
});
expect(isStorageAvailable()).toBe(false);
Storage.prototype.setItem = originalSetItem;
});
});
});