blob: d689f1ea764275463d3daa57bcb572fe4c4dca42 [file] [log] [blame]
/**
* 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 isValidChild from 'src/dashboard/util/isValidChild';
import {
CHART_TYPE as CHART,
COLUMN_TYPE as COLUMN,
DASHBOARD_GRID_TYPE as GRID,
DASHBOARD_ROOT_TYPE as ROOT,
DIVIDER_TYPE as DIVIDER,
HEADER_TYPE as HEADER,
MARKDOWN_TYPE as MARKDOWN,
ROW_TYPE as ROW,
TABS_TYPE as TABS,
TAB_TYPE as TAB,
} from 'src/dashboard/util/componentTypes';
const getIndentation = (depth: number) =>
Array(depth * 3)
.fill('')
.join('-');
describe('isValidChild', () => {
describe('valid calls', () => {
// these are representations of nested structures for easy testing
// [ROOT (depth 0) > GRID (depth 1) > HEADER (depth 2)]
// every unique parent > child relationship is tested, but because this
// test representation WILL result in duplicates, we hash each test
// to keep track of which we've run
const didTest = {};
const validExamples = [
[ROOT, GRID, CHART], // chart is valid because it is wrapped in a row
[ROOT, GRID, MARKDOWN], // markdown is valid because it is wrapped in a row
[ROOT, GRID, COLUMN], // column is valid because it is wrapped in a row
[ROOT, GRID, HEADER],
[ROOT, GRID, ROW, MARKDOWN],
[ROOT, GRID, ROW, CHART],
[ROOT, GRID, ROW, COLUMN, HEADER],
[ROOT, GRID, ROW, COLUMN, DIVIDER],
[ROOT, GRID, ROW, COLUMN, CHART],
[ROOT, GRID, ROW, COLUMN, MARKDOWN],
[ROOT, GRID, ROW, COLUMN, ROW, CHART],
[ROOT, GRID, ROW, COLUMN, ROW, MARKDOWN],
[ROOT, GRID, ROW, COLUMN, ROW, COLUMN, CHART],
[ROOT, GRID, ROW, COLUMN, ROW, COLUMN, MARKDOWN],
[ROOT, GRID, TABS, TAB, ROW, COLUMN, ROW, COLUMN, MARKDOWN],
// tab equivalents
[ROOT, TABS, TAB, CHART],
[ROOT, TABS, TAB, MARKDOWN],
[ROOT, TABS, TAB, COLUMN],
[ROOT, TABS, TAB, HEADER],
[ROOT, TABS, TAB, ROW, MARKDOWN],
[ROOT, TABS, TAB, ROW, CHART],
[ROOT, TABS, TAB, ROW, COLUMN, HEADER],
[ROOT, TABS, TAB, ROW, COLUMN, DIVIDER],
[ROOT, TABS, TAB, ROW, COLUMN, CHART],
[ROOT, TABS, TAB, ROW, COLUMN, MARKDOWN],
[ROOT, TABS, TAB, ROW, COLUMN, ROW, CHART],
[ROOT, TABS, TAB, ROW, COLUMN, ROW, MARKDOWN],
[ROOT, TABS, TAB, ROW, COLUMN, ROW, COLUMN, CHART],
[ROOT, TABS, TAB, ROW, COLUMN, ROW, COLUMN, MARKDOWN],
[ROOT, TABS, TAB, TABS, TAB, ROW, COLUMN, ROW, COLUMN, MARKDOWN],
];
validExamples.forEach((example, exampleIdx) => {
let childDepth = 0;
example.forEach((childType, i) => {
const parentDepth = childDepth - 1;
const parentType = example[i - 1];
const testKey = `${parentType}-${childType}-${parentDepth}`;
if (i > 0 && !didTest[testKey]) {
didTest[testKey] = true;
it(`(${exampleIdx})${getIndentation(
childDepth,
)}${parentType} (depth ${parentDepth}) > ${childType} ✅`, () => {
expect(
isValidChild({
parentDepth,
parentType,
childType,
}),
).toBe(true);
});
}
// see isValidChild.js for why tabs do not increment the depth of their children
childDepth += childType !== TABS && childType !== TAB ? 1 : 0;
});
});
});
describe('invalid calls', () => {
// In order to assert that a parent > child hierarchy at a given depth is invalid
// we also define some valid hierarchies in doing so. we indicate which
// parent > [child] relationships should be asserted as invalid using a nested array
const invalidExamples = [
[ROOT, [DIVIDER]],
[ROOT, [CHART]],
[ROOT, [MARKDOWN]],
[ROOT, GRID, [TAB]],
[ROOT, GRID, TABS, [ROW]],
// [ROOT, GRID, TABS, TAB, [TABS]], // @TODO this needs to be fixed
[ROOT, GRID, ROW, [TABS]],
[ROOT, GRID, ROW, [TAB]],
[ROOT, GRID, ROW, [DIVIDER]],
[ROOT, GRID, ROW, COLUMN, [TABS]],
[ROOT, GRID, ROW, COLUMN, [TAB]],
[ROOT, GRID, ROW, COLUMN, ROW, [DIVIDER]],
[ROOT, GRID, ROW, COLUMN, ROW, COLUMN, [ROW]], // too nested
];
invalidExamples.forEach((example, exampleIdx) => {
let childDepth = 0;
example.forEach((childType, i) => {
// should test child
if (i > 0 && Array.isArray(childType)) {
const parentDepth = childDepth - 1;
const parentType = example[i - 1];
if (typeof parentType !== 'string')
throw TypeError('parent must be string');
it(`(${exampleIdx})${getIndentation(
childDepth,
)}${parentType} (depth ${parentDepth}) > ${childType} ❌`, () => {
expect(
isValidChild({
parentDepth,
parentType,
childType: childType[0],
}),
).toBe(false);
});
}
// see isValidChild.js for why tabs do not increment the depth of their children
childDepth += childType !== TABS && childType !== TAB ? 1 : 0;
});
});
});
});