fix: superset-ui/core codes coverage (#20324)

This commit is contained in:
Yongjie Zhao 2022-06-09 17:43:42 +08:00 committed by GitHub
parent fd129873ce
commit d04357c47b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 119 additions and 48 deletions

View File

@ -47,7 +47,7 @@ module.exports = {
'tmp/', 'tmp/',
'dist/', 'dist/',
], ],
coverageReporters: ['lcov', 'json-summary', 'html'], coverageReporters: ['lcov', 'json-summary', 'html', 'text'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
snapshotSerializers: ['@emotion/jest/enzyme-serializer'], snapshotSerializers: ['@emotion/jest/enzyme-serializer'],
globals: { globals: {

View File

@ -17,17 +17,17 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import React, { ReactNode, ReactText, ReactElement } from 'react'; import React, { ReactElement, ReactNode, ReactText } from 'react';
import type { import type {
AdhocColumn, AdhocColumn,
Column, Column,
DatasourceType, DatasourceType,
JsonValue, JsonValue,
Metric, Metric,
QueryFormData,
QueryResponse,
QueryFormMetric,
QueryFormColumn, QueryFormColumn,
QueryFormData,
QueryFormMetric,
QueryResponse,
} from '@superset-ui/core'; } from '@superset-ui/core';
import { sharedControls } from './shared-controls'; import { sharedControls } from './shared-controls';
import sharedControlComponents from './shared-controls/components'; import sharedControlComponents from './shared-controls/components';
@ -437,3 +437,19 @@ export function isControlPanelSectionConfig(
): section is ControlPanelSectionConfig { ): section is ControlPanelSectionConfig {
return section !== null; return section !== null;
} }
export function isDataset(
datasource: Dataset | QueryResponse | null | undefined,
): datasource is Dataset {
return !!datasource && 'columns' in datasource;
}
export function isQueryResponse(
datasource: Dataset | QueryResponse | null | undefined,
): datasource is QueryResponse {
return (
!!datasource &&
('results' in datasource ||
datasource?.type === ('query' as DatasourceType.Query))
);
}

View File

@ -16,8 +16,8 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { QueryResponse } from '@superset-ui/core'; import { ensureIsArray, QueryResponse } from '@superset-ui/core';
import { Dataset } from '../types'; import { Dataset, isColumnMeta, isDataset, isQueryResponse } from '../types';
/** /**
* Convert Datasource columns to column choices * Convert Datasource columns to column choices
@ -25,23 +25,24 @@ import { Dataset } from '../types';
export default function columnChoices( export default function columnChoices(
datasource?: Dataset | QueryResponse | null, datasource?: Dataset | QueryResponse | null,
): [string, string][] { ): [string, string][] {
if (datasource?.columns[0]?.hasOwnProperty('column_name')) { if (isDataset(datasource) && isColumnMeta(datasource.columns[0])) {
return ( return datasource.columns
(datasource as Dataset)?.columns .map((col): [string, string] => [
.map((col): [string, string] => [ col.column_name,
col.column_name, col.verbose_name || col.column_name,
col.verbose_name || col.column_name, ])
]) .sort((opt1, opt2) =>
.sort((opt1, opt2) => opt1[1].toLowerCase() > opt2[1].toLowerCase() ? 1 : -1,
opt1[1].toLowerCase() > opt2[1].toLowerCase() ? 1 : -1, );
) || []
);
} }
return (
(datasource as QueryResponse)?.columns if (isQueryResponse(datasource)) {
return ensureIsArray(datasource.columns)
.map((col): [string, string] => [col.name, col.name]) .map((col): [string, string] => [col.name, col.name])
.sort((opt1, opt2) => .sort((opt1, opt2) =>
opt1[1].toLowerCase() > opt2[1].toLowerCase() ? 1 : -1, opt1[1].toLowerCase() > opt2[1].toLowerCase() ? 1 : -1,
) || [] );
); }
return [];
} }

View File

@ -26,30 +26,31 @@ import { defineSavedMetrics } from '@superset-ui/chart-controls';
describe('defineSavedMetrics', () => { describe('defineSavedMetrics', () => {
it('defines saved metrics if source is a Dataset', () => { it('defines saved metrics if source is a Dataset', () => {
expect( const dataset = {
defineSavedMetrics({ id: 1,
id: 1, metrics: [
metrics: [ {
{ metric_name: 'COUNT(*) non-default-dataset-metric',
metric_name: 'COUNT(*) non-default-dataset-metric', expression: 'COUNT(*) non-default-dataset-metric',
expression: 'COUNT(*) non-default-dataset-metric', },
}, ],
], type: DatasourceType.Table,
type: DatasourceType.Table, main_dttm_col: 'test',
main_dttm_col: 'test', time_grain_sqla: 'P1D',
time_grain_sqla: 'P1D', columns: [],
columns: [], verbose_map: {},
verbose_map: {}, column_format: {},
column_format: {}, datasource_name: 'my_datasource',
datasource_name: 'my_datasource', description: 'this is my datasource',
description: 'this is my datasource', };
}), expect(defineSavedMetrics(dataset)).toEqual([
).toEqual([
{ {
metric_name: 'COUNT(*) non-default-dataset-metric', metric_name: 'COUNT(*) non-default-dataset-metric',
expression: 'COUNT(*) non-default-dataset-metric', expression: 'COUNT(*) non-default-dataset-metric',
}, },
]); ]);
// @ts-ignore
expect(defineSavedMetrics({ ...dataset, metrics: undefined })).toEqual([]);
}); });
it('returns default saved metrics if souce is a Query', () => { it('returns default saved metrics if souce is a Query', () => {

View File

@ -22,7 +22,6 @@ export * from './utils';
export * from './types'; export * from './types';
export * from './translation'; export * from './translation';
export * from './connection'; export * from './connection';
export * from './dashboard';
export * from './dynamic-plugins'; export * from './dynamic-plugins';
export * from './query'; export * from './query';
export * from './number-format'; export * from './number-format';

View File

@ -127,3 +127,5 @@ export type DashboardComponentMetadata = {
nativeFilters: NativeFiltersState; nativeFilters: NativeFiltersState;
dataMask: DataMaskStateWithId; dataMask: DataMaskStateWithId;
}; };
export default {};

View File

@ -362,16 +362,16 @@ export const testQuery: Query = {
type: DatasourceType.Query, type: DatasourceType.Query,
is_dttm: false, is_dttm: false,
}, },
{
name: 'Column 2',
type: DatasourceType.Query,
is_dttm: true,
},
{ {
name: 'Column 3', name: 'Column 3',
type: DatasourceType.Query, type: DatasourceType.Query,
is_dttm: false, is_dttm: false,
}, },
{
name: 'Column 2',
type: DatasourceType.Query,
is_dttm: true,
},
], ],
}; };

View File

@ -27,6 +27,7 @@ export * from './QueryResponse';
export * from './Time'; export * from './Time';
export * from './AdvancedAnalytics'; export * from './AdvancedAnalytics';
export * from './PostProcessing'; export * from './PostProcessing';
export * from './Dashboard';
export { default as __hack_reexport_Datasource } from './Datasource'; export { default as __hack_reexport_Datasource } from './Datasource';
export { default as __hack_reexport_Column } from './Column'; export { default as __hack_reexport_Column } from './Column';
@ -36,5 +37,6 @@ export { default as __hack_reexport_QueryResponse } from './QueryResponse';
export { default as __hack_reexport_QueryFormData } from './QueryFormData'; export { default as __hack_reexport_QueryFormData } from './QueryFormData';
export { default as __hack_reexport_Time } from './Time'; export { default as __hack_reexport_Time } from './Time';
export { default as __hack_reexport_AdvancedAnalytics } from './AdvancedAnalytics'; export { default as __hack_reexport_AdvancedAnalytics } from './AdvancedAnalytics';
export { default as __hack_reexport_Dashboard } from './Dashboard';
export default {}; export default {};

View File

@ -0,0 +1,47 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
isNativeFilter,
isFilterDivider,
Filter,
NativeFilterType,
} from '@superset-ui/core';
test('should do native filter type guard', () => {
const dummyFilter: Filter = {
cascadeParentIds: [],
defaultDataMask: {},
id: 'dummyID',
name: 'dummyName',
scope: { rootPath: [], excluded: [] },
filterType: 'dummyType',
targets: [{}],
controlValues: {},
type: NativeFilterType.NATIVE_FILTER,
description: 'dummyDesc',
};
expect(isNativeFilter(dummyFilter)).toBeTruthy();
expect(
isFilterDivider({
...dummyFilter,
type: NativeFilterType.DIVIDER,
title: 'dummyTitle',
}),
).toBeTruthy();
});

View File

@ -16,5 +16,8 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { getUiOverrideRegistry } from '@superset-ui/core';
export * from './types/Base'; test('should get instance of getUiOverrideRegistry', () => {
expect(getUiOverrideRegistry().name).toBe('UiOverrideRegistry');
});