import React from 'react'; import { mount } from 'enzyme'; import Anchor from '..'; import { spyElementPrototypes } from '../../__tests__/util/domHook'; import { sleep } from '../../../tests/utils'; const { Link } = Anchor; describe('Anchor Render', () => { const getBoundingClientRectMock = jest.fn(() => ({ width: 100, height: 100, top: 1000, })); const getClientRectsMock = jest.fn(() => ({ length: 1, })); const headingSpy = spyElementPrototypes(HTMLHeadingElement, { getBoundingClientRect: getBoundingClientRectMock, getClientRects: getClientRectsMock, }); afterAll(() => { headingSpy.mockRestore(); }); it('Anchor render perfectly', () => { const wrapper = mount( , ); wrapper.find('a[href="#API"]').simulate('click'); wrapper.instance().handleScroll(); expect(wrapper.instance().state).not.toBe(null); }); it('Anchor render perfectly for complete href - click', () => { const wrapper = mount( , ); wrapper.find('a[href="http://www.example.com/#API"]').simulate('click'); expect(wrapper.instance().state.activeLink).toBe('http://www.example.com/#API'); }); it('Anchor render perfectly for complete href - scroll', () => { let root = document.getElementById('root'); if (!root) { root = document.createElement('div', { id: 'root' }); root.id = 'root'; document.body.appendChild(root); } mount(
Hello
, { attachTo: root }); const wrapper = mount( , ); wrapper.instance().handleScroll(); expect(wrapper.instance().state.activeLink).toBe('http://www.example.com/#API'); }); it('Anchor render perfectly for complete href - scrollTo', async () => { const scrollToSpy = jest.spyOn(window, 'scrollTo'); let root = document.getElementById('root'); if (!root) { root = document.createElement('div', { id: 'root' }); root.id = 'root'; document.body.appendChild(root); } mount(
Hello
, { attachTo: root }); const wrapper = mount( , ); wrapper.instance().handleScrollTo('##API'); expect(wrapper.instance().state.activeLink).toBe('##API'); expect(scrollToSpy).not.toHaveBeenCalled(); await sleep(1000); expect(scrollToSpy).toHaveBeenCalled(); }); it('should remove listener when unmount', async () => { const wrapper = mount( , ); const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove'); wrapper.unmount(); expect(removeListenerSpy).toHaveBeenCalled(); }); it('should unregister link when unmount children', async () => { const wrapper = mount( , ); expect(wrapper.instance().links).toEqual(['#API']); wrapper.setProps({ children: null }); expect(wrapper.instance().links).toEqual([]); }); it('should update links when link href update', async () => { let anchorInstance = null; function AnchorUpdate({ href }) { return ( { anchorInstance = c; }} > ); } const wrapper = mount(); expect(anchorInstance.links).toEqual(['#API']); wrapper.setProps({ href: '#API_1' }); expect(anchorInstance.links).toEqual(['#API_1']); }); it('Anchor onClick event', () => { let event; let link; const handleClick = (...arg) => { [event, link] = arg; }; const href = '#API'; const title = 'API'; const wrapper = mount( , ); wrapper.find(`a[href="${href}"]`).simulate('click'); wrapper.instance().handleScroll(); expect(event).not.toBe(undefined); expect(link).toEqual({ href, title }); }); it('Different function returns the same DOM', async () => { let root = document.getElementById('root'); if (!root) { root = document.createElement('div', { id: 'root' }); root.id = 'root'; document.body.appendChild(root); } mount(
Hello
, { attachTo: root }); const getContainerA = () => { return document.getElementById('API'); }; const getContainerB = () => { return document.getElementById('API'); }; const wrapper = mount( , ); const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove'); await sleep(1000); wrapper.setProps({ getContainer: getContainerB }); expect(removeListenerSpy).not.toHaveBeenCalled(); }); it('Different function returns different DOM', async () => { let root = document.getElementById('root'); if (!root) { root = document.createElement('div', { id: 'root' }); root.id = 'root'; document.body.appendChild(root); } mount(
Hello
World
, { attachTo: root }, ); const getContainerA = () => { return document.getElementById('API1'); }; const getContainerB = () => { return document.getElementById('API2'); }; const wrapper = mount( , ); const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove'); expect(removeListenerSpy).not.toHaveBeenCalled(); await sleep(1000); wrapper.setProps({ getContainer: getContainerB }); expect(removeListenerSpy).toHaveBeenCalled(); }); it('Same function returns the same DOM', () => { let root = document.getElementById('root'); if (!root) { root = document.createElement('div', { id: 'root' }); root.id = 'root'; document.body.appendChild(root); } mount(
Hello
, { attachTo: root }); const getContainer = () => document.getElementById('API'); const wrapper = mount( , ); wrapper.find('a[href="#API"]').simulate('click'); wrapper.instance().handleScroll(); expect(wrapper.instance().state).not.toBe(null); }); it('Same function returns different DOM', async () => { let root = document.getElementById('root'); if (!root) { root = document.createElement('div', { id: 'root' }); root.id = 'root'; document.body.appendChild(root); } mount(
Hello
World
, { attachTo: root }, ); const holdContainer = { container: document.getElementById('API1'), }; const getContainer = () => { return holdContainer.container; }; const wrapper = mount( , ); const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove'); expect(removeListenerSpy).not.toHaveBeenCalled(); await sleep(1000); holdContainer.container = document.getElementById('API2'); wrapper.setProps({ 'data-only-trigger-re-render': true }); expect(removeListenerSpy).toHaveBeenCalled(); }); it('Anchor getCurrentAnchor prop', () => { const getCurrentAnchor = () => '#API2'; const wrapper = mount( , ); expect(wrapper.instance().state.activeLink).toBe('#API2'); }); it('Anchor targetOffset prop', () => { jest.useFakeTimers(); let dateNowMock; function dataNowMockFn() { let start = 0; const handler = () => { return (start += 1000); }; return jest.spyOn(Date, 'now').mockImplementation(handler); } dateNowMock = dataNowMockFn(); const scrollToSpy = jest.spyOn(window, 'scrollTo'); let root = document.getElementById('root'); if (!root) { root = document.createElement('div', { id: 'root' }); root.id = 'root'; document.body.appendChild(root); } mount(

Hello

, { attachTo: root }); const wrapper = mount( , ); wrapper.instance().handleScrollTo('#API'); jest.runAllTimers(); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000); dateNowMock = dataNowMockFn(); wrapper.setProps({ offsetTop: 100 }); wrapper.instance().handleScrollTo('#API'); jest.runAllTimers(); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900); dateNowMock = dataNowMockFn(); wrapper.setProps({ targetOffset: 200 }); wrapper.instance().handleScrollTo('#API'); jest.runAllTimers(); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800); dateNowMock.mockRestore(); jest.useRealTimers(); }); it('Anchor onChange prop', async () => { const onChange = jest.fn(); const wrapper = mount( , ); expect(onChange).toHaveBeenCalledTimes(1); wrapper.instance().handleScrollTo('#API2'); expect(onChange).toHaveBeenCalledTimes(2); expect(onChange).toHaveBeenCalledWith('#API2'); }); });