mirror of
https://github.com/josdejong/mathjs.git
synced 2025-12-08 19:46:04 +00:00
* Add support for scopes with get and set methods * Fix build for node v12 * Fixup cli and parser tests * Add tests for simplify and evaluate * Add example for a custom scope object * Function calls need child scopes * Transitionary step: Separate Safe and Scope Property calls * Renamed identifiers in FunctionNode * Evaluate with ObjectScopeWrapper * Simplify tests passing * Assume all scopes are map-like. Except parser * Remove isMapLike check in customs.*SafeProperty() methods * Change MapLike to Map * Move keywords from an Object to a Set * Move ScopeProperty functions in to scope.js * Removed deprecation warning * Rename scope.js to map.js * Rename ScopeProperty to MapProperty * Add tests and docs for map.js * Put back the micro-optimization of function calls * Use Map in the parser * Called scope methods directly in cli.js * Coercing of scope into a Map is done in Node, not evaluate * Move createSubScope to its own file * Fixup following self-review * Add scope docs * Final self-review changes * Address reviewer comments * Remove MapProperty witness marks * Converted broken benchmark possibly lost in a rebase * Use bare map as scope in benchmark Co-authored-by: Jos de Jong <wjosdejong@gmail.com>
157 lines
3.6 KiB
JavaScript
157 lines
3.6 KiB
JavaScript
import assert from 'assert'
|
|
import { isMap, ObjectWrappingMap, toObject, createMap, assign } from '../../../src/utils/map.js'
|
|
|
|
describe('maps', function () {
|
|
it('should provide isMap, a function to tell maps from non-maps', () => {
|
|
assert.ok(isMap(new Map()))
|
|
assert.ok(!isMap([]))
|
|
assert.ok(!isMap({}))
|
|
|
|
const duckMap = {
|
|
has: () => 0,
|
|
keys: () => 0,
|
|
get: () => 0,
|
|
set: () => 0
|
|
}
|
|
|
|
assert.ok(isMap(duckMap))
|
|
|
|
const duckNotMap = {
|
|
has: () => 0,
|
|
keys: () => 0,
|
|
set: () => 0
|
|
}
|
|
assert.ok(!isMap(duckNotMap))
|
|
|
|
const notMaps = [null, undefined, true, false, 'string', 42, /regular-expression/, new Date(), {}, []]
|
|
for (const thing of notMaps) {
|
|
assert.ok(!isMap(thing))
|
|
}
|
|
})
|
|
|
|
it('should wrap an object in a map-like object', () => {
|
|
const obj = {
|
|
a: 1,
|
|
b: 2,
|
|
c: 3
|
|
}
|
|
const map = new ObjectWrappingMap(obj)
|
|
|
|
// isMap thinks it's a map.
|
|
assert.ok(isMap(map))
|
|
|
|
// get
|
|
for (const key of ['a', 'b', 'c']) {
|
|
assert.strictEqual(map.get(key), obj[key])
|
|
}
|
|
|
|
// get with a key not there gives an undefined.
|
|
for (const key of ['e', 'f']) {
|
|
assert.strictEqual(map.get(key), undefined)
|
|
}
|
|
|
|
// We can behind the scenes add to the wrapped object.
|
|
Object.assign(obj, {
|
|
d: 4,
|
|
e: 5
|
|
})
|
|
|
|
// set()
|
|
map.set('f', 6)
|
|
map.set('g', 7)
|
|
|
|
// we set the properties in obj, too.
|
|
assert.strictEqual(obj.f, 6)
|
|
assert.strictEqual(obj.g, 7)
|
|
|
|
for (const key of ['d', 'e', 'f', 'g']) {
|
|
assert.strictEqual(map.get(key), obj[key])
|
|
}
|
|
|
|
// keys()
|
|
assert.deepStrictEqual(map.keys(), ['a', 'b', 'c', 'd', 'e', 'f', 'g'])
|
|
|
|
for (const key of map.keys()) {
|
|
assert.ok(map.has(key))
|
|
}
|
|
|
|
assert.ok(!map.has('not-in-this-map'))
|
|
|
|
// We can get the same object out using toObject
|
|
const innerObject = toObject(map)
|
|
assert.strictEqual(innerObject, obj)
|
|
})
|
|
|
|
it('should create a map from objects, maps, or undefined', () => {
|
|
const emptyMap = createMap()
|
|
assert.ok(isMap(emptyMap))
|
|
|
|
const actualMap = createMap(new Map())
|
|
assert.ok(isMap(actualMap))
|
|
|
|
const wrappedMap = createMap({ a: 1 })
|
|
assert.ok(isMap(wrappedMap))
|
|
|
|
for (const notMap of ['string', new Date(), []]) {
|
|
assert.throws(() => createMap(notMap))
|
|
}
|
|
})
|
|
|
|
it('should let us transform a map into an object', () => {
|
|
const actualMap = new Map()
|
|
.set('a', 1)
|
|
.set('b', 2)
|
|
|
|
const obj = {
|
|
a: 1,
|
|
b: 2
|
|
}
|
|
|
|
assert.deepStrictEqual(toObject(actualMap), obj)
|
|
assert.notStrictEqual(toObject(actualMap), obj)
|
|
|
|
// The wrapped map gives back the backing object.
|
|
const wrappedMap = createMap(obj)
|
|
assert.deepStrictEqual(toObject(wrappedMap), obj)
|
|
assert.strictEqual(toObject(wrappedMap), obj)
|
|
})
|
|
|
|
it('should provide an assign function like Object.assign', () => {
|
|
const target = new Map()
|
|
.set('a', 1)
|
|
.set('b', 2)
|
|
|
|
assign(target, null, undefined, 'string', new Date())
|
|
|
|
assert.deepStrictEqual(
|
|
target,
|
|
new Map()
|
|
.set('a', 1)
|
|
.set('b', 2)
|
|
)
|
|
|
|
const src1 = new Map()
|
|
.set('c', 3)
|
|
.set('d', 4)
|
|
|
|
const src2 = { e: 5, f: 6 }
|
|
|
|
const sameTarget = assign(target, src1, src2)
|
|
|
|
// it returns back the first argument…
|
|
assert.strictEqual(target, sameTarget)
|
|
|
|
// …copying the contents of the others into it.
|
|
assert.deepStrictEqual(
|
|
target,
|
|
new Map()
|
|
.set('a', 1)
|
|
.set('b', 2)
|
|
.set('c', 3)
|
|
.set('d', 4)
|
|
.set('e', 5)
|
|
.set('f', 6)
|
|
)
|
|
})
|
|
})
|