test(SegmentationService): Adding 98.63% of test line coverage to Segmentation Service through unit tests (#5421)
This commit is contained in:
1 parent
9353a840ee
commit
12ac509c40
7 files changed
+3142
-111
No files matched your search
@@ -1,9 +1,13 @@
|
||||
const base = require('../../jest.config.base.js');
|
||||
const pkg = require('./package');
|
||||
|
||||
module.exports = {
|
||||
...base,
|
||||
displayName: pkg.name,
|
||||
moduleNameMapper: {
|
||||
...base.moduleNameMapper,
|
||||
'@ohif/(.*)': '<rootDir>/../../platform/$1/src',
|
||||
'^@cornerstonejs/([^/]+)/(.*)$': '<rootDir>/../../node_modules/@cornerstonejs/$1/dist/esm/$2',
|
||||
'^@cornerstonejs/([^/]+)$': '<rootDir>/../../node_modules/@cornerstonejs/$1/dist/esm',
|
||||
},
|
||||
// rootDir: "../.."
|
||||
// testMatch: [
|
||||
// //`<rootDir>/platform/${pack.name}/**/*.spec.js`
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -9,30 +9,34 @@ import {
|
||||
utilities as csUtils,
|
||||
metaData,
|
||||
} from '@cornerstonejs/core';
|
||||
import { ViewportType } from '@cornerstonejs/core/enums';
|
||||
|
||||
import {
|
||||
Enums as csToolsEnums,
|
||||
segmentation as cstSegmentation,
|
||||
Types as cstTypes,
|
||||
} from '@cornerstonejs/tools';
|
||||
|
||||
import { PubSubService, Types as OHIFTypes } from '@ohif/core';
|
||||
import i18n from '@ohif/i18n';
|
||||
import { EasingFunctionEnum, EasingFunctionMap } from '../../utils/transitions';
|
||||
import { mapROIContoursToRTStructData } from './RTSTRUCT/mapROIContoursToRTStructData';
|
||||
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
|
||||
import { addColorLUT } from '@cornerstonejs/tools/segmentation/addColorLUT';
|
||||
import { getNextColorLUTIndex } from '@cornerstonejs/tools/segmentation/getNextColorLUTIndex';
|
||||
import { Segment } from '@cornerstonejs/tools/types/SegmentationStateTypes';
|
||||
import { ContourStyle, LabelmapStyle, SurfaceStyle } from '@cornerstonejs/tools/types';
|
||||
import { ViewportType } from '@cornerstonejs/core/enums';
|
||||
import { SegmentationPresentation, SegmentationPresentationItem } from '../../types/Presentation';
|
||||
import { updateLabelmapSegmentationImageReferences } from '@cornerstonejs/tools/segmentation/updateLabelmapSegmentationImageReferences';
|
||||
import { triggerSegmentationRepresentationModified } from '@cornerstonejs/tools/segmentation/triggerSegmentationEvents';
|
||||
import { convertStackToVolumeLabelmap } from '@cornerstonejs/tools/segmentation/helpers/convertStackToVolumeLabelmap';
|
||||
import { getLabelmapImageIds } from '@cornerstonejs/tools/segmentation';
|
||||
import { VOLUME_LOADER_SCHEME } from '../../constants';
|
||||
|
||||
const LABELMAP = csToolsEnums.SegmentationRepresentations.Labelmap;
|
||||
const CONTOUR = csToolsEnums.SegmentationRepresentations.Contour;
|
||||
import { VOLUME_LOADER_SCHEME } from '../../constants';
|
||||
import { mapROIContoursToRTStructData } from './RTSTRUCT/mapROIContoursToRTStructData';
|
||||
import { SegmentationPresentation, SegmentationPresentationItem } from '../../types/Presentation';
|
||||
import { EasingFunctionEnum, EasingFunctionMap } from '../../utils/transitions';
|
||||
|
||||
const {
|
||||
Labelmap: LABELMAP,
|
||||
Contour: CONTOUR,
|
||||
Surface: SURFACE,
|
||||
} = csToolsEnums.SegmentationRepresentations;
|
||||
|
||||
const {
|
||||
getLabelmapImageIds,
|
||||
helpers: { convertStackToVolumeLabelmap },
|
||||
state: { addColorLUT, updateLabelmapSegmentationImageReferences },
|
||||
triggerSegmentationEvents: { triggerSegmentationRepresentationModified },
|
||||
} = cstSegmentation;
|
||||
|
||||
export type SegmentRepresentation = {
|
||||
segmentIndex: number;
|
||||
@@ -149,13 +153,11 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
const representations = this.getSegmentationRepresentations(viewportId);
|
||||
for (const representation of representations) {
|
||||
const { segmentationId } = representation;
|
||||
|
||||
if (!representation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { type } = representation;
|
||||
const { segmentationId, type } = representation;
|
||||
|
||||
segmentationsMap.set(segmentationId, {
|
||||
segmentationId,
|
||||
@@ -212,7 +214,7 @@ class SegmentationService extends PubSubService {
|
||||
viewportId: string,
|
||||
specifier: {
|
||||
segmentationId?: string;
|
||||
type?: SegmentationRepresentations;
|
||||
type?: csToolsEnums.SegmentationRepresentations;
|
||||
} = {}
|
||||
): SegmentationRepresentation[] {
|
||||
// Get all representations for the viewportId
|
||||
@@ -245,9 +247,19 @@ class SegmentationService extends PubSubService {
|
||||
this._onSegmentationDataModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_MODIFIED,
|
||||
this._onSegmentationRepresentationModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_ADDED,
|
||||
this._onSegmentationModifiedFromSource
|
||||
this._onSegmentationRepresentationModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_REMOVED,
|
||||
this._onSegmentationRepresentationModifiedFromSource
|
||||
);
|
||||
|
||||
eventTarget.removeEventListener(
|
||||
@@ -283,11 +295,11 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
const colorLUTIndex = this._segmentationIdToColorLUTIndexMap.get(segmentationId);
|
||||
|
||||
const defaultRepresentationType = csToolsEnums.SegmentationRepresentations.Labelmap;
|
||||
const defaultRepresentationType = LABELMAP;
|
||||
let representationTypeToUse = type || defaultRepresentationType;
|
||||
let isConverted = false;
|
||||
|
||||
if (type === csToolsEnums.SegmentationRepresentations.Labelmap) {
|
||||
if (representationTypeToUse === LABELMAP) {
|
||||
const { isVolumeViewport, isVolumeSegmentation } = this.determineViewportAndSegmentationType(
|
||||
csViewport,
|
||||
segmentation
|
||||
@@ -354,7 +366,7 @@ class SegmentationService extends PubSubService {
|
||||
const derivedImages = await imageLoader.createAndCacheDerivedLabelmapImages(referenceImageIds);
|
||||
|
||||
const segs = this.getSegmentations();
|
||||
const label = options.label || `Segmentation ${segs.length + 1}`;
|
||||
const label = options?.label || `Segmentation ${segs.length + 1}`;
|
||||
|
||||
const segImageIds = derivedImages.map(image => image.imageId);
|
||||
|
||||
@@ -371,7 +383,7 @@ class SegmentationService extends PubSubService {
|
||||
config: {
|
||||
label,
|
||||
segments:
|
||||
options.segments && Object.keys(options.segments).length > 0
|
||||
options?.segments && Object.keys(options.segments).length > 0
|
||||
? options.segments
|
||||
: {
|
||||
1: {
|
||||
@@ -393,7 +405,7 @@ class SegmentationService extends PubSubService {
|
||||
segDisplaySet,
|
||||
options: {
|
||||
segmentationId?: string;
|
||||
type: SegmentationRepresentations;
|
||||
type: csToolsEnums.SegmentationRepresentations;
|
||||
} = {
|
||||
type: LABELMAP,
|
||||
}
|
||||
@@ -503,9 +515,7 @@ class SegmentationService extends PubSubService {
|
||||
};
|
||||
});
|
||||
|
||||
// get next color lut index
|
||||
const colorLUTIndex = getNextColorLUTIndex();
|
||||
addColorLUT(colorLUT, colorLUTIndex);
|
||||
const colorLUTIndex = addColorLUT(colorLUT);
|
||||
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
|
||||
|
||||
this._broadcastEvent(EVENTS.SEGMENTATION_LOADING_COMPLETE, {
|
||||
@@ -540,7 +550,7 @@ class SegmentationService extends PubSubService {
|
||||
rtDisplaySet,
|
||||
options: {
|
||||
segmentationId?: string;
|
||||
type: SegmentationRepresentations;
|
||||
type: csToolsEnums.SegmentationRepresentations;
|
||||
} = {
|
||||
type: CONTOUR,
|
||||
}
|
||||
@@ -616,7 +626,9 @@ class SegmentationService extends PubSubService {
|
||||
const colorLUT = [[0, 0, 0, 0]]; // First entry is transparent for index 0
|
||||
|
||||
// Process each segment similarly to the SEG function
|
||||
for (const rtStructData of allRTStructData) {
|
||||
for (let i = 0; i < allRTStructData.length; i++) {
|
||||
const rtStructData = allRTStructData[i];
|
||||
|
||||
const { data, id, color, segmentIndex, geometryId, group } = rtStructData;
|
||||
|
||||
// Add the color to the colorLUT array
|
||||
@@ -665,8 +677,7 @@ class SegmentationService extends PubSubService {
|
||||
}
|
||||
|
||||
// Create and register the colorLUT
|
||||
const colorLUTIndex = getNextColorLUTIndex();
|
||||
addColorLUT(colorLUT, colorLUTIndex);
|
||||
const colorLUTIndex = addColorLUT(colorLUT);
|
||||
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
|
||||
|
||||
// Assign processed segments to segmentation config
|
||||
@@ -763,7 +774,7 @@ class SegmentationService extends PubSubService {
|
||||
public hasCustomStyles(specifier: {
|
||||
viewportId: string;
|
||||
segmentationId: string;
|
||||
type: SegmentationRepresentations;
|
||||
type: csToolsEnums.SegmentationRepresentations;
|
||||
}): boolean {
|
||||
return cstSegmentation.config.style.hasCustomStyle(specifier);
|
||||
}
|
||||
@@ -771,7 +782,7 @@ class SegmentationService extends PubSubService {
|
||||
public getStyle = (specifier: {
|
||||
viewportId: string;
|
||||
segmentationId: string;
|
||||
type: SegmentationRepresentations;
|
||||
type: csToolsEnums.SegmentationRepresentations;
|
||||
segmentIndex?: number;
|
||||
}) => {
|
||||
const style = cstSegmentation.config.style.getStyle(specifier);
|
||||
@@ -781,12 +792,12 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
public setStyle = (
|
||||
specifier: {
|
||||
type: SegmentationRepresentations;
|
||||
type: csToolsEnums.SegmentationRepresentations;
|
||||
viewportId?: string;
|
||||
segmentationId?: string;
|
||||
segmentIndex?: number;
|
||||
},
|
||||
style: LabelmapStyle | ContourStyle | SurfaceStyle
|
||||
style: cstTypes.LabelmapStyle | cstTypes.ContourStyle | cstTypes.SurfaceStyle
|
||||
) => {
|
||||
cstSegmentation.config.style.setStyle(specifier, style);
|
||||
};
|
||||
@@ -904,7 +915,7 @@ class SegmentationService extends PubSubService {
|
||||
segmentationId: string,
|
||||
segmentIndex: number,
|
||||
isVisible: boolean,
|
||||
type?: SegmentationRepresentations
|
||||
type?: csToolsEnums.SegmentationRepresentations
|
||||
): void {
|
||||
this._setSegmentVisibility(viewportId, segmentationId, segmentIndex, isVisible, type);
|
||||
}
|
||||
@@ -941,7 +952,7 @@ class SegmentationService extends PubSubService {
|
||||
viewportId: string,
|
||||
segmentationId: string,
|
||||
segmentIndex: number,
|
||||
type: SegmentationRepresentations
|
||||
type: csToolsEnums.SegmentationRepresentations
|
||||
): void {
|
||||
const isVisible = cstSegmentation.config.visibility.getSegmentIndexVisibility(
|
||||
viewportId,
|
||||
@@ -1013,7 +1024,7 @@ class SegmentationService extends PubSubService {
|
||||
public getLabelmapVolume(segmentationId: string) {
|
||||
const csSegmentation = cstSegmentation.state.getSegmentation(segmentationId);
|
||||
const labelmapData = csSegmentation.representationData[
|
||||
SegmentationRepresentations.Labelmap
|
||||
LABELMAP
|
||||
] as cstTypes.LabelmapToolOperationDataVolume;
|
||||
|
||||
if (!labelmapData || !labelmapData.volumeId) {
|
||||
@@ -1115,7 +1126,10 @@ class SegmentationService extends PubSubService {
|
||||
*/
|
||||
public toggleSegmentationRepresentationVisibility = (
|
||||
viewportId: string,
|
||||
{ segmentationId, type }: { segmentationId: string; type: SegmentationRepresentations }
|
||||
{
|
||||
segmentationId,
|
||||
type,
|
||||
}: { segmentationId: string; type: csToolsEnums.SegmentationRepresentations }
|
||||
): void => {
|
||||
this._toggleSegmentationRepresentationVisibility(viewportId, segmentationId, type);
|
||||
};
|
||||
@@ -1164,7 +1178,7 @@ class SegmentationService extends PubSubService {
|
||||
viewportId: string,
|
||||
specifier: {
|
||||
segmentationId?: string;
|
||||
type?: SegmentationRepresentations;
|
||||
type?: csToolsEnums.SegmentationRepresentations;
|
||||
} = {}
|
||||
): void {
|
||||
cstSegmentation.removeSegmentationRepresentations(viewportId, specifier);
|
||||
@@ -1276,7 +1290,7 @@ class SegmentationService extends PubSubService {
|
||||
private _setSegmentationRepresentationVisibility(
|
||||
viewportId: string,
|
||||
segmentationId: string,
|
||||
type: SegmentationRepresentations,
|
||||
type: csToolsEnums.SegmentationRepresentations,
|
||||
isVisible: boolean
|
||||
): void {
|
||||
const representations = this.getSegmentationRepresentations(viewportId, {
|
||||
@@ -1336,14 +1350,17 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
private async handleVolumeViewportCase(csViewport, segmentation, isVolumeSegmentation) {
|
||||
if (csViewport.type === ViewportType.VOLUME_3D) {
|
||||
return { representationTypeToUse: SegmentationRepresentations.Surface, isConverted: false };
|
||||
return {
|
||||
representationTypeToUse: SURFACE,
|
||||
isConverted: false,
|
||||
};
|
||||
} else {
|
||||
await this.handleVolumeViewport(
|
||||
csViewport as csTypes.IVolumeViewport,
|
||||
segmentation,
|
||||
isVolumeSegmentation
|
||||
);
|
||||
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted: false };
|
||||
return { representationTypeToUse: LABELMAP, isConverted: false };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1353,14 +1370,17 @@ class SegmentationService extends PubSubService {
|
||||
isVolumeSegmentation: boolean,
|
||||
viewportId: string,
|
||||
segmentationId: string
|
||||
): Promise<{ representationTypeToUse: SegmentationRepresentations; isConverted: boolean }> {
|
||||
): Promise<{
|
||||
representationTypeToUse: csToolsEnums.SegmentationRepresentations;
|
||||
isConverted: boolean;
|
||||
}> {
|
||||
if (isVolumeSegmentation) {
|
||||
const isConverted = await this.convertStackToVolumeViewport(csViewport);
|
||||
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted };
|
||||
return { representationTypeToUse: LABELMAP, isConverted };
|
||||
}
|
||||
|
||||
if (updateLabelmapSegmentationImageReferences(viewportId, segmentationId)) {
|
||||
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted: false };
|
||||
return { representationTypeToUse: LABELMAP, isConverted: false };
|
||||
}
|
||||
|
||||
const isConverted = await this.attemptStackToVolumeConversion(
|
||||
@@ -1370,7 +1390,7 @@ class SegmentationService extends PubSubService {
|
||||
segmentationId
|
||||
);
|
||||
|
||||
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted };
|
||||
return { representationTypeToUse: LABELMAP, isConverted };
|
||||
}
|
||||
|
||||
private async _addSegmentationRepresentation(
|
||||
@@ -1481,11 +1501,7 @@ class SegmentationService extends PubSubService {
|
||||
segImage.FrameOfReferenceUID === frameOfReferenceUID
|
||||
) {
|
||||
const isConverted = await this.convertStackToVolumeViewport(viewport);
|
||||
triggerSegmentationRepresentationModified(
|
||||
viewportId,
|
||||
segmentationId,
|
||||
SegmentationRepresentations.Labelmap
|
||||
);
|
||||
triggerSegmentationRepresentationModified(viewportId, segmentationId, LABELMAP);
|
||||
|
||||
return isConverted;
|
||||
}
|
||||
@@ -1613,7 +1629,7 @@ class SegmentationService extends PubSubService {
|
||||
segmentIndex: number,
|
||||
alpha: number,
|
||||
hideOthers: boolean,
|
||||
segments: Segment[],
|
||||
segments: cstTypes.Segment[],
|
||||
viewportId: string,
|
||||
animationLength: number,
|
||||
representation: cstTypes.SegmentationRepresentation,
|
||||
@@ -1685,7 +1701,7 @@ class SegmentationService extends PubSubService {
|
||||
segmentIndex: number,
|
||||
alpha: number,
|
||||
hideOthers: boolean,
|
||||
segments: Segment[],
|
||||
segments: cstTypes.Segment[],
|
||||
viewportId: string,
|
||||
animationLength: number,
|
||||
representation: cstTypes.SegmentationRepresentation,
|
||||
@@ -1696,7 +1712,7 @@ class SegmentationService extends PubSubService {
|
||||
|
||||
const prevStyle = cstSegmentation.config.style.getStyle({
|
||||
type: CONTOUR,
|
||||
}) as ContourStyle;
|
||||
}) as cstTypes.ContourStyle;
|
||||
|
||||
const prevOutlineWidth = prevStyle.outlineWidth;
|
||||
|
||||
@@ -1730,7 +1746,7 @@ class SegmentationService extends PubSubService {
|
||||
private _toggleSegmentationRepresentationVisibility = (
|
||||
viewportId: string,
|
||||
segmentationId: string,
|
||||
type: SegmentationRepresentations
|
||||
type: csToolsEnums.SegmentationRepresentations
|
||||
): void => {
|
||||
const representations = this.getSegmentationRepresentations(viewportId, {
|
||||
segmentationId,
|
||||
@@ -1798,7 +1814,7 @@ class SegmentationService extends PubSubService {
|
||||
segmentationId: string,
|
||||
segmentIndex: number,
|
||||
isVisible: boolean,
|
||||
type?: SegmentationRepresentations
|
||||
type?: csToolsEnums.SegmentationRepresentations
|
||||
) {
|
||||
cstSegmentation.config.visibility.setSegmentIndexVisibility(
|
||||
viewportId,
|
||||
|
||||
Reference in new issue
Block a user