Skip to content

Commit 388e660

Browse files
author
Alan Smith
committed
Add tests
1 parent 4125e2c commit 388e660

File tree

6 files changed

+224
-65
lines changed

6 files changed

+224
-65
lines changed

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist
2+
node_modules

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
22
"name": "vue3-highcharts",
33
"version": "0.1.0",
4-
"main": "./src/index.js",
4+
"main": "./dist/vue3-highcharts.common.js",
55
"private": false,
66
"scripts": {
77
"test": "vue-cli-service test:unit",
88
"lint": "vue-cli-service lint",
9+
"build": "vue-cli-service build --target lib --name vue3-highcharts src/index.js",
910
"publish": "npm run lint && npm run test && npm publish"
1011
},
1112
"author": "Alan Smith <[email protected]>",

src/index.js

Lines changed: 6 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,9 @@
1-
/* eslint-disable func-names */
2-
/* eslint-disable prefer-rest-params */
3-
import { h, ref, watch, onMounted, onUnmounted, defineComponent, toRefs } from 'vue';
4-
import Highcharts from 'highcharts';
1+
import Vue3Highcharts from './vue3-highcharts';
52

6-
export default defineComponent({
7-
props: {
8-
type: {
9-
type: String,
10-
default: 'chart',
11-
},
12-
options: {
13-
type: Object,
14-
required: true,
15-
},
16-
},
3+
const install = (app) => {
4+
app.component(Vue3Highcharts.name, Vue3Highcharts);
5+
};
176

18-
setup(props, { emit }) {
19-
const chartRef = ref(null);
7+
Vue3Highcharts.install = install;
208

21-
const { options } = toRefs(props);
22-
23-
if (options.value && Highcharts[props.constructorType]) {
24-
const chart = ref(null);
25-
26-
watch(options, (newValue) => {
27-
if (chart.value) {
28-
chart.value.update(newValue, ...props.updateArgs);
29-
emit('updated');
30-
}
31-
});
32-
33-
onMounted(() => {
34-
chart.value = Highcharts[props.constructorType](chartRef.value, options.value, () => {
35-
emit('rendered');
36-
});
37-
});
38-
39-
onUnmounted(() => {
40-
if (chart.value) chart.value.destroy();
41-
emit('destroyed');
42-
});
43-
44-
return () => h('div', {
45-
class: 'vue3-highcharts',
46-
ref: chartRef,
47-
});
48-
}
49-
50-
if (!props.options) {
51-
console.warn('The "options" parameter is required.');
52-
} else {
53-
console.warn(`${props.constructorType} is not a valid highcharts type`);
54-
}
55-
56-
return () => h();
57-
},
58-
});
9+
export default Vue3Highcharts;

src/vue3-highcharts.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* eslint-disable func-names */
2+
/* eslint-disable prefer-rest-params */
3+
import { defineComponent, h, ref, onMounted, onUnmounted, watch, toRefs } from 'vue';
4+
import Highcharts from 'highcharts';
5+
6+
const vueHighcharts = defineComponent({
7+
name: 'VueHighchart',
8+
props: {
9+
type: {
10+
type: String,
11+
default: 'chart',
12+
},
13+
14+
options: {
15+
type: Object,
16+
required: true,
17+
},
18+
19+
redrawOnUpdate: {
20+
type: Boolean,
21+
default: true,
22+
},
23+
24+
oneToOneUpdate: {
25+
type: Boolean,
26+
default: false,
27+
},
28+
29+
animateOnUpdate: {
30+
type: Boolean,
31+
default: true,
32+
},
33+
},
34+
35+
setup(props, { emit }) {
36+
const chartRef = ref(null);
37+
const chart = ref(null);
38+
39+
const { options } = toRefs(props);
40+
41+
if (options.value && Highcharts[props.type]) {
42+
watch(options, (newValue) => {
43+
if (chart.value) {
44+
chart.value.update(newValue, props.redrawOnUpdate, props.oneToOneOnUpdate, props.oneToOneUpdate, props.animateOnUpdate);
45+
emit('updated');
46+
}
47+
});
48+
49+
onMounted(() => {
50+
chart.value = Highcharts[props.type](chartRef.value, options.value, () => {
51+
emit('rendered');
52+
});
53+
});
54+
55+
onUnmounted(() => {
56+
if (chart.value) chart.value.destroy();
57+
emit('destroyed');
58+
});
59+
} else if (!props.options) {
60+
console.warn('The "options" parameter is required.');
61+
} else {
62+
console.warn(`${props.type} is not a valid highcharts type or has not been imported`);
63+
}
64+
65+
// Rather than returning a render function here. We'll return the chart ref and highcharts
66+
// instance so there exposed.
67+
return {
68+
chartRef,
69+
chart,
70+
};
71+
},
72+
73+
render() {
74+
return h('div', {
75+
class: 'vue-highcharts',
76+
ref: 'chartRef',
77+
});
78+
},
79+
});
80+
81+
export default vueHighcharts;

tests/unit/index.spec.js

Lines changed: 126 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,130 @@
1-
import { shallowMount } from '@vue/test-utils';
2-
import Chart from '@/index';
1+
import { mount } from '@vue/test-utils';
2+
import VueHighchart from '@/index';
3+
import { wrap } from 'highcharts';
34

4-
describe('HelloWorld.vue', () => {
5-
it('renders props.msg when passed', () => {
6-
const msg = 'new message';
7-
const wrapper = shallowMount(Chart, {
8-
props: { msg },
5+
const defaultOptions = {
6+
series: [{
7+
name: 'Test Series',
8+
data: [1, 2, 3],
9+
}],
10+
};
11+
12+
describe('VueHighchart', () => {
13+
describe('Plugin', () => {
14+
it('should install when used as a plugin', () => {
15+
const componentStub = jest.fn();
16+
17+
const appMock = {
18+
component: componentStub,
19+
};
20+
21+
expect(VueHighchart).toHaveProperty('install');
22+
23+
VueHighchart.install(appMock);
24+
25+
expect(componentStub).toHaveBeenCalledWith(VueHighchart.name, VueHighchart);
26+
});
27+
});
28+
29+
describe('Component', () => {
30+
let wrapper = null;
31+
32+
afterEach(() => {
33+
if (wrapper) {
34+
wrapper.unmount();
35+
wrapper = null;
36+
}
37+
});
38+
39+
it('should have the correct props', () => {
40+
wrapper = mount(VueHighchart, {
41+
props: {
42+
options: { ...defaultOptions },
43+
},
44+
});
45+
46+
expect(wrapper.props()).toEqual({
47+
type: 'chart',
48+
options: { ...defaultOptions },
49+
redrawOnUpdate: true,
50+
oneToOneUpdate: false,
51+
animateOnUpdate: true,
52+
});
53+
});
54+
55+
it('should expose the rendered highcharts instance', () => {
56+
wrapper = mount(VueHighchart, {
57+
props: {
58+
options: { ...defaultOptions },
59+
},
60+
});
61+
62+
expect(wrapper.vm.chart).toBeDefined();
63+
});
64+
65+
it('should render a highchart chart with the expected data', () => {
66+
wrapper = mount(VueHighchart, {
67+
props: {
68+
options: { ...defaultOptions },
69+
},
70+
});
71+
72+
const { vm } = wrapper;
73+
74+
expect(wrapper.get('.vue-highcharts')).toBeTruthy();
75+
expect(wrapper.get('.highcharts-container')).toBeTruthy();
76+
77+
expect(vm.chart.series[0].yData).toEqual(wrapper.props().options.series[0].data);
78+
expect(vm.chart.series[0].name).toEqual(wrapper.props().options.series[0].name);
79+
});
80+
81+
it('should emit a rendered event when the chart is rendered', () => {
82+
wrapper = mount(VueHighchart, {
83+
props: {
84+
options: { ...defaultOptions },
85+
},
86+
});
87+
88+
expect(wrapper.emitted()).toHaveProperty('rendered');
89+
});
90+
91+
it('should emit an updated event when the chart is updated due to options changes', async () => {
92+
const options = { ...defaultOptions };
93+
94+
wrapper = mount(VueHighchart, {
95+
props: {
96+
options,
97+
},
98+
});
99+
100+
expect(wrapper.get('.highcharts-container')).toBeTruthy();
101+
102+
await wrapper.setProps({
103+
options: {
104+
series: [{
105+
name: 'Test Series 2',
106+
data: [1, 2, 3, 4],
107+
}],
108+
},
109+
});
110+
111+
expect(wrapper.emitted()).toHaveProperty('updated');
112+
});
113+
114+
it('should emit a destroyed event when the highcharts instance is destroyed', async () => {
115+
const options = { ...defaultOptions };
116+
117+
wrapper = mount(VueHighchart, {
118+
props: {
119+
options,
120+
},
121+
});
122+
123+
expect(wrapper.get('.highcharts-container')).toBeTruthy();
124+
125+
wrapper.unmount();
126+
127+
expect(wrapper.emitted()).toHaveProperty('destroyed');
9128
});
10-
expect(wrapper.text()).toMatch(msg);
11129
});
12130
});

vue.config.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
module.exports = {
22
configureWebpack: {
3-
externals: ['highcharts', 'vue'],
3+
externals: {
4+
highcharts: {
5+
root: 'Highcharts',
6+
commonjs: 'highcharts',
7+
commonjs2: 'highcharts',
8+
},
9+
},
410
},
511
};

0 commit comments

Comments
 (0)