diff --git a/core/dialog.ts b/core/dialog.ts index 7e2112985..ade36aa25 100644 --- a/core/dialog.ts +++ b/core/dialog.ts @@ -6,31 +6,6 @@ // 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. @@ -38,9 +13,12 @@ let promptImplementation = function ( * @param message The message to display to the user. * @param opt_callback The callback when the alert is dismissed. */ -export function alert(message: string, opt_callback?: () => void) { - alertImplementation(message, opt_callback); -} +export let alert = (message: string, opt_callback?: () => void) => { + window.alert(message); + if (opt_callback) { + opt_callback(); + } +}; /** * Sets the function to be run when Blockly.dialog.alert() is called. @@ -48,8 +26,10 @@ export function alert(message: string, opt_callback?: () => void) { * @param alertFunction The function to be run. * @see Blockly.dialog.alert */ -export function setAlert(alertFunction: (p1: string, p2?: () => void) => void) { - alertImplementation = alertFunction; +export function setAlert( + alertFunction: (message: string, callback?: () => void) => void, +) { + alert = alertFunction; } /** @@ -59,16 +39,12 @@ export function setAlert(alertFunction: (p1: string, p2?: () => void) => void) { * @param message The message to display to the user. * @param callback The callback for handling user response. */ -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); -} +export let confirm = ( + message: string, + callback: (confirmed: boolean) => void, +) => { + callback(window.confirm(message)); +}; /** * Sets the function to be run when Blockly.dialog.confirm() is called. @@ -77,9 +53,12 @@ function confirmInternal(message: string, callback: (p1: boolean) => void) { * @see Blockly.dialog.confirm */ export function setConfirm( - confirmFunction: (p1: string, p2: (p1: boolean) => void) => void, + confirmFunction: ( + message: string, + callback: (confirmed: boolean) => void, + ) => void, ) { - confirmImplementation = confirmFunction; + confirm = confirmFunction; } /** @@ -92,13 +71,13 @@ export function setConfirm( * @param defaultValue The value to initialize the prompt with. * @param callback The callback for handling user response. */ -export function prompt( +export let prompt = ( message: string, defaultValue: string, - callback: (p1: string | null) => void, -) { - promptImplementation(message, defaultValue, callback); -} + callback: (userInput: string | null) => void, +) => { + callback(window.prompt(message, defaultValue)); +}; /** * Sets the function to be run when Blockly.dialog.prompt() is called. @@ -108,14 +87,10 @@ export function prompt( */ export function setPrompt( promptFunction: ( - p1: string, - p2: string, - p3: (p1: string | null) => void, + message: string, + defaultValue: string, + callback: (userInput: string | null) => void, ) => void, ) { - promptImplementation = promptFunction; + prompt = promptFunction; } - -export const TEST_ONLY = { - confirmInternal, -}; diff --git a/tests/mocha/contextmenu_items_test.js b/tests/mocha/contextmenu_items_test.js index 4596513c6..ef1a9530c 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(Blockly.dialog.TEST_ONLY, 'confirmInternal') - .callsArgWith(1, true); + // Mocks the confirmation dialog and calls the callback with 'true' + // simulating ok. + const confirmStub = sinon.stub().callsArgWith(1, true); + Blockly.dialog.setConfirm(confirmStub); this.workspace.newBlock('text'); this.workspace.newBlock('text'); @@ -337,9 +337,8 @@ 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(Blockly.dialog.TEST_ONLY, 'confirmInternal') - .callsArgWith(1, false); + const confirmStub = sinon.stub().callsArgWith(1, false); + Blockly.dialog.setConfirm(confirmStub); this.workspace.newBlock('text'); this.workspace.newBlock('text'); @@ -350,10 +349,9 @@ suite('Context Menu Items', function () { }); test('No dialog for single block', function () { - const confirmStub = sinon.stub( - Blockly.dialog.TEST_ONLY, - 'confirmInternal', - ); + const confirmStub = sinon.stub(); + Blockly.dialog.setConfirm(confirmStub); + 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 new file mode 100644 index 000000000..22831c58d --- /dev/null +++ b/tests/mocha/dialog_test.js @@ -0,0 +1,58 @@ +/** + * @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 9c7b10cab..34738605a 100644 --- a/tests/mocha/index.html +++ b/tests/mocha/index.html @@ -52,6 +52,7 @@ 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 6da113f8b..ce8822019 100644 --- a/tests/mocha/test_helpers/workspace.js +++ b/tests/mocha/test_helpers/workspace.js @@ -99,9 +99,8 @@ export function testAWorkspace() { test('deleteVariableById(id2) one usage', function () { // Deleting variable one usage should not trigger confirm dialog. - const stub = sinon - .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') - .callsArgWith(1, true); + const stub = sinon.stub().callsArgWith(1, true); + Blockly.dialog.setConfirm(stub); this.workspace.deleteVariableById('id2'); sinon.assert.notCalled(stub); @@ -113,9 +112,8 @@ export function testAWorkspace() { test('deleteVariableById(id1) multiple usages confirm', function () { // Deleting variable with multiple usages triggers confirm dialog. - const stub = sinon - .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') - .callsArgWith(1, true); + const stub = sinon.stub().callsArgWith(1, true); + Blockly.dialog.setConfirm(stub); this.workspace.deleteVariableById('id1'); sinon.assert.calledOnce(stub); @@ -127,9 +125,8 @@ export function testAWorkspace() { test('deleteVariableById(id1) multiple usages cancel', function () { // Deleting variable with multiple usages triggers confirm dialog. - const stub = sinon - .stub(Blockly.dialog.TEST_ONLY, 'confirmInternal') - .callsArgWith(1, false); + const stub = sinon.stub().callsArgWith(1, false); + Blockly.dialog.setConfirm(stub); this.workspace.deleteVariableById('id1'); sinon.assert.calledOnce(stub);