Merge pull request 'fix: Prevent PocomathInstance from clobbering its own methods' (#16) from protect_reserve into main

Reviewed-on: #16
This commit is contained in:
Glen Whitney 2022-07-22 21:29:17 +00:00
commit 4a2d53a68a
2 changed files with 25 additions and 2 deletions

View File

@ -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]

View File

@ -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)
})
})