From 6a22f31723a2319594cbb32aa34fa0e18a665584 Mon Sep 17 00:00:00 2001 From: Matthijs Smets <93487259+MatthijsSmets@users.noreply.github.com> Date: Fri, 12 Jul 2024 15:06:55 +0200 Subject: [PATCH] refactor: create class for transforming report to hierarchy structure for reusability (#499) --- .../debug/debug-tree/debug-tree.component.ts | 74 +---------------- .../classes/report-hierarchy-transformer.ts | 81 +++++++++++++++++++ 2 files changed, 83 insertions(+), 72 deletions(-) create mode 100644 src/app/shared/classes/report-hierarchy-transformer.ts diff --git a/src/app/debug/debug-tree/debug-tree.component.ts b/src/app/debug/debug-tree/debug-tree.component.ts index c6f8a425..364e0e49 100644 --- a/src/app/debug/debug-tree/debug-tree.component.ts +++ b/src/app/debug/debug-tree/debug-tree.component.ts @@ -21,8 +21,7 @@ import { NgbDropdownToggle, } from '@ng-bootstrap/ng-bootstrap'; import { ButtonComponent } from '../../shared/components/button/button.component'; -import { Checkpoint } from '../../shared/interfaces/checkpoint'; -import { CheckpointType } from '../../shared/enums/checkpoint-type'; +import { ReportHierarchyTransformer } from '../../shared/classes/report-hierarchy-transformer'; @Component({ selector: 'app-debug-tree', @@ -143,7 +142,7 @@ export class DebugTreeComponent implements OnDestroy { if (!this.showMultipleAtATime) { this.tree.clearItems(); } - const newReport: CreateTreeItem = this.transformReportToHierarchyStructure(report); + const newReport: CreateTreeItem = new ReportHierarchyTransformer().transform(report); const optional: OptionalParameters = { childrenKey: 'checkpoints', pathAttribute: 'uid' }; const path: string = this.tree.addItem(newReport, optional); this.tree.selectItem(path); @@ -152,75 +151,6 @@ export class DebugTreeComponent implements OnDestroy { } } - transformReportToHierarchyStructure(report: Report): Report { - const checkpoints = report.checkpoints; - let checkpointsTemplate: Checkpoint[] = []; - let startPointStack: Checkpoint[] = []; - - for (const checkpoint of checkpoints) { - checkpoint.icon = this.helperService.getImage(checkpoint.type, checkpoint.encoding, checkpoint.level); - - if (checkpoint.type === CheckpointType.Startpoint) { - this.handleStartpoint(checkpoint, checkpointsTemplate, startPointStack); - } else if (checkpoint.type === CheckpointType.Endpoint) { - this.handleEndpoint(checkpoint, checkpointsTemplate, startPointStack); - } else { - this.handleIntermediatePoint(checkpoint, checkpointsTemplate, startPointStack); - } - } - - report.checkpoints = checkpointsTemplate; - return report; - } - - private handleStartpoint( - checkpoint: Checkpoint, - checkpointsTemplate: Checkpoint[], - startPointStack: Checkpoint[], - ): void { - if (startPointStack.length > 0) { - this.addCheckpointToParent(checkpoint, startPointStack); - } else { - checkpointsTemplate.push(checkpoint); - } - startPointStack.push(checkpoint); - } - - private handleEndpoint( - checkpoint: Checkpoint, - checkpointsTemplate: Checkpoint[], - startPointStack: Checkpoint[], - ): void { - if (startPointStack.length > 0) { - const currentStartpoint = startPointStack.pop(); - if (currentStartpoint) { - this.addCheckpointToParent(checkpoint, [currentStartpoint]); - } - } else { - checkpointsTemplate.push(checkpoint); - } - } - - private handleIntermediatePoint( - checkpoint: Checkpoint, - checkpointsTemplate: Checkpoint[], - startPointStack: Checkpoint[], - ): void { - if (startPointStack.length > 0) { - this.addCheckpointToParent(checkpoint, startPointStack); - } else { - checkpointsTemplate.push(checkpoint); - } - } - - private addCheckpointToParent(checkpoint: Checkpoint, startPointStack: Checkpoint[]): void { - const parentStartpoint = startPointStack.at(-1)!; - if (!parentStartpoint.checkpoints) { - parentStartpoint.checkpoints = []; - } - parentStartpoint.checkpoints.push(checkpoint); - } - selectReport(value: FileTreeItem): void { this.selectReportEvent.emit(value.originalValue); } diff --git a/src/app/shared/classes/report-hierarchy-transformer.ts b/src/app/shared/classes/report-hierarchy-transformer.ts new file mode 100644 index 00000000..a22a62a7 --- /dev/null +++ b/src/app/shared/classes/report-hierarchy-transformer.ts @@ -0,0 +1,81 @@ +import { Report } from '../interfaces/report'; +import { Checkpoint } from '../interfaces/checkpoint'; +import { CHECKPOINT_TYPE_STRINGS, CheckpointType } from '../enums/checkpoint-type'; + +export class ReportHierarchyTransformer { + private readonly THROWABLE_ENCODER: string = 'printStackTrace()'; + private checkpointsTemplate: Checkpoint[] = []; + private startPointStack: Checkpoint[] = []; + + transform(report: Report): Report { + const checkpoints: Checkpoint[] = report.checkpoints; + + for (const checkpoint of checkpoints) { + checkpoint.icon = this.getImage(checkpoint.type, checkpoint.encoding, checkpoint.level); + + if (checkpoint.type === CheckpointType.Startpoint) { + this.handleStartpoint(checkpoint); + } else if (checkpoint.type === CheckpointType.Endpoint) { + this.handleEndpoint(checkpoint); + } else { + this.handleIntermediatePoint(checkpoint); + } + } + + report.checkpoints = this.checkpointsTemplate; + return report; + } + + private handleStartpoint(checkpoint: Checkpoint): void { + if (this.startPointStack.length > 0) { + this.addCheckpointToParent(checkpoint, this.startPointStack); + } else { + this.checkpointsTemplate.push(checkpoint); + } + this.startPointStack.push(checkpoint); + } + + private handleEndpoint(checkpoint: Checkpoint): void { + if (this.startPointStack.length > 0) { + const currentStartpoint = this.startPointStack.pop(); + if (currentStartpoint) { + this.addCheckpointToParent(checkpoint, [currentStartpoint]); + } + } else { + this.checkpointsTemplate.push(checkpoint); + } + } + + private handleIntermediatePoint(checkpoint: Checkpoint): void { + if (this.startPointStack.length > 0) { + this.addCheckpointToParent(checkpoint, this.startPointStack); + } else { + this.checkpointsTemplate.push(checkpoint); + } + } + + private addCheckpointToParent(checkpoint: Checkpoint, startPointStack: Checkpoint[]): void { + const parentStartpoint = startPointStack.at(-1)!; + if (!parentStartpoint.checkpoints) { + parentStartpoint.checkpoints = []; + } + parentStartpoint.checkpoints.push(checkpoint); + } + + getImage(type: CheckpointType, encoding: string, level: number): string { + const even: boolean = this.determineEvenCheckpoint(level); + let img = `assets/tree-icons/${CHECKPOINT_TYPE_STRINGS[type]}`; + if (encoding === this.THROWABLE_ENCODER) { + img += '-error'; + } + + if (even) { + return `${img}-even.gif`; + } + return `${img}-odd.gif`; + } + + private determineEvenCheckpoint(level: number): boolean { + return level % 2 == 0; + } +}