diff options
Diffstat (limited to 'spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js')
-rw-r--r-- | spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js | 107 |
1 files changed, 50 insertions, 57 deletions
diff --git a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js index ab579945e22..6a9ea75127d 100644 --- a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js +++ b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js @@ -1,24 +1,38 @@ import hljs from 'highlight.js/lib/core'; -import { GlLoadingIcon } from '@gitlab/ui'; -import Vue, { nextTick } from 'vue'; +import Vue from 'vue'; import VueRouter from 'vue-router'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import SourceViewer from '~/vue_shared/components/source_viewer/source_viewer.vue'; +import Chunk from '~/vue_shared/components/source_viewer/components/chunk.vue'; import { ROUGE_TO_HLJS_LANGUAGE_MAP } from '~/vue_shared/components/source_viewer/constants'; -import LineNumbers from '~/vue_shared/components/line_numbers.vue'; import waitForPromises from 'helpers/wait_for_promises'; -import * as sourceViewerUtils from '~/vue_shared/components/source_viewer/utils'; +import LineHighlighter from '~/blob/line_highlighter'; +import eventHub from '~/notes/event_hub'; +jest.mock('~/blob/line_highlighter'); jest.mock('highlight.js/lib/core'); Vue.use(VueRouter); const router = new VueRouter(); +const generateContent = (content, totalLines = 1) => { + let generatedContent = ''; + for (let i = 0; i < totalLines; i += 1) { + generatedContent += `Line: ${i + 1} = ${content}\n`; + } + return generatedContent; +}; + +const execImmediately = (callback) => callback(); + describe('Source Viewer component', () => { let wrapper; const language = 'docker'; const mappedLanguage = ROUGE_TO_HLJS_LANGUAGE_MAP[language]; - const content = `// Some source code`; - const DEFAULT_BLOB_DATA = { language, rawTextBlob: content }; + const chunk1 = generateContent('// Some source code 1', 70); + const chunk2 = generateContent('// Some source code 2', 70); + const content = chunk1 + chunk2; + const path = 'some/path.js'; + const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path }; const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`; const createComponent = async (blob = {}) => { @@ -29,15 +43,13 @@ describe('Source Viewer component', () => { await waitForPromises(); }; - const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); - const findLineNumbers = () => wrapper.findComponent(LineNumbers); - const findHighlightedContent = () => wrapper.findByTestId('test-highlighted'); - const findFirstLine = () => wrapper.find('#LC1'); + const findChunks = () => wrapper.findAllComponents(Chunk); beforeEach(() => { hljs.highlight.mockImplementation(() => ({ value: highlightedContent })); hljs.highlightAuto.mockImplementation(() => ({ value: highlightedContent })); - jest.spyOn(sourceViewerUtils, 'wrapLines'); + jest.spyOn(window, 'requestIdleCallback').mockImplementation(execImmediately); + jest.spyOn(eventHub, '$emit'); return createComponent(); }); @@ -45,6 +57,8 @@ describe('Source Viewer component', () => { afterEach(() => wrapper.destroy()); describe('highlight.js', () => { + beforeEach(() => createComponent({ language: mappedLanguage })); + it('registers the language definition', async () => { const languageDefinition = await import(`highlight.js/lib/languages/${mappedLanguage}`); @@ -54,72 +68,51 @@ describe('Source Viewer component', () => { ); }); - it('highlights the content', () => { - expect(hljs.highlight).toHaveBeenCalledWith(content, { language: mappedLanguage }); + it('highlights the first chunk', () => { + expect(hljs.highlight).toHaveBeenCalledWith(chunk1.trim(), { language: mappedLanguage }); }); describe('auto-detects if a language cannot be loaded', () => { beforeEach(() => createComponent({ language: 'some_unknown_language' })); it('highlights the content with auto-detection', () => { - expect(hljs.highlightAuto).toHaveBeenCalledWith(content); + expect(hljs.highlightAuto).toHaveBeenCalledWith(chunk1.trim()); }); }); }); describe('rendering', () => { - it('renders a loading icon if no highlighted content is available yet', async () => { - hljs.highlight.mockImplementation(() => ({ value: null })); - await createComponent(); - - expect(findLoadingIcon().exists()).toBe(true); - }); + it('renders the first chunk', async () => { + const firstChunk = findChunks().at(0); - it('calls the wrapLines helper method with highlightedContent and mappedLanguage', () => { - expect(sourceViewerUtils.wrapLines).toHaveBeenCalledWith(highlightedContent, mappedLanguage); - }); - - it('renders Line Numbers', () => { - expect(findLineNumbers().props('lines')).toBe(1); - }); + expect(firstChunk.props('content')).toContain(chunk1); - it('renders the highlighted content', () => { - expect(findHighlightedContent().exists()).toBe(true); + expect(firstChunk.props()).toMatchObject({ + totalLines: 70, + startingFrom: 0, + }); }); - }); - describe('selecting a line', () => { - let firstLine; - let firstLineElement; + it('renders the second chunk', async () => { + const secondChunk = findChunks().at(1); - beforeEach(() => { - firstLine = findFirstLine(); - firstLineElement = firstLine.element; + expect(secondChunk.props('content')).toContain(chunk2.trim()); - 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'); + expect(secondChunk.props()).toMatchObject({ + totalLines: 70, + startingFrom: 70, + }); }); + }); - 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('emits showBlobInteractionZones on the eventHub when chunk appears', () => { + findChunks().at(0).vm.$emit('appear'); + expect(eventHub.$emit).toBeCalledWith('showBlobInteractionZones', path); + }); - it('scrolls the line into view', () => { - expect(firstLineElement.scrollIntoView).toHaveBeenCalledWith({ - behavior: 'smooth', - block: 'center', - }); + describe('LineHighlighter', () => { + it('instantiates the lineHighlighter class', async () => { + expect(LineHighlighter).toHaveBeenCalledWith({ scrollBehavior: 'auto' }); }); }); }); |