UNPKG

3.21 kBJavaScriptView Raw
1import { shallowMount } from '@vue/test-utils';
2import { useMockIntersectionObserver } from '~/utils/use_mock_intersection_observer';
3import GlIntersectionObserver from './intersection_observer.vue';
4
5const TEST_SLOT = '<p>Hello world! Lorem ipsum.</p>';
6const ENTRY_INTERSECTING = { ratio: 0.75, isIntersecting: true };
7const ENTRY_NOT_INTERSECTING = { ratio: 0, isIntersecting: false };
8const TEST_OPTIONS = {};
9
10describe('IntersectionObserver', () => {
11 let wrapper;
12 let allWrappers;
13 const { getInstances, trigger } = useMockIntersectionObserver();
14
15 const hasPrivateProps = (obj) => Object.keys(obj).some((x) => x.startsWith('$_gl_'));
16 const triggerIntersectionObserver = (entry) => {
17 trigger(getInstances()[0], null, { entry });
18 };
19 const createComponent = (props = {}) => {
20 wrapper = shallowMount(GlIntersectionObserver, {
21 propsData: {
22 ...props,
23 },
24 slots: {
25 default: TEST_SLOT,
26 },
27 });
28 allWrappers.push(wrapper);
29 };
30
31 beforeEach(() => {
32 allWrappers = [];
33 });
34
35 afterEach(() => {
36 allWrappers.forEach((x) => x.destroy());
37 allWrappers = null;
38 wrapper = null;
39
40 // Clear memoization for test determinism
41 GlIntersectionObserver.getObserver.cache.clear();
42 });
43
44 describe('with default', () => {
45 beforeEach(() => {
46 createComponent();
47 });
48
49 it('renders slot', () => {
50 expect(wrapper.html()).toContain(TEST_SLOT);
51 });
52
53 it('creates 1 intersection observer', () => {
54 expect(getInstances()).toHaveLength(1);
55 });
56
57 it('adds some private props to element', () => {
58 expect(hasPrivateProps(wrapper.vm.$el)).toBe(true);
59 });
60
61 describe('when destroyed', () => {
62 beforeEach(() => {
63 wrapper.destroy();
64 });
65
66 it('clears private props on element', () => {
67 expect(hasPrivateProps(wrapper.vm.$el)).toBe(false);
68 });
69
70 it('stops observing on element', () => {
71 triggerIntersectionObserver(ENTRY_INTERSECTING);
72
73 expect(wrapper.emitted()).toEqual({});
74 });
75 });
76 });
77
78 describe('with 2 instances', () => {
79 beforeEach(() => {
80 createComponent();
81 createComponent();
82 });
83
84 it('creates 1 IntersectionObserver', () => {
85 expect(getInstances()).toHaveLength(1);
86 });
87
88 it.each`
89 desc | entry | event
90 ${'with interesecting'} | ${ENTRY_INTERSECTING} | ${'appear'}
91 ${'without interesecting'} | ${ENTRY_NOT_INTERSECTING} | ${'disappear'}
92 `('when triggered $desc, emits events', ({ entry, event }) => {
93 const createExpectation = ({ element }) => ({
94 [event]: [[]],
95 update: [[{ ...entry, target: element }]],
96 });
97
98 triggerIntersectionObserver(entry);
99
100 expect(allWrappers).toHaveLength(2);
101 expect(allWrappers.map((x) => x.emitted())).toEqual(allWrappers.map(createExpectation));
102 });
103 });
104
105 describe('with 2 instances with different options', () => {
106 beforeEach(() => {
107 createComponent();
108 createComponent({ options: TEST_OPTIONS });
109 });
110
111 it('creates 2 IntersectionObservers', () => {
112 expect(getInstances()).toHaveLength(2);
113 });
114 });
115});