mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
* Add `.js` extension to source file imports * Specify package `exports` in `package.json` Specify package type as `commonjs` (It's good to be specific) * Move all compiled scripts into `lib` directory Remove ./number.js (You can use the compiled ones in `./lib/*`) Tell node that the `esm` directory is type `module` and enable tree shaking. Remove unused files from packages `files` property * Allow importing of package.json * Make library ESM first * - Fix merge conflicts - Refactor `bundleAny` into `defaultInstance.js` and `browserBundle.cjs` - Refactor unit tests to be able to run with plain nodejs (no transpiling) - Fix browser examples * Fix browser and browserstack tests * Fix running unit tests on Node 10 (which has no support for modules) * Fix node.js examples (those are still commonjs) * Remove the need for `browserBundle.cjs` * Generate minified bundle only * [Security] Bump node-fetch from 2.6.0 to 2.6.1 (#1963) Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. **This update includes a security fix.** - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> * Cleanup console.log * Add integration tests to test the entry points (commonjs/esm, full/number only) * Create backward compatibility error messages in the files moved/removed since v8 * Describe breaking changes in HISTORY.md * Bump karma from 5.2.1 to 5.2.2 (#1965) Bumps [karma](https://github.com/karma-runner/karma) from 5.2.1 to 5.2.2. - [Release notes](https://github.com/karma-runner/karma/releases) - [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) - [Commits](https://github.com/karma-runner/karma/compare/v5.2.1...v5.2.2) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Lee Langley-Rees <lee@greenimp.co.uk> Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
256 lines
9.7 KiB
JavaScript
256 lines
9.7 KiB
JavaScript
// test RelationalNode
|
|
import assert from 'assert'
|
|
|
|
import math from '../../../../src/defaultInstance.js'
|
|
const Node = math.Node
|
|
const ConstantNode = math.ConstantNode
|
|
const SymbolNode = math.SymbolNode
|
|
const RelationalNode = math.RelationalNode
|
|
|
|
describe('RelationalNode', function () {
|
|
const one = new ConstantNode(1)
|
|
const two = new ConstantNode(2)
|
|
const three = new ConstantNode(3)
|
|
const four = new ConstantNode(4)
|
|
|
|
it('should create a RelationalNode', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
assert(n instanceof RelationalNode)
|
|
assert(n instanceof Node)
|
|
assert.strictEqual(n.type, 'RelationalNode')
|
|
})
|
|
|
|
it('should have isRelationalNode', function () {
|
|
const node = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
assert(node.isRelationalNode)
|
|
})
|
|
|
|
it('should throw an error when calling without new operator', function () {
|
|
assert.throws(function () { RelationalNode() }, SyntaxError)
|
|
})
|
|
|
|
it('should throw an error when creating without arguments', function () {
|
|
assert.throws(function () { console.log(new RelationalNode()) }, TypeError)
|
|
assert.throws(function () { console.log(new RelationalNode('smaller')) }, TypeError)
|
|
assert.throws(function () { console.log(new RelationalNode(['smaller'])) }, TypeError)
|
|
assert.throws(function () { console.log(new RelationalNode(['smaller'], one)) }, TypeError)
|
|
assert.throws(function () { console.log(new RelationalNode(['smaller'], [one])) }, TypeError)
|
|
})
|
|
|
|
it('should evaluate a RelationalNode', function () {
|
|
let n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
let expr = n.compile()
|
|
const scope = {}
|
|
assert.strictEqual(expr.evaluate(scope), true)
|
|
|
|
n = new RelationalNode(['smaller', 'smaller'], [three, two, one])
|
|
expr = n.compile()
|
|
assert.strictEqual(expr.evaluate(scope), false)
|
|
})
|
|
|
|
it('should filter a RelationalNode', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
|
|
assert.deepStrictEqual(n.filter(function (node) { return node instanceof RelationalNode }), [n])
|
|
assert.deepStrictEqual(n.filter(function (node) { return node instanceof ConstantNode }), [one, two, three])
|
|
assert.deepStrictEqual(n.filter(function (node) { return node instanceof ConstantNode && node.value === 2 }), [two])
|
|
})
|
|
|
|
it('should run forEach on a RelationalNode', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
|
|
const nodes = []
|
|
const paths = []
|
|
n.forEach(function (node, path, parent) {
|
|
nodes.push(node)
|
|
paths.push(path)
|
|
assert.strictEqual(parent, n)
|
|
})
|
|
|
|
assert.strictEqual(nodes.length, 3)
|
|
assert.strictEqual(nodes[0], one)
|
|
assert.strictEqual(nodes[1], two)
|
|
assert.strictEqual(nodes[2], three)
|
|
assert.deepStrictEqual(paths, ['params[0]', 'params[1]', 'params[2]'])
|
|
})
|
|
|
|
it('should map a RelationalNode', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
|
|
const nodes = []
|
|
const paths = []
|
|
const f = n.map(function (node, path, parent) {
|
|
nodes.push(node)
|
|
paths.push(path)
|
|
assert.strictEqual(parent, n)
|
|
|
|
return node instanceof ConstantNode && node.value === 1 ? four : node
|
|
})
|
|
|
|
assert.strictEqual(nodes.length, 3)
|
|
assert.strictEqual(nodes[0], one)
|
|
assert.strictEqual(nodes[1], two)
|
|
assert.strictEqual(nodes[2], three)
|
|
assert.deepStrictEqual(paths, ['params[0]', 'params[1]', 'params[2]'])
|
|
|
|
assert.notStrictEqual(f, n)
|
|
assert.strictEqual(f.params[0], four)
|
|
assert.strictEqual(f.params[1], two)
|
|
assert.strictEqual(f.params[2], three)
|
|
})
|
|
|
|
it('should throw an error when the map callback does not return a node', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
|
|
assert.throws(function () {
|
|
n.map(function () {})
|
|
}, /Callback function must return a Node/)
|
|
})
|
|
|
|
it('should transform a RelationalNodes param', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
|
|
const f = n.transform(function (node) {
|
|
return node instanceof ConstantNode && node.value === 1 ? four : node
|
|
})
|
|
|
|
assert.notStrictEqual(f, n)
|
|
assert.deepStrictEqual(f.params[0], four)
|
|
assert.deepStrictEqual(f.params[1], two)
|
|
assert.deepStrictEqual(f.params[2], three)
|
|
})
|
|
|
|
it('should transform a RelationalNode itself', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
|
|
const f = n.transform(function (node) {
|
|
return node instanceof RelationalNode ? four : node
|
|
})
|
|
|
|
assert.notStrictEqual(f, n)
|
|
assert.deepStrictEqual(f, four)
|
|
})
|
|
|
|
it('should clone a RelationalNode itself', function () {
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
|
|
const m = n.clone()
|
|
|
|
assert(m instanceof RelationalNode)
|
|
assert.deepStrictEqual(m, n)
|
|
assert.notStrictEqual(m, n)
|
|
assert.strictEqual(m.params[0], n.params[0])
|
|
assert.strictEqual(m.params[1], n.params[1])
|
|
assert.strictEqual(m.params[2], n.params[2])
|
|
assert.strictEqual(m.conditionals[0], n.conditionals[0])
|
|
assert.strictEqual(m.conditionals[1], n.conditionals[1])
|
|
})
|
|
|
|
it('test equality another Node', function () {
|
|
const n1 = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
const n2 = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
const m = new RelationalNode(['smaller', 'larger'], [one, two, three])
|
|
const p = new RelationalNode(['smaller', 'smaller', 'larger'], [one, two, three, four])
|
|
const q = new RelationalNode(['smaller', 'smaller'], [two, two, two])
|
|
|
|
assert.strictEqual(n1.equals(null), false)
|
|
assert.strictEqual(n1.equals(undefined), false)
|
|
assert.strictEqual(n1.equals(n2), true)
|
|
assert.strictEqual(n1.equals(m), false)
|
|
assert.strictEqual(n1.equals(p), false)
|
|
assert.strictEqual(n1.equals(q), false)
|
|
})
|
|
|
|
it('should perform short-circuit evaluation', function () {
|
|
const n = math.parse('(a = a+1) > (b = b+1) > (c = c+1) > (d = d+1)')
|
|
const scope = { a: 0, b: 0, c: 0, d: 0 }
|
|
const result = n.evaluate(scope)
|
|
assert.strictEqual(scope.a, 1)
|
|
assert.strictEqual(scope.b, 1)
|
|
assert.strictEqual(scope.c, 0)
|
|
assert.strictEqual(scope.d, 0)
|
|
assert.strictEqual(result, false)
|
|
})
|
|
|
|
it('should not evaluate params more than once', function () {
|
|
const n = math.parse('(a = a+1) >= (b = b+1) >= (c = c+1) >= (d = d+1)')
|
|
const scope = { a: 0, b: 0, c: 0, d: 0 }
|
|
const result = n.evaluate(scope)
|
|
assert.strictEqual(scope.a, 1)
|
|
assert.strictEqual(scope.b, 1)
|
|
assert.strictEqual(scope.c, 1)
|
|
assert.strictEqual(scope.d, 1)
|
|
assert.strictEqual(result, true)
|
|
})
|
|
|
|
it('should respect the \'all\' parenthesis option', function () {
|
|
assert.strictEqual(math.parse('a<b<c').toString({ parenthesis: 'all' }), '(a) < (b) < (c)')
|
|
})
|
|
|
|
it('should stringify a RelationalNode', function () {
|
|
const n1 = new RelationalNode(['smaller', 'smaller'], [one, two, three])
|
|
const n2 = new RelationalNode(['smaller', 'larger', 'smallerEq', 'largerEq', 'equal', 'unequal'], [one, three, two, three, two, two, one])
|
|
const n3 = math.parse('(1 < 2 < 3) == (6 > 5 > 4) != (1 > 2 > 3)')
|
|
|
|
assert.strictEqual(n1.toString(), '1 < 2 < 3')
|
|
assert.strictEqual(n2.toString(), '1 < 3 > 2 <= 3 >= 2 == 2 != 1')
|
|
assert.strictEqual(n3.toString(), '(1 < 2 < 3) == (6 > 5 > 4) != (1 > 2 > 3)')
|
|
})
|
|
|
|
it('should stringify a RelationalNode with custom toString', function () {
|
|
// Also checks if the custom functions get passed on to the children
|
|
const customFunction = function (node, options) {
|
|
if (node.type === 'RelationalNode') {
|
|
let ret = node.params[0].toString(options)
|
|
for (let i = 0; i < node.conditionals.length; i++) {
|
|
ret += ' ' + node.conditionals[i] + ' ' + node.params[i + 1].toString(options)
|
|
}
|
|
return ret
|
|
} else if (node.type === 'ConstantNode') {
|
|
switch (node.value) {
|
|
case 1: return 'one'
|
|
case 2: return 'two'
|
|
case 3: return 'three'
|
|
default: return 'NaN'
|
|
}
|
|
}
|
|
}
|
|
|
|
const n = new RelationalNode(['smaller', 'larger', 'smallerEq', 'largerEq', 'equal', 'unequal'], [one, three, two, three, two, two, one])
|
|
|
|
assert.strictEqual(n.toString({ handler: customFunction }), 'one smaller three larger two smallerEq three largerEq two equal two unequal one')
|
|
})
|
|
|
|
it('toJSON and fromJSON', function () {
|
|
const x = new SymbolNode('x')
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, x, three])
|
|
|
|
const json = n.toJSON()
|
|
|
|
assert.deepStrictEqual(json, {
|
|
mathjs: 'RelationalNode',
|
|
conditionals: ['smaller', 'smaller'],
|
|
params: [one, x, three]
|
|
})
|
|
|
|
const parsed = RelationalNode.fromJSON(json)
|
|
assert.deepStrictEqual(parsed, n)
|
|
})
|
|
|
|
it('should LaTeX a RelationalNode', function () {
|
|
const x = new SymbolNode('x')
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, x, three])
|
|
|
|
assert.strictEqual(n.toTex(), '1< x<3')
|
|
assert.strictEqual(math.parse('1<x<sqrt(1+2)').toTex(), '1< x<\\sqrt{1+2}')
|
|
assert.strictEqual(math.parse('(-1 < 4/2 < 3) == (3! > 2+3 > 4) != (1 > 2 > 1*3)').toTex(), '\\left(-1<\\frac{4}{2}<3\\right)=\\left(3!>2+3>4\\right)\\neq\\left(1>2>1\\cdot3\\right)')
|
|
})
|
|
|
|
it('should HTML a RelationalNode', function () {
|
|
const x = new SymbolNode('x')
|
|
const n = new RelationalNode(['smaller', 'smaller'], [one, x, three])
|
|
|
|
assert.strictEqual(n.toHTML(), '<span class="math-number">1</span><span class="math-operator math-binary-operator math-explicit-binary-operator"><</span><span class="math-symbol">x</span><span class="math-operator math-binary-operator math-explicit-binary-operator"><</span><span class="math-number">3</span>')
|
|
})
|
|
})
|