Skip to content

Commit 8d3a500

Browse files
richipargopaveltiunov
authored andcommitted
fix: support for deep nested watchers on 'QueryRenderer' (#207)
* support for deep nested watchers on 'QueryRenderer' * missing on queries as well * add test script replacing test:unit
1 parent e5d9ae7 commit 8d3a500

File tree

4 files changed

+110
-15
lines changed

4 files changed

+110
-15
lines changed

packages/cubejs-vue/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"serve": "vue-cli-service serve",
88
"build": "vue-cli-service build",
99
"lint": "vue-cli-service lint",
10+
"test": "vue-cli-service test:unit",
1011
"test:unit": "vue-cli-service test:unit",
1112
"test:unit:watch": "vue-cli-service test:unit --watch --require tests/setup.js"
1213
},
@@ -17,7 +18,7 @@
1718
"src"
1819
],
1920
"dependencies": {
20-
"core-js": "^2.6.5",
21+
"core-js": "^2.6.9",
2122
"ramda": "^0.26.1"
2223
},
2324
"devDependencies": {

packages/cubejs-vue/src/QueryRenderer.js

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default {
3636
const { query, queries } = this;
3737

3838
if (query) {
39-
await this.load(query);
39+
await this.load();
4040
}
4141

4242
if (queries) {
@@ -58,7 +58,7 @@ export default {
5858
const slotProps = {
5959
resultSet,
6060
sqlQuery,
61-
query: this.builderProps.query,
61+
query: this.builderProps.query || this.query,
6262
};
6363

6464
if (onlyDefault) {
@@ -84,7 +84,8 @@ export default {
8484
);
8585
},
8686
methods: {
87-
async load(query) {
87+
async load() {
88+
const { query } = this;
8889
try {
8990
this.loading = true;
9091
this.error = undefined;
@@ -107,7 +108,8 @@ export default {
107108
this.loading = false;
108109
}
109110
},
110-
async loadQueries(queries) {
111+
async loadQueries() {
112+
const { queries } = this;
111113
try {
112114
this.error = undefined;
113115
this.loading = true;
@@ -126,15 +128,21 @@ export default {
126128
},
127129
},
128130
watch: {
129-
query(val) {
130-
if (val) {
131-
this.load(val);
132-
}
131+
query: {
132+
handler(val) {
133+
if (val) {
134+
this.load();
135+
}
136+
},
137+
deep: true,
133138
},
134-
queries(val) {
135-
if (val) {
136-
this.loadQueries(val);
137-
}
139+
queries: {
140+
handler(val) {
141+
if (val) {
142+
this.loadQueries();
143+
}
144+
},
145+
deep: true,
138146
},
139147
},
140148
};

packages/cubejs-vue/tests/unit/QueryRenderer.spec.js

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { shallowMount } from '@vue/test-utils';
1+
import { shallowMount, mount } from '@vue/test-utils';
22
import CubejsApi from '@cubejs-client/core';
33
import flushPromises from 'flush-promises';
44
import QueryRenderer from '../../src/QueryRenderer';
5-
import fetchMock, { load } from './__mocks__/responses';
5+
import fetchMock, { load, single } from './__mocks__/responses';
66

77
describe('QueryRenderer.vue', () => {
88
describe('Loads single query from api', () => {
@@ -67,5 +67,58 @@ describe('QueryRenderer.vue', () => {
6767
expect(wrapper.text()).toContain('Result set is loaded');
6868
expect(cube.request.mock.calls.length).toBe(1);
6969
});
70+
71+
it('Rerender on query nested property change', async () => {
72+
const cube = CubejsApi('token');
73+
jest.spyOn(cube, 'request').mockImplementation(fetchMock(single));
74+
75+
const parent = mount({
76+
components: {
77+
QueryRenderer,
78+
},
79+
template: `
80+
<div>
81+
<query-renderer :cubejs-api="cubejsApi" :query="query" v-slot="{ query }">
82+
<span class="query">{{query}}</span>
83+
</query-renderer>
84+
</div>
85+
`,
86+
data() {
87+
return {
88+
cubejsApi: cube ,
89+
query: {
90+
measures: ['Stories.count'],
91+
dimensions: [],
92+
filters: [],
93+
segments: [],
94+
timeDimensions: [],
95+
},
96+
};
97+
},
98+
});
99+
100+
await flushPromises();
101+
102+
expect(cube.request.mock.calls.length).toBe(1);
103+
expect(parent.find('.query').element.textContent).toContain('Stories.count');
104+
105+
parent.vm.query.measures = ['Users.count'];
106+
await flushPromises();
107+
108+
expect(cube.request.mock.calls.length).toBe(2);
109+
expect(parent.find('.query').element.textContent).toContain('Users.count');
110+
111+
parent.vm.query.measures.push('Users.count');
112+
await flushPromises();
113+
114+
expect(cube.request.mock.calls.length).toBe(3);
115+
expect(parent.find('.query').element.textContent).toContain('Users.count');
116+
117+
parent.vm.query.timeDimensions.push({ dimension: 'Users.count', dateRange: 'last 6 days', granularity: 'week' });
118+
await flushPromises();
119+
120+
expect(cube.request.mock.calls.length).toBe(4);
121+
expect(parent.find('.query').element.textContent).toContain('week');
122+
});
70123
});
71124
});

packages/cubejs-vue/tests/unit/__mocks__/responses.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,39 @@ export const load = {
697697
}
698698
};
699699

700+
export const single = {
701+
"query": {
702+
"measures": [
703+
"Users.count"
704+
],
705+
"dimensions": [],
706+
"timezone": "UTC",
707+
"timeDimensions": []
708+
},
709+
"data": [
710+
{
711+
"Users.city": "Mülheim",
712+
"Users.count": "4"
713+
},
714+
{
715+
"Users.city": "Metairie",
716+
"Users.count": "4"
717+
},
718+
],
719+
"annotation": {
720+
"measures": {
721+
"Users.count": {
722+
"title": "Users Count",
723+
"shortTitle": "Count",
724+
"type": "number"
725+
}
726+
},
727+
"dimensions": {},
728+
"segments": {},
729+
"timeDimensions": {}
730+
}
731+
};
732+
700733
export const sql = {};
701734

702735
export default (body = {}, status = 200) => () => Promise.resolve({

0 commit comments

Comments
 (0)