From df0f1ebc4b249c12374392e5cf78174dc0b8118e Mon Sep 17 00:00:00 2001 From: md-prog <26860200+md-prog@users.noreply.github.com> Date: Mon, 27 Mar 2023 12:21:28 -0400 Subject: [PATCH 1/4] [bugfix] give default values for cachedStats values to avoid undefined error --- src/tools/annotation/EllipticalRoiTool.js | 9 ++++++++- src/tools/annotation/RectangleRoiTool.js | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/tools/annotation/EllipticalRoiTool.js b/src/tools/annotation/EllipticalRoiTool.js index 43ffbff5f..a1d534aa4 100644 --- a/src/tools/annotation/EllipticalRoiTool.js +++ b/src/tools/annotation/EllipticalRoiTool.js @@ -355,7 +355,14 @@ function _getUnit(modality, showHounsfieldUnits) { function _createTextBoxContent( context, isColorImage, - { area, mean, stdDev, min, max, meanStdDevSUV } = {}, + { + area = 0, + mean = 0, + stdDev = 0, + min = 0, + max = 0, + meanStdDevSUV = 0, + } = {}, modality, hasPixelSpacing, options = {} diff --git a/src/tools/annotation/RectangleRoiTool.js b/src/tools/annotation/RectangleRoiTool.js index 173692f38..4f2405489 100644 --- a/src/tools/annotation/RectangleRoiTool.js +++ b/src/tools/annotation/RectangleRoiTool.js @@ -478,7 +478,14 @@ function _getUnit(modality, showHounsfieldUnits) { function _createTextBoxContent( context, isColorImage, - { area, mean, stdDev, min, max, meanStdDevSUV }, + { + area = 0, + mean = 0, + stdDev = 0, + min = 0, + max = 0, + meanStdDevSUV = 0, + } = {}, modality, hasPixelSpacing, options = {} From 26484c67ba88149eaf339dcd2b10137cf32bb9b4 Mon Sep 17 00:00:00 2001 From: md-prog <26860200+md-prog@users.noreply.github.com> Date: Mon, 27 Mar 2023 12:39:28 -0400 Subject: [PATCH 2/4] coding rule fix --- src/tools/annotation/EllipticalRoiTool.js | 9 +-------- src/tools/annotation/RectangleRoiTool.js | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/tools/annotation/EllipticalRoiTool.js b/src/tools/annotation/EllipticalRoiTool.js index a1d534aa4..fe7e3baa4 100644 --- a/src/tools/annotation/EllipticalRoiTool.js +++ b/src/tools/annotation/EllipticalRoiTool.js @@ -355,14 +355,7 @@ function _getUnit(modality, showHounsfieldUnits) { function _createTextBoxContent( context, isColorImage, - { - area = 0, - mean = 0, - stdDev = 0, - min = 0, - max = 0, - meanStdDevSUV = 0, - } = {}, + { area = 0, mean = 0, stdDev = 0, min = 0, max = 0, meanStdDevSUV = 0 } = {}, modality, hasPixelSpacing, options = {} diff --git a/src/tools/annotation/RectangleRoiTool.js b/src/tools/annotation/RectangleRoiTool.js index 4f2405489..f0c1ce3bf 100644 --- a/src/tools/annotation/RectangleRoiTool.js +++ b/src/tools/annotation/RectangleRoiTool.js @@ -478,14 +478,7 @@ function _getUnit(modality, showHounsfieldUnits) { function _createTextBoxContent( context, isColorImage, - { - area = 0, - mean = 0, - stdDev = 0, - min = 0, - max = 0, - meanStdDevSUV = 0, - } = {}, + { area = 0, mean = 0, stdDev = 0, min = 0, max = 0, meanStdDevSUV = 0 } = {}, modality, hasPixelSpacing, options = {} From 3e5b11074db9f3d812fc96e68831b06e00433285 Mon Sep 17 00:00:00 2001 From: md-prog <26860200+md-prog@users.noreply.github.com> Date: Mon, 27 Mar 2023 13:47:24 -0400 Subject: [PATCH 3/4] added new tests to increaes coverage --- .../annotation/EllipticalRoiTool.test.js | 81 +++++++++++++++++++ src/tools/annotation/RectangleRoiTool.test.js | 81 +++++++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/src/tools/annotation/EllipticalRoiTool.test.js b/src/tools/annotation/EllipticalRoiTool.test.js index cb67e91f6..0d3ae6fcd 100644 --- a/src/tools/annotation/EllipticalRoiTool.test.js +++ b/src/tools/annotation/EllipticalRoiTool.test.js @@ -1,11 +1,27 @@ import EllipticalRoiTool from './EllipticalRoiTool.js'; import { getToolState } from './../../stateManagement/toolState.js'; import { getLogger } from '../../util/logger.js'; +import getNewContext from '../../drawing/getNewContext.js'; +import drawEllipse from '../../drawing/drawEllipse.js'; + +/* ~ Setup + * To mock properly, Jest needs jest.mock('moduleName') to be in the + * same scope as the require/import statement. + */ +import external from '../../externalModules.js'; jest.mock('../../util/logger.js'); jest.mock('./../../stateManagement/toolState.js', () => ({ getToolState: jest.fn(), })); +jest.mock('../../drawing/drawEllipse', () => ({ + __esModule: true, + default: jest.fn(), +})); +jest.mock('../../drawing/getNewContext', () => ({ + __esModule: true, + default: jest.fn(), +})); jest.mock('./../../importInternal.js', () => ({ default: jest.fn(), @@ -19,6 +35,7 @@ jest.mock('./../../externalModules.js', () => ({ /* eslint-disable prettier/prettier */ getPixels: () => [100, 100, 100, 100, 4, 5, 100, 3, 6], /* eslint-enable prettier/prettier */ + pixelToCanvas: jest.fn(), }, })); @@ -215,6 +232,20 @@ describe('EllipticalRoiTool.js', () => { }); describe('renderToolData', () => { + beforeAll(() => { + getNewContext.mockReturnValue({ + save: jest.fn(), + restore: jest.fn(), + beginPath: jest.fn(), + arc: jest.fn(), + stroke: jest.fn(), + fillRect: jest.fn(), + fillText: jest.fn(), + measureText: jest.fn(() => ({ width: 1 })), + }); + external.cornerstone.pixelToCanvas.mockImplementation((comp, val) => val); + }); + it('returns undefined when no toolData exists for the tool', () => { const instantiatedTool = new EllipticalRoiTool(); const mockEvent = { @@ -228,5 +259,55 @@ describe('EllipticalRoiTool.js', () => { expect(renderResult).toBe(undefined); }); + + describe('draw ellipse with color', () => { + const defaulColor = 'white'; + const mockEvent = { + detail: { + element: {}, + canvasContext: { + canvas: {}, + }, + image: {}, + viewport: {}, + }, + }; + const instantiatedTool = new EllipticalRoiTool({ + configuration: {}, + }); + + const toolState = { + data: [ + { + visible: true, + active: false, + handles: { + start: { + x: 0, + y: 0, + }, + end: { + x: 3, + y: 3, + }, + textBox: {}, + }, + }, + ], + }; + + const expectDraw = color => { + expect(drawEllipse.mock.calls.length).toBe(1); + }; + + it('should draw an ellipse with the inactive color', () => { + toolState.data[0].active = false; + getToolState.mockReturnValue(toolState); + + instantiatedTool.renderToolData(mockEvent); + + expectDraw(defaulColor); + }); + }); }); }); diff --git a/src/tools/annotation/RectangleRoiTool.test.js b/src/tools/annotation/RectangleRoiTool.test.js index 03c43e3a4..1c25161fd 100644 --- a/src/tools/annotation/RectangleRoiTool.test.js +++ b/src/tools/annotation/RectangleRoiTool.test.js @@ -1,11 +1,27 @@ import RectangleRoiTool from './RectangleRoiTool.js'; import { getToolState } from './../../stateManagement/toolState.js'; import { getLogger } from '../../util/logger.js'; +import getNewContext from '../../drawing/getNewContext.js'; +import drawRect from '../../drawing/drawRect.js'; + +/* ~ Setup + * To mock properly, Jest needs jest.mock('moduleName') to be in the + * same scope as the require/import statement. + */ +import external from '../../externalModules.js'; jest.mock('../../util/logger.js'); jest.mock('./../../stateManagement/toolState.js', () => ({ getToolState: jest.fn(), })); +jest.mock('../../drawing/drawRect', () => ({ + __esModule: true, + default: jest.fn(), +})); +jest.mock('../../drawing/getNewContext', () => ({ + __esModule: true, + default: jest.fn(), +})); jest.mock('./../../importInternal.js', () => ({ default: jest.fn(), @@ -19,6 +35,7 @@ jest.mock('./../../externalModules.js', () => ({ /* eslint-enable prettier/prettier */ getPixels: () => [100, 100, 100, 100, 4, 5, 100, 3, 6], /* eslint-enable prettier/prettier */ + pixelToCanvas: jest.fn(), }, })); @@ -218,6 +235,20 @@ describe('RectangleRoiTool.js', () => { }); describe('renderToolData', () => { + beforeAll(() => { + getNewContext.mockReturnValue({ + save: jest.fn(), + restore: jest.fn(), + beginPath: jest.fn(), + arc: jest.fn(), + stroke: jest.fn(), + fillRect: jest.fn(), + fillText: jest.fn(), + measureText: jest.fn(() => ({ width: 1 })), + }); + external.cornerstone.pixelToCanvas.mockImplementation((comp, val) => val); + }); + it('returns undefined when no toolData exists for the tool', () => { const instantiatedTool = new RectangleRoiTool(); const mockEvent = { @@ -231,5 +262,55 @@ describe('RectangleRoiTool.js', () => { expect(renderResult).toBe(undefined); }); + + describe('draw rectangle with color', () => { + const defaulColor = 'white'; + const mockEvent = { + detail: { + element: {}, + canvasContext: { + canvas: {}, + }, + image: {}, + viewport: {}, + }, + }; + const instantiatedTool = new RectangleRoiTool({ + configuration: {}, + }); + + const toolState = { + data: [ + { + visible: true, + active: false, + handles: { + start: { + x: 0, + y: 0, + }, + end: { + x: 3, + y: 3, + }, + textBox: {}, + }, + }, + ], + }; + + const expectDraw = color => { + expect(drawRect.mock.calls.length).toBe(1); + }; + + it('should draw a rectangle with the inactive color', () => { + toolState.data[0].active = false; + getToolState.mockReturnValue(toolState); + + instantiatedTool.renderToolData(mockEvent); + + expectDraw(defaulColor); + }); + }); }); }); From d675825806da917d62a54da36f5dda1615594daf Mon Sep 17 00:00:00 2001 From: md-prog <26860200+md-prog@users.noreply.github.com> Date: Mon, 27 Mar 2023 13:53:45 -0400 Subject: [PATCH 4/4] test refactor --- src/tools/annotation/RectangleRoiTool.test.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tools/annotation/RectangleRoiTool.test.js b/src/tools/annotation/RectangleRoiTool.test.js index 1c25161fd..49726902c 100644 --- a/src/tools/annotation/RectangleRoiTool.test.js +++ b/src/tools/annotation/RectangleRoiTool.test.js @@ -23,10 +23,6 @@ jest.mock('../../drawing/getNewContext', () => ({ default: jest.fn(), })); -jest.mock('./../../importInternal.js', () => ({ - default: jest.fn(), -})); - jest.mock('./../../externalModules.js', () => ({ cornerstone: { metaData: {