mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-23 23:50:36 +03:00
improve tests and prettier
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { push, each, from, indexOf, runEach } from 'support/utils/array';
|
||||
import { push, each, from, indexOf, runEach, isEmptyArray } from 'support/utils/array';
|
||||
|
||||
describe('array utilities', () => {
|
||||
describe('push', () => {
|
||||
@@ -306,4 +306,10 @@ describe('array utilities', () => {
|
||||
const idx = indexOf([1, 2, 3], 2);
|
||||
expect(idx).toBe(1);
|
||||
});
|
||||
|
||||
test('isEmptyArray', () => {
|
||||
expect(isEmptyArray([])).toBe(true);
|
||||
expect(isEmptyArray([1, 2, 3])).toBe(false);
|
||||
expect(isEmptyArray(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
import { noop, debounce } from 'support/utils/function';
|
||||
import { rAF } from 'support/compatibility/apis';
|
||||
|
||||
jest.mock('support/compatibility/apis', () => {
|
||||
const originalModule = jest.requireActual('support/compatibility/apis');
|
||||
return {
|
||||
...originalModule,
|
||||
rAF: jest.fn().mockImplementation((...args) => originalModule.rAF(...args)),
|
||||
};
|
||||
});
|
||||
|
||||
const mockSetTimeout = () => {
|
||||
const original = window.setTimeout;
|
||||
// @ts-ignore
|
||||
const setT = (window.setTimeout = jest.fn((...args) => original(...args)));
|
||||
return [
|
||||
setT,
|
||||
() => {
|
||||
window.setTimeout = original;
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-return-await
|
||||
const timeout = async (timeout = 100) => await new Promise((r) => setTimeout(r, timeout));
|
||||
|
||||
describe('function', () => {
|
||||
test('noop', () => {
|
||||
expect(typeof noop).toBe('function');
|
||||
expect(noop()).toBe(undefined);
|
||||
});
|
||||
|
||||
describe('debounce', () => {
|
||||
describe('timeout', () => {
|
||||
test('without timeout', () => {
|
||||
let i = 0;
|
||||
const [setT, unmockSetTimeout] = mockSetTimeout();
|
||||
const debouncedFn = debounce(() => {
|
||||
i += 1;
|
||||
});
|
||||
expect(rAF).not.toHaveBeenCalled();
|
||||
expect(setT).not.toHaveBeenCalled();
|
||||
debouncedFn();
|
||||
expect(rAF).not.toHaveBeenCalled();
|
||||
expect(setT).not.toHaveBeenCalled();
|
||||
expect(i).toBe(1);
|
||||
unmockSetTimeout();
|
||||
});
|
||||
|
||||
test('with timeout 0', async () => {
|
||||
let i = 0;
|
||||
const [setT, unmockSetTimeout] = mockSetTimeout();
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: 0 }
|
||||
);
|
||||
|
||||
expect(rAF).not.toHaveBeenCalled();
|
||||
expect(setT).not.toHaveBeenCalled();
|
||||
debouncedFn();
|
||||
expect(rAF).toHaveBeenCalledTimes(1);
|
||||
expect(setT).not.toHaveBeenCalled();
|
||||
expect(i).toBe(0);
|
||||
|
||||
await timeout();
|
||||
|
||||
expect(i).toBe(1);
|
||||
unmockSetTimeout();
|
||||
});
|
||||
|
||||
test('with timeout > 0', async () => {
|
||||
let i = 0;
|
||||
const [setT, unmockSetTimeout] = mockSetTimeout();
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: 1 }
|
||||
);
|
||||
|
||||
expect(rAF).not.toHaveBeenCalled();
|
||||
expect(setT).not.toHaveBeenCalled();
|
||||
debouncedFn();
|
||||
expect(rAF).not.toHaveBeenCalled();
|
||||
expect(setT).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(i).toBe(0);
|
||||
await timeout();
|
||||
expect(i).toBe(1);
|
||||
|
||||
unmockSetTimeout();
|
||||
});
|
||||
|
||||
test('with timeout > 0 and multiple calls', async () => {
|
||||
let i = 0;
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: 200 }
|
||||
);
|
||||
|
||||
debouncedFn();
|
||||
await timeout();
|
||||
expect(i).toBe(0);
|
||||
|
||||
debouncedFn();
|
||||
await timeout();
|
||||
expect(i).toBe(0);
|
||||
|
||||
debouncedFn();
|
||||
await timeout();
|
||||
expect(i).toBe(0);
|
||||
|
||||
debouncedFn();
|
||||
await timeout();
|
||||
expect(i).toBe(0);
|
||||
|
||||
debouncedFn();
|
||||
await timeout(300);
|
||||
expect(i).toBe(1);
|
||||
});
|
||||
|
||||
test('with timeout function', async () => {
|
||||
let i = 0;
|
||||
let timeoutMs = 200;
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: () => timeoutMs }
|
||||
);
|
||||
|
||||
debouncedFn();
|
||||
await timeout();
|
||||
expect(i).toBe(0);
|
||||
|
||||
timeoutMs = 1000;
|
||||
|
||||
debouncedFn();
|
||||
await timeout(500);
|
||||
expect(i).toBe(0);
|
||||
|
||||
await timeout(500);
|
||||
expect(i).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('maxDelay', () => {
|
||||
test('without maxDelay', async () => {
|
||||
let i = 0;
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: 100 }
|
||||
);
|
||||
debouncedFn();
|
||||
expect(i).toBe(0);
|
||||
|
||||
await timeout(150);
|
||||
|
||||
expect(i).toBe(1);
|
||||
});
|
||||
|
||||
test('with maxDelay and longer timeout', async () => {
|
||||
let i = 0;
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: 10000, _maxDelay: 100 }
|
||||
);
|
||||
debouncedFn();
|
||||
expect(i).toBe(0);
|
||||
|
||||
await timeout(150);
|
||||
|
||||
expect(i).toBe(1);
|
||||
});
|
||||
|
||||
test('with maxDelay and shorter timeout with multiple calls', async () => {
|
||||
let i = 0;
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: 200, _maxDelay: 500 }
|
||||
);
|
||||
debouncedFn();
|
||||
await timeout(150);
|
||||
expect(i).toBe(0);
|
||||
|
||||
debouncedFn();
|
||||
await timeout(150);
|
||||
|
||||
debouncedFn();
|
||||
await timeout(150);
|
||||
expect(i).toBe(0);
|
||||
|
||||
debouncedFn();
|
||||
await timeout(150);
|
||||
expect(i).toBe(1);
|
||||
});
|
||||
|
||||
test('with maxDelay function', async () => {
|
||||
let i = 0;
|
||||
let maxDelayMs = 300;
|
||||
const debouncedFn = debounce(
|
||||
() => {
|
||||
i += 1;
|
||||
},
|
||||
{ _timeout: 400, _maxDelay: () => maxDelayMs }
|
||||
);
|
||||
debouncedFn();
|
||||
expect(i).toBe(0);
|
||||
|
||||
await timeout();
|
||||
|
||||
debouncedFn();
|
||||
expect(i).toBe(0);
|
||||
|
||||
await timeout();
|
||||
|
||||
maxDelayMs = 800; // this delay will be applied in the next cycle, not instantly
|
||||
|
||||
debouncedFn();
|
||||
expect(i).toBe(0);
|
||||
|
||||
await timeout();
|
||||
|
||||
debouncedFn();
|
||||
expect(i).toBe(1); // max delay 300 invoked here
|
||||
|
||||
await timeout(300);
|
||||
|
||||
debouncedFn();
|
||||
expect(i).toBe(1);
|
||||
|
||||
await timeout(300);
|
||||
|
||||
debouncedFn();
|
||||
expect(i).toBe(1);
|
||||
|
||||
await timeout(300);
|
||||
|
||||
debouncedFn();
|
||||
expect(i).toBe(2); // max delay 800 invoked here
|
||||
});
|
||||
});
|
||||
|
||||
describe('mergeParams', () => {
|
||||
test('with correct mergeParams function', async () => {
|
||||
let i = 0;
|
||||
const _mergeParams = jest.fn((prev: [number, number], curr: [number, number]) => {
|
||||
const [prevA, prevB] = prev;
|
||||
const [currA, currB] = curr;
|
||||
|
||||
return [prevA + currA, prevB + currB] as [number, number];
|
||||
});
|
||||
const debouncedFn = debounce(
|
||||
(a: number, b: number) => {
|
||||
i += a * b;
|
||||
},
|
||||
{ _timeout: 200, _mergeParams }
|
||||
);
|
||||
debouncedFn(1, 1);
|
||||
expect(i).toBe(0);
|
||||
expect(_mergeParams).not.toHaveBeenCalled();
|
||||
|
||||
await timeout();
|
||||
|
||||
debouncedFn(4, 4);
|
||||
expect(i).toBe(0);
|
||||
expect(_mergeParams).toHaveBeenLastCalledWith([1, 1], [4, 4]);
|
||||
|
||||
await timeout();
|
||||
|
||||
debouncedFn(10, 10);
|
||||
expect(i).toBe(0);
|
||||
expect(_mergeParams).toHaveBeenLastCalledWith([5, 5], [10, 10]);
|
||||
|
||||
await timeout(250);
|
||||
|
||||
expect(i).toBe(15 * 15);
|
||||
});
|
||||
|
||||
test('without correct mergeParams function', async () => {
|
||||
let i = 0;
|
||||
const _mergeParams = jest.fn(() => null);
|
||||
const debouncedFn = debounce(
|
||||
(a, b) => {
|
||||
i += a * b;
|
||||
},
|
||||
{ _timeout: 200, _mergeParams }
|
||||
);
|
||||
debouncedFn(1, 1);
|
||||
expect(i).toBe(0);
|
||||
expect(_mergeParams).not.toHaveBeenCalled();
|
||||
|
||||
await timeout();
|
||||
|
||||
debouncedFn(2, 2);
|
||||
expect(i).toBe(0);
|
||||
expect(_mergeParams).toHaveBeenLastCalledWith([1, 1], [2, 2]);
|
||||
|
||||
await timeout();
|
||||
|
||||
debouncedFn(3, 3);
|
||||
expect(i).toBe(0);
|
||||
expect(_mergeParams).toHaveBeenLastCalledWith([2, 2], [3, 3]);
|
||||
|
||||
await timeout(250);
|
||||
|
||||
expect(i).toBe(3 * 3);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { getLexicon } from 'support/utils/lexicon';
|
||||
|
||||
describe('getLexicon', () => {
|
||||
test('Get vertical Lexicon', () => {
|
||||
const lexicon = getLexicon();
|
||||
expect(lexicon._widthHeight).toBe('height');
|
||||
expect(lexicon._WidthHeight).toBe('Height');
|
||||
expect(lexicon._leftTop).toBe('top');
|
||||
expect(lexicon._LeftTop).toBe('Top');
|
||||
expect(lexicon._xy).toBe('y');
|
||||
expect(lexicon._XY).toBe('Y');
|
||||
expect(lexicon._wh).toBe('h');
|
||||
expect(lexicon._lt).toBe('t');
|
||||
});
|
||||
|
||||
test('Get horizontal Lexicon', () => {
|
||||
const lexicon = getLexicon(true);
|
||||
expect(lexicon._widthHeight).toBe('width');
|
||||
expect(lexicon._WidthHeight).toBe('Width');
|
||||
expect(lexicon._leftTop).toBe('left');
|
||||
expect(lexicon._LeftTop).toBe('Left');
|
||||
expect(lexicon._xy).toBe('x');
|
||||
expect(lexicon._XY).toBe('X');
|
||||
expect(lexicon._wh).toBe('w');
|
||||
expect(lexicon._lt).toBe('l');
|
||||
});
|
||||
});
|
||||
@@ -154,8 +154,8 @@ const targetDomObserver = createDOMObserver(
|
||||
|
||||
const createContentDomOserver = (
|
||||
eventContentChange: Array<[string?, string?] | null | undefined>
|
||||
) => {
|
||||
return createDOMObserver(
|
||||
) =>
|
||||
createDOMObserver(
|
||||
trargetContentElm!,
|
||||
true,
|
||||
(contentChangedTroughEvent: boolean) => {
|
||||
@@ -188,7 +188,7 @@ const createContentDomOserver = (
|
||||
? liesBetween(target as Element, hostSelector, '.content')
|
||||
: false;
|
||||
},
|
||||
_ignoreNestedTargetChange: (target, attrName, oldValue, newValue) => {
|
||||
_ignoreNestedTargetChange: (_target, attrName, oldValue, newValue) => {
|
||||
if (attrName === 'class' && oldValue && newValue) {
|
||||
const diff = diffClass(oldValue, newValue);
|
||||
const ignore = diff.length === 1 && diff[0].startsWith(ignorePrefix);
|
||||
@@ -204,7 +204,6 @@ const createContentDomOserver = (
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
let contentDomObserver = createContentDomOserver(contentChange);
|
||||
|
||||
@@ -229,12 +228,10 @@ const changedThrough = <ChangeThrough extends DOMContentObserverResult | DOMTarg
|
||||
observationLists = [observationLists] as Array<ChangeThrough[]>;
|
||||
}
|
||||
|
||||
const getStats = (): Stat => {
|
||||
return {
|
||||
total: getTotalObservations(),
|
||||
lists: (observationLists as Array<ChangeThrough[]>).map((list) => [list, list.length]),
|
||||
};
|
||||
};
|
||||
const getStats = (): Stat => ({
|
||||
total: getTotalObservations(),
|
||||
lists: (observationLists as Array<ChangeThrough[]>).map((list) => [list, list.length]),
|
||||
});
|
||||
|
||||
return {
|
||||
before: () => {
|
||||
|
||||
Reference in New Issue
Block a user