mirror of
https://github.com/apache/superset.git
synced 2026-04-07 10:31:50 +00:00
chore: Moves spec files to the src folder - iteration 4 (#14380)
This commit is contained in:
committed by
GitHub
parent
331310db9b
commit
68058b0ad9
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* 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 { cacheWrapper } from 'src/utils/cacheWrapper';
|
||||
|
||||
describe('cacheWrapper', () => {
|
||||
const fnResult = 'fnResult';
|
||||
const fn = jest.fn<string, [number, number]>().mockReturnValue(fnResult);
|
||||
|
||||
let wrappedFn: (a: number, b: number) => string;
|
||||
|
||||
beforeEach(() => {
|
||||
const cache = new Map<string, any>();
|
||||
wrappedFn = cacheWrapper(fn, cache);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('calls fn with its arguments once when the key is not found', () => {
|
||||
const returnedValue = wrappedFn(1, 2);
|
||||
|
||||
expect(returnedValue).toEqual(fnResult);
|
||||
expect(fn).toBeCalledTimes(1);
|
||||
expect(fn).toBeCalledWith(1, 2);
|
||||
});
|
||||
|
||||
describe('subsequent calls', () => {
|
||||
it('returns the correct value without fn being called multiple times', () => {
|
||||
const returnedValue1 = wrappedFn(1, 2);
|
||||
const returnedValue2 = wrappedFn(1, 2);
|
||||
|
||||
expect(returnedValue1).toEqual(fnResult);
|
||||
expect(returnedValue2).toEqual(fnResult);
|
||||
expect(fn).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it('fn is called multiple times for different arguments', () => {
|
||||
wrappedFn(1, 2);
|
||||
wrappedFn(1, 3);
|
||||
|
||||
expect(fn).toBeCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with custom keyFn', () => {
|
||||
let cache: Map<string, any>;
|
||||
|
||||
beforeEach(() => {
|
||||
cache = new Map<string, any>();
|
||||
wrappedFn = cacheWrapper(fn, cache, (...args) => `key-${args[0]}`);
|
||||
});
|
||||
|
||||
it('saves fn result in cache under generated key', () => {
|
||||
wrappedFn(1, 2);
|
||||
expect(cache.get('key-1')).toEqual(fnResult);
|
||||
});
|
||||
|
||||
it('subsequent calls with same generated key calls fn once, even if other arguments have changed', () => {
|
||||
wrappedFn(1, 1);
|
||||
wrappedFn(1, 2);
|
||||
wrappedFn(1, 3);
|
||||
|
||||
expect(fn).toBeCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,89 +0,0 @@
|
||||
/**
|
||||
* 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 {
|
||||
applyFormattingToTabularData,
|
||||
optionFromValue,
|
||||
prepareCopyToClipboardTabularData,
|
||||
NULL_STRING,
|
||||
} from 'src/utils/common';
|
||||
|
||||
describe('utils/common', () => {
|
||||
describe('optionFromValue', () => {
|
||||
it('converts values as expected', () => {
|
||||
expect(optionFromValue(false)).toEqual({
|
||||
value: false,
|
||||
label: '<false>',
|
||||
});
|
||||
expect(optionFromValue(true)).toEqual({ value: true, label: '<true>' });
|
||||
expect(optionFromValue(null)).toEqual({
|
||||
value: NULL_STRING,
|
||||
label: NULL_STRING,
|
||||
});
|
||||
expect(optionFromValue('')).toEqual({
|
||||
value: '',
|
||||
label: '<empty string>',
|
||||
});
|
||||
expect(optionFromValue('foo')).toEqual({ value: 'foo', label: 'foo' });
|
||||
expect(optionFromValue(5)).toEqual({ value: 5, label: '5' });
|
||||
});
|
||||
});
|
||||
describe('prepareCopyToClipboardTabularData', () => {
|
||||
it('converts empty array', () => {
|
||||
const array = [];
|
||||
expect(prepareCopyToClipboardTabularData(array)).toEqual('');
|
||||
});
|
||||
it('converts non empty array', () => {
|
||||
const array = [
|
||||
{ column1: 'lorem', column2: 'ipsum' },
|
||||
{ column1: 'dolor', column2: 'sit', column3: 'amet' },
|
||||
];
|
||||
expect(prepareCopyToClipboardTabularData(array)).toEqual(
|
||||
'lorem\tipsum\ndolor\tsit\tamet\n',
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('applyFormattingToTabularData', () => {
|
||||
it('does not mutate empty array', () => {
|
||||
const data = [];
|
||||
expect(applyFormattingToTabularData(data)).toEqual(data);
|
||||
});
|
||||
it('does not mutate array without temporal column', () => {
|
||||
const data = [
|
||||
{ column1: 'lorem', column2: 'ipsum' },
|
||||
{ column1: 'dolor', column2: 'sit', column3: 'amet' },
|
||||
];
|
||||
expect(applyFormattingToTabularData(data)).toEqual(data);
|
||||
});
|
||||
it('changes formatting of temporal column', () => {
|
||||
const originalData = [
|
||||
{ __timestamp: null, column1: 'lorem' },
|
||||
{ __timestamp: 0, column1: 'ipsum' },
|
||||
{ __timestamp: 1594285437771, column1: 'dolor' },
|
||||
{ __timestamp: 1594285441675, column1: 'sit' },
|
||||
];
|
||||
const expectedData = [
|
||||
{ __timestamp: null, column1: 'lorem' },
|
||||
{ __timestamp: '1970-01-01 00:00:00', column1: 'ipsum' },
|
||||
{ __timestamp: '2020-07-09 09:03:57', column1: 'dolor' },
|
||||
{ __timestamp: '2020-07-09 09:04:01', column1: 'sit' },
|
||||
];
|
||||
expect(applyFormattingToTabularData(originalData)).toEqual(expectedData);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* 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 { ErrorTypeEnum } from 'src/components/ErrorMessage/types';
|
||||
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||
|
||||
describe('getClientErrorObject()', () => {
|
||||
it('Returns a Promise', () => {
|
||||
const response = getClientErrorObject('error');
|
||||
expect(response instanceof Promise).toBe(true);
|
||||
});
|
||||
|
||||
it('Returns a Promise that resolves to an object with an error key', () => {
|
||||
const error = 'error';
|
||||
|
||||
return getClientErrorObject(error).then(errorObj => {
|
||||
expect(errorObj).toMatchObject({ error });
|
||||
});
|
||||
});
|
||||
|
||||
it('Handles Response that can be parsed as json', () => {
|
||||
const jsonError = { something: 'something', error: 'Error message' };
|
||||
const jsonErrorString = JSON.stringify(jsonError);
|
||||
|
||||
return getClientErrorObject(new Response(jsonErrorString)).then(
|
||||
errorObj => {
|
||||
expect(errorObj).toMatchObject(jsonError);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('Handles backwards compatibility between old error messages and the new SIP-40 errors format', () => {
|
||||
const jsonError = {
|
||||
errors: [
|
||||
{
|
||||
error_type: ErrorTypeEnum.GENERIC_DB_ENGINE_ERROR,
|
||||
extra: { engine: 'presto', link: 'https://www.google.com' },
|
||||
level: 'error',
|
||||
message: 'presto error: test error',
|
||||
},
|
||||
],
|
||||
};
|
||||
const jsonErrorString = JSON.stringify(jsonError);
|
||||
|
||||
return getClientErrorObject(new Response(jsonErrorString)).then(
|
||||
errorObj => {
|
||||
expect(errorObj.error).toEqual(jsonError.errors[0].message);
|
||||
expect(errorObj.link).toEqual(jsonError.errors[0].extra.link);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('Handles Response that can be parsed as text', () => {
|
||||
const textError = 'Hello I am a text error';
|
||||
|
||||
return getClientErrorObject(new Response(textError)).then(errorObj => {
|
||||
expect(errorObj).toMatchObject({ error: textError });
|
||||
});
|
||||
});
|
||||
|
||||
it('Handles plain text as input', () => {
|
||||
const error = 'error';
|
||||
|
||||
return getClientErrorObject(error).then(errorObj => {
|
||||
expect(errorObj).toMatchObject({ error });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* 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 { getChartControlPanelRegistry, t } from '@superset-ui/core';
|
||||
import getControlsForVizType from 'src/utils/getControlsForVizType';
|
||||
|
||||
const fakePluginControls = {
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: 'Fake Control Panel Sections',
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['label_colors'],
|
||||
[
|
||||
{
|
||||
name: 'y_axis_bounds',
|
||||
config: {
|
||||
type: 'BoundsControl',
|
||||
label: 'Value bounds',
|
||||
default: [null, null],
|
||||
description: 'Value bounds for the y axis',
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'adhoc_filters',
|
||||
config: {
|
||||
type: 'AdhocFilterControl',
|
||||
label: 'Fake Filters',
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Fake Control Panel Sections 2',
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[
|
||||
{
|
||||
name: 'column_collection',
|
||||
config: {
|
||||
type: 'CollectionControl',
|
||||
label: 'Fake Collection Control',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe('getControlsForVizType', () => {
|
||||
beforeEach(() => {
|
||||
getChartControlPanelRegistry().registerValue(
|
||||
'chart_controls_inventory_fake',
|
||||
fakePluginControls,
|
||||
);
|
||||
});
|
||||
|
||||
it('returns a map of the controls', () => {
|
||||
expect(
|
||||
JSON.stringify(getControlsForVizType('chart_controls_inventory_fake')),
|
||||
).toEqual(
|
||||
JSON.stringify({
|
||||
label_colors: {
|
||||
type: 'ColorMapControl',
|
||||
label: t('Color map'),
|
||||
default: {},
|
||||
renderTrigger: true,
|
||||
mapStateToProps: state => ({
|
||||
colorNamespace: state.form_data.color_namespace,
|
||||
colorScheme: state.form_data.color_scheme,
|
||||
}),
|
||||
},
|
||||
y_axis_bounds: {
|
||||
type: 'BoundsControl',
|
||||
label: 'Value bounds',
|
||||
default: [null, null],
|
||||
description: 'Value bounds for the y axis',
|
||||
},
|
||||
adhoc_filters: {
|
||||
type: 'AdhocFilterControl',
|
||||
label: 'Fake Filters',
|
||||
default: null,
|
||||
},
|
||||
column_collection: {
|
||||
type: 'CollectionControl',
|
||||
label: 'Fake Collection Control',
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* 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 parseCookie from 'src/utils/parseCookie';
|
||||
|
||||
describe('parseCookie', () => {
|
||||
let cookieVal = '';
|
||||
Object.defineProperty(document, 'cookie', {
|
||||
get: jest.fn().mockImplementation(() => cookieVal),
|
||||
});
|
||||
it('parses cookie strings', () => {
|
||||
cookieVal = 'val1=foo; val2=bar';
|
||||
expect(parseCookie()).toEqual({ val1: 'foo', val2: 'bar' });
|
||||
});
|
||||
|
||||
it('parses empty cookie strings', () => {
|
||||
cookieVal = '';
|
||||
expect(parseCookie()).toEqual({});
|
||||
});
|
||||
|
||||
it('accepts an arg', () => {
|
||||
expect(parseCookie('val=foo')).toEqual({ val: 'foo' });
|
||||
});
|
||||
});
|
||||
@@ -1,114 +0,0 @@
|
||||
/**
|
||||
* 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 { safeStringify } from 'src/utils/safeStringify';
|
||||
|
||||
class Noise {
|
||||
public next?: Noise;
|
||||
}
|
||||
|
||||
describe('Stringify utility testing', () => {
|
||||
it('correctly parses a simple object just like JSON', () => {
|
||||
const noncircular = {
|
||||
b: 'foo',
|
||||
c: 'bar',
|
||||
d: [
|
||||
{
|
||||
e: 'hello',
|
||||
f: ['world'],
|
||||
},
|
||||
{
|
||||
e: 'hello',
|
||||
f: ['darkness', 'my', 'old', 'friend'],
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(safeStringify(noncircular)).toEqual(JSON.stringify(noncircular));
|
||||
// Checking that it works with quick-deepish-copies as well.
|
||||
expect(JSON.parse(safeStringify(noncircular))).toEqual(
|
||||
JSON.parse(JSON.stringify(noncircular)),
|
||||
);
|
||||
});
|
||||
|
||||
it('handles simple circular json as expected', () => {
|
||||
const ping = new Noise();
|
||||
const pong = new Noise();
|
||||
const pang = new Noise();
|
||||
ping.next = pong;
|
||||
pong.next = ping;
|
||||
|
||||
// ping.next is pong (the circular reference) now
|
||||
const safeString = safeStringify(ping);
|
||||
ping.next = pang;
|
||||
|
||||
// ping.next is pang now, which has no circular reference, so it's safe to use JSON.stringify
|
||||
const ordinaryString = JSON.stringify(ping);
|
||||
expect(safeString).toEqual(ordinaryString);
|
||||
});
|
||||
|
||||
it('creates a parseable object even when the input is circular', () => {
|
||||
const ping = new Noise();
|
||||
const pong = new Noise();
|
||||
ping.next = pong;
|
||||
pong.next = ping;
|
||||
|
||||
const newNoise: Noise = JSON.parse(safeStringify(ping));
|
||||
expect(newNoise).toBeTruthy();
|
||||
expect(newNoise.next).toEqual({});
|
||||
});
|
||||
|
||||
it('does not remove noncircular duplicates', () => {
|
||||
const a = {
|
||||
foo: 'bar',
|
||||
};
|
||||
|
||||
const repeating = {
|
||||
first: a,
|
||||
second: a,
|
||||
third: a,
|
||||
};
|
||||
|
||||
expect(safeStringify(repeating)).toEqual(JSON.stringify(repeating));
|
||||
});
|
||||
|
||||
it('does not remove nodes with empty objects', () => {
|
||||
const emptyObjectValues = {
|
||||
a: {},
|
||||
b: 'foo',
|
||||
c: {
|
||||
d: 'good data here',
|
||||
e: {},
|
||||
},
|
||||
};
|
||||
expect(safeStringify(emptyObjectValues)).toEqual(
|
||||
JSON.stringify(emptyObjectValues),
|
||||
);
|
||||
});
|
||||
|
||||
it('does not remove nested same keys', () => {
|
||||
const nestedKeys = {
|
||||
a: 'b',
|
||||
c: {
|
||||
a: 'd',
|
||||
x: 'y',
|
||||
},
|
||||
};
|
||||
|
||||
expect(safeStringify(nestedKeys)).toEqual(JSON.stringify(nestedKeys));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user