From b72212d92950729b802156c79653664337d62f02 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Fri, 22 Jul 2022 14:25:26 -0700 Subject: [PATCH] fix: Prevent PocomathInstance from clobbering its own methods Resolves #6. --- src/core/PocomathInstance.mjs | 15 +++++++++++++++ test/core/_PocomathInstance.mjs | 12 ++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/core/PocomathInstance.mjs b/src/core/PocomathInstance.mjs index 307f832..2436032 100644 --- a/src/core/PocomathInstance.mjs +++ b/src/core/PocomathInstance.mjs @@ -2,6 +2,12 @@ import typed from 'typed-function' export default class PocomathInstance { + /* Disallowed names for ops; beware, this is slightly non-DRY + * in that if a new top-level PocomathInstance method is added, its name + * must be added to this list. + */ + static reserved = new Set(['install']) + constructor(name) { this.name = name this._imps = {} @@ -48,6 +54,15 @@ export default class PocomathInstance { /* Used internally by install, see the documentation there */ _installOp(name, implementations) { + if (name.charAt(0) === '_') { + throw new SyntaxError( + `Pocomath: Cannot install ${name}, ` + + 'initial _ reserved for internal use.') + } + if (PocomathInstance.reserved.has(name)) { + throw new SyntaxError( + `Pocomath: the meaning of function '${name}' cannot be modified.`) + } // new implementations, so set the op up to lazily recreate itself this._invalidate(name) const opImps = this._imps[name] diff --git a/test/core/_PocomathInstance.mjs b/test/core/_PocomathInstance.mjs index 28176e2..5f64774 100644 --- a/test/core/_PocomathInstance.mjs +++ b/test/core/_PocomathInstance.mjs @@ -1,13 +1,21 @@ import assert from 'assert' import PocomathInstance from '../../src/core/PocomathInstance.mjs' +const pi = new PocomathInstance('dummy') describe('PocomathInstance', () => { it('creates an instance that can define typed-functions', () => { - const pi = new PocomathInstance('dummy') - pi.install({'add': {'any,any': [[], (a,b) => a+b]}}) + pi.install({add: {'any,any': [[], (a,b) => a+b]}}) assert.strictEqual(pi.add(2,2), 4) assert.strictEqual(pi.add('Kilroy', 17), 'Kilroy17') assert.strictEqual(pi.add(1, undefined), NaN) assert.throws(() => pi.add(1), TypeError) }) + + it('reserves certain function names', () => { + assert.throws( + () => pi.install({install: {any: [[], x => x]}}), SyntaxError) + assert.throws( + () => pi.install({_foo: {any: [[], x => x]}}), SyntaxError) + }) + })