diff options
Diffstat (limited to 'spec/frontend/lib/utils/intersection_observer_spec.js')
-rw-r--r-- | spec/frontend/lib/utils/intersection_observer_spec.js | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/spec/frontend/lib/utils/intersection_observer_spec.js b/spec/frontend/lib/utils/intersection_observer_spec.js new file mode 100644 index 00000000000..71b1daffe0d --- /dev/null +++ b/spec/frontend/lib/utils/intersection_observer_spec.js @@ -0,0 +1,86 @@ +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(); + }); + }); +}); |