Skip to content

Commit

Permalink
feat: validate on unique ID values
Browse files Browse the repository at this point in the history
  • Loading branch information
BrightGrafana committed Oct 17, 2023
1 parent baa2440 commit ad8c4de
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 5 deletions.
6 changes: 2 additions & 4 deletions src/utils.test.ts
Expand Up @@ -50,7 +50,7 @@ describe('Utils', () => {
} as unknown as PanelData;

const result = Utils.extractSelectedTreeNodes(data, ['2', '4'], 'id');
console.log(result);

expect(result).toEqual({
length: 2,
fields: [
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('Utils', () => {
const result = Utils.dfToNodeArray(new MutableDataFrame(data), 'id', 'parentId', 'label');

expect(result).toEqual([
{ name: 'Node 1', id: '1', parent: null, children: [] },
{ name: 'Node 1', id: '1', parent: undefined, children: [] },
{ name: 'Node 2', id: '2', parent: '1', children: [] },
]);
});
Expand All @@ -115,7 +115,6 @@ describe('Utils', () => {
{ id: '2', children: [], parent: 'n1', name: 'n2' },
{ id: '3', children: [], parent: 'n1', name: 'n3' },
],
parent: null,
name: 'n1',
},
{
Expand All @@ -130,7 +129,6 @@ describe('Utils', () => {
name: 'n5',
},
],
parent: null,
name: 'n4',
},
];
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Expand Up @@ -76,7 +76,7 @@ export class Utils {
return data.map((dfRow) => ({
name: `${dfRow[labelColumn]}`,
id: `${dfRow[idColumn]}`,
parent: dfRow[parentColumn] != null ? `${dfRow[parentColumn]}` : null,
parent: dfRow[parentColumn] != null ? `${dfRow[parentColumn]}` : undefined,
children: [] as Node[],
}));
}
Expand Down
39 changes: 39 additions & 0 deletions src/validator.test.ts
@@ -0,0 +1,39 @@
import { Validator } from 'validator';
import { Node } from './models';

describe('Validator', () => {
describe('validateTreeInput', () => {
it('should throw error if ids are duplicated', () => {
// arrange
const input: Node[] = [
{ id: '1', name: 'n1', children: [] },
{ id: '1', name: 'n1', children: [] },
];

// act
const result = () => Validator.validateTreeInput(input);

// assert
expect(result).toThrowError('Duplicated ID found for: 1');
});

it('should throw error if ids are duplicated in child nodes', () => {
// arrange
const input: Node[] = [
{ id: '1', name: 'n1', children: [{ id: '1', name: 'n1', children: [] }] },
];

// act
const result = () => Validator.validateTreeInput(input);

// assert
expect(result).toThrowError('Duplicated ID found for: 1');
});
});
});
// id, label, parent
// 1, n1,
// 2, n2, 1
// 3, , 1
// 3, , 1
// 4, n4n,3
38 changes: 38 additions & 0 deletions src/validator.ts
@@ -0,0 +1,38 @@
import { Node } from './models';

/**
* A utility class for validating a tree structure represented by an array of nodes.
*/
export class Validator {
/**
* Validates the input tree for duplicate node IDs and child relationships.
* @param {Node[]} tree - The array of nodes representing the tree structure.
* @throws {Error} If a duplicate node ID is found.
*/
public static validateTreeInput(tree: Node[]): void {
/**
* Set to store encountered node IDs.
* @type {Set<Node['id']>}
*/
const nodeIds: Set<Node['id']> = new Set();

/**
* Recursively validates node IDs and child relationships.
* @param {Node} node - The node to validate.
* @throws {Error} If a duplicate node ID is found.
*/
function validateIds(node: Node): void {
if (nodeIds.has(node.id)) {
throw new Error(`Duplicated ID found for: ${node.id}`);
}

nodeIds.add(node.id);

if (node.children) {
node.children.forEach(validateIds);
}
}

tree.forEach(validateIds);
}
}

0 comments on commit ad8c4de

Please sign in to comment.