import hljs from 'highlight.js/lib/core'; import Vue, { nextTick } from 'vue'; import VueRouter from 'vue-router'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import SourceViewer from '~/vue_shared/components/source_viewer.vue'; import LineNumbers from '~/vue_shared/components/line_numbers.vue'; import waitForPromises from 'helpers/wait_for_promises'; jest.mock('highlight.js/lib/core'); Vue.use(VueRouter); const router = new VueRouter(); describe('Source Viewer component', () => { let wrapper; const content = `// Some source code`; const highlightedContent = `${content}`; const language = 'javascript'; hljs.highlight.mockImplementation(() => ({ value: highlightedContent })); hljs.highlightAuto.mockImplementation(() => ({ value: highlightedContent })); const createComponent = async (props = {}) => { wrapper = shallowMountExtended(SourceViewer, { router, propsData: { content, language, ...props }, }); await waitForPromises(); }; const findLineNumbers = () => wrapper.findComponent(LineNumbers); const findHighlightedContent = () => wrapper.findByTestId('test-highlighted'); const findFirstLine = () => wrapper.find('#LC1'); beforeEach(() => createComponent()); afterEach(() => wrapper.destroy()); describe('highlight.js', () => { it('registers the language definition', async () => { const languageDefinition = await import(`highlight.js/lib/languages/${language}`); expect(hljs.registerLanguage).toHaveBeenCalledWith(language, languageDefinition.default); }); it('highlights the content', () => { expect(hljs.highlight).toHaveBeenCalledWith(content, { language }); }); describe('auto-detect enabled', () => { beforeEach(() => createComponent({ autoDetect: true })); it('highlights the content with auto-detection', () => { expect(hljs.highlightAuto).toHaveBeenCalledWith(content); }); }); }); describe('rendering', () => { it('renders Line Numbers', () => { expect(findLineNumbers().props('lines')).toBe(1); }); it('renders the highlighted content', () => { expect(findHighlightedContent().exists()).toBe(true); }); }); describe('selecting a line', () => { let firstLine; let firstLineElement; beforeEach(() => { firstLine = findFirstLine(); firstLineElement = firstLine.element; jest.spyOn(firstLineElement, 'scrollIntoView'); jest.spyOn(firstLineElement.classList, 'add'); jest.spyOn(firstLineElement.classList, 'remove'); }); it('adds the highlight (hll) class', async () => { wrapper.vm.$router.push('#LC1'); await nextTick(); expect(firstLineElement.classList.add).toHaveBeenCalledWith('hll'); }); it('removes the highlight (hll) class from a previously highlighted line', async () => { wrapper.vm.$router.push('#LC2'); await nextTick(); expect(firstLineElement.classList.remove).toHaveBeenCalledWith('hll'); }); it('scrolls the line into view', () => { expect(firstLineElement.scrollIntoView).toHaveBeenCalledWith({ behavior: 'smooth', block: 'center', }); }); }); });