mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Cb 5757 unit tests for core utils and core blocks (#2961)
* CB-5757 adds unit tests for getDomainFromUrl helper * CB-5757 adds unit tests for getTextFileReadingProcess helper * CB-5757 adds unit tests for TextTools helper * CB-5757 adds unit tests for downloadFromURL helper * CB-5757 adds unit tests for Deferred and PromiseExecutor * CB-5757 adds unit tests for core-blocks hooks * CB-5757 fixes the tests
This commit is contained in:
@@ -219,7 +219,6 @@ export * from './useClipboard.js';
|
||||
export * from './useCombinedHandler.js';
|
||||
export * from './useCombinedRef.js';
|
||||
export * from './useExecutor.js';
|
||||
export * from './useFn.js';
|
||||
export * from './useFocus.js';
|
||||
export * from './useFormValidator.js';
|
||||
export * from './ResourcesHooks/useOffsetPagination.js';
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
|
||||
import { useActivationDelay } from './useActivationDelay.js';
|
||||
|
||||
describe('useActivationDelay', () => {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should initially return false', () => {
|
||||
const { result } = renderHook(() => useActivationDelay(false, 1000));
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('should not change state before delay when activated', () => {
|
||||
const { result } = renderHook(() => useActivationDelay(true, 1000));
|
||||
|
||||
expect(result.current).toBe(false);
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(500);
|
||||
});
|
||||
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('should change state after delay when activated', () => {
|
||||
const { result } = renderHook(() => useActivationDelay(true, 1000));
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(1000);
|
||||
});
|
||||
|
||||
expect(result.current).toBe(true);
|
||||
});
|
||||
|
||||
it('should fire callback after delay when activated', () => {
|
||||
const callback = jest.fn();
|
||||
renderHook(() => useActivationDelay(true, 1000, callback));
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(1000);
|
||||
});
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should handle callback changes', () => {
|
||||
const initialCallback = jest.fn();
|
||||
const newCallback = jest.fn();
|
||||
|
||||
const { rerender } = renderHook(({ callback }) => useActivationDelay(true, 1000, callback), { initialProps: { callback: initialCallback } });
|
||||
|
||||
rerender({ callback: newCallback });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(1000);
|
||||
});
|
||||
|
||||
expect(initialCallback).not.toHaveBeenCalled();
|
||||
expect(newCallback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should clear timeout on unmount', () => {
|
||||
const callback = jest.fn();
|
||||
const { unmount } = renderHook(() => useActivationDelay(true, 1000, callback));
|
||||
|
||||
unmount();
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(1000);
|
||||
});
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not fire callback if delay changed', () => {
|
||||
const callback = jest.fn();
|
||||
const { rerender } = renderHook(({ delay }) => useActivationDelay(true, delay, callback), { initialProps: { delay: 1000 } });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(500);
|
||||
});
|
||||
|
||||
rerender({ delay: 2000 });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(1500);
|
||||
});
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should not fire callback when state changed to false', () => {
|
||||
const callback = jest.fn();
|
||||
const { rerender } = renderHook(({ state }) => useActivationDelay(state, 1000, callback), { initialProps: { state: true } });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(500);
|
||||
});
|
||||
|
||||
rerender({ state: false });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(500);
|
||||
});
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should handle rapid state changes', () => {
|
||||
const callback = jest.fn();
|
||||
const { rerender } = renderHook(({ state }) => useActivationDelay(state, 1000, callback), { initialProps: { state: true } });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(500);
|
||||
});
|
||||
|
||||
rerender({ state: false });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(100);
|
||||
});
|
||||
|
||||
rerender({ state: true });
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(1000);
|
||||
});
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should work with zero delay', () => {
|
||||
const callback = jest.fn();
|
||||
renderHook(() => useActivationDelay(true, 0, callback));
|
||||
|
||||
act(() => {
|
||||
jest.advanceTimersByTime(0);
|
||||
});
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { describe, expect, jest, test } from '@jest/globals';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
|
||||
import { useCombinedHandler } from './useCombinedHandler.js';
|
||||
|
||||
jest.mock('./useObjectRef', () => ({
|
||||
useObjectRef: jest.fn(value => value),
|
||||
}));
|
||||
|
||||
describe('useCombinedHandler', () => {
|
||||
test('should call all provided handlers', () => {
|
||||
const handler1 = jest.fn();
|
||||
const handler2 = jest.fn();
|
||||
|
||||
const { result } = renderHook(() => useCombinedHandler(handler1, handler2));
|
||||
|
||||
result.current('arg1', 'arg2');
|
||||
|
||||
expect(handler1).toHaveBeenCalledWith('arg1', 'arg2');
|
||||
expect(handler2).toHaveBeenCalledWith('arg1', 'arg2');
|
||||
});
|
||||
|
||||
test('should handle null and undefined handlers', () => {
|
||||
const { result } = renderHook(() => useCombinedHandler(null, undefined));
|
||||
|
||||
expect(() => result.current('testArg')).not.toThrow();
|
||||
});
|
||||
|
||||
test('should not fail when no handlers are provided', () => {
|
||||
const { result } = renderHook(() => useCombinedHandler());
|
||||
|
||||
expect(() => result.current()).not.toThrow();
|
||||
});
|
||||
|
||||
test('should allow the combined handler to be called multiple times', () => {
|
||||
const handler1 = jest.fn();
|
||||
const handler2 = jest.fn();
|
||||
|
||||
const { result } = renderHook(() => useCombinedHandler(handler1, handler2));
|
||||
|
||||
result.current('firstCall');
|
||||
result.current('secondCall');
|
||||
|
||||
expect(handler1).toHaveBeenNthCalledWith(1, 'firstCall');
|
||||
expect(handler1).toHaveBeenNthCalledWith(2, 'secondCall');
|
||||
|
||||
expect(handler2).toHaveBeenNthCalledWith(1, 'firstCall');
|
||||
expect(handler2).toHaveBeenNthCalledWith(2, 'secondCall');
|
||||
});
|
||||
|
||||
test('should work with asynchronous handlers', async () => {
|
||||
const handler1 = jest.fn(async arg => await Promise.resolve(arg));
|
||||
const handler2 = jest.fn(async arg => await Promise.resolve(arg));
|
||||
|
||||
const { result } = renderHook(() => useCombinedHandler(handler1, handler2));
|
||||
|
||||
result.current('asyncArg');
|
||||
|
||||
expect(handler1).toHaveBeenCalledWith('asyncArg');
|
||||
expect(handler2).toHaveBeenCalledWith('asyncArg');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { describe, expect, it, jest } from '@jest/globals';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { useCombinedRef } from './useCombinedRef.js';
|
||||
|
||||
describe('useCombinedRef', () => {
|
||||
it('should handle ref as function', () => {
|
||||
const callbackRef = jest.fn();
|
||||
const { result } = renderHook(() => useCombinedRef(callbackRef));
|
||||
|
||||
const testInstance = { test: true };
|
||||
|
||||
act(() => {
|
||||
result.current(testInstance);
|
||||
});
|
||||
|
||||
expect(callbackRef).toHaveBeenCalledWith(testInstance);
|
||||
});
|
||||
|
||||
it('should handle ref as RefObject', () => {
|
||||
const mutableRef = React.createRef();
|
||||
const { result } = renderHook(() => useCombinedRef(mutableRef));
|
||||
|
||||
const testInstance = { test: true };
|
||||
|
||||
act(() => {
|
||||
result.current(testInstance);
|
||||
});
|
||||
|
||||
expect(mutableRef.current).toBe(testInstance);
|
||||
});
|
||||
|
||||
it('should handle ref as null', () => {
|
||||
const { result } = renderHook(() => useCombinedRef(null));
|
||||
|
||||
const testInstance = { test: true };
|
||||
|
||||
expect(() => {
|
||||
act(() => {
|
||||
result.current(testInstance);
|
||||
});
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should handle multiple refs', () => {
|
||||
const callbackRef = jest.fn();
|
||||
const mutableRef = React.createRef();
|
||||
const anotherMutableRef = React.createRef();
|
||||
const { result } = renderHook(() => useCombinedRef(callbackRef, mutableRef, anotherMutableRef));
|
||||
|
||||
const testInstance = { test: true };
|
||||
|
||||
act(() => {
|
||||
result.current(testInstance);
|
||||
});
|
||||
|
||||
expect(callbackRef).toHaveBeenCalledWith(testInstance);
|
||||
expect(mutableRef.current).toBe(testInstance);
|
||||
expect(anotherMutableRef.current).toBe(testInstance);
|
||||
});
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { useCallback, useRef } from 'react';
|
||||
|
||||
const noop: any[] = [];
|
||||
|
||||
export function useFn<TArgs extends any[], TValue>(fn: (...args: TArgs) => TValue): (...args: TArgs) => TValue {
|
||||
const ref = useRef(fn);
|
||||
ref.current = fn;
|
||||
|
||||
return useCallback((...args: TArgs) => ref.current(...args), noop);
|
||||
}
|
||||
@@ -7,8 +7,6 @@
|
||||
*/
|
||||
import { action, computed, makeObservable, observable } from 'mobx';
|
||||
|
||||
import { errorOf } from '../errorOf.js';
|
||||
import { PromiseCancelledError } from './PromiseCancelledError.js';
|
||||
import { PromiseExecutor } from './PromiseExecutor.js';
|
||||
|
||||
export enum EDeferredState {
|
||||
@@ -111,20 +109,3 @@ export class Deferred<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class DeferredFromPromise<T> extends Deferred<T> {
|
||||
constructor(promise: Promise<T>) {
|
||||
super();
|
||||
promise.then(
|
||||
value => this.toResolved(value),
|
||||
err => {
|
||||
const promiseCancelledError = errorOf(err, PromiseCancelledError);
|
||||
if (promiseCancelledError) {
|
||||
this.toCancelled(promiseCancelledError.cause);
|
||||
} else {
|
||||
this.toRejected(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { beforeEach, describe, expect, it } from '@jest/globals';
|
||||
|
||||
import { PromiseExecutor } from './PromiseExecutor.js';
|
||||
|
||||
describe('PromiseExecutor', () => {
|
||||
let promiseExecutor: PromiseExecutor<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
promiseExecutor = new PromiseExecutor();
|
||||
});
|
||||
|
||||
it('should initialize with a promise', () => {
|
||||
expect(promiseExecutor.promise).toBeInstanceOf(Promise);
|
||||
});
|
||||
|
||||
it('should resolve the promise with the correct value', async () => {
|
||||
const testValue = 'resolved value';
|
||||
|
||||
promiseExecutor.resolve(testValue);
|
||||
|
||||
await expect(promiseExecutor.promise).resolves.toBe(testValue);
|
||||
});
|
||||
|
||||
it('should reject the promise with the correct reason', async () => {
|
||||
const testError = new Error('test error');
|
||||
|
||||
promiseExecutor.reject(testError);
|
||||
|
||||
await expect(promiseExecutor.promise).rejects.toBe(testError);
|
||||
});
|
||||
|
||||
it('should resolve with a PromiseLike object', async () => {
|
||||
const testPromiseLike = Promise.resolve('promise-like value');
|
||||
|
||||
promiseExecutor.resolve(testPromiseLike);
|
||||
|
||||
await expect(promiseExecutor.promise).resolves.toBe('promise-like value');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
|
||||
import { TextTools } from './TextTools.js';
|
||||
|
||||
const TEXT_WIDTH = 100;
|
||||
const LETTER_SPACING = 0.4;
|
||||
|
||||
function getLength(value: string): number {
|
||||
return TEXT_WIDTH + (value.length - 1) * LETTER_SPACING;
|
||||
}
|
||||
|
||||
describe('TextTools', () => {
|
||||
let mockContext: jest.Mocked<CanvasRenderingContext2D>;
|
||||
|
||||
beforeEach(() => {
|
||||
mockContext = {
|
||||
measureText: jest.fn().mockReturnValue({ width: TEXT_WIDTH }),
|
||||
font: '',
|
||||
} as unknown as jest.Mocked<CanvasRenderingContext2D>;
|
||||
|
||||
const mockCanvas = {
|
||||
getContext: jest.fn().mockReturnValue(mockContext),
|
||||
};
|
||||
|
||||
jest.spyOn(document, 'createElement').mockImplementation(() => mockCanvas as unknown as HTMLCanvasElement);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('getWidth', () => {
|
||||
it('should calculate width without container', () => {
|
||||
const options = {
|
||||
font: 'bold 16px Arial',
|
||||
text: ['Hello', 'World'],
|
||||
};
|
||||
|
||||
const result = TextTools.getWidth(options);
|
||||
|
||||
expect(mockContext.font).toBe('bold 16px Arial');
|
||||
expect(result).toEqual(options.text.map(getLength));
|
||||
expect(mockContext.measureText).toHaveBeenCalledTimes(options.text.length);
|
||||
});
|
||||
|
||||
it('should use container styles when provided', () => {
|
||||
const mockContainer = document.createElement('div');
|
||||
const mockStyles = {
|
||||
getPropertyValue: jest.fn().mockReturnValueOnce('bold').mockReturnValueOnce('16px').mockReturnValueOnce('Arial, sans'),
|
||||
};
|
||||
|
||||
jest.spyOn(window, 'getComputedStyle').mockReturnValue(mockStyles as unknown as CSSStyleDeclaration);
|
||||
|
||||
const options = {
|
||||
font: 'default',
|
||||
container: mockContainer,
|
||||
text: ['Test'],
|
||||
};
|
||||
|
||||
const result = TextTools.getWidth(options);
|
||||
|
||||
expect(mockContext.font).toBe('bold 16px Arial');
|
||||
expect(result).toEqual(options.text.map(getLength));
|
||||
});
|
||||
|
||||
it('should use provided font when container styles are incomplete', () => {
|
||||
const mockContainer = document.createElement('div');
|
||||
const mockStyles = {
|
||||
getPropertyValue: jest.fn().mockReturnValue(''),
|
||||
};
|
||||
|
||||
jest.spyOn(window, 'getComputedStyle').mockReturnValue(mockStyles as unknown as CSSStyleDeclaration);
|
||||
|
||||
const options = {
|
||||
font: 'italic 14px Times',
|
||||
container: mockContainer,
|
||||
text: ['Test'],
|
||||
};
|
||||
|
||||
const result = TextTools.getWidth(options);
|
||||
|
||||
expect(mockContext.font).toBe('italic 14px Times');
|
||||
expect(result).toEqual(options.text.map(getLength));
|
||||
});
|
||||
|
||||
it('should handle empty text array', () => {
|
||||
const options = {
|
||||
font: 'bold 16px Arial',
|
||||
text: [],
|
||||
};
|
||||
|
||||
const result = TextTools.getWidth(options);
|
||||
|
||||
expect(result).toEqual([]);
|
||||
expect(mockContext.measureText).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle single-character strings', () => {
|
||||
const options = {
|
||||
font: 'bold 16px Arial',
|
||||
text: ['A', 'B'],
|
||||
};
|
||||
|
||||
const result = TextTools.getWidth(options);
|
||||
|
||||
expect(result).toEqual(options.text.map(getLength));
|
||||
expect(mockContext.measureText).toHaveBeenCalledTimes(options.text.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
|
||||
import { downloadFromURL } from './downloadFromURL.js';
|
||||
|
||||
type MockXHR = {
|
||||
open: jest.Mock;
|
||||
send: jest.Mock;
|
||||
setRequestHeader: jest.Mock;
|
||||
responseType: string;
|
||||
onload: jest.Mock;
|
||||
onerror: jest.Mock;
|
||||
response: Blob | null;
|
||||
};
|
||||
|
||||
describe('downloadFromURL', () => {
|
||||
let mockXHR: MockXHR;
|
||||
|
||||
beforeEach(() => {
|
||||
mockXHR = {
|
||||
open: jest.fn(),
|
||||
send: jest.fn(),
|
||||
setRequestHeader: jest.fn(),
|
||||
responseType: '',
|
||||
onload: jest.fn(),
|
||||
onerror: jest.fn(),
|
||||
response: null,
|
||||
};
|
||||
|
||||
(global as any).XMLHttpRequest = jest.fn(() => mockXHR);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should open and send request to the specified URL', async () => {
|
||||
const url = 'http://example.com/test';
|
||||
downloadFromURL(url);
|
||||
|
||||
expect(mockXHR.open).toHaveBeenCalledWith('GET', url, true);
|
||||
expect(mockXHR.send).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should resolve with a Blob when the request is successful', async () => {
|
||||
const mockBlob = new Blob(['test'], { type: 'text/plain' });
|
||||
mockXHR.response = mockBlob;
|
||||
|
||||
setTimeout(() => {
|
||||
mockXHR.onload?.();
|
||||
}, 0);
|
||||
|
||||
const url = 'http://example.com/test';
|
||||
const result = await downloadFromURL(url);
|
||||
|
||||
expect(mockXHR.responseType).toBe('blob');
|
||||
expect(result).toBe(mockBlob);
|
||||
});
|
||||
|
||||
it('should reject with an error when the request fails', async () => {
|
||||
const mockError = new Error('Network error');
|
||||
|
||||
setTimeout(() => {
|
||||
mockXHR.onerror?.(mockError);
|
||||
}, 0);
|
||||
|
||||
const url = 'http://example.com/test';
|
||||
|
||||
await expect(downloadFromURL(url)).rejects.toThrow('Network error');
|
||||
expect(mockXHR.responseType).toBe('blob');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
|
||||
import { getTextFileReadingProcess } from './getTextFileReadingProcess.js';
|
||||
|
||||
describe('getTextFileReadingProcess', () => {
|
||||
let file: File;
|
||||
let mockFileReader: Partial<FileReader>;
|
||||
|
||||
beforeEach(() => {
|
||||
file = new File(['file content'], 'test.txt', { type: 'text/plain' });
|
||||
|
||||
mockFileReader = {
|
||||
readAsText: jest.fn(),
|
||||
onload: null,
|
||||
onerror: null,
|
||||
onabort: null,
|
||||
};
|
||||
|
||||
jest.spyOn(window, 'FileReader').mockImplementation(() => mockFileReader as FileReader);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should return correct instances', () => {
|
||||
const { promise, reader } = getTextFileReadingProcess(file);
|
||||
|
||||
expect(promise).toBeInstanceOf(Promise);
|
||||
expect(reader).toBe(mockFileReader);
|
||||
});
|
||||
|
||||
it('should resolve with file content on successful read', async () => {
|
||||
const { promise } = getTextFileReadingProcess(file);
|
||||
|
||||
(mockFileReader.onload as any)({
|
||||
target: { result: 'file content' },
|
||||
});
|
||||
|
||||
await expect(promise).resolves.toBe('file content');
|
||||
expect(mockFileReader.readAsText).toHaveBeenCalledWith(file);
|
||||
});
|
||||
|
||||
it('should reject with an error if file has no data', async () => {
|
||||
const { promise } = getTextFileReadingProcess(file);
|
||||
|
||||
const results = [null, undefined, ''];
|
||||
|
||||
for (const result of results) {
|
||||
(mockFileReader.onload as any)({
|
||||
target: { result: result },
|
||||
});
|
||||
|
||||
await expect(promise).rejects.toThrow(`No data for the file: "${file.name}"`);
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject with an error if reading fails', async () => {
|
||||
const { promise } = getTextFileReadingProcess(file);
|
||||
const error = new Error('Read error');
|
||||
|
||||
(mockFileReader.onerror as any)({
|
||||
target: { error: error },
|
||||
});
|
||||
|
||||
await expect(promise).rejects.toThrow(`Error occurred reading file: "${file.name}"`);
|
||||
});
|
||||
|
||||
it('should reject if the read is aborted', async () => {
|
||||
const { promise } = getTextFileReadingProcess(file);
|
||||
|
||||
(mockFileReader.onabort as any)();
|
||||
|
||||
await expect(promise).rejects.toThrow(`Reading "${file.name}" is aborted`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user