UNPKG

3.35 kBJavaScriptView Raw
1import { shallowMount } from '@vue/test-utils';
2import FriendlyWrap from './friendly_wrap.vue';
3
4describe('Friendly wrap component', () => {
5 let wrapper;
6
7 const createComponent = (props) => {
8 wrapper = shallowMount(FriendlyWrap, {
9 propsData: props,
10 });
11 };
12
13 it('wraps text on slashes by default', () => {
14 const text = '/some/file/path';
15 const textWrapped = '/<wbr>some/<wbr>file/<wbr>path';
16 createComponent({
17 text,
18 });
19
20 expect(wrapper.text()).toBe(text);
21 expect(wrapper.html()).toMatch(textWrapped);
22 });
23
24 it('supports backslashes', () => {
25 const text = '\\some\\long\\file\\path';
26 const textWrapped = '\\<wbr>some\\<wbr>long\\<wbr>file\\<wbr>path';
27 createComponent({
28 text,
29 symbols: ['\\'],
30 });
31 expect(wrapper.text()).toBe(text);
32 expect(wrapper.html()).toMatch(textWrapped);
33 });
34
35 it('accepts multiple symbols', () => {
36 const text = 'some;text-that.needs;to-be.wrapped';
37 const textWrapped = 'some;<wbr>text-<wbr>that.<wbr>needs;<wbr>to-<wbr>be.<wbr>wrapped';
38 createComponent({
39 text,
40 symbols: [';', '-', '.'],
41 });
42 expect(wrapper.text()).toBe(text);
43 expect(wrapper.html()).toMatch(textWrapped);
44 });
45
46 it('works with words', () => {
47 const text = 'it goes on and on and on and on';
48 const textWrapped = 'it goes on and<wbr> on and<wbr> on and<wbr> on';
49 createComponent({
50 text,
51 symbols: ['and'],
52 });
53 expect(wrapper.text()).toBe(text);
54 expect(wrapper.html()).toMatch(textWrapped);
55 });
56
57 it(`does not break with sensitive symbols like '<' or 'w' or 'b' or 'r' or '>'`, () => {
58 const text = '< or w or b or r or >';
59 const textWrapped = '&lt;<wbr> or<wbr> w<wbr> or<wbr> b<wbr> or<wbr> r<wbr> or<wbr> &gt;';
60 createComponent({
61 text,
62 symbols: ['<', ...'wbr'.split(''), '>'],
63 });
64
65 expect(wrapper.text()).toBe(text);
66 expect(wrapper.html()).toMatch(textWrapped);
67 });
68
69 it('allows HTML entities as words', () => {
70 const text = 'foo&lt;foo&gt;foo>foo<foo';
71 const textWrapped = 'foo&amp;lt;<wbr>foo&amp;gt;<wbr>foo&gt;foo&lt;foo';
72 createComponent({
73 text,
74 symbols: ['&lt;', '&gt;'],
75 });
76
77 expect(wrapper.text()).toBe(text);
78 expect(wrapper.html()).toMatch(textWrapped);
79 });
80
81 it('escapes text to prevent XSS', () => {
82 const text = '<script>alert(1)</script>';
83 const textWrapped = '&lt;script&gt;alert(1)&lt;/<wbr>script&gt;';
84 createComponent({
85 text,
86 });
87
88 expect(wrapper.text()).toBe(text);
89 expect(wrapper.html()).toMatch(textWrapped);
90 });
91
92 it('does not unnecessarily insert a wbr at the end', () => {
93 const text = '/';
94 createComponent({
95 text,
96 });
97
98 expect(wrapper.text()).toBe(text);
99 expect(wrapper.find('wbr').exists()).toBe(false);
100 });
101
102 it('does not insert unnecessary whitespace', () => {
103 const text = '';
104 createComponent({
105 text,
106 });
107
108 // Cannot use `wrapper.text()`, since that automatically trims whitespace
109 expect(wrapper.element.textContent).toBe(text);
110 });
111
112 it.each([null, undefined])('gracefully handles %p', (text) => {
113 createComponent({
114 text,
115 });
116
117 // Assert prop validation failed
118 expect(wrapper).toHaveLoggedVueErrors();
119
120 // But it still rendered
121 expect(wrapper.text()).toBe('');
122 });
123});