mirror of
https://github.com/josdejong/mathjs.git
synced 2025-12-08 19:46:04 +00:00
313 lines
11 KiB
JavaScript
313 lines
11 KiB
JavaScript
// test parse
|
|
var assert = require('assert'),
|
|
approx = require('../../../tools/approx.js'),
|
|
math = require('../../../index.js');
|
|
|
|
describe('parse', function() {
|
|
|
|
it('should parse constants', function() {
|
|
assert.ok(math.parse('pi') instanceof math.expression.node.Node);
|
|
assert.equal(math.parse('pi').eval(), Math.PI);
|
|
});
|
|
|
|
it('should parse arithmetic operations', function() {
|
|
assert.equal(math.parse('(2+3)/4').eval(), 1.25);
|
|
assert.equal(math.parse('0 + 2').toString(), 'ans = 0 + 2');
|
|
});
|
|
|
|
it('should parse functions', function() {
|
|
assert.equal(math.parse('sqrt(-4)').eval().toString(), '2i');
|
|
});
|
|
|
|
it('should parse a series of expressions', function() {
|
|
assert.deepEqual(math.parse(['a=3', 'b=4', 'a*b']).map(function (node) {
|
|
return node.eval();
|
|
}), [3, 4, 12]);
|
|
|
|
assert.deepEqual(math.parse(math.matrix(['a=3', 'b=4', 'a*b'])).map(function (node) {
|
|
return node.eval();
|
|
}), math.matrix([3, 4, 12]));
|
|
});
|
|
|
|
it('should parse multiple expressions', function() {
|
|
assert.deepEqual(math.parse('a=3\nb=4\na*b').eval(), [3, 4, 12]);
|
|
assert.deepEqual(math.parse('b = 43; b * 4').eval(), [172]);
|
|
});
|
|
|
|
it('should parse a custom function', function() {
|
|
assert.deepEqual(math.parse('function f(x) = a * x; a=2; f(4)').eval(), [8]);
|
|
});
|
|
|
|
it('should throw an error if called with wrong number of arguments', function() {
|
|
assert.throws(function () {math.parse()}, SyntaxError);
|
|
assert.throws(function () {math.parse(1,2,3)}, SyntaxError);
|
|
});
|
|
|
|
it('should throw an error if called with a number', function() {
|
|
assert.throws(function () {math.parse(23)}, TypeError);
|
|
});
|
|
|
|
it('should throw an error if called with a unit', function() {
|
|
assert.throws(function () {math.parse(math.unit('5cm'))}, TypeError);
|
|
});
|
|
|
|
it('should throw an error if called with a complex number', function() {
|
|
assert.throws(function () {math.parse(new math.type.Complex(2,3))}, TypeError);
|
|
});
|
|
|
|
it('should throw an error if called with a boolean', function() {
|
|
assert.throws(function () {math.parse(true)}, TypeError);
|
|
});
|
|
|
|
it('should handle the given scope', function() {
|
|
var scope = {
|
|
a: 3,
|
|
b: 4
|
|
};
|
|
assert.deepEqual(math.parse('a*b', scope).eval(), 12);
|
|
assert.deepEqual(math.parse('c=5', scope).eval(), 5);
|
|
assert.deepEqual(math.parse('function f(x) = x^a', scope).eval(), 'f(x)');
|
|
assert.deepEqual(scope, {
|
|
a: 3,
|
|
b: 4,
|
|
c: 5,
|
|
f: 'f(x)',
|
|
ans: 'f(x)'
|
|
});
|
|
assert.equal(scope.f(3), 27);
|
|
scope.a = 2;
|
|
assert.equal(scope.f(3), 9);
|
|
scope.hello = function (name) {
|
|
return 'hello, ' + name + '!';
|
|
};
|
|
assert.deepEqual(math.parse('hello("jos")', scope).eval(), 'hello, jos!');
|
|
});
|
|
|
|
it('should parse zero', function() {
|
|
assert.equal(math.parse('0').toString(), 'ans = 0');
|
|
});
|
|
|
|
it('should parse a string', function() {
|
|
assert.equal(math.parse('"hello"').toString(), 'ans = "hello"');
|
|
});
|
|
|
|
it('should parse a matrix', function() {
|
|
assert.equal(math.parse('[1, 2 + 3i, 4]').toString(), 'ans = [[1, 2 + 3i, 4]]');
|
|
});
|
|
|
|
it('shouldn\'t break with multiple unary minuses', function() {
|
|
assert.equal(math.eval('5-3'), 2);
|
|
assert.equal(math.eval('5--3'), 8);
|
|
assert.equal(math.eval('5---3'), 2);
|
|
assert.equal(math.eval('5+---3'), 2);
|
|
assert.equal(math.eval('5----3'), 8);
|
|
assert.equal(math.eval('5+--(2+1)'), 8);
|
|
});
|
|
|
|
|
|
it('operators', function () {
|
|
|
|
it('should parse +', function() {
|
|
assert.equal(math.eval('2 + 3'), 5);
|
|
assert.equal(math.eval('2 + 3 + 4'), 9);
|
|
});
|
|
|
|
it('should parse /', function() {
|
|
assert.equal(math.eval('4 / 2'), 2);
|
|
assert.equal(math.eval('8 / 2 / 2'), 2);
|
|
});
|
|
|
|
it('should parse ./', function() {
|
|
assert.equal(math.eval('4 ./ 2'), 2);
|
|
assert.equal(math.eval('8 ./ 2 / 2'), 2);
|
|
});
|
|
|
|
it('should parse .*', function() {
|
|
approx.equal(math.eval('4 .* 2'), 8);
|
|
approx.equal(math.eval('8 .* 2 .* 2'), 32);
|
|
});
|
|
|
|
it('should parse .^', function() {
|
|
approx.equal(math.eval('2.^3'), 8);
|
|
approx.equal(math.eval('-2.^2'), -4); // -(2^2)
|
|
approx.equal(math.eval('2.^3.^4'), 2.41785163922926e+24); // 2^(3^4)
|
|
});
|
|
|
|
it('should parse ==', function() {
|
|
assert.equal(math.eval('2 == 3'), false);
|
|
assert.equal(math.eval('2 == 2'), true);
|
|
});
|
|
|
|
it('should parse >', function() {
|
|
assert.equal(math.eval('2 > 3'), false);
|
|
assert.equal(math.eval('2 > 2'), false);
|
|
assert.equal(math.eval('2 > 1'), true);
|
|
});
|
|
|
|
it('should parse >=', function() {
|
|
assert.equal(math.eval('2 >= 3'), false);
|
|
assert.equal(math.eval('2 >= 2'), true);
|
|
assert.equal(math.eval('2 >= 1'), true);
|
|
});
|
|
|
|
it('should parse %', function() {
|
|
approx.equal(math.eval('8 % 3'), 2);
|
|
});
|
|
|
|
it.skip('should parse mod', function() {
|
|
approx.equal(math.eval('8 mod 3'), 2);
|
|
});
|
|
|
|
it.skip('should parse *', function() {
|
|
approx.equal(math.eval('4 * 2'), 8);
|
|
approx.equal(math.eval('8 * 2 * 2'), 32);
|
|
});
|
|
|
|
it.skip('should parse ^', function() {
|
|
approx.equal(math.eval('2^3'), 8);
|
|
approx.equal(math.eval('-2^2'), -4); // -(2^2)
|
|
approx.equal(math.eval('2^3^4'), 2.41785163922926e+24); // 2^(3^4)
|
|
});
|
|
|
|
it.skip('should parse <', function() {
|
|
assert.equal(math.eval('2 < 3'), true);
|
|
assert.equal(math.eval('2 < 2'), false);
|
|
assert.equal(math.eval('2 < 1'), false);
|
|
});
|
|
|
|
it.skip('should parse <=', function() {
|
|
assert.equal(math.eval('2 <= 3'), true);
|
|
assert.equal(math.eval('2 <= 2'), true);
|
|
assert.equal(math.eval('2 <= 1'), false);
|
|
});
|
|
|
|
it.skip('should parse -', function() {
|
|
assert.equal(math.eval('4 - 2'), 2);
|
|
assert.equal(math.eval('8 - 2 - 2'), 4);
|
|
});
|
|
|
|
it.skip('should parse unary -', function() {
|
|
assert.equal(math.eval('-2'), -2);
|
|
assert.equal(math.eval('4*-2'), -8);
|
|
assert.equal(math.eval('4 * -2'), -8);
|
|
assert.equal(math.eval('4+-2'), 2);
|
|
assert.equal(math.eval('4 + -2'), 2);
|
|
assert.equal(math.eval('4--2'), 6);
|
|
assert.equal(math.eval('4 - -2'), 6);
|
|
});
|
|
|
|
it.skip('should parse unary !=', function() {
|
|
assert.equal(math.eval('2 != 3'), true);
|
|
assert.equal(math.eval('2 != 2'), false);
|
|
});
|
|
|
|
it.skip('should parse :', function() {
|
|
assert.equal(math.eval('2:5'), [2,3,4,5]);
|
|
assert.equal(math.eval('5:-1:2'), [5,4,3,2]);
|
|
});
|
|
|
|
it('should parse in', function() {
|
|
assert.equal(math.eval('2.54 cm in inch').toString(), '1 inch');
|
|
assert.equal(math.eval('2.54 cm + 2 inch in foot').toString(), '0.25 foot');
|
|
});
|
|
|
|
});
|
|
|
|
|
|
describe('functions', function () {
|
|
|
|
it('should parse all arithmetic functions', function () {
|
|
assert.equal(math.eval('abs(-4.2)'), 4.2);
|
|
assert.equal(math.eval('add(2, 3)'), 5);
|
|
assert.equal(math.eval('ceil(1.3)'), 2);
|
|
assert.equal(math.eval('ceil(1.8)'), 2);
|
|
assert.equal(math.eval('cube(4)'), 64);
|
|
assert.equal(math.eval('divide(4, 2)'), 2);
|
|
assert.equal(math.eval('edivide(4, 2)'), 2);
|
|
assert.equal(math.eval('emultiply(4, 2)'), 8);
|
|
approx.equal(math.eval('epow(2,3)'), 8);
|
|
approx.equal(math.eval('epow(-2,2)'), 4);
|
|
assert.equal(math.eval('equal(2, 3)'), false);
|
|
assert.equal(math.eval('equal(2, 2)'), true);
|
|
approx.equal(math.eval('exp(1)'), Math.E);
|
|
approx.deepEqual(math.eval('1+exp(pi*i)'), new math.type.Complex(0, 0));
|
|
assert.equal(math.eval('fix(1.3)'), 1);
|
|
assert.equal(math.eval('fix(1.8)'), 1);
|
|
assert.equal(math.eval('floor(1.3)'), 1);
|
|
assert.equal(math.eval('floor(1.8)'), 1);
|
|
assert.equal(math.eval('gcd(12, 8)'), 4);
|
|
assert.equal(math.eval('larger(2, 3)'), false);
|
|
assert.equal(math.eval('larger(2, 2)'), false);
|
|
assert.equal(math.eval('larger(2, 1)'), true);
|
|
assert.equal(math.eval('largereq(2, 3)'), false);
|
|
assert.equal(math.eval('largereq(2, 2)'), true);
|
|
assert.equal(math.eval('largereq(2, 1)'), true);
|
|
assert.equal(math.eval('lcm(4, 6)'), 12);
|
|
approx.equal(math.eval('log(e)'), 1);
|
|
approx.equal(math.eval('log(2.71828182845905)'), 1);
|
|
approx.equal(math.eval('log10(1000)'), 3);
|
|
approx.equal(math.eval('mod(8, 3)'), 2);
|
|
approx.equal(math.eval('multiply(4, 2)'), 8);
|
|
approx.equal(math.eval('pow(2,3)'), 8);
|
|
approx.equal(math.eval('pow(-2,2)'), 4);
|
|
assert.equal(math.eval('round(pi)'), 3);
|
|
assert.equal(math.eval('round(pi, 3)'), 3.142);
|
|
assert.equal(math.eval('sign(3)'), 1);
|
|
assert.equal(math.eval('sign(-3)'), -1);
|
|
assert.equal(math.eval('sign(0)'), 0);
|
|
assert.equal(math.eval('smaller(2, 3)'), true);
|
|
assert.equal(math.eval('smaller(2, 2)'), false);
|
|
assert.equal(math.eval('smaller(2, 1)'), false);
|
|
assert.equal(math.eval('smallereq(2, 3)'), true);
|
|
assert.equal(math.eval('smallereq(2, 2)'), true);
|
|
assert.equal(math.eval('smallereq(2, 1)'), false);
|
|
assert.equal(math.eval('sqrt(25)'), 5);
|
|
assert.equal(math.eval('square(4)'), 16);
|
|
assert.equal(math.eval('subtract(4, 2)'), 2);
|
|
assert.equal(math.eval('unary(4)'), -4);
|
|
assert.equal(math.eval('unequal(2, 3)'), true);
|
|
assert.equal(math.eval('unequal(2, 2)'), false);
|
|
assert.deepEqual(math.eval('xgcd(36163, 21199)'), [1247, -7, 12]);
|
|
});
|
|
|
|
describe('construction', function () {
|
|
|
|
it('should parse construction function boolean correctly', function() {
|
|
assert.equal(math.eval('boolean("true")'), true);
|
|
assert.equal(math.eval('boolean("false")'), false);
|
|
assert.equal(math.eval('boolean(true)'), true);
|
|
assert.equal(math.eval('boolean(false)'), false);
|
|
assert.equal(math.eval('boolean(1)'), true);
|
|
assert.equal(math.eval('boolean(2)'), true);
|
|
assert.equal(math.eval('boolean(0)'), false);
|
|
});
|
|
|
|
it('should parse construction function complex correctly', function() {
|
|
assert.deepEqual(math.eval('complex()'), new math.type.Complex(0,0));
|
|
assert.deepEqual(math.eval('complex(2,3)'), new math.type.Complex(2,3));
|
|
assert.deepEqual(math.eval('complex("2+3i")'), new math.type.Complex(2,3));
|
|
});
|
|
|
|
it('should pasre construction function number correctly', function() {
|
|
assert.equal(math.eval('number(123)'), 123);
|
|
assert.equal(math.eval('number("123")'), 123);
|
|
assert.equal(math.eval('number()'), 0);
|
|
});
|
|
|
|
it('should pasre construction function string correctly', function() {
|
|
assert.equal(math.eval('string(123)'), '123');
|
|
assert.equal(math.eval('string(2+3i)'), '2 + 3i');
|
|
assert.equal(math.eval('string(1:5)'), '[1, 2, 3, 4, 5]');
|
|
assert.equal(math.eval('string(2 inch)'), '2 inch');
|
|
assert.equal(math.eval('string([1,2;3,4])'), '[[1, 2], [3, 4]]');
|
|
});
|
|
|
|
it('should pasre construction function unit correctly', function() {
|
|
assert.deepEqual(math.eval('unit(2, "m")'), new math.type.Unit(2, 'm'));
|
|
assert.deepEqual(math.eval('unit("2m")'), new math.type.Unit(2, 'm'));
|
|
});
|
|
|
|
});
|
|
});
|
|
|
|
}); |