diff options
Diffstat (limited to 'spec/frontend/lib/utils')
-rw-r--r-- | spec/frontend/lib/utils/common_utils_spec.js | 23 | ||||
-rw-r--r-- | spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/lib/utils/rails_ujs_spec.js | 12 | ||||
-rw-r--r-- | spec/frontend/lib/utils/recurrence_spec.js | 5 | ||||
-rw-r--r-- | spec/frontend/lib/utils/sticky_spec.js | 6 | ||||
-rw-r--r-- | spec/frontend/lib/utils/text_markdown_spec.js | 136 | ||||
-rw-r--r-- | spec/frontend/lib/utils/url_utility_spec.js | 66 |
7 files changed, 204 insertions, 48 deletions
diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js index 7cf101a5e59..a2ace8857ed 100644 --- a/spec/frontend/lib/utils/common_utils_spec.js +++ b/spec/frontend/lib/utils/common_utils_spec.js @@ -292,16 +292,11 @@ describe('common_utils', () => { const spy = jest.fn(); const debouncedSpy = commonUtils.debounceByAnimationFrame(spy); - return new Promise((resolve) => { - window.requestAnimationFrame(() => { - debouncedSpy(); - debouncedSpy(); - window.requestAnimationFrame(() => { - expect(spy).toHaveBeenCalledTimes(1); - resolve(); - }); - }); - }); + debouncedSpy(); + debouncedSpy(); + jest.runOnlyPendingTimers(); + + expect(spy).toHaveBeenCalledTimes(1); }); }); @@ -633,7 +628,7 @@ describe('common_utils', () => { it('returns an empty object if `conversionFunction` parameter is not a function', () => { const result = commonUtils.convertObjectProps(null, mockObjects.convertObjectProps.obj); - expect(isEmptyObject(result)).toBeTruthy(); + expect(isEmptyObject(result)).toBe(true); }); }); @@ -650,9 +645,9 @@ describe('common_utils', () => { : commonUtils[functionName]; it('returns an empty object if `obj` parameter is null, undefined or an empty object', () => { - expect(isEmptyObject(testFunction(null))).toBeTruthy(); - expect(isEmptyObject(testFunction())).toBeTruthy(); - expect(isEmptyObject(testFunction({}))).toBeTruthy(); + expect(isEmptyObject(testFunction(null))).toBe(true); + expect(isEmptyObject(testFunction())).toBe(true); + expect(isEmptyObject(testFunction({}))).toBe(true); }); it('converts object properties', () => { diff --git a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js index d6131b1a1d7..313e028d861 100644 --- a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js +++ b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js @@ -42,12 +42,12 @@ describe('Confirm Modal', () => { it('should emit `confirmed` event on `primary` modal event', () => { findGlModal().vm.$emit('primary'); - expect(wrapper.emitted('confirmed')).toBeTruthy(); + expect(wrapper.emitted('confirmed')).toHaveLength(1); }); it('should emit closed` event on `hidden` modal event', () => { modal.vm.$emit('hidden'); - expect(wrapper.emitted('closed')).toBeTruthy(); + expect(wrapper.emitted('closed')).toHaveLength(1); }); }); diff --git a/spec/frontend/lib/utils/rails_ujs_spec.js b/spec/frontend/lib/utils/rails_ujs_spec.js index c10301523c9..da9cc5c6f3c 100644 --- a/spec/frontend/lib/utils/rails_ujs_spec.js +++ b/spec/frontend/lib/utils/rails_ujs_spec.js @@ -18,14 +18,12 @@ function mockXHRResponse({ responseText, responseContentType } = {}) { .mockReturnValue(responseContentType); jest.spyOn(global.XMLHttpRequest.prototype, 'send').mockImplementation(function send() { - requestAnimationFrame(() => { - Object.defineProperties(this, { - readyState: { value: XMLHttpRequest.DONE }, - status: { value: 200 }, - response: { value: responseText }, - }); - this.onreadystatechange(); + Object.defineProperties(this, { + readyState: { value: XMLHttpRequest.DONE }, + status: { value: 200 }, + response: { value: responseText }, }); + this.onreadystatechange(); }); } diff --git a/spec/frontend/lib/utils/recurrence_spec.js b/spec/frontend/lib/utils/recurrence_spec.js index fc22529dffc..8bf3ea4e25a 100644 --- a/spec/frontend/lib/utils/recurrence_spec.js +++ b/spec/frontend/lib/utils/recurrence_spec.js @@ -211,9 +211,10 @@ describe('recurrence', () => { describe('eject', () => { it('removes the handler assigned to the particular count slot', () => { - recurInstance.handle(1, jest.fn()); + const func = jest.fn(); + recurInstance.handle(1, func); - expect(recurInstance.handlers[1]).toBeTruthy(); + expect(recurInstance.handlers[1]).toStrictEqual(func); recurInstance.eject(1); diff --git a/spec/frontend/lib/utils/sticky_spec.js b/spec/frontend/lib/utils/sticky_spec.js index 01e8fe777af..ec9e746c838 100644 --- a/spec/frontend/lib/utils/sticky_spec.js +++ b/spec/frontend/lib/utils/sticky_spec.js @@ -34,13 +34,13 @@ describe('sticky', () => { isSticky(el, 0, el.offsetTop); isSticky(el, 0, el.offsetTop); - expect(el.classList.contains('is-stuck')).toBeTruthy(); + expect(el.classList.contains('is-stuck')).toBe(true); }); it('adds is-stuck class', () => { isSticky(el, 0, el.offsetTop); - expect(el.classList.contains('is-stuck')).toBeTruthy(); + expect(el.classList.contains('is-stuck')).toBe(true); }); it('inserts placeholder element', () => { @@ -64,7 +64,7 @@ describe('sticky', () => { it('does not add is-stuck class', () => { isSticky(el, 0, 0); - expect(el.classList.contains('is-stuck')).toBeFalsy(); + expect(el.classList.contains('is-stuck')).toBe(false); }); it('removes placeholder', () => { diff --git a/spec/frontend/lib/utils/text_markdown_spec.js b/spec/frontend/lib/utils/text_markdown_spec.js index d1bca3c73b6..733d89fe08c 100644 --- a/spec/frontend/lib/utils/text_markdown_spec.js +++ b/spec/frontend/lib/utils/text_markdown_spec.js @@ -193,6 +193,7 @@ describe('init markdown', () => { ${'- [ ] item'} | ${'- [ ] item\n- [ ] '} ${'- [x] item'} | ${'- [x] item\n- [ ] '} ${'- [X] item'} | ${'- [X] item\n- [ ] '} + ${'- [~] item'} | ${'- [~] item\n- [ ] '} ${'- [ ] nbsp (U+00A0)'} | ${'- [ ] nbsp (U+00A0)\n- [ ] '} ${'- item\n - second'} | ${'- item\n - second\n - '} ${'- - -'} | ${'- - -'} @@ -205,6 +206,7 @@ describe('init markdown', () => { ${'1. [ ] item'} | ${'1. [ ] item\n2. [ ] '} ${'1. [x] item'} | ${'1. [x] item\n2. [ ] '} ${'1. [X] item'} | ${'1. [X] item\n2. [ ] '} + ${'1. [~] item'} | ${'1. [~] item\n2. [ ] '} ${'108. item'} | ${'108. item\n109. '} ${'108. item\n - second'} | ${'108. item\n - second\n - '} ${'108. item\n 1. second'} | ${'108. item\n 1. second\n 2. '} @@ -228,11 +230,13 @@ describe('init markdown', () => { ${'- [ ] item\n- [ ] '} | ${'- [ ] item\n'} ${'- [x] item\n- [x] '} | ${'- [x] item\n'} ${'- [X] item\n- [X] '} | ${'- [X] item\n'} + ${'- [~] item\n- [~] '} | ${'- [~] item\n'} ${'- item\n - second\n - '} | ${'- item\n - second\n'} ${'1. item\n2. '} | ${'1. item\n'} ${'1. [ ] item\n2. [ ] '} | ${'1. [ ] item\n'} ${'1. [x] item\n2. [x] '} | ${'1. [x] item\n'} ${'1. [X] item\n2. [X] '} | ${'1. [X] item\n'} + ${'1. [~] item\n2. [~] '} | ${'1. [~] item\n'} ${'108. item\n109. '} | ${'108. item\n'} ${'108. item\n - second\n - '} | ${'108. item\n - second\n'} ${'108. item\n 1. second\n 1. '} | ${'108. item\n 1. second\n'} @@ -301,6 +305,129 @@ describe('init markdown', () => { }); }); + describe('shifting selected lines left or right', () => { + const indentEvent = new KeyboardEvent('keydown', { key: ']', metaKey: true }); + const outdentEvent = new KeyboardEvent('keydown', { key: '[', metaKey: true }); + + beforeEach(() => { + textArea.addEventListener('keydown', keypressNoteText); + textArea.addEventListener('compositionstart', compositionStartNoteText); + textArea.addEventListener('compositionend', compositionEndNoteText); + }); + + it.each` + selectionStart | selectionEnd | expected | expectedSelectionStart | expectedSelectionEnd + ${0} | ${0} | ${' 012\n456\n89'} | ${2} | ${2} + ${5} | ${5} | ${'012\n 456\n89'} | ${7} | ${7} + ${10} | ${10} | ${'012\n456\n 89'} | ${12} | ${12} + ${0} | ${2} | ${' 012\n456\n89'} | ${0} | ${4} + ${1} | ${2} | ${' 012\n456\n89'} | ${3} | ${4} + ${5} | ${7} | ${'012\n 456\n89'} | ${7} | ${9} + ${0} | ${7} | ${' 012\n 456\n89'} | ${0} | ${11} + ${2} | ${9} | ${' 012\n 456\n 89'} | ${4} | ${15} + `( + 'indents the selected lines two spaces to the right', + ({ + selectionStart, + selectionEnd, + expected, + expectedSelectionStart, + expectedSelectionEnd, + }) => { + const text = '012\n456\n89'; + textArea.value = text; + textArea.setSelectionRange(selectionStart, selectionEnd); + + textArea.dispatchEvent(indentEvent); + + expect(textArea.value).toEqual(expected); + expect(textArea.selectionStart).toEqual(expectedSelectionStart); + expect(textArea.selectionEnd).toEqual(expectedSelectionEnd); + }, + ); + + it('indents a blank line two spaces to the right', () => { + textArea.value = '012\n\n89'; + textArea.setSelectionRange(4, 4); + + textArea.dispatchEvent(indentEvent); + + expect(textArea.value).toEqual('012\n \n89'); + expect(textArea.selectionStart).toEqual(6); + expect(textArea.selectionEnd).toEqual(6); + }); + + it.each` + selectionStart | selectionEnd | expected | expectedSelectionStart | expectedSelectionEnd + ${0} | ${0} | ${'234\n 789\n 34'} | ${0} | ${0} + ${3} | ${3} | ${'234\n 789\n 34'} | ${1} | ${1} + ${7} | ${7} | ${' 234\n789\n 34'} | ${6} | ${6} + ${0} | ${3} | ${'234\n 789\n 34'} | ${0} | ${1} + ${8} | ${10} | ${' 234\n789\n 34'} | ${7} | ${9} + ${14} | ${15} | ${' 234\n 789\n34'} | ${12} | ${13} + ${0} | ${15} | ${'234\n789\n34'} | ${0} | ${10} + ${3} | ${13} | ${'234\n789\n34'} | ${1} | ${8} + ${6} | ${6} | ${' 234\n789\n 34'} | ${6} | ${6} + `( + 'outdents the selected lines two spaces to the left', + ({ + selectionStart, + selectionEnd, + expected, + expectedSelectionStart, + expectedSelectionEnd, + }) => { + const text = ' 234\n 789\n 34'; + textArea.value = text; + textArea.setSelectionRange(selectionStart, selectionEnd); + + textArea.dispatchEvent(outdentEvent); + + expect(textArea.value).toEqual(expected); + expect(textArea.selectionStart).toEqual(expectedSelectionStart); + expect(textArea.selectionEnd).toEqual(expectedSelectionEnd); + }, + ); + + it('outdent a blank line has no effect', () => { + textArea.value = '012\n\n89'; + textArea.setSelectionRange(4, 4); + + textArea.dispatchEvent(outdentEvent); + + expect(textArea.value).toEqual('012\n\n89'); + expect(textArea.selectionStart).toEqual(4); + expect(textArea.selectionEnd).toEqual(4); + }); + + it('does not indent if meta is not set', () => { + const indentNoMetaEvent = new KeyboardEvent('keydown', { key: ']' }); + const text = '012\n456\n89'; + textArea.value = text; + textArea.setSelectionRange(0, 0); + + textArea.dispatchEvent(indentNoMetaEvent); + + expect(textArea.value).toEqual(text); + }); + + it.each` + keyEvent + ${new KeyboardEvent('keydown', { key: ']', metaKey: false })} + ${new KeyboardEvent('keydown', { key: ']', metaKey: true, shiftKey: true })} + ${new KeyboardEvent('keydown', { key: ']', metaKey: true, altKey: true })} + ${new KeyboardEvent('keydown', { key: ']', metaKey: true, ctrlKey: true })} + `('does not indent if meta is not set', ({ keyEvent }) => { + const text = '012\n456\n89'; + textArea.value = text; + textArea.setSelectionRange(0, 0); + + textArea.dispatchEvent(keyEvent); + + expect(textArea.value).toEqual(text); + }); + }); + describe('with selection', () => { let text = 'initial selected value'; let selected = 'selected'; @@ -377,6 +504,15 @@ describe('init markdown', () => { expect(textArea.value).toEqual(text); }); + + it('does nothing if meta is set', () => { + const event = new KeyboardEvent('keydown', { key: '[', metaKey: true }); + + textArea.addEventListener('keydown', keypressNoteText); + textArea.dispatchEvent(event); + + expect(textArea.value).toEqual(text); + }); }); describe('and text to be selected', () => { diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js index 81cf4bd293b..2c6b603197d 100644 --- a/spec/frontend/lib/utils/url_utility_spec.js +++ b/spec/frontend/lib/utils/url_utility_spec.js @@ -348,15 +348,13 @@ describe('URL utility', () => { describe('urlContainsSha', () => { it('returns true when there is a valid 40-character SHA1 hash in the URL', () => { shas.valid.forEach((sha) => { - expect( - urlUtils.urlContainsSha({ url: `http://urlstuff/${sha}/moreurlstuff` }), - ).toBeTruthy(); + expect(urlUtils.urlContainsSha({ url: `http://urlstuff/${sha}/moreurlstuff` })).toBe(true); }); }); it('returns false when there is not a valid 40-character SHA1 hash in the URL', () => { shas.invalid.forEach((str) => { - expect(urlUtils.urlContainsSha({ url: `http://urlstuff/${str}/moreurlstuff` })).toBeFalsy(); + expect(urlUtils.urlContainsSha({ url: `http://urlstuff/${str}/moreurlstuff` })).toBe(false); }); }); }); @@ -555,18 +553,22 @@ describe('URL utility', () => { describe('relativePathToAbsolute', () => { it.each` - path | base | result - ${'./foo'} | ${'bar/'} | ${'/bar/foo'} - ${'../john.md'} | ${'bar/baz/foo.php'} | ${'/bar/john.md'} - ${'../images/img.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/img.png'} - ${'../images/Image 1.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/Image 1.png'} - ${'/images/img.png'} | ${'bar/baz/foo.php'} | ${'/images/img.png'} - ${'/images/img.png'} | ${'/bar/baz/foo.php'} | ${'/images/img.png'} - ${'../john.md'} | ${'/bar/baz/foo.php'} | ${'/bar/john.md'} - ${'../john.md'} | ${'///bar/baz/foo.php'} | ${'/bar/john.md'} - ${'/images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/images/img.png'} - ${'../images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/img.png'} - ${'../images/Image 1.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/Image%201.png'} + path | base | result + ${'./foo'} | ${'bar/'} | ${'/bar/foo'} + ${'../john.md'} | ${'bar/baz/foo.php'} | ${'/bar/john.md'} + ${'../images/img.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/img.png'} + ${'../images/Image 1.png'} | ${'bar/baz/foo.php'} | ${'/bar/images/Image 1.png'} + ${'/images/img.png'} | ${'bar/baz/foo.php'} | ${'/images/img.png'} + ${'/images/img.png'} | ${'bar/baz//foo.php'} | ${'/images/img.png'} + ${'/images//img.png'} | ${'bar/baz/foo.php'} | ${'/images/img.png'} + ${'/images/img.png'} | ${'/bar/baz/foo.php'} | ${'/images/img.png'} + ${'../john.md'} | ${'/bar/baz/foo.php'} | ${'/bar/john.md'} + ${'../john.md'} | ${'///bar/baz/foo.php'} | ${'/bar/john.md'} + ${'/images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/images/img.png'} + ${'/images/img.png'} | ${'https://gitlab.com////user/project/'} | ${'https://gitlab.com/images/img.png'} + ${'/images////img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/images/img.png'} + ${'../images/img.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/img.png'} + ${'../images/Image 1.png'} | ${'https://gitlab.com/user/project/'} | ${'https://gitlab.com/user/images/Image%201.png'} `( 'converts relative path "$path" with base "$base" to absolute path => "expected"', ({ path, base, result }) => { @@ -809,13 +811,13 @@ describe('URL utility', () => { }); it('should compare against the window location if no compare value is provided', () => { - expect(urlUtils.urlIsDifferent('different')).toBeTruthy(); - expect(urlUtils.urlIsDifferent(current)).toBeFalsy(); + expect(urlUtils.urlIsDifferent('different')).toBe(true); + expect(urlUtils.urlIsDifferent(current)).toBe(false); }); it('should use the provided compare value', () => { - expect(urlUtils.urlIsDifferent('different', current)).toBeTruthy(); - expect(urlUtils.urlIsDifferent(current, current)).toBeFalsy(); + expect(urlUtils.urlIsDifferent('different', current)).toBe(true); + expect(urlUtils.urlIsDifferent(current, current)).toBe(false); }); }); @@ -1058,4 +1060,28 @@ describe('URL utility', () => { expect(urlUtils.PROMO_URL).toBe(url); }); }); + + describe('removeUrlProtocol', () => { + it.each` + input | output + ${'http://gitlab.com'} | ${'gitlab.com'} + ${'https://gitlab.com'} | ${'gitlab.com'} + ${'foo:bar.com'} | ${'bar.com'} + ${'gitlab.com'} | ${'gitlab.com'} + `('transforms $input to $output', ({ input, output }) => { + expect(urlUtils.removeUrlProtocol(input)).toBe(output); + }); + }); + + describe('removeLastSlashInUrlPath', () => { + it.each` + input | output + ${'https://www.gitlab.com/path/'} | ${'https://www.gitlab.com/path'} + ${'https://www.gitlab.com/?query=search'} | ${'https://www.gitlab.com?query=search'} + ${'https://www.gitlab.com/#fragment'} | ${'https://www.gitlab.com#fragment'} + ${'https://www.gitlab.com/hello'} | ${'https://www.gitlab.com/hello'} + `('transforms $input to $output', ({ input, output }) => { + expect(urlUtils.removeLastSlashInUrlPath(input)).toBe(output); + }); + }); }); |