253 lines
6.6 KiB
TypeScript
253 lines
6.6 KiB
TypeScript
import {
|
|
afterAll,
|
|
afterEach,
|
|
beforeAll,
|
|
beforeEach,
|
|
describe,
|
|
expect,
|
|
it,
|
|
vi,
|
|
} from 'vitest';
|
|
|
|
import {
|
|
MediaHeightController,
|
|
SET_HEIGHT_DEBOUNCE_SECONDS,
|
|
} from '../../src/components-lib/media-height-controller';
|
|
import {
|
|
callMutationHandler,
|
|
callResizeHandler,
|
|
MutationObserverMock,
|
|
ResizeObserverMock,
|
|
} from '../test-utils';
|
|
|
|
// @vitest-environment jsdom
|
|
describe('MediaHeightController', () => {
|
|
beforeAll(() => {
|
|
vi.stubGlobal('MutationObserver', MutationObserverMock);
|
|
vi.stubGlobal('ResizeObserver', ResizeObserverMock);
|
|
});
|
|
|
|
afterAll(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
vi.useFakeTimers();
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
describe('should set height', () => {
|
|
it('should set height on selection', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
const child = document.createElement('div');
|
|
child.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 600,
|
|
});
|
|
root.appendChild(child);
|
|
|
|
controller.setRoot(root);
|
|
|
|
// Calling a second time has no effect.
|
|
controller.setRoot(root);
|
|
|
|
controller.setSelected(0);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe(`600px`);
|
|
});
|
|
|
|
it('should not set height without children', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
|
|
controller.setRoot(root);
|
|
|
|
controller.setSelected(10);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('');
|
|
});
|
|
|
|
it('should respond to resize observer of selected child', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
const child = document.createElement('div');
|
|
root.appendChild(child);
|
|
|
|
controller.setRoot(root);
|
|
controller.setSelected(0);
|
|
|
|
child.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 800,
|
|
});
|
|
|
|
callResizeHandler([
|
|
{
|
|
target: child,
|
|
height: 800,
|
|
width: 400,
|
|
},
|
|
]);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('800px');
|
|
});
|
|
|
|
it('should not respond to resize observer without a selected child', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
const child = document.createElement('div');
|
|
root.appendChild(child);
|
|
|
|
controller.setRoot(root);
|
|
|
|
child.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 800,
|
|
});
|
|
|
|
callResizeHandler([
|
|
{
|
|
target: child,
|
|
height: 800,
|
|
width: 400,
|
|
},
|
|
]);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('');
|
|
});
|
|
|
|
it('should respond to new children being added', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
const child_0 = document.createElement('div');
|
|
child_0.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 100,
|
|
});
|
|
root.appendChild(child_0);
|
|
|
|
controller.setRoot(root);
|
|
|
|
const child_1 = document.createElement('div');
|
|
child_1.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 200,
|
|
});
|
|
root.appendChild(child_1);
|
|
|
|
callMutationHandler();
|
|
|
|
controller.setSelected(1);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('200px');
|
|
});
|
|
|
|
it('should set height on recalculate', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
const child = document.createElement('div');
|
|
child.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 700,
|
|
});
|
|
root.appendChild(child);
|
|
|
|
controller.setRoot(root);
|
|
controller.setSelected(0);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('700px');
|
|
|
|
child.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 900,
|
|
});
|
|
|
|
controller.recalculate();
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('900px');
|
|
});
|
|
|
|
it('should not set height when the selected child has no height', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
const child = document.createElement('div');
|
|
child.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 0,
|
|
});
|
|
root.appendChild(child);
|
|
|
|
controller.setRoot(root);
|
|
controller.setSelected(0);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('');
|
|
});
|
|
|
|
it('should allow height to shrink when selected child is shorter', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
const root = document.createElement('div');
|
|
const child_0 = document.createElement('div');
|
|
child_0.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 750,
|
|
});
|
|
const child_1 = document.createElement('div');
|
|
child_1.getBoundingClientRect = vi.fn().mockReturnValue({
|
|
height: 562,
|
|
});
|
|
root.appendChild(child_0);
|
|
root.appendChild(child_1);
|
|
|
|
controller.setRoot(root);
|
|
controller.setSelected(0);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('750px');
|
|
|
|
controller.setSelected(1);
|
|
|
|
vi.advanceTimersByTime(SET_HEIGHT_DEBOUNCE_SECONDS * 1000);
|
|
|
|
expect(host.style.maxHeight).toBe('562px');
|
|
});
|
|
});
|
|
|
|
it('should destroy', () => {
|
|
const host = document.createElement('div');
|
|
const controller = new MediaHeightController(host, 'div');
|
|
|
|
controller.destroy();
|
|
|
|
// No observable effect.
|
|
});
|
|
});
|