diff --git a/core/dialog.ts b/core/dialog.ts index ade36aa25..7e2112985 100644 --- a/core/dialog.ts +++ b/core/dialog.ts @@ -6,6 +6,31 @@ // Former goog.module ID: Blockly.dialog +let alertImplementation = function ( + message: string, + opt_callback?: () => void, +) { + window.alert(message); + if (opt_callback) { + opt_callback(); + } +}; + +let confirmImplementation = function ( + message: string, + callback: (result: boolean) => void, +) { + callback(window.confirm(message)); +}; + +let promptImplementation = function ( + message: string, + defaultValue: string, + callback: (result: string | null) => void, +) { + callback(window.prompt(message, defaultValue)); +}; + /** * Wrapper to window.alert() that app developers may override via setAlert to * provide alternatives to the modal browser window. @@ -13,12 +38,9 @@ * @param message The message to display to the user. * @param opt_callback The callback when the alert is dismissed. */ -export let alert = (message: string, opt_callback?: () => void) => { - window.alert(message); - if (opt_callback) { - opt_callback(); - } -}; +export function alert(message: string, opt_callback?: () => void) { + alertImplementation(message, opt_callback); +} /** * Sets the function to be run when Blockly.dialog.alert() is called. @@ -26,10 +48,8 @@ export let alert = (message: string, opt_callback?: () => void) => { * @param alertFunction The function to be run. * @see Blockly.dialog.alert */ -export function setAlert( - alertFunction: (message: string, callback?: () => void) => void, -) { - alert = alertFunction; +export function setAlert(alertFunction: (p1: string, p2?: () => void) => void) { + alertImplementation = alertFunction; } /** @@ -39,12 +59,16 @@ export function setAlert( * @param message The message to display to the user. * @param callback The callback for handling user response. */ -export let confirm = ( - message: string, - callback: (confirmed: boolean) => void, -) => { - callback(window.confirm(message)); -}; +export function confirm(message: string, callback: (p1: boolean) => void) { + TEST_ONLY.confirmInternal(message, callback); +} + +/** + * Private version of confirm for stubbing in tests. + */ +function confirmInternal(message: string, callback: (p1: boolean) => void) { + confirmImplementation(message, callback); +} /** * Sets the function to be run when Blockly.dialog.confirm() is called. @@ -53,12 +77,9 @@ export let confirm = ( * @see Blockly.dialog.confirm */ export function setConfirm( - confirmFunction: ( - message: string, - callback: (confirmed: boolean) => void, - ) => void, + confirmFunction: (p1: string, p2: (p1: boolean) => void) => void, ) { - confirm = confirmFunction; + confirmImplementation = confirmFunction; } /** @@ -71,13 +92,13 @@ export function setConfirm( * @param defaultValue The value to initialize the prompt with. * @param callback The callback for handling user response. */ -export let prompt = ( +export function prompt( message: string, defaultValue: string, - callback: (userInput: string | null) => void, -) => { - callback(window.prompt(message, defaultValue)); -}; + callback: (p1: string | null) => void, +) { + promptImplementation(message, defaultValue, callback); +} /** * Sets the function to be run when Blockly.dialog.prompt() is called. @@ -87,10 +108,14 @@ export let prompt = ( */ export function setPrompt( promptFunction: ( - message: string, - defaultValue: string, - callback: (userInput: string | null) => void, + p1: string, + p2: string, + p3: (p1: string | null) => void, ) => void, ) { - prompt = promptFunction; + promptImplementation = promptFunction; } + +export const TEST_ONLY = { + confirmInternal, +}; diff --git a/tests/mocha/contextmenu_items_test.js b/tests/mocha/contextmenu_items_test.js index ef1a9530c..4596513c6 100644 --- a/tests/mocha/contextmenu_items_test.js +++ b/tests/mocha/contextmenu_items_test.js @@ -322,10 +322,10 @@ suite('Context Menu Items', function () { }); test('Deletes all blocks after confirming', function () { - // Mocks the confirmation dialog and calls the callback with 'true' - // simulating ok. - const confirmStub = sinon.stub().callsArgWith(1, true); - Blockly.dialog.setConfirm(confirmStub); + // Mocks the confirmation dialog and calls the callback with 'true' simulating ok. + const confirmStub = sinon + .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') + .callsArgWith(1, true); this.workspace.newBlock('text'); this.workspace.newBlock('text'); @@ -337,8 +337,9 @@ suite('Context Menu Items', function () { test('Does not delete blocks if not confirmed', function () { // Mocks the confirmation dialog and calls the callback with 'false' simulating cancel. - const confirmStub = sinon.stub().callsArgWith(1, false); - Blockly.dialog.setConfirm(confirmStub); + const confirmStub = sinon + .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') + .callsArgWith(1, false); this.workspace.newBlock('text'); this.workspace.newBlock('text'); @@ -349,9 +350,10 @@ suite('Context Menu Items', function () { }); test('No dialog for single block', function () { - const confirmStub = sinon.stub(); - Blockly.dialog.setConfirm(confirmStub); - + const confirmStub = sinon.stub( + Blockly.dialog.TEST_ONLY, + 'confirmInternal', + ); this.workspace.newBlock('text'); this.deleteOption.callback(this.scope); this.clock.runAll(); diff --git a/tests/mocha/dialog_test.js b/tests/mocha/dialog_test.js deleted file mode 100644 index 22831c58d..000000000 --- a/tests/mocha/dialog_test.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -suite.only('Dialog', function () { - teardown(function () { - sinon.restore(); - }); - - suite('Prompt', function () { - test('setPrompt can take in a function with additional parameters', function () { - const spy = sinon.spy(); - Blockly.dialog.setPrompt(spy); - const callback = () => {}; - - Blockly.dialog.prompt( - 'message', - 'defaultVal', - callback, - 'extra parameter', - ); - - chai.assert.isTrue( - spy.calledWith('message', 'defaultVal', callback, 'extra parameter'), - ); - }); - }); - - suite('Confirm', function () { - test('setConfirm can take in a function with additional parameters', function () { - const spy = sinon.spy(); - Blockly.dialog.setConfirm(spy); - const callback = () => {}; - - Blockly.dialog.confirm('message', callback, 'extra parameter'); - - chai.assert.isTrue( - spy.calledWith('message', callback, 'extra parameter'), - ); - }); - }); - - suite('Alert', function () { - test('setAlert can take in a function with additional parameters', function () { - const spy = sinon.spy(); - Blockly.dialog.setAlert(spy); - const callback = () => {}; - - Blockly.dialog.alert('message', callback, 'extra parameter'); - - chai.assert.isTrue( - spy.calledWith('message', callback, 'extra parameter'), - ); - }); - }); -}); diff --git a/tests/mocha/index.html b/tests/mocha/index.html index 34738605a..9c7b10cab 100644 --- a/tests/mocha/index.html +++ b/tests/mocha/index.html @@ -52,7 +52,6 @@ import './contextmenu_items_test.js'; import './contextmenu_test.js'; import './cursor_test.js'; - import './dialog_test.js'; import './dropdowndiv_test.js'; import './event_test.js'; import './event_block_change_test.js'; diff --git a/tests/mocha/test_helpers/workspace.js b/tests/mocha/test_helpers/workspace.js index ce8822019..6da113f8b 100644 --- a/tests/mocha/test_helpers/workspace.js +++ b/tests/mocha/test_helpers/workspace.js @@ -99,8 +99,9 @@ export function testAWorkspace() { test('deleteVariableById(id2) one usage', function () { // Deleting variable one usage should not trigger confirm dialog. - const stub = sinon.stub().callsArgWith(1, true); - Blockly.dialog.setConfirm(stub); + const stub = sinon + .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') + .callsArgWith(1, true); this.workspace.deleteVariableById('id2'); sinon.assert.notCalled(stub); @@ -112,8 +113,9 @@ export function testAWorkspace() { test('deleteVariableById(id1) multiple usages confirm', function () { // Deleting variable with multiple usages triggers confirm dialog. - const stub = sinon.stub().callsArgWith(1, true); - Blockly.dialog.setConfirm(stub); + const stub = sinon + .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') + .callsArgWith(1, true); this.workspace.deleteVariableById('id1'); sinon.assert.calledOnce(stub); @@ -125,8 +127,9 @@ export function testAWorkspace() { test('deleteVariableById(id1) multiple usages cancel', function () { // Deleting variable with multiple usages triggers confirm dialog. - const stub = sinon.stub().callsArgWith(1, false); - Blockly.dialog.setConfirm(stub); + const stub = sinon + .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') + .callsArgWith(1, false); this.workspace.deleteVariableById('id1'); sinon.assert.calledOnce(stub);