From f7a498ccc3bcbf92cc1043b4d9ecf2f3091aae17 Mon Sep 17 00:00:00 2001 From: Paul Gascou-Vaillancourt Date: Tue, 23 Apr 2019 16:04:14 -0400 Subject: Add FriendlyWrap component The FriendlyWrap component wraps text at specific places by inserting a element after each symbols occurence --- app/assets/javascripts/lib/utils/text_utility.js | 8 +++ .../vue_shared/components/friendly_wrap.vue | 31 +++++++++++ .../unreleased/10450-friendly-wrap-component.yml | 5 ++ spec/frontend/lib/utils/text_utility_spec.js | 7 +++ .../vue_shared/components/friendly_wrap_spec.js | 63 ++++++++++++++++++++++ 5 files changed, 114 insertions(+) create mode 100644 app/assets/javascripts/vue_shared/components/friendly_wrap.vue create mode 100644 changelogs/unreleased/10450-friendly-wrap-component.yml create mode 100644 spec/frontend/vue_shared/components/friendly_wrap_spec.js diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js index cc1d85fd97d..09d9ae35e70 100644 --- a/app/assets/javascripts/lib/utils/text_utility.js +++ b/app/assets/javascripts/lib/utils/text_utility.js @@ -192,3 +192,11 @@ export const truncateNamespace = (string = '') => { return namespace; }; + +/** + * Escapes RegExp special characters + * + * @param {String} str + * @returns String + */ +export const escapeRegExp = str => str.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'); diff --git a/app/assets/javascripts/vue_shared/components/friendly_wrap.vue b/app/assets/javascripts/vue_shared/components/friendly_wrap.vue new file mode 100644 index 00000000000..dfebd67c54a --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/friendly_wrap.vue @@ -0,0 +1,31 @@ + + + diff --git a/changelogs/unreleased/10450-friendly-wrap-component.yml b/changelogs/unreleased/10450-friendly-wrap-component.yml new file mode 100644 index 00000000000..f10c15a2931 --- /dev/null +++ b/changelogs/unreleased/10450-friendly-wrap-component.yml @@ -0,0 +1,5 @@ +--- +title: Add FriendlyWrap component +merge_request: 27600 +author: +type: other diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js index 0878c1de095..e31cbbaf99e 100644 --- a/spec/frontend/lib/utils/text_utility_spec.js +++ b/spec/frontend/lib/utils/text_utility_spec.js @@ -176,4 +176,11 @@ describe('text_utility', () => { }); }); }); + + describe('escapeRegExp', () => { + it('escapes regexp special characters', () => { + const str = '[\\^$.*+?()[]{}|]'; + expect(textUtils.escapeRegExp(str)).toBe('\\[\\\\\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\]'); + }); + }); }); diff --git a/spec/frontend/vue_shared/components/friendly_wrap_spec.js b/spec/frontend/vue_shared/components/friendly_wrap_spec.js new file mode 100644 index 00000000000..170820dfadc --- /dev/null +++ b/spec/frontend/vue_shared/components/friendly_wrap_spec.js @@ -0,0 +1,63 @@ +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import FriendlyWrap from '~/vue_shared/components/friendly_wrap'; + +const localVue = createLocalVue(); + +describe('Friendly wrap component', () => { + let wrapper; + + const createComponent = props => { + wrapper = shallowMount(FriendlyWrap, { + localVue, + propsData: props, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + it('wraps text on slashes by default', () => { + const text = '/some/file/path'; + const textWrapped = '/some/file/path'; + createComponent({ + text, + }); + + expect(wrapper.text()).toBe(text); + expect(wrapper.html()).toMatch(textWrapped); + }); + + it('supports backslashes', () => { + const text = '\\some\\long\\file\\path'; + const textWrapped = '\\some\\long\\file\\path'; + createComponent({ + text, + symbols: ['\\'], + }); + expect(wrapper.text()).toBe(text); + expect(wrapper.html()).toMatch(textWrapped); + }); + + it('accepts multiple symbols', () => { + const text = 'some;text-that.needs;to-be.wrapped'; + const textWrapped = 'some;text-that.needs;to-be.wrapped'; + createComponent({ + text, + symbols: [';', '-', '.'], + }); + expect(wrapper.text()).toBe(text); + expect(wrapper.html()).toMatch(textWrapped); + }); + + it('works with words', () => { + const text = 'it goes on and on and on and on'; + const textWrapped = 'it goes on and on and on and on'; + createComponent({ + text, + symbols: ['and'], + }); + expect(wrapper.text()).toBe(text); + expect(wrapper.html()).toMatch(textWrapped); + }); +}); -- cgit v1.2.3