diff --git a/public/app/features/query/state/mergePanelAndDashData.test.ts b/public/app/features/query/state/mergePanelAndDashData.test.ts index ededc6a122d..e5abbd1ea90 100644 --- a/public/app/features/query/state/mergePanelAndDashData.test.ts +++ b/public/app/features/query/state/mergePanelAndDashData.test.ts @@ -1,9 +1,8 @@ -import { asyncScheduler, Observable, of, scheduled } from 'rxjs'; import { AlertState, getDefaultTimeRange, LoadingState, PanelData, toDataFrame } from '@grafana/data'; import { DashboardQueryRunnerResult } from './DashboardQueryRunner/types'; import { mergePanelAndDashData } from './mergePanelAndDashData'; -import { delay } from 'rxjs/operators'; +import { TestScheduler } from 'rxjs/testing'; function getTestContext() { const timeRange = getDefaultTimeRange(); @@ -17,104 +16,123 @@ function getTestContext() { annotations: [{ id: 'dashData' }], alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, }; - const panelObservable: Observable = scheduled(of(panelData), asyncScheduler); - const dashObservable: Observable = scheduled(of(dashData), asyncScheduler); + const scheduler: TestScheduler = new TestScheduler((actual, expected) => { + expect(actual).toEqual(expected); + }); - return { timeRange, panelObservable, dashObservable }; + return { timeRange, scheduler, panelData, dashData }; } describe('mergePanelAndDashboardData', () => { describe('when both results are fast', () => { - it('then just combine the results', async () => { - const { dashObservable, panelObservable, timeRange } = getTestContext(); + it('then just combine the results', () => { + const { panelData, dashData, timeRange, scheduler } = getTestContext(); - await expect(mergePanelAndDashData(panelObservable, dashObservable)).toEmitValuesWith((received) => { - expect(received).toHaveLength(1); - const results = received[0]; - expect(results).toEqual({ - state: LoadingState.Done, - series: [], - annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], - alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, - timeRange, + scheduler.run(({ cold, expectObservable }) => { + const panelObservable = cold('10ms a', { a: panelData }); + const dashObservable = cold('10ms a', { a: dashData }); + + const result = mergePanelAndDashData(panelObservable, dashObservable); + + expectObservable(result).toBe('10ms a', { + a: { + state: LoadingState.Done, + series: [], + annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], + alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, + timeRange, + }, }); }); + + scheduler.flush(); }); }); describe('when dashboard results are slow', () => { - it('then flush panel data first', async () => { - const { dashObservable, panelObservable, timeRange } = getTestContext(); + it('then flush panel data first', () => { + const { panelData, dashData, timeRange, scheduler } = getTestContext(); - await expect(mergePanelAndDashData(panelObservable, dashObservable.pipe(delay(250)))).toEmitValuesWith( - (received) => { - expect(received).toHaveLength(2); - const fastResults = received[0]; - const slowResults = received[1]; - expect(fastResults).toEqual({ + scheduler.run(({ cold, expectObservable }) => { + const panelObservable = cold('10ms a', { a: panelData }); + const dashObservable = cold('210ms a', { a: dashData }); + + const result = mergePanelAndDashData(panelObservable, dashObservable); + + expectObservable(result).toBe('200ms a 9ms b', { + a: { state: LoadingState.Done, series: [], annotations: [toDataFrame([{ id: 'panelData' }])], - alertState: undefined, timeRange, - }); - expect(slowResults).toEqual({ + }, + b: { state: LoadingState.Done, series: [], annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, timeRange, - }); - } - ); + }, + }); + }); + + scheduler.flush(); }); }); describe('when panel results are slow', () => { - it('then just combine the results', async () => { - const { dashObservable, panelObservable, timeRange } = getTestContext(); + it('then just combine the results', () => { + const { panelData, dashData, timeRange, scheduler } = getTestContext(); - await expect(mergePanelAndDashData(panelObservable.pipe(delay(250)), dashObservable)).toEmitValuesWith( - (received) => { - expect(received).toHaveLength(1); - const results = received[0]; - expect(results).toEqual({ + scheduler.run(({ cold, expectObservable }) => { + const panelObservable = cold('210ms a', { a: panelData }); + const dashObservable = cold('10ms a', { a: dashData }); + + const result = mergePanelAndDashData(panelObservable, dashObservable); + + expectObservable(result).toBe('210ms a', { + a: { state: LoadingState.Done, series: [], annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, timeRange, - }); - } - ); + }, + }); + }); + + scheduler.flush(); }); }); describe('when both results are slow', () => { - it('then flush panel data first', async () => { - const { dashObservable, panelObservable, timeRange } = getTestContext(); + it('then flush panel data first', () => { + const { panelData, dashData, timeRange, scheduler } = getTestContext(); - await expect( - mergePanelAndDashData(panelObservable.pipe(delay(250)), dashObservable.pipe(delay(250))) - ).toEmitValuesWith((received) => { - expect(received).toHaveLength(2); - const fastResults = received[0]; - const slowResults = received[1]; - expect(fastResults).toEqual({ - state: LoadingState.Done, - series: [], - annotations: [toDataFrame([{ id: 'panelData' }])], - alertState: undefined, - timeRange, - }); - expect(slowResults).toEqual({ - state: LoadingState.Done, - series: [], - annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], - alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, - timeRange, + scheduler.run(({ cold, expectObservable }) => { + const panelObservable = cold('210ms a', { a: panelData }); + const dashObservable = cold('210ms a', { a: dashData }); + + const result = mergePanelAndDashData(panelObservable, dashObservable); + + expectObservable(result).toBe('210ms (ab)', { + a: { + state: LoadingState.Done, + series: [], + annotations: [toDataFrame([{ id: 'panelData' }])], + timeRange, + }, + b: { + state: LoadingState.Done, + series: [], + annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], + alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, + timeRange, + }, }); }); + + scheduler.flush(); }); }); });