fix: Prevent PocomathInstance from clobbering its own methods #16
@ -2,6 +2,12 @@
|
|||||||
import typed from 'typed-function'
|
import typed from 'typed-function'
|
||||||
|
|
||||||
export default class PocomathInstance {
|
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) {
|
constructor(name) {
|
||||||
this.name = name
|
this.name = name
|
||||||
this._imps = {}
|
this._imps = {}
|
||||||
@ -48,6 +54,15 @@ export default class PocomathInstance {
|
|||||||
|
|
||||||
/* Used internally by install, see the documentation there */
|
/* Used internally by install, see the documentation there */
|
||||||
_installOp(name, implementations) {
|
_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
|
// new implementations, so set the op up to lazily recreate itself
|
||||||
this._invalidate(name)
|
this._invalidate(name)
|
||||||
const opImps = this._imps[name]
|
const opImps = this._imps[name]
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
import PocomathInstance from '../../src/core/PocomathInstance.mjs'
|
import PocomathInstance from '../../src/core/PocomathInstance.mjs'
|
||||||
|
|
||||||
|
const pi = new PocomathInstance('dummy')
|
||||||
describe('PocomathInstance', () => {
|
describe('PocomathInstance', () => {
|
||||||
it('creates an instance that can define typed-functions', () => {
|
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(2,2), 4)
|
||||||
assert.strictEqual(pi.add('Kilroy', 17), 'Kilroy17')
|
assert.strictEqual(pi.add('Kilroy', 17), 'Kilroy17')
|
||||||
assert.strictEqual(pi.add(1, undefined), NaN)
|
assert.strictEqual(pi.add(1, undefined), NaN)
|
||||||
assert.throws(() => pi.add(1), TypeError)
|
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)
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user