Skip to content

Commit 8ef677e

Browse files
Add tests
1 parent 46d3ac1 commit 8ef677e

File tree

5 files changed

+242
-60
lines changed

5 files changed

+242
-60
lines changed
Lines changed: 140 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,171 @@
11
import VCodeBlock from '../VCodeBlock.vue';
2+
import { h } from 'vue';
23
import { describe, it, expect } from 'vitest';
34
import { mount } from '@vue/test-utils';
45
import { pluginName } from '../utils/globals';
5-
6+
import { codeBlockOptions } from '../';
67

78
describe('VCodeBlock Component', () => {
89

9-
it('should mount the component', () => {
10-
const wrapper = mount(VCodeBlock, {
11-
props: {
12-
prismjs: true,
13-
}
10+
// -------------------------------------------------- Component //
11+
describe('Component', () => {
12+
it('should mount the component', () => {
13+
const wrapper = mount(VCodeBlock, {
14+
props: { highlightjs: true }
15+
});
16+
17+
const returnedProps = wrapper.getComponent(VCodeBlock).props();
18+
19+
expect(returnedProps).toMatchSnapshot();
1420
});
1521

16-
const returnedProps = wrapper.getComponent(VCodeBlock).props();
22+
it('should mount the component using global options', () => {
23+
const wrapper = mount(VCodeBlock, {
24+
global: {
25+
provide: {
26+
[codeBlockOptions]: {
27+
browserWindow: true,
28+
},
29+
}
30+
},
31+
props: { highlightjs: true }
32+
});
1733

18-
expect(returnedProps).toMatchSnapshot();
34+
expect(wrapper.html()).toContain('v-code-block--code-browser');
35+
});
1936
});
2037

21-
it('should emit run event', () => {
22-
const wrapper = mount(VCodeBlock, {
23-
props: {
24-
prismjs: true,
25-
runTab: true,
26-
tabs: true,
27-
}
28-
});
2938

30-
wrapper.find(`.${pluginName}--tab-run`).trigger('click');
39+
// -------------------------------------------------- Slots //
40+
describe('Slots', () => {
41+
it('should use label slot', () => {
42+
const wrapper = mount(VCodeBlock, {
43+
props: { highlightjs: true },
44+
slots: {
45+
label: h('div', { class: 'using-label-slot' }, 'Hello World'),
46+
}
47+
});
3148

32-
expect(wrapper.emitted()).toHaveProperty('run');
33-
});
49+
const labelHtml = wrapper.find('.using-label-slot').html();
3450

51+
expect(labelHtml).toMatchSnapshot();
52+
});
3553

36-
// -------------------------------------------------- Errors //
37-
const throwErrors = {
38-
bothSet: '[vue-code-block]: You cannot have both prismjs and highlightjs props set at the same time.',
39-
neitherSet: '[vue-code-block]: You must set either the prismjs or highlightjs props.',
40-
};
41-
42-
it('should throw error if both prismjs and highlightjs props are true', () => {
43-
expect(() => {
44-
mount(VCodeBlock, {
45-
props: {
46-
prismjs: true,
47-
highlightjs: true,
54+
it('should use tabs slot', () => {
55+
const wrapper = mount(VCodeBlock, {
56+
props: { highlightjs: true },
57+
slots: {
58+
tabs: h('div', { class: 'using-tabs-slot' }, 'This is the tabs slot'),
4859
}
4960
});
50-
}).toThrowError(throwErrors.bothSet);
51-
});
5261

53-
it('should throw error if both prismjs and highlightjs props are not set', () => {
54-
expect(() => {
55-
mount(VCodeBlock, {
56-
props: {
62+
const tabsHtml = wrapper.find('.using-tabs-slot').html();
63+
64+
expect(tabsHtml).toMatchSnapshot();
65+
});
66+
67+
it('should use copyButton slot', () => {
68+
const wrapper = mount(VCodeBlock, {
69+
props: { highlightjs: true },
70+
slots: {
71+
copyButton: h('div', { class: 'using-copy-button-slot' }, 'This is the copy button slot'),
5772
}
5873
});
59-
}).toThrowError(throwErrors.neitherSet);
74+
75+
const copyButtonSlotHtml = wrapper.find('.using-copy-button-slot').html();
76+
77+
expect(copyButtonSlotHtml).toMatchSnapshot();
78+
});
6079
});
6180

62-
it('should throw error if neither prismjs or highlightjs props are true', () => {
63-
expect(() => {
64-
mount(VCodeBlock, {
81+
82+
// -------------------------------------------------- Events //
83+
describe('Events', () => {
84+
it('should emit run event', () => {
85+
const wrapper = mount(VCodeBlock, {
6586
props: {
66-
prismjs: false,
67-
highlightjs: false,
87+
prismjs: true,
88+
runTab: true,
89+
tabs: true,
6890
}
6991
});
70-
}).toThrowError(throwErrors.neitherSet);
92+
93+
wrapper.find(`.${pluginName}--tab-run`).trigger('click');
94+
95+
expect(wrapper.emitted()).toHaveProperty('run');
96+
});
7197
});
7298

73-
it('should throw error if highlightjs used with prismPlugin prop', () => {
74-
expect(() => {
75-
mount(VCodeBlock, {
76-
props: {
77-
highlightjs: true,
78-
prismPlugin: true,
79-
}
99+
100+
// -------------------------------------------------- Attributes //
101+
describe('Attributes', () => {
102+
it('should add class hljs class to code tag when highlightjs prop is true', () => {
103+
const wrapper = mount(VCodeBlock, {
104+
props: { highlightjs: true }
80105
});
81-
}).toThrowError('[vue-code-block]: Highlight.js does not support PrismJS plugins. Unexpected results may occur. Remove the `prism-plugin` prop from the vue-code-block component.');
106+
107+
const codeTag = wrapper.getComponent(VCodeBlock).find('code').attributes();
108+
109+
expect(codeTag.class).toContain('hljs');
110+
});
111+
112+
it('should add class attribute line-numbers to pre tag', () => {
113+
const wrapper = mount(VCodeBlock, {
114+
attrs: { class: 'line-numbers' },
115+
props: { highlightjs: true }
116+
});
117+
118+
const preTag = wrapper.getComponent(VCodeBlock).find('pre').attributes();
119+
120+
expect(preTag.class).toContain('line-numbers');
121+
});
122+
});
123+
124+
125+
// -------------------------------------------------- Errors //
126+
describe('Errors', () => {
127+
const throwErrors = {
128+
bothSet: '[vue-code-block]: You cannot have both prismjs and highlightjs props set at the same time.',
129+
neitherSet: '[vue-code-block]: You must set either the prismjs or highlightjs props.',
130+
};
131+
132+
it('should throw error if both prismjs and highlightjs props are true', () => {
133+
expect(() => {
134+
mount(VCodeBlock, {
135+
props: {
136+
prismjs: true,
137+
highlightjs: true,
138+
}
139+
});
140+
}).toThrowError(throwErrors.bothSet);
141+
});
142+
143+
it('should throw error if both prismjs and highlightjs props are not set', () => {
144+
expect(() => {
145+
mount(VCodeBlock);
146+
}).toThrowError(throwErrors.neitherSet);
147+
});
148+
149+
it('should throw error if neither prismjs or highlightjs props are true', () => {
150+
expect(() => {
151+
mount(VCodeBlock, {
152+
props: {
153+
prismjs: false,
154+
highlightjs: false,
155+
}
156+
});
157+
}).toThrowError(throwErrors.neitherSet);
158+
});
159+
160+
it('should throw error if highlightjs used with prismPlugin prop', () => {
161+
expect(() => {
162+
mount(VCodeBlock, {
163+
props: {
164+
highlightjs: true,
165+
prismPlugin: true,
166+
}
167+
});
168+
}).toThrowError('[vue-code-block]: Highlight.js does not support PrismJS plugins. Unexpected results may occur. Remove the `prism-plugin` prop from the vue-code-block component.');
169+
});
82170
});
83171
});

src/plugin/__tests__/__snapshots__/VCodeBlock.test.ts.snap

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`VCodeBlock Component > should mount the component 1`] = `
3+
exports[`VCodeBlock Component > Component > should ... 1`] = `
44
{
55
"browserWindow": false,
66
"code": "",
@@ -15,19 +15,57 @@ exports[`VCodeBlock Component > should mount the component 1`] = `
1515
"floatingTabs": true,
1616
"globalOptions": false,
1717
"height": "auto",
18-
"highlightjs": false,
18+
"highlightjs": true,
1919
"indent": 2,
2020
"label": "",
2121
"lang": "javascript",
2222
"languages": undefined,
2323
"maxHeight": "auto",
2424
"persistentCopyButton": false,
2525
"prismPlugin": false,
26-
"prismjs": true,
26+
"prismjs": false,
2727
"runTab": false,
2828
"runText": "Run",
2929
"tabGap": "0.25rem",
3030
"tabs": false,
3131
"theme": "neon-bunny",
3232
}
3333
`;
34+
35+
exports[`VCodeBlock Component > Component > should mount the component 1`] = `
36+
{
37+
"browserWindow": false,
38+
"code": "",
39+
"codeBlockRadius": "0.5rem",
40+
"copyButton": true,
41+
"copyFailedText": "Copy failed!",
42+
"copyIcons": true,
43+
"copySuccessText": "Copied!",
44+
"copyTab": true,
45+
"copyText": "Copy Code",
46+
"cssPath": undefined,
47+
"floatingTabs": true,
48+
"globalOptions": false,
49+
"height": "auto",
50+
"highlightjs": true,
51+
"indent": 2,
52+
"label": "",
53+
"lang": "javascript",
54+
"languages": undefined,
55+
"maxHeight": "auto",
56+
"persistentCopyButton": false,
57+
"prismPlugin": false,
58+
"prismjs": false,
59+
"runTab": false,
60+
"runText": "Run",
61+
"tabGap": "0.25rem",
62+
"tabs": false,
63+
"theme": "neon-bunny",
64+
}
65+
`;
66+
67+
exports[`VCodeBlock Component > Slots > should use copyButton slot 1`] = `"<div class="using-copy-button-slot">This is the copy button slot</div>"`;
68+
69+
exports[`VCodeBlock Component > Slots > should use label slot 1`] = `"<div class="using-label-slot">Hello World</div>"`;
70+
71+
exports[`VCodeBlock Component > Slots > should use tabs slot 1`] = `"<div class="using-tabs-slot">This is the tabs slot</div>"`;

src/plugin/__tests__/index.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ import { createVCodeBlock } from '../';
33

44

55
describe('Plugin Index', () => {
6-
describe('install', () => {
7-
it('should return install function', () => {
8-
const VCodeBlock = createVCodeBlock();
6+
it('should return install function', () => {
7+
const VCodeBlock = createVCodeBlock();
98

10-
expect('install' in VCodeBlock).toBe(true);
11-
});
9+
expect('install' in VCodeBlock).toBe(true);
1210
});
1311
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import StatusIcons from '../StatusIcons.vue';
2+
import { describe, it, expect } from 'vitest';
3+
import { mount } from '@vue/test-utils';
4+
5+
6+
describe('StatusIcons Component', () => {
7+
8+
it('should mount the copy icon', () => {
9+
const wrapper = mount(StatusIcons, {
10+
props: { icon: 'copy' }
11+
});
12+
13+
expect(wrapper.html()).toMatchSnapshot();
14+
});
15+
16+
it('should mount the success icon', () => {
17+
const wrapper = mount(StatusIcons, {
18+
props: { icon: 'success' }
19+
});
20+
21+
expect(wrapper.html()).toMatchSnapshot();
22+
});
23+
24+
it('should mount the failed icon', () => {
25+
const wrapper = mount(StatusIcons, {
26+
props: { icon: 'failed' }
27+
});
28+
29+
expect(wrapper.html()).toMatchSnapshot();
30+
});
31+
});
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`StatusIcons Component > should mount the copy icon 1`] = `
4+
"<!-- Copy Icon -->
5+
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
6+
<!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
7+
<path d="M224 0c-35.3 0-64 28.7-64 64V288c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H224zM64 160c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H288c35.3 0 64-28.7 64-64V384H288v64H64V224h64V160H64z"></path>
8+
</svg>"
9+
`;
10+
11+
exports[`StatusIcons Component > should mount the failed icon 1`] = `
12+
"<!-- Copy Icon -->
13+
<!-- Failed Icon -->
14+
<svg viewBox="0 0 320 512" xmlns="http://www.w3.org/2000/svg">
15+
<!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
16+
<path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"></path>
17+
</svg>"
18+
`;
19+
20+
exports[`StatusIcons Component > should mount the success icon 1`] = `
21+
"<!-- Copy Icon -->
22+
<!-- Success Icon -->
23+
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
24+
<!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
25+
<path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"></path>
26+
</svg>"
27+
`;

0 commit comments

Comments
 (0)