diff --git a/package-lock.json b/package-lock.json index 24ebdfe1..da74be50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "chs-js-lib", - "version": "0.3.0", + "version": "0.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.3.0", + "version": "0.3.1", "license": "ISC", "dependencies": { "http-server": "^14.1.0", diff --git a/package.json b/package.json index f43d5b43..3464d4f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chs-js-lib", - "version": "0.3.0", + "version": "0.3.1", "description": "JavaScript graphics library used in CodeHS's platform.", "main": "dist/chs.cjs", "module": "dist/chs.mjs", diff --git a/src/console/index.js b/src/console/index.js index deb40360..a4a32972 100644 --- a/src/console/index.js +++ b/src/console/index.js @@ -45,11 +45,17 @@ class Console { * or `println` or internal calls within the library. If onPrint is undefined, console.log * is used as a fallback. * @param {function} options.clear Function invoked when clear() is called. + * @param {function} options.prompt Function that transforms the prompt string to a function like `readInt` before it is passed to `prompt`. */ constructor(options = {}) { this.onInput = options.input ?? (async promptString => await prompt(promptString)); this.onOutput = options.output ?? window.console.log.bind(window.console); this.onClear = options.clear ?? window.console.clear.bind(window.console); + this.promptTransform = + options.prompt ?? + ((promptString, defaultValue) => { + return promptString; + }); } /** @@ -67,11 +73,13 @@ class Console { * or `println` or internal calls within the library. If onPrint is undefined, console.log * is used as a fallback. * @param {function} options.clear Function invoked when clear() is called. + * @param {function} options.prompt Function that transforms the prompt string to a function like `readInt` before it is passed to `prompt`. */ configure(options = {}) { this.onInput = options.input ?? this.onInput; this.onOutput = options.output ?? this.onOutput; this.onClear = options.clear ?? this.onClear; + this.promptTransform = options.prompt ?? this.promptTransform; } /** @@ -79,7 +87,7 @@ class Console { * @param {string} promptString - The line to be printed before prompting. */ readLinePrivate(promptString) { - const input = prompt(promptString); + const input = prompt(this.promptTransform(promptString)); return input; } diff --git a/test/console.test.js b/test/console.test.js index 7eaf1d9f..d2801fe5 100644 --- a/test/console.test.js +++ b/test/console.test.js @@ -125,6 +125,14 @@ describe('Console', () => { const c = new Console(); expect(c.readLine('Next line?')).toBeNull(); }); + it('Will invoke a configured prompt first', () => { + const promptSpy = jasmine.createSpy().and.returnValue('modified prompt'); + const windowPromptSpy = spyOn(window, 'prompt').and.returnValue(null); + const c = new Console({ prompt: promptSpy }); + c.readLine('give me a line!'); + expect(promptSpy).toHaveBeenCalledOnceWith('give me a line!'); + expect(windowPromptSpy).toHaveBeenCalledOnceWith('modified prompt'); + }); }); describe('readFloat', () => { it('Errors for >1 argument', () => { @@ -146,6 +154,14 @@ describe('Console', () => { ]); expect(int).toBe(3.0); }); + it('Will invoke a configured prompt first', () => { + const promptSpy = jasmine.createSpy().and.returnValue('modified prompt'); + const windowPromptSpy = spyOn(window, 'prompt').and.returnValue(null); + const c = new Console({ prompt: promptSpy }); + c.readFloat('give me a float!'); + expect(promptSpy).toHaveBeenCalledOnceWith('give me a float!'); + expect(windowPromptSpy).toHaveBeenCalledOnceWith('modified prompt'); + }); }); describe('readInt', () => { it('Errors for >1 argument', () => { @@ -187,6 +203,14 @@ describe('Console', () => { expect(promptSpy).toHaveBeenCalledTimes(100); expect(int).toBe(0); }); + it('Will invoke a configured prompt first', () => { + const promptSpy = jasmine.createSpy().and.returnValue('modified prompt'); + const windowPromptSpy = spyOn(window, 'prompt').and.returnValue(null); + const c = new Console({ prompt: promptSpy }); + c.readInt('give me an int!'); + expect(promptSpy).toHaveBeenCalledOnceWith('give me an int!'); + expect(windowPromptSpy).toHaveBeenCalledOnceWith('modified prompt'); + }); }); describe('readBoolean', () => { it('Errors for >1 argument', () => { @@ -225,6 +249,14 @@ describe('Console', () => { ]); expect(bool).toBeTrue(); }); + it('Will invoke a configured prompt first', () => { + const promptSpy = jasmine.createSpy().and.returnValue('modified prompt'); + const windowPromptSpy = spyOn(window, 'prompt').and.returnValue(null); + const c = new Console({ prompt: promptSpy }); + c.readInt('give me a boolean!'); + expect(promptSpy).toHaveBeenCalledOnceWith('give me a boolean!'); + expect(windowPromptSpy).toHaveBeenCalledOnceWith('modified prompt'); + }); }); }); describe('Output', () => {