diff options
Diffstat (limited to 'spec/javascripts/vue_shared')
10 files changed, 0 insertions, 1320 deletions
diff --git a/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js b/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js deleted file mode 100644 index e031583b43a..00000000000 --- a/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js +++ /dev/null @@ -1,261 +0,0 @@ -import $ from 'jquery'; -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue'; - -const modalComponent = Vue.extend(DeprecatedModal2); - -describe('DeprecatedModal2', () => { - let vm; - - afterEach(() => { - vm.$destroy(); - }); - - describe('props', () => { - describe('with id', () => { - const props = { - id: 'my-modal', - }; - - beforeEach(() => { - vm = mountComponent(modalComponent, props); - }); - - it('assigns the id to the modal', () => { - expect(vm.$el.id).toBe(props.id); - }); - }); - - describe('without id', () => { - beforeEach(() => { - vm = mountComponent(modalComponent, {}); - }); - - it('does not add an id attribute to the modal', () => { - expect(vm.$el.hasAttribute('id')).toBe(false); - }); - }); - - describe('with headerTitleText', () => { - const props = { - headerTitleText: 'my title text', - }; - - beforeEach(() => { - vm = mountComponent(modalComponent, props); - }); - - it('sets the modal title', () => { - const modalTitle = vm.$el.querySelector('.modal-title'); - - expect(modalTitle.innerHTML.trim()).toBe(props.headerTitleText); - }); - }); - - describe('with footerPrimaryButtonVariant', () => { - const props = { - footerPrimaryButtonVariant: 'danger', - }; - - beforeEach(() => { - vm = mountComponent(modalComponent, props); - }); - - it('sets the primary button class', () => { - const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type'); - - expect(primaryButton).toHaveClass(`btn-${props.footerPrimaryButtonVariant}`); - }); - }); - - describe('with footerPrimaryButtonText', () => { - const props = { - footerPrimaryButtonText: 'my button text', - }; - - beforeEach(() => { - vm = mountComponent(modalComponent, props); - }); - - it('sets the primary button text', () => { - const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type'); - - expect(primaryButton.innerHTML.trim()).toBe(props.footerPrimaryButtonText); - }); - }); - }); - - it('works with data-toggle="modal"', done => { - setFixtures(` - <button id="modal-button" data-toggle="modal" data-target="#my-modal"></button> - <div id="modal-container"></div> - `); - - const modalContainer = document.getElementById('modal-container'); - const modalButton = document.getElementById('modal-button'); - vm = mountComponent( - modalComponent, - { - id: 'my-modal', - }, - modalContainer, - ); - $(vm.$el).on('shown.bs.modal', () => done()); - - modalButton.click(); - }); - - describe('methods', () => { - const dummyEvent = 'not really an event'; - - beforeEach(() => { - vm = mountComponent(modalComponent, {}); - spyOn(vm, '$emit'); - }); - - describe('emitCancel', () => { - it('emits a cancel event', () => { - vm.emitCancel(dummyEvent); - - expect(vm.$emit).toHaveBeenCalledWith('cancel', dummyEvent); - }); - }); - - describe('emitSubmit', () => { - it('emits a submit event', () => { - vm.emitSubmit(dummyEvent); - - expect(vm.$emit).toHaveBeenCalledWith('submit', dummyEvent); - }); - }); - - describe('opened', () => { - it('emits a open event', () => { - vm.opened(); - - expect(vm.$emit).toHaveBeenCalledWith('open'); - }); - }); - - describe('closed', () => { - it('emits a closed event', () => { - vm.closed(); - - expect(vm.$emit).toHaveBeenCalledWith('closed'); - }); - }); - }); - - describe('slots', () => { - const slotContent = 'this should go into the slot'; - const modalWithSlot = slotName => { - let template; - if (slotName) { - template = ` - <deprecated-modal-2> - <template slot="${slotName}">${slotContent}</template> - </deprecated-modal-2> - `; - } else { - template = `<deprecated-modal-2>${slotContent}</deprecated-modal-2>`; - } - - return Vue.extend({ - components: { - DeprecatedModal2, - }, - template, - }); - }; - - describe('default slot', () => { - beforeEach(() => { - vm = mountComponent(modalWithSlot()); - }); - - it('sets the modal body', () => { - const modalBody = vm.$el.querySelector('.modal-body'); - - expect(modalBody.innerHTML).toBe(slotContent); - }); - }); - - describe('header slot', () => { - beforeEach(() => { - vm = mountComponent(modalWithSlot('header')); - }); - - it('sets the modal header', () => { - const modalHeader = vm.$el.querySelector('.modal-header'); - - expect(modalHeader.innerHTML).toBe(slotContent); - }); - }); - - describe('title slot', () => { - beforeEach(() => { - vm = mountComponent(modalWithSlot('title')); - }); - - it('sets the modal title', () => { - const modalTitle = vm.$el.querySelector('.modal-title'); - - expect(modalTitle.innerHTML).toBe(slotContent); - }); - }); - - describe('footer slot', () => { - beforeEach(() => { - vm = mountComponent(modalWithSlot('footer')); - }); - - it('sets the modal footer', () => { - const modalFooter = vm.$el.querySelector('.modal-footer'); - - expect(modalFooter.innerHTML).toBe(slotContent); - }); - }); - }); - - describe('handling sizes', () => { - it('should render modal-sm', () => { - vm = mountComponent(modalComponent, { - modalSize: 'sm', - }); - - expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-sm')).toEqual(true); - }); - - it('should render modal-lg', () => { - vm = mountComponent(modalComponent, { - modalSize: 'lg', - }); - - expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-lg')).toEqual(true); - }); - - it('should render modal-xl', () => { - vm = mountComponent(modalComponent, { - modalSize: 'xl', - }); - - expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-xl')).toEqual(true); - }); - - it('should not add modal size classes when md size is passed', () => { - vm = mountComponent(modalComponent, { - modalSize: 'md', - }); - - expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-md')).toEqual(false); - }); - - it('should not add modal size classes by default', () => { - vm = mountComponent(modalComponent, {}); - - expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-sm')).toEqual(false); - expect(vm.$el.querySelector('.modal-dialog').classList.contains('modal-lg')).toEqual(false); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/deprecated_modal_spec.js b/spec/javascripts/vue_shared/components/deprecated_modal_spec.js deleted file mode 100644 index d6c10e32794..00000000000 --- a/spec/javascripts/vue_shared/components/deprecated_modal_spec.js +++ /dev/null @@ -1,71 +0,0 @@ -import $ from 'jquery'; -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; - -const modalComponent = Vue.extend(DeprecatedModal); - -describe('DeprecatedModal', () => { - let vm; - - afterEach(() => { - vm.$destroy(); - }); - - describe('props', () => { - describe('without primaryButtonLabel', () => { - beforeEach(() => { - vm = mountComponent(modalComponent, { - primaryButtonLabel: null, - }); - }); - - it('does not render a primary button', () => { - expect(vm.$el.querySelector('.js-primary-button')).toBeNull(); - }); - }); - - describe('with id', () => { - describe('does not render a primary button', () => { - beforeEach(() => { - vm = mountComponent(modalComponent, { - id: 'my-modal', - }); - }); - - it('assigns the id to the modal', () => { - expect(vm.$el.querySelector('#my-modal.modal')).not.toBeNull(); - }); - - it('does not show the modal immediately', () => { - expect(vm.$el.querySelector('#my-modal.modal')).not.toHaveClass('show'); - }); - - it('does not show a backdrop', () => { - expect(vm.$el.querySelector('modal-backdrop')).toBeNull(); - }); - }); - }); - - it('works with data-toggle="modal"', done => { - setFixtures(` - <button id="modal-button" data-toggle="modal" data-target="#my-modal"></button> - <div id="modal-container"></div> - `); - - const modalContainer = document.getElementById('modal-container'); - const modalButton = document.getElementById('modal-button'); - vm = mountComponent( - modalComponent, - { - id: 'my-modal', - }, - modalContainer, - ); - const modalElement = vm.$el.querySelector('#my-modal'); - $(modalElement).on('shown.bs.modal', () => done()); - - modalButton.click(); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/file_finder/index_spec.js b/spec/javascripts/vue_shared/components/file_finder/index_spec.js deleted file mode 100644 index 7ded228d3ea..00000000000 --- a/spec/javascripts/vue_shared/components/file_finder/index_spec.js +++ /dev/null @@ -1,368 +0,0 @@ -import Vue from 'vue'; -import Mousetrap from 'mousetrap'; -import { file } from 'spec/ide/helpers'; -import timeoutPromise from 'spec/helpers/set_timeout_promise_helper'; -import FindFileComponent from '~/vue_shared/components/file_finder/index.vue'; -import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; - -describe('File finder item spec', () => { - const Component = Vue.extend(FindFileComponent); - let vm; - - function createComponent(props) { - vm = new Component({ - propsData: { - files: [], - visible: true, - loading: false, - ...props, - }, - }); - - vm.$mount('#app'); - } - - beforeEach(() => { - setFixtures('<div id="app"></div>'); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('with entries', () => { - beforeEach(done => { - createComponent({ - files: [ - { - ...file('index.js'), - path: 'index.js', - type: 'blob', - url: '/index.jsurl', - }, - { - ...file('component.js'), - path: 'component.js', - type: 'blob', - }, - ], - }); - - setTimeout(done); - }); - - it('renders list of blobs', () => { - expect(vm.$el.textContent).toContain('index.js'); - expect(vm.$el.textContent).toContain('component.js'); - expect(vm.$el.textContent).not.toContain('folder'); - }); - - it('filters entries', done => { - vm.searchText = 'index'; - - setTimeout(() => { - expect(vm.$el.textContent).toContain('index.js'); - expect(vm.$el.textContent).not.toContain('component.js'); - - done(); - }); - }); - - it('shows clear button when searchText is not empty', done => { - vm.searchText = 'index'; - - setTimeout(() => { - expect(vm.$el.querySelector('.dropdown-input').classList).toContain('has-value'); - expect(vm.$el.querySelector('.dropdown-input-search').classList).toContain('hidden'); - - done(); - }); - }); - - it('clear button resets searchText', done => { - vm.searchText = 'index'; - - timeoutPromise() - .then(() => { - vm.$el.querySelector('.dropdown-input-clear').click(); - }) - .then(timeoutPromise) - .then(() => { - expect(vm.searchText).toBe(''); - }) - .then(done) - .catch(done.fail); - }); - - it('clear button focues search input', done => { - spyOn(vm.$refs.searchInput, 'focus'); - vm.searchText = 'index'; - - timeoutPromise() - .then(() => { - vm.$el.querySelector('.dropdown-input-clear').click(); - }) - .then(timeoutPromise) - .then(() => { - expect(vm.$refs.searchInput.focus).toHaveBeenCalled(); - }) - .then(done) - .catch(done.fail); - }); - - describe('listShowCount', () => { - it('returns 1 when no filtered entries exist', done => { - vm.searchText = 'testing 123'; - - setTimeout(() => { - expect(vm.listShowCount).toBe(1); - - done(); - }); - }); - - it('returns entries length when not filtered', () => { - expect(vm.listShowCount).toBe(2); - }); - }); - - describe('listHeight', () => { - it('returns 55 when entries exist', () => { - expect(vm.listHeight).toBe(55); - }); - - it('returns 33 when entries dont exist', done => { - vm.searchText = 'testing 123'; - - setTimeout(() => { - expect(vm.listHeight).toBe(33); - - done(); - }); - }); - }); - - describe('filteredBlobsLength', () => { - it('returns length of filtered blobs', done => { - vm.searchText = 'index'; - - setTimeout(() => { - expect(vm.filteredBlobsLength).toBe(1); - - done(); - }); - }); - }); - - describe('watches', () => { - describe('searchText', () => { - it('resets focusedIndex when updated', done => { - vm.focusedIndex = 1; - vm.searchText = 'test'; - - setTimeout(() => { - expect(vm.focusedIndex).toBe(0); - - done(); - }); - }); - }); - - describe('visible', () => { - it('returns searchText when false', done => { - vm.searchText = 'test'; - vm.visible = true; - - timeoutPromise() - .then(() => { - vm.visible = false; - }) - .then(timeoutPromise) - .then(() => { - expect(vm.searchText).toBe(''); - }) - .then(done) - .catch(done.fail); - }); - }); - }); - - describe('openFile', () => { - beforeEach(() => { - spyOn(vm, '$emit'); - }); - - it('closes file finder', () => { - vm.openFile(vm.files[0]); - - expect(vm.$emit).toHaveBeenCalledWith('toggle', false); - }); - - it('pushes to router', () => { - vm.openFile(vm.files[0]); - - expect(vm.$emit).toHaveBeenCalledWith('click', vm.files[0]); - }); - }); - - describe('onKeyup', () => { - it('opens file on enter key', done => { - const event = new CustomEvent('keyup'); - event.keyCode = ENTER_KEY_CODE; - - spyOn(vm, 'openFile'); - - vm.$refs.searchInput.dispatchEvent(event); - - setTimeout(() => { - expect(vm.openFile).toHaveBeenCalledWith(vm.files[0]); - - done(); - }); - }); - - it('closes file finder on esc key', done => { - const event = new CustomEvent('keyup'); - event.keyCode = ESC_KEY_CODE; - - spyOn(vm, '$emit'); - - vm.$refs.searchInput.dispatchEvent(event); - - setTimeout(() => { - expect(vm.$emit).toHaveBeenCalledWith('toggle', false); - - done(); - }); - }); - }); - - describe('onKeyDown', () => { - let el; - - beforeEach(() => { - el = vm.$refs.searchInput; - }); - - describe('up key', () => { - const event = new CustomEvent('keydown'); - event.keyCode = UP_KEY_CODE; - - it('resets to last index when at top', () => { - el.dispatchEvent(event); - - expect(vm.focusedIndex).toBe(1); - }); - - it('minus 1 from focusedIndex', () => { - vm.focusedIndex = 1; - - el.dispatchEvent(event); - - expect(vm.focusedIndex).toBe(0); - }); - }); - - describe('down key', () => { - const event = new CustomEvent('keydown'); - event.keyCode = DOWN_KEY_CODE; - - it('resets to first index when at bottom', () => { - vm.focusedIndex = 1; - el.dispatchEvent(event); - - expect(vm.focusedIndex).toBe(0); - }); - - it('adds 1 to focusedIndex', () => { - el.dispatchEvent(event); - - expect(vm.focusedIndex).toBe(1); - }); - }); - }); - }); - - describe('without entries', () => { - it('renders loading text when loading', () => { - createComponent({ - loading: true, - }); - - expect(vm.$el.textContent).toContain('Loading...'); - }); - - it('renders no files text', () => { - createComponent(); - - expect(vm.$el.textContent).toContain('No files found.'); - }); - }); - - describe('keyboard shortcuts', () => { - beforeEach(done => { - createComponent(); - - spyOn(vm, 'toggle'); - - vm.$nextTick(done); - }); - - it('calls toggle on `t` key press', done => { - Mousetrap.trigger('t'); - - vm.$nextTick() - .then(() => { - expect(vm.toggle).toHaveBeenCalled(); - }) - .then(done) - .catch(done.fail); - }); - - it('calls toggle on `command+p` key press', done => { - Mousetrap.trigger('command+p'); - - vm.$nextTick() - .then(() => { - expect(vm.toggle).toHaveBeenCalled(); - }) - .then(done) - .catch(done.fail); - }); - - it('calls toggle on `ctrl+p` key press', done => { - Mousetrap.trigger('ctrl+p'); - - vm.$nextTick() - .then(() => { - expect(vm.toggle).toHaveBeenCalled(); - }) - .then(done) - .catch(done.fail); - }); - - it('always allows `command+p` to trigger toggle', () => { - expect( - vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 'command+p'), - ).toBe(false); - }); - - it('always allows `ctrl+p` to trigger toggle', () => { - expect( - vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 'ctrl+p'), - ).toBe(false); - }); - - it('onlys handles `t` when focused in input-field', () => { - expect( - vm.mousetrapStopCallback(null, vm.$el.querySelector('.dropdown-input-field'), 't'), - ).toBe(true); - }); - - it('stops callback in monaco editor', () => { - setFixtures('<div class="inputarea"></div>'); - - expect(vm.mousetrapStopCallback(null, document.querySelector('.inputarea'), 't')).toBe(true); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/icon_spec.js b/spec/javascripts/vue_shared/components/icon_spec.js deleted file mode 100644 index 5a3e483fb03..00000000000 --- a/spec/javascripts/vue_shared/components/icon_spec.js +++ /dev/null @@ -1,73 +0,0 @@ -import Vue from 'vue'; -import { mount } from '@vue/test-utils'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import Icon from '~/vue_shared/components/icon.vue'; - -describe('Sprite Icon Component', function() { - describe('Initialization', function() { - let icon; - - beforeEach(function() { - const IconComponent = Vue.extend(Icon); - - icon = mountComponent(IconComponent, { - name: 'commit', - size: 32, - }); - }); - - afterEach(() => { - icon.$destroy(); - }); - - it('should return a defined Vue component', function() { - expect(icon).toBeDefined(); - }); - - it('should have <svg> as a child element', function() { - expect(icon.$el.tagName).toBe('svg'); - }); - - it('should have <use> as a child element with the correct href', function() { - expect(icon.$el.firstChild.tagName).toBe('use'); - expect(icon.$el.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_icons}#commit`); - }); - - it('should properly compute iconSizeClass', function() { - expect(icon.iconSizeClass).toBe('s32'); - }); - - it('forbids invalid size prop', () => { - expect(icon.$options.props.size.validator(NaN)).toBeFalsy(); - expect(icon.$options.props.size.validator(0)).toBeFalsy(); - expect(icon.$options.props.size.validator(9001)).toBeFalsy(); - }); - - it('should properly render img css', function() { - const { classList } = icon.$el; - const containsSizeClass = classList.contains('s32'); - - expect(containsSizeClass).toBe(true); - }); - - it('`name` validator should return false for non existing icons', () => { - expect(Icon.props.name.validator('non_existing_icon_sprite')).toBe(false); - }); - - it('`name` validator should return false for existing icons', () => { - expect(Icon.props.name.validator('commit')).toBe(true); - }); - }); - - it('should call registered listeners when they are triggered', () => { - const clickHandler = jasmine.createSpy('clickHandler'); - const wrapper = mount(Icon, { - propsData: { name: 'commit' }, - listeners: { click: clickHandler }, - }); - - wrapper.find('svg').trigger('click'); - - expect(clickHandler).toHaveBeenCalled(); - }); -}); diff --git a/spec/javascripts/vue_shared/components/issue/related_issuable_mock_data.js b/spec/javascripts/vue_shared/components/issue/related_issuable_mock_data.js deleted file mode 100644 index 3c42f0c2aa9..00000000000 --- a/spec/javascripts/vue_shared/components/issue/related_issuable_mock_data.js +++ /dev/null @@ -1 +0,0 @@ -export * from '../../../../frontend/vue_shared/components/issue/related_issuable_mock_data'; diff --git a/spec/javascripts/vue_shared/components/panel_resizer_spec.js b/spec/javascripts/vue_shared/components/panel_resizer_spec.js deleted file mode 100644 index d65ee8eeb2d..00000000000 --- a/spec/javascripts/vue_shared/components/panel_resizer_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import panelResizer from '~/vue_shared/components/panel_resizer.vue'; - -describe('Panel Resizer component', () => { - let vm; - let PanelResizer; - - const triggerEvent = (eventName, el = vm.$el, clientX = 0) => { - const event = document.createEvent('MouseEvents'); - event.initMouseEvent( - eventName, - true, - true, - window, - 1, - clientX, - 0, - clientX, - 0, - false, - false, - false, - false, - 0, - null, - ); - - el.dispatchEvent(event); - }; - - beforeEach(() => { - PanelResizer = Vue.extend(panelResizer); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('should render a div element with the correct classes and styles', () => { - vm = mountComponent(PanelResizer, { - startSize: 100, - side: 'left', - }); - - expect(vm.$el.tagName).toEqual('DIV'); - expect(vm.$el.getAttribute('class')).toBe( - 'position-absolute position-top-0 position-bottom-0 drag-handle position-left-0', - ); - - expect(vm.$el.getAttribute('style')).toBe('cursor: ew-resize;'); - }); - - it('should render a div element with the correct classes for a right side panel', () => { - vm = mountComponent(PanelResizer, { - startSize: 100, - side: 'right', - }); - - expect(vm.$el.tagName).toEqual('DIV'); - expect(vm.$el.getAttribute('class')).toBe( - 'position-absolute position-top-0 position-bottom-0 drag-handle position-right-0', - ); - }); - - it('drag the resizer', () => { - vm = mountComponent(PanelResizer, { - startSize: 100, - side: 'left', - }); - - spyOn(vm, '$emit'); - triggerEvent('mousedown', vm.$el); - triggerEvent('mousemove', document); - triggerEvent('mouseup', document); - - expect(vm.$emit.calls.allArgs()).toEqual([ - ['resize-start', 100], - ['update:size', 100], - ['resize-end', 100], - ]); - - expect(vm.size).toBe(100); - }); -}); diff --git a/spec/javascripts/vue_shared/components/smart_virtual_list_spec.js b/spec/javascripts/vue_shared/components/smart_virtual_list_spec.js deleted file mode 100644 index 47ebdc505c9..00000000000 --- a/spec/javascripts/vue_shared/components/smart_virtual_list_spec.js +++ /dev/null @@ -1,83 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import SmartVirtualScrollList from '~/vue_shared/components/smart_virtual_list.vue'; - -describe('Toggle Button', () => { - let vm; - - const createComponent = ({ length, remain }) => { - const smartListProperties = { - rtag: 'section', - wtag: 'ul', - wclass: 'test-class', - // Size in pixels does not matter for our tests here - size: 35, - length, - remain, - }; - - const Component = Vue.extend({ - components: { - SmartVirtualScrollList, - }, - smartListProperties, - items: Array(length).fill(1), - template: ` - <smart-virtual-scroll-list v-bind="$options.smartListProperties"> - <li v-for="(val, key) in $options.items" :key="key">{{ key + 1 }}</li> - </smart-virtual-scroll-list>`, - }); - - return mountComponent(Component); - }; - - afterEach(() => { - vm.$destroy(); - }); - - describe('if the list is shorter than the maximum shown elements', () => { - const listLength = 10; - - beforeEach(() => { - vm = createComponent({ length: listLength, remain: 20 }); - }); - - it('renders without the vue-virtual-scroll-list component', () => { - expect(vm.$el.classList).not.toContain('js-virtual-list'); - expect(vm.$el.classList).toContain('js-plain-element'); - }); - - it('renders list with provided tags and classes for the wrapper elements', () => { - expect(vm.$el.tagName).toEqual('SECTION'); - expect(vm.$el.firstChild.tagName).toEqual('UL'); - expect(vm.$el.firstChild.classList).toContain('test-class'); - }); - - it('renders all children list elements', () => { - expect(vm.$el.querySelectorAll('li').length).toEqual(listLength); - }); - }); - - describe('if the list is longer than the maximum shown elements', () => { - const maxItemsShown = 20; - - beforeEach(() => { - vm = createComponent({ length: 1000, remain: maxItemsShown }); - }); - - it('uses the vue-virtual-scroll-list component', () => { - expect(vm.$el.classList).toContain('js-virtual-list'); - expect(vm.$el.classList).not.toContain('js-plain-element'); - }); - - it('renders list with provided tags and classes for the wrapper elements', () => { - expect(vm.$el.tagName).toEqual('SECTION'); - expect(vm.$el.firstChild.tagName).toEqual('UL'); - expect(vm.$el.firstChild.classList).toContain('test-class'); - }); - - it('renders at max twice the maximum shown elements', () => { - expect(vm.$el.querySelectorAll('li').length).toBeLessThanOrEqual(2 * maxItemsShown); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/directives/autofocusonshow_spec.js b/spec/javascripts/vue_shared/directives/autofocusonshow_spec.js deleted file mode 100644 index f1ca5f61496..00000000000 --- a/spec/javascripts/vue_shared/directives/autofocusonshow_spec.js +++ /dev/null @@ -1,38 +0,0 @@ -import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; - -/** - * We're testing this directive's hooks as pure functions - * since behaviour of this directive is highly-dependent - * on underlying DOM methods. - */ -describe('AutofocusOnShow directive', () => { - describe('with input invisible on component render', () => { - let el; - - beforeAll(() => { - setFixtures('<div id="container" style="display: none;"><input id="inputel"/></div>'); - el = document.querySelector('#inputel'); - }); - - it('should bind IntersectionObserver on input element', () => { - spyOn(el, 'focus'); - - autofocusonshow.inserted(el); - - expect(el.visibilityObserver).toBeDefined(); - expect(el.focus).not.toHaveBeenCalled(); - }); - - it('should stop IntersectionObserver on input element on unbind hook', () => { - el.visibilityObserver = { - disconnect: () => {}, - }; - spyOn(el.visibilityObserver, 'disconnect'); - - autofocusonshow.unbind(el); - - expect(el.visibilityObserver).toBeDefined(); - expect(el.visibilityObserver.disconnect).toHaveBeenCalled(); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/directives/tooltip_spec.js b/spec/javascripts/vue_shared/directives/tooltip_spec.js deleted file mode 100644 index 1d516a280b0..00000000000 --- a/spec/javascripts/vue_shared/directives/tooltip_spec.js +++ /dev/null @@ -1,89 +0,0 @@ -import $ from 'jquery'; -import Vue from 'vue'; -import tooltip from '~/vue_shared/directives/tooltip'; - -describe('Tooltip directive', () => { - let vm; - - afterEach(() => { - if (vm) { - vm.$destroy(); - } - }); - - describe('with a single tooltip', () => { - beforeEach(() => { - setFixtures('<div id="dummy-element"></div>'); - vm = new Vue({ - el: '#dummy-element', - directives: { - tooltip, - }, - data() { - return { - tooltip: 'some text', - }; - }, - template: '<div v-tooltip :title="tooltip"></div>', - }); - }); - - it('should have tooltip plugin applied', () => { - expect($(vm.$el).data('bs.tooltip')).toBeDefined(); - }); - - it('displays the title as tooltip', () => { - $(vm.$el).tooltip('show'); - const tooltipElement = document.querySelector('.tooltip-inner'); - - expect(tooltipElement.innerText).toContain('some text'); - }); - - it('updates a visible tooltip', done => { - $(vm.$el).tooltip('show'); - const tooltipElement = document.querySelector('.tooltip-inner'); - - vm.tooltip = 'other text'; - - Vue.nextTick() - .then(() => { - expect(tooltipElement).toContainText('other text'); - done(); - }) - .catch(done.fail); - }); - }); - - describe('with multiple tooltips', () => { - beforeEach(() => { - const SomeComponent = Vue.extend({ - directives: { - tooltip, - }, - template: ` - <div> - <div - v-tooltip - class="js-look-for-tooltip" - title="foo"> - </div> - <div - v-tooltip - title="bar"> - </div> - </div> - `, - }); - - vm = new SomeComponent().$mount(); - }); - - it('should have tooltip plugin applied to all instances', () => { - expect( - $(vm.$el) - .find('.js-look-for-tooltip') - .data('bs.tooltip'), - ).toBeDefined(); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/translate_spec.js b/spec/javascripts/vue_shared/translate_spec.js deleted file mode 100644 index adca7cd64a1..00000000000 --- a/spec/javascripts/vue_shared/translate_spec.js +++ /dev/null @@ -1,251 +0,0 @@ -import Vue from 'vue'; -import Jed from 'jed'; - -import { trimText } from 'spec/helpers/text_helper'; -import locale from '~/locale'; -import Translate from '~/vue_shared/translate'; - -describe('Vue translate filter', () => { - let el; - - const createTranslationMock = (key, ...translations) => { - const fakeLocale = new Jed({ - domain: 'app', - locale_data: { - app: { - '': { - domain: 'app', - lang: 'vo', - plural_forms: 'nplurals=2; plural=(n != 1);', - }, - [key]: translations, - }, - }, - }); - - // eslint-disable-next-line no-underscore-dangle - locale.__Rewire__('locale', fakeLocale); - }; - - afterEach(() => { - // eslint-disable-next-line no-underscore-dangle - locale.__ResetDependency__('locale'); - }); - - beforeEach(() => { - Vue.use(Translate); - - el = document.createElement('div'); - - document.body.appendChild(el); - }); - - it('translate singular text (`__`)', done => { - const key = 'singular'; - const translation = 'singular_translated'; - createTranslationMock(key, translation); - - const vm = new Vue({ - el, - template: ` - <span> - {{ __('${key}') }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe(translation); - - done(); - }); - }); - - it('translate plural text (`n__`) without any substituting text', done => { - const key = 'plural'; - const translationPlural = 'plural_multiple translation'; - createTranslationMock(key, 'plural_singular translation', translationPlural); - - const vm = new Vue({ - el, - template: ` - <span> - {{ n__('${key}', 'plurals', 2) }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe(translationPlural); - - done(); - }); - }); - - describe('translate plural text (`n__`) with substituting %d', () => { - const key = '%d day'; - - beforeEach(() => { - createTranslationMock(key, '%d singular translated', '%d plural translated'); - }); - - it('and n === 1', done => { - const vm = new Vue({ - el, - template: ` - <span> - {{ n__('${key}', '%d days', 1) }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe('1 singular translated'); - - done(); - }); - }); - - it('and n > 1', done => { - const vm = new Vue({ - el, - template: ` - <span> - {{ n__('${key}', '%d days', 2) }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe('2 plural translated'); - - done(); - }); - }); - }); - - describe('translates text with context `s__`', () => { - const key = 'Context|Foobar'; - const translation = 'Context|Foobar translated'; - const expectation = 'Foobar translated'; - - beforeEach(() => { - createTranslationMock(key, translation); - }); - - it('and using two parameters', done => { - const vm = new Vue({ - el, - template: ` - <span> - {{ s__('Context', 'Foobar') }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe(expectation); - - done(); - }); - }); - - it('and using the pipe syntax', done => { - const vm = new Vue({ - el, - template: ` - <span> - {{ s__('${key}') }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe(expectation); - - done(); - }); - }); - }); - - it('translate multi line text', done => { - const translation = 'multiline string translated'; - createTranslationMock('multiline string', translation); - - const vm = new Vue({ - el, - template: ` - <span> - {{ __(\` - multiline - string - \`) }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe(translation); - - done(); - }); - }); - - it('translate pluralized multi line text', done => { - const translation = 'multiline string plural'; - - createTranslationMock('multiline string', 'multiline string singular', translation); - - const vm = new Vue({ - el, - template: ` - <span> - {{ n__( - \` - multiline - string - \`, - \` - multiline - strings - \`, - 2 - ) }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe(translation); - - done(); - }); - }); - - it('translate pluralized multi line text with context', done => { - const translation = 'multiline string with context'; - - createTranslationMock('Context| multiline string', translation); - - const vm = new Vue({ - el, - template: ` - <span> - {{ s__( - \` - Context| - multiline - string - \` - ) }} - </span> - `, - }).$mount(); - - Vue.nextTick(() => { - expect(trimText(vm.$el.textContent)).toBe(translation); - - done(); - }); - }); -}); |