gitlab-org--gitlab-foss/spec/frontend/lib/utils/intersection_observer_spec.js

87 lines
2.3 KiB
JavaScript

import { create } from '~/lib/utils/intersection_observer';
describe('IntersectionObserver Utility', () => {
beforeAll(() => {
global.IntersectionObserver = class MockIntersectionObserver {
constructor(callback) {
this.callback = callback;
this.entries = [];
}
addEntry(entry) {
this.entries.push(entry);
}
trigger() {
this.callback(this.entries);
}
};
});
describe('create', () => {
describe('memoization', () => {
const options = { rootMargin: '1px 1px 1px 1px' };
let expectedOutput;
beforeEach(() => {
create.cache.clear();
expectedOutput = create(options);
});
it('returns the same Observer for the same options input', () => {
expect(expectedOutput.id).toBe(create(options).id);
});
it('creates a new Observer for unique input options', () => {
expect(expectedOutput.id).not.toBe(create({ rootMargin: '1px 2px 3px 4px' }));
});
it('creates a new Observer for the same input options in different object references', () => {
expect(expectedOutput.id).not.toBe(create({ rootMargin: '1px 1px 1px 1px' }));
});
});
});
describe('Observer behavior', () => {
let observer = null;
let id = null;
beforeEach(() => {
create.cache.clear();
({ observer, id } = create());
});
it.each`
isIntersecting | event
${false} | ${'IntersectionDisappear'}
${true} | ${'IntersectionAppear'}
`(
'should emit the correct event on the entry target based on the computed Intersection',
async ({ isIntersecting, event }) => {
const target = document.createElement('div');
observer.addEntry({ target, isIntersecting });
target.addEventListener(event, (e) => {
expect(e.detail.observer).toBe(id);
});
observer.trigger();
},
);
it('should always emit an Update event with the entry and the observer', () => {
const target = document.createElement('div');
const entry = { target };
observer.addEntry(entry);
target.addEventListener('IntersectionUpdate', (e) => {
expect(e.detail.observer).toBe(id);
expect(e.detail.entry).toStrictEqual(entry);
});
observer.trigger();
});
});
});