UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.

993 lines (818 loc) 38.8 kB
var assert = require('assert'); var approx = require('../../../tools/approx'); var math = require('../../../index'); var Unit = math.type.Unit; describe('Unit', function() { describe('constructor', function() { it('should create unit correctly', function() { var unit1 = new Unit(5000, 'cm'); assert.equal(unit1.value, 50); assert.equal(unit1.units[0].unit.name, 'm'); unit1 = new Unit(5, 'kg'); assert.equal(unit1.value, 5); assert.equal(unit1.units[0].unit.name, 'g'); unit1 = new Unit(null, 'kg'); assert.equal(unit1.value, null); assert.equal(unit1.units[0].unit.name, 'g'); unit1 = new Unit(10, 'Hz'); assert.equal(unit1.value, 10); assert.equal(unit1.units[0].unit.name, 'Hz'); unit1 = new Unit(9.81, "kg m/s^2"); assert.equal(unit1.value, 9.81); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[1].unit.name, 'm'); assert.equal(unit1.units[2].unit.name, 's'); }); it('should create a unit with Fraction value', function () { var unit1 = new Unit(math.fraction(1000, 3), 'cm'); assert.deepEqual(unit1.value, math.fraction(10,3)); assert.equal(unit1.units[0].unit.name, 'm'); }); it('should create a unit with BigNumber value', function () { var unit1 = new Unit(math.bignumber(5000), 'cm'); assert.deepEqual(unit1.value, math.bignumber(50)); assert.equal(unit1.units[0].unit.name, 'm'); }); it('should create a unit with Complex value', function () { var unit1 = new Unit(math.complex(500, 600), 'cm'); assert.deepEqual(unit1.value, math.complex(5, 6)); assert.equal(unit1.units[0].unit.name, 'm'); }); it('should create square meter correctly', function() { var unit1 = new Unit(0.000001, 'km2'); assert.equal(unit1.value, 1); assert.equal(unit1.units[0].unit.name, 'm2'); }); it('should create cubic meter correctly', function() { var unit1 = new Unit(0.000000001, 'km3'); assert.equal(unit1.value, 1); assert.equal(unit1.units[0].unit.name, 'm3'); }); it('should ignore properties on Object.prototype', function() { Object.prototype.foo = Unit.UNITS['meter']; assert.throws(function () {new Unit(1, 'foo')}, /Unit "foo" not found/); delete Object.prototype.foo; }); it('should throw an error if called without new keyword', function() { assert.throws(function () { Unit(2, 'inch'); }); }); it('should throw an error if called with wrong type of arguments', function() { assert.throws(function () { new Unit('24', 'inch'); }); assert.throws(function () { new Unit(0, 'bla'); }); assert.throws(function () { new Unit(4, ''); }); assert.throws(function () { new Unit(0, 3); }); }); it('should flag unit as already simplified', function() { unit1 = new Unit(9.81, "kg m/s^2"); assert.equal(unit1.isUnitListSimplified, true); assert.equal(unit1.toString(), "9.81 (kg m) / s^2"); unit1 = new Unit(null, "kg m/s^2"); assert.equal(unit1.isUnitListSimplified, true); assert.equal(unit1.toString(), "(kg m) / s^2"); }); }); describe('isValuelessUnit', function() { it('should return true if the string is a plain unit', function() { assert.equal(Unit.isValuelessUnit('cm'), true); assert.equal(Unit.isValuelessUnit('inch'), true); assert.equal(Unit.isValuelessUnit('kb'), true); }); it('should return false if the unit is not a plain unit', function() { assert.equal(Unit.isValuelessUnit('bla'), false); assert.equal(Unit.isValuelessUnit('5cm'), false); }); }); describe('type', function() { it('should have a property isUnit', function () { var a = new math.type.Unit(5, 'cm'); assert.strictEqual(a.isUnit, true); }); it('should have a property type', function () { var a = new math.type.Unit(5, 'cm'); assert.strictEqual(a.type, 'Unit'); }); }); describe('hasBase', function() { it('should test whether a unit has a certain base unit', function() { assert.equal(new Unit(5, 'cm').hasBase(Unit.BASE_UNITS.ANGLE), false); assert.equal(new Unit(5, 'cm').hasBase(Unit.BASE_UNITS.LENGTH), true); assert.equal(new Unit(5, 'kg m / s ^ 2').hasBase(Unit.BASE_UNITS.FORCE), true); }); }); describe('equalBase', function() { it('should test whether two units have the same base unit', function() { assert.equal(new Unit(5, 'cm').equalBase(new Unit(10, 'm')), true); assert.equal(new Unit(5, 'cm').equalBase(new Unit(10, 'kg')), false); assert.equal(new Unit(5, 'N').equalBase(new Unit(10, 'kg m / s ^ 2')), true); assert.equal(new Unit(8.314, 'J / mol K').equalBase(new Unit(0.02366, 'ft^3 psi / mol degF')), true); }); }); describe('equals', function() { it('should test whether two units are equal', function() { assert.equal(new Unit(100, 'cm').equals(new Unit(1, 'm')), true); assert.equal(new Unit(100, 'cm').equals(new Unit(2, 'm')), false); assert.equal(new Unit(100, 'cm').equals(new Unit(1, 'kg')), false); assert.equal(new Unit(100, 'ft lbf').equals(new Unit(1200, 'in lbf')), true); assert.equal(new Unit(100, 'N').equals(new Unit(100, 'kg m / s ^ 2')), true); assert.equal(new Unit(100, 'N').equals(new Unit(100, 'kg m / s')), false); assert.equal(new Unit(100, 'Hz').equals(new Unit (100, 's ^ -1')), true); }); it('should test whether two units with Fractions are equal', function() { assert.equal(new Unit(math.fraction(100), 'cm').equals(new Unit(math.fraction(1), 'm')), true); assert.equal(new Unit(math.fraction(100), 'cm').equals(new Unit(math.fraction(2), 'm')), false); }); it('should test whether two units with a Fraction and a number are equal', function() { assert.equal(new Unit(math.fraction(100), 'cm').equals(new Unit(1, 'm')), true); assert.equal(new Unit(100, 'cm').equals(new Unit(math.fraction(2), 'm')), false); }); it('should test whether two Complex units are equal', function() { assert.equal(new Unit(math.complex(3, 4), 'km').equals(new Unit(math.complex(3000, 4000), 'm')), true); assert.equal(new Unit(math.complex(3, 4), 'km').equals(new Unit(math.complex(3000, 10), 'm')), false); }); it('should test whether a Complex unit and a unit with a number are equal', function() { assert.equal(new Unit(math.complex(3, 0), 'km').equals(new Unit(3000, 'm')), true); assert.equal(new Unit(math.complex(3, 4), 'km').equals(new Unit(3000, 'm')), false); }); }); describe('clone', function() { it('should clone a unit', function() { var u1 = new Unit(100, 'cm'); var u2 = u1.clone(); assert(u1 !== u2); assert.deepEqual(u1, u2); var u3 = new Unit(100, 'cm').to('inch'); var u4 = u3.clone(); assert(u3 !== u4); assert.deepEqual(u3, u4); var u5 = new Unit(null, 'cm').to('inch'); var u6 = u5.clone(); assert(u5 !== u6); assert.deepEqual(u5, u6); var u7 = new Unit(8.314, 'kg m^2 / s^2 K mol'); var u8 = u7.clone(); assert(u7 !== u8); assert.deepEqual(u7, u8); }); it('should clone a with a Fraction', function() { var u1 = new Unit(math.fraction(1,3), 'cm'); var u2 = u1.clone(); assert(u1 !== u2); assert.deepEqual(u1, u2); assert(u1.value !== u2.value); // should be cloned }); it('should clone a Complex unit', function() { var u1 = new Unit(math.complex(1,3), 'cm'); var u2 = u1.clone(); assert(u1 !== u2); assert.deepEqual(u1, u2); assert(u1.value !== u2.value); // should be cloned }); }); describe('toNumber', function() { it ('should convert a unit to a number', function () { var u = new Unit(5000, 'cm'); approx.equal(u.toNumber('mm'), 50000); approx.equal(new Unit(5.08, 'cm').toNumber('inch'), 2); approx.equal(new Unit(101325, 'N/m^2').toNumber('lbf/in^2'), 14.6959487763741); }); it ('should convert a unit with fixed prefix to a number', function () { var u1 = new Unit(5000, 'cm'); var u2 = u1.to('km'); approx.equal(u2.toNumber('mm'), 50000); var u1 = new Unit(981, 'cm/s^2'); var u2 = u1.to('km/ms^2'); approx.equal(u2.toNumber('m/s^2'), 9.81); }); it ('should convert a unit with fraction to a number', function () { var u = new Unit(math.fraction(5), 'cm'); assert.strictEqual(u.toNumber('mm'), 50); }); }); describe('toNumeric', function() { it ('should convert a unit to a numeric value', function () { var u = new Unit(math.fraction(1,3), 'cm'); assert.deepEqual(u.toNumeric('mm'), math.fraction(10,3)); }); }); describe('to', function() { it ('should convert a unit to a fixed unitName', function () { var u1 = new Unit(5000, 'cm'); assert.equal(u1.value, 50); assert.equal(u1.units[0].unit.name, 'm'); assert.equal(u1.units[0].prefix.name, 'c'); assert.equal(u1.fixPrefix, false); var u2 = u1.to('inch'); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 50); assert.equal(u2.units[0].unit.name, 'inch'); assert.equal(u2.units[0].prefix.name, ''); assert.equal(u2.fixPrefix, true); var u3 = new Unit(299792.458, 'km/s'); assert.equal(u3.value, 299792458); assert.equal(u3.units[0].unit.name, 'm'); assert.equal(u3.units[1].unit.name, 's'); assert.equal(u3.units[0].prefix.name, 'k'); assert.equal(u3.fixPrefix, false); var u4 = u3.to('mi/h'); assert.notStrictEqual(u3, u4); // u4 must be a clone assert.equal(u4.value, 299792458); assert.equal(u4.units[0].unit.name, 'mi'); assert.equal(u4.units[1].unit.name, 'h'); assert.equal(u4.units[0].prefix.name, ''); assert.equal(u4.fixPrefix, true); }); it ('should convert a unit with a fraction', function () { var u1 = new Unit(math.fraction(1,3), 'm'); var u2 = u1.to('cm'); assert.deepEqual(u2.value, math.fraction(1,3)); assert(u2.value.isFraction); assert.equal(u2.units[0].unit.name, 'm'); assert.equal(u2.units[0].prefix.name, 'c'); assert.equal(u2.fixPrefix, true); }); it ('should convert a Complex unit', function() { var u1 = new Unit(math.complex(300,400), 'kPa'); var u2 = u1.to('lbf/in^2'); approx.deepEqual(u2.value, math.complex(300000, 400000)); assert.deepEqual(u2.toString(), "(43.511321319062766 + 58.01509509208368i) lbf / in^2"); }); it ('should convert a unit to a fixed unit', function () { var u1 = new Unit(5000, 'cm'); assert.equal(u1.value, 50); assert.equal(u1.units[0].unit.name, 'm'); assert.equal(u1.units[0].prefix.name, 'c'); assert.equal(u1.fixPrefix, false); var u2 = u1.to(new Unit(null, 'km')); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 50); assert.equal(u2.units[0].unit.name, 'm'); assert.equal(u2.units[0].prefix.name, 'k'); assert.equal(u2.fixPrefix, true); var u1 = new Unit(5000, 'cm/s'); assert.equal(u1.value, 50); assert.equal(u1.units[0].unit.name, 'm'); assert.equal(u1.units[1].unit.name, 's'); assert.equal(u1.units[0].prefix.name, 'c'); assert.equal(u1.fixPrefix, false); var u2 = u1.to(new Unit(null, 'km/h')); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 50); assert.equal(u2.units[0].unit.name, 'm'); assert.equal(u2.units[1].unit.name, 'h'); assert.equal(u2.units[0].prefix.name, 'k'); assert.equal(u2.fixPrefix, true); }); it ('should convert a valueless unit', function () { var u1 = new Unit(null, 'm'); assert.equal(u1.value, null); assert.equal(u1.units[0].unit.name, 'm'); assert.equal(u1.units[0].prefix.name, ''); assert.equal(u1.fixPrefix, false); var u2 = u1.to(new Unit(null, 'cm')); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 1); // u2 must have a value assert.equal(u2.units[0].unit.name, 'm'); assert.equal(u2.units[0].prefix.name, 'c'); assert.equal(u2.fixPrefix, true); var u1 = new Unit(null, 'm/s'); assert.equal(u1.value, null); assert.equal(u1.units[0].unit.name, 'm'); assert.equal(u1.units[1].unit.name, 's'); assert.equal(u1.units[0].prefix.name, ''); assert.equal(u1.fixPrefix, false); var u2 = u1.to(new Unit(null, 'cm/s')); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 1); // u2 must have a value assert.equal(u2.units[0].unit.name, 'm'); assert.equal(u2.units[1].unit.name, 's'); assert.equal(u2.units[0].prefix.name, 'c'); assert.equal(u2.fixPrefix, true); }); it ('should convert a binary prefixes (1)', function () { var u1 = new Unit(1, 'Kib'); assert.equal(u1.value, 1024); assert.equal(u1.units[0].unit.name, 'b'); assert.equal(u1.units[0].prefix.name, 'Ki'); assert.equal(u1.fixPrefix, false); var u2 = u1.to(new Unit(null, 'b')); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 1024); // u2 must have a value assert.equal(u2.units[0].unit.name, 'b'); assert.equal(u2.units[0].prefix.name, ''); assert.equal(u2.fixPrefix, true); var u1 = new Unit(1, 'Kib/s'); assert.equal(u1.value, 1024); assert.equal(u1.units[0].unit.name, 'b'); assert.equal(u1.units[1].unit.name, 's'); assert.equal(u1.units[0].prefix.name, 'Ki'); assert.equal(u1.fixPrefix, false); var u2 = u1.to(new Unit(null, 'b/s')); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 1024); // u2 must have a value assert.equal(u2.units[0].unit.name, 'b'); assert.equal(u2.units[1].unit.name, 's'); assert.equal(u2.units[0].prefix.name, ''); assert.equal(u2.fixPrefix, true); }); it ('should convert a binary prefixes (2)', function () { var u1 = new Unit(1, 'kb'); assert.equal(u1.value, 1000); assert.equal(u1.units[0].unit.name, 'b'); assert.equal(u1.units[0].prefix.name, 'k'); assert.equal(u1.fixPrefix, false); var u2 = u1.to(new Unit(null, 'b')); assert.notStrictEqual(u1, u2); // u2 must be a clone assert.equal(u2.value, 1000); // u2 must have a value assert.equal(u2.units[0].unit.name, 'b'); assert.equal(u2.units[0].prefix.name, ''); assert.equal(u2.fixPrefix, true); }); it ('should set isUnitListSimplified to true', function () { var u1 = new Unit(1, 'ft lbf'); var u2 = u1.to('in lbf'); assert.equal(u2.isUnitListSimplified, true); assert.equal(u2.toString(), "12 in lbf"); }); it ('should throw an error when converting to an incompatible unit', function () { var u1 = new Unit(5000, 'cm'); assert.throws(function () {u1.to('kg')}, /Units do not match/); var u1 = new Unit(5000, 'N s'); assert.throws(function () {u1.to('kg^5 / s')}, /Units do not match/); }); it ('should throw an error when converting to a unit having a value', function () { var u1 = new Unit(5000, 'cm'); assert.throws(function () {u1.to(new Unit(4, 'm'))}, /Cannot convert to a unit with a value/); }); it ('should throw an error when converting to an unsupported type of argument', function () { var u1 = new Unit(5000, 'cm'); assert.throws(function () {u1.to(new Date())}, /String or Unit expected as parameter/); }); }); describe('toString', function() { it('should convert to string properly', function() { assert.equal(new Unit(5000, 'cm').toString(), '50 m'); assert.equal(new Unit(5, 'kg').toString(), '5 kg'); assert.equal(new Unit(2/3, 'm').toString(), '0.6666666666666666 m'); assert.equal(new Unit(5, 'N').toString(), '5 N'); assert.equal(new Unit(5, 'kg^1.0e0 m^1.0e0 s^-2.0e0').toString(), '5 (kg m) / s^2'); assert.equal(new Unit(5, 's^-2').toString(), '5 s^-2'); assert.equal(new Unit(5, 'm / s ^ 2').toString(), '5 m / s^2'); assert.equal(new Unit(null, 'kg m^2 / s^2 / mol').toString(), '(kg m^2) / (s^2 mol)'); assert.equal(new Unit(10, 'hertz').toString(), '10 hertz'); }); it('should render with the best prefix', function() { assert.equal(new Unit(0.001 ,'m').toString(), '1 mm'); assert.equal(new Unit(0.01 ,'m').toString(), '10 mm'); assert.equal(new Unit(0.1 ,'m').toString(), '100 mm'); assert.equal(new Unit(0.5 ,'m').toString(), '500 mm'); assert.equal(new Unit(0.6 ,'m').toString(), '0.6 m'); assert.equal(new Unit(1 ,'m').toString(), '1 m'); assert.equal(new Unit(10 ,'m').toString(), '10 m'); assert.equal(new Unit(100 ,'m').toString(), '100 m'); assert.equal(new Unit(300 ,'m').toString(), '300 m'); assert.equal(new Unit(500 ,'m').toString(), '500 m'); assert.equal(new Unit(600 ,'m').toString(), '0.6 km'); assert.equal(new Unit(1000 ,'m').toString(), '1 km'); assert.equal(new Unit(1000 ,'ohm').toString(), '1 kohm'); }); it('should render best prefix for a single unit raised to integral power', function() { assert.equal(new Unit(3.2e7, 'm^2').toString(), "32 km^2"); assert.equal(new Unit(3.2e-7, 'm^2').toString(), "0.32 mm^2"); assert.equal(new Unit(15000, 'm^-1').toString(), "15 mm^-1"); assert.equal(new Unit(3e-9, 'm^-2').toString(), "3000 Mm^-2"); assert.equal(new Unit(3e-9, 'm^-1.5').toString(), "3e-9 m^-1.5"); assert.equal(new Unit(2, 'kg^0').toString(), "2"); }); it('should not render best prefix if "fixPrefix" is set', function() { var u = new Unit(5e-3, 'm'); u.fixPrefix = true; assert.equal(u.toString(), "0.005 m"); u.fixPrefix = false; assert.equal(u.toString(), "5 mm"); }); it('should convert a unit with Fraction to string properly', function() { assert.equal(new Unit(math.fraction(9/10), 'mm').toString(), '9/10 mm'); }); it('should convert a Complex unit to string properly', function() { assert.equal(new Unit(math.complex(-1,-2), 'J / (mol K)').toString(), '(-1 - 2i) J / (mol K)'); }); }); describe('simplifyUnitListLazy', function() { it('should not simplify units created with new Unit()', function() { var unit1 = new Unit(10, "kg m/s^2"); assert.equal(unit1.units[0].unit.name, "g"); assert.equal(unit1.units[1].unit.name, "m"); assert.equal(unit1.units[2].unit.name, "s"); assert.equal(unit1.toString(), "10 (kg m) / s^2"); }); it('should only simplify units with values', function() { var unit1 = new Unit(null, "kg m mol / s^2 / mol"); unit1.isUnitListSimplified = false; unit1.simplifyUnitListLazy(); assert.equal(unit1.toString(), "(kg m mol) / (s^2 mol)"); unit1 = math.multiply(unit1, 1); assert.equal(unit1.toString(), "1 N"); }); it('should simplify units resulting from multiply/divide/power functions only when formatting for output', function() { var unit1 = new Unit(2, "kg"); var unit2 = new Unit(5, "m/s^2"); var unit3 = math.multiply(unit1, unit2); assert.equal(unit3.units[0].unit.name, "g"); assert.equal(unit3.units[1].unit.name, "m"); assert.equal(unit3.units[2].unit.name, "s"); assert.equal(unit3.toString(), "10 N"); // Triggers simplification assert.equal(unit3.units[0].unit.name, "N"); }); it('should simplify units even when they cancel out', function() { var unit1 = new Unit (2, "Hz"); var unit2 = new Unit(2, "s"); var unit3 = math.multiply(unit1, unit2); assert.equal(unit3.toString(), "4"); assert.equal(unit3.units.length, 0); }) it('should simplify units according to chosen unit system', function() { var unit1 = new Unit(10, "N"); Unit.setUnitSystem('us'); unit1.isUnitListSimplified = false; assert.equal(unit1.toString(), "2.248089430997105 lbf"); assert.equal(unit1.units[0].unit.name, "lbf"); Unit.setUnitSystem('cgs'); unit1.isUnitListSimplified = false; assert.equal(unit1.format(2), "1 Mdyn"); assert.equal(unit1.units[0].unit.name, "dyn"); }); it('should correctly simplify units when unit system is "auto"', function() { Unit.setUnitSystem('auto'); var unit1 = new Unit(5, "lbf min / s"); unit1.isUnitListSimplified = false; assert.equal(unit1.toString(), "300 lbf"); }); }); describe('valueOf', function() { it('should return string representation when calling valueOf', function() { assert.strictEqual(new Unit(5000, 'cm').valueOf(), '50 m'); assert.strictEqual(new Unit(5, 'kg').valueOf(), '5 kg'); assert.strictEqual(new Unit(2/3, 'm').valueOf(), '0.6666666666666666 m'); assert.strictEqual(new Unit(5, 'N').valueOf(), '5 N'); assert.strictEqual(new Unit(5, 'kg^1.0e0 m^1.0e0 s^-2.0e0').valueOf(), '5 (kg m) / s^2'); assert.strictEqual(new Unit(5, 's^-2').valueOf(), '5 s^-2'); }); }); describe('json', function () { it('toJSON', function () { assert.deepEqual(new Unit(5, 'cm').toJSON(), {'mathjs': 'Unit', value: 5, unit: 'cm', fixPrefix: false}); assert.deepEqual(new Unit(5, 'cm').to('mm').toJSON(), {'mathjs': 'Unit', value: 50, unit: 'mm', fixPrefix: true}); assert.deepEqual(new Unit(5, 'kN').to('kg m s ^ -2').toJSON(), {'mathjs': 'Unit', value: 5000, unit: '(kg m) / s^2', fixPrefix: true}); assert.deepEqual(new Unit(math.fraction(0.375), 'cm').toJSON(), { mathjs: 'Unit', value: math.fraction(0.375), // Note that value is not serialized at this point, that will be done by JSON.stringify unit: 'cm', fixPrefix: false }); approx.deepEqual(new Unit(math.complex(2, 4), 'g').toJSON(), { mathjs: 'Unit', value: math.complex(2, 4), unit: 'g', fixPrefix: false }); var str = JSON.stringify(new Unit(math.fraction(0.375), 'cm')); assert.deepEqual(str, '{"mathjs":"Unit","value":{"mathjs":"Fraction","n":3,"d":8},"unit":"cm","fixPrefix":false}'); var cmpx = JSON.stringify(new Unit(math.complex(2, 4), 'g')); assert.equal(cmpx, '{"mathjs":"Unit","value":{"mathjs":"Complex","re":2,"im":4},"unit":"g","fixPrefix":false}'); }); it('fromJSON', function () { var u1 = new Unit(5, 'cm'); var u2 = Unit.fromJSON({'mathjs': 'Unit', value: 5, unit: 'cm', fixPrefix: false}); assert.ok(u2 instanceof Unit); assert.deepEqual(u2, u1); var u3 = new Unit(5, 'cm').to('mm'); var u4 = Unit.fromJSON({'mathjs': 'Unit', value: 50, unit: 'mm', fixPrefix: true}); assert.ok(u4 instanceof Unit); assert.deepEqual(u4, u3); var u5 = new Unit(5, 'kN').to('kg m/s^2'); var u6 = Unit.fromJSON({'mathjs': 'Unit', value: 5000, unit: 'kg m s^-2', fixPrefix: true}); assert.ok(u6 instanceof Unit); assert.deepEqual(u5, u6); var u7 = Unit.fromJSON({ mathjs: 'Unit', value: math.fraction(0.375), // Note that value is already a Fraction at this point, that will be done by JSON.parse(str, reviver) unit: 'cm', fixPrefix: false }); assert.deepEqual(u7, new Unit(math.fraction(0.375), 'cm')) var u8 = Unit.fromJSON({ mathjs: 'Unit', value: math.complex(2, 4), unit: 'g', fixPrefix: false }); assert.deepEqual(u8, new Unit(math.complex(2,4), 'g')); }); it('toJSON -> fromJSON should recover an "equal" unit', function() { var unit1 = Unit.parse('1.23(m/(s/(kg mol)/(lbm/h)K))'); var unit2 = Unit.fromJSON(unit1.toJSON()); assert.equal(unit1.equals(unit2), true); }); }); describe('format', function () { it('should format units with given precision', function() { assert.equal(new Unit(2/3, 'm').format(3), '0.667 m'); assert.equal(new Unit(2/3, 'm').format(4), '0.6667 m'); assert.equal(new Unit(2/3, 'm').format(), '0.6666666666666666 m'); }); it('should format a unit without value', function() { assert.equal(new Unit(null, 'cm').format(), 'cm'); assert.equal(new Unit(null, 'm').format(), 'm'); assert.equal(new Unit(null, 'kg m/s').format(), '(kg m) / s'); }); it('should format a unit with fixed prefix and without value', function() { assert.equal(new Unit(null, 'km').to('cm').format(), '1e+5 cm'); assert.equal(new Unit(null, 'inch').to('cm').format(), '2.54 cm'); assert.equal(new Unit(null, 'N/m^2').to('lbf/inch^2').format(5), '1.4504e-4 lbf / inch^2'); }); it('should format a unit with a bignumber', function() { assert.equal(new Unit(math.bignumber(1).plus(1e-24), 'm').format(), '1.000000000000000000000001 m'); assert.equal(new Unit(math.bignumber(1e24).plus(1), 'm').format(), '1.000000000000000000000001 Ym'); }); it('should format a unit with a fraction', function() { assert.equal(new Unit(math.fraction(4/5), 'm').format(), '4/5 m'); }); it('should format a Complex unit', function() { assert.equal(new Unit(math.complex(-2, 4.5), 'mm').format(14), '(-2 + 4.5i) mm'); }); it('should format units with VA and VAR correctly', function() { assert.equal(math.eval('4000 VAR + 3000 VA').format(), "(3 + 4i) kVA"); assert.equal(math.eval('3000 VA + 4000 VAR').format(), "(3 + 4i) kVA"); assert.equal(math.eval('4000 VAR').format(), "(4) kVAR"); assert.equal(math.eval('4000i VA').format(), "(4) kVAR"); assert.equal(math.eval('4000i VAR').format(), "(-4) kVA"); assert.equal(math.eval('abs(4000 VAR + 3000 VA)').format(), "5 kW"); assert.equal(math.eval('abs(3000 VA + 4000 VAR)').format(), "5 kW"); assert.equal(math.eval('abs(4000 VAR)').format(), "4 kW"); assert.equal(math.eval('abs(4000i VA)').format(), "4 kW"); assert.equal(math.eval('abs(4000i VAR)').format(), "4 kW"); }); it('should ignore properties in Object.prototype when finding the best prefix', function() { Object.prototype.foo = 'bar'; assert.equal(new Unit(5e5, 'cm').format(), '5 km'); delete Object.prototype.foo; }); }); describe('parse', function() { it('should parse units correctly', function() { var unit1; unit1 = Unit.parse('5kg'); assert.equal(unit1.value, 5); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('5 kg'); assert.equal(unit1.value, 5); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse(' 5 kg '); assert.equal(unit1.value, 5); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('5e-3kg'); assert.equal(unit1.value, 0.005); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('5e+3kg'); assert.equal(unit1.value, 5000); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('5e3kg'); assert.equal(unit1.value, 5000); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('-5kg'); assert.equal(unit1.value, -5); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('+5kg'); assert.equal(unit1.value, 5); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('.5kg'); assert.equal(unit1.value, .5); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('-5mg'); approx.equal(unit1.value, -0.000005); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'm'); unit1 = Unit.parse('5.2mg'); approx.equal(unit1.value, 0.0000052); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[0].prefix.name, 'm'); unit1 = Unit.parse('300 kg/minute'); approx.equal(unit1.value, 5); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[1].unit.name, 'minute'); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('981 cm/s^2'); approx.equal(unit1.value, 9.81); assert.equal(unit1.units[0].unit.name, 'm'); assert.equal(unit1.units[1].unit.name, 's'); assert.equal(unit1.units[1].power, -2); assert.equal(unit1.units[0].prefix.name, 'c'); unit1 = Unit.parse('981 cm*s^-2'); approx.equal(unit1.value, 9.81); assert.equal(unit1.units[0].unit.name, 'm'); assert.equal(unit1.units[1].unit.name, 's'); assert.equal(unit1.units[1].power, -2); assert.equal(unit1.units[0].prefix.name, 'c'); unit1 = Unit.parse('8.314 kg m^2 / s^2 / K / mol'); approx.equal(unit1.value, 8.314); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[1].unit.name, 'm'); assert.equal(unit1.units[2].unit.name, 's'); assert.equal(unit1.units[3].unit.name, 'K'); assert.equal(unit1.units[4].unit.name, 'mol'); assert.equal(unit1.units[0].power, 1); assert.equal(unit1.units[1].power, 2); assert.equal(unit1.units[2].power, -2); assert.equal(unit1.units[3].power, -1); assert.equal(unit1.units[4].power, -1); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('5exabytes'); approx.equal(unit1.value, 4e19); assert.equal(unit1.units[0].unit.name, 'bytes'); }); it('should parse expressions with nested parentheses correctly', function() { unit1 = Unit.parse('8.314 kg (m^2 / (s^2 / (K^-1 / mol)))'); approx.equal(unit1.value, 8.314); assert.equal(unit1.units[0].unit.name, 'g'); assert.equal(unit1.units[1].unit.name, 'm'); assert.equal(unit1.units[2].unit.name, 's'); assert.equal(unit1.units[3].unit.name, 'K'); assert.equal(unit1.units[4].unit.name, 'mol'); assert.equal(unit1.units[0].power, 1); assert.equal(unit1.units[1].power, 2); assert.equal(unit1.units[2].power, -2); assert.equal(unit1.units[3].power, -1); assert.equal(unit1.units[4].power, -1); assert.equal(unit1.units[0].prefix.name, 'k'); unit1 = Unit.parse('1 (m / ( s / ( kg mol ) / ( lbm / h ) K ) )'); assert.equal(unit1.units[0].unit.name, 'm'); assert.equal(unit1.units[1].unit.name, 's'); assert.equal(unit1.units[2].unit.name, 'g'); assert.equal(unit1.units[3].unit.name, 'mol'); assert.equal(unit1.units[4].unit.name, 'lbm'); assert.equal(unit1.units[5].unit.name, 'h'); assert.equal(unit1.units[6].unit.name, 'K'); assert.equal(unit1.units[0].power, 1); assert.equal(unit1.units[1].power, -1); assert.equal(unit1.units[2].power, 1); assert.equal(unit1.units[3].power, 1); assert.equal(unit1.units[4].power, 1); assert.equal(unit1.units[5].power, -1); assert.equal(unit1.units[6].power, -1); unit2 = Unit.parse('1(m/(s/(kg mol)/(lbm/h)K))'); assert.deepEqual(unit1, unit2); }); it('should parse units with correct precedence', function() { var unit1 = Unit.parse('1 m^3 / kg s^2'); // implicit multiplication approx.equal(unit1.value, 1); assert.equal(unit1.units[0].unit.name, 'm'); assert.equal(unit1.units[1].unit.name, 'g'); assert.equal(unit1.units[2].unit.name, 's'); assert.equal(unit1.units[0].power, 3); assert.equal(unit1.units[1].power, -1); assert.equal(unit1.units[2].power, 2); assert.equal(unit1.units[0].prefix.name, ''); }); it('should throw an exception when parsing an invalid unit', function() { assert.throws(function () {Unit.parse('.meter')}, /Unexpected "\."/); assert.throws(function () {Unit.parse('5e')}, /Unit "e" not found/); assert.throws(function () {Unit.parse('5e.')}, /Unit "e" not found/); assert.throws(function () {Unit.parse('5e1.3')}, /Unexpected "\."/); assert.throws(function () {Unit.parse('5')}, /contains no units/); assert.throws(function () {Unit.parse('')}, /contains no units/); assert.throws(function () {Unit.parse('meter.')}, /Unexpected "\."/); assert.throws(function () {Unit.parse('meter/')}, /Trailing characters/); assert.throws(function () {Unit.parse('/meter')}, /Unexpected "\/"/); assert.throws(function () {Unit.parse('45 kg 34 m')}, /Unexpected "3"/); }); it('should throw an exception when parsing an invalid type of argument', function() { assert.throws(function () {Unit.parse(123)}, /TypeError: Invalid argument in Unit.parse, string expected/); }); it('should parse the value of the unit as Fraction or BigNumber when math.js is configured so', function() { var origConfig = math.config(); math.config({number: 'Fraction'}); var unit1 = Unit.parse('5kg'); assert(unit1.value.isFraction); math.config({number: 'BigNumber'}); var unit1 = Unit.parse('5kg'); assert(unit1.value.isBigNumber); math.config(origConfig); }); }); describe('_isDerived', function() { it('should return the correct value', function () { assert.equal(Unit.parse('34 kg')._isDerived(), false); assert.equal(Unit.parse('34 kg/s')._isDerived(), true); assert.equal(Unit.parse('34 kg^2')._isDerived(), true); assert.equal(Unit.parse('34 N')._isDerived(), false); assert.equal(Unit.parse('34 kg m / s^2')._isDerived(), true); var unit1 = Unit.parse('34 kg m / s^2'); assert.equal(unit1._isDerived(), true); unit1.isUnitListSimplified = false; unit1.simplifyUnitListLazy(); assert.equal(unit1._isDerived(), false); }); }); describe('multiply, divide, and pow', function() { it('should flag the unit as requiring simplification', function() { var unit1 = new Unit(10, 'kg'); var unit2 = new Unit(9.81, 'm/s^2'); assert.equal(unit1.multiply(unit2).isUnitListSimplified, false); assert.equal(unit1.divide(unit2).isUnitListSimplified, false); assert.equal(unit1.pow(2).isUnitListSimplified, false); }); it('should retain the units of their operands without simplifying', function() { var unit1 = new Unit(10, "N/s"); var unit2 = new Unit(10, "h"); var unitM = unit1.multiply(unit2); assert.equal(unitM.units[0].unit.name, 'N'); assert.equal(unitM.units[1].unit.name, 's'); assert.equal(unitM.units[2].unit.name, 'h'); var unit3 = new Unit(14.7, "lbf"); var unit4 = new Unit(1, "in in"); var unitD = unit3.divide(unit4); assert.equal(unitD.units[0].unit.name, 'lbf'); assert.equal(unitD.units[1].unit.name, 'in'); assert.equal(unitD.units[2].unit.name, 'in'); var unit5 = new Unit(1, "N h/s"); var unitP = unit5.pow(-3.5); assert.equal(unitP.units[0].unit.name, 'N'); assert.equal(unitP.units[1].unit.name, 'h'); assert.equal(unitP.units[2].unit.name, 's'); }); it('should keep the same numeric type for the units value', function() { var unit1 = new Unit(math.bignumber(10), "N/s"); var unit2 = new Unit(math.bignumber(10), "h"); var unitM = unit1.multiply(unit2); assert(unitM.value.isBigNumber); var unit3 = new Unit(math.bignumber(14.7), "lbf"); var unit4 = new Unit(math.bignumber(1), "in in"); var unitD = unit3.divide(unit4); assert(unitD.value.isBigNumber); var unit5 = new Unit(math.bignumber(1), "N h/s"); var unitP = unit5.pow(math.bignumber(-3.5)); assert(unitP.value.isBigNumber); }); }); describe('plurals', function() { it('should support plurals', function () { var unit1 = new Unit(5, 'meters'); assert.equal(unit1.value, 5); assert.equal(unit1.units[0].unit.name, 'meters'); assert.equal(unit1.units[0].prefix.name, ''); var unit2 = new Unit(5, 'kilometers'); assert.equal(unit2.value, 5000); assert.equal(unit2.units[0].unit.name, 'meters'); assert.equal(unit2.units[0].prefix.name, 'kilo'); var unit3 = new Unit(5, 'inches'); approx.equal(unit3.value, 0.127); assert.equal(unit3.units[0].unit.name, 'inches'); assert.equal(unit3.units[0].prefix.name, ''); var unit3 = new Unit(9.81, 'meters/second^2'); approx.equal(unit3.value, 9.81); assert.equal(unit3.units[0].unit.name, 'meters'); assert.equal(unit3.units[0].prefix.name, ''); }); }); describe('aliases', function() { it('should support aliases', function () { var unit1 = new Unit(5, 'lt'); assert.equal(unit1.value, 5e-3); assert.equal(unit1.units[0].unit.name, 'lt'); assert.equal(unit1.units[0].prefix.name, ''); var unit2 = new Unit(1, 'lb'); assert.equal(unit2.value, 453.59237e-3); assert.equal(unit2.units[0].unit.name, 'lb'); assert.equal(unit2.units[0].prefix.name, ''); }); }); describe('UNITS', function() { it('should be of the correct value and dimension', function() { assert.equal(new Unit(1, 's A') .equals(new Unit(1, 'C')) , true); assert.equal(new Unit(1, 'W/A') .equals(new Unit(1, 'V')) , true); assert.equal(new Unit(1, 'V/A') .equals(new Unit(1, 'ohm')), true); assert.equal(new Unit(1, 'C/V') .equals(new Unit(1, 'F')) , true); assert.equal(new Unit(1, 'J/A') .equals(new Unit(1, 'Wb')) , true); assert.equal(new Unit(1, 'Wb/m^2').equals(new Unit(1, 'T')) , true); assert.equal(new Unit(1, 'Wb/A') .equals(new Unit(1, 'H')) , true); assert.equal(new Unit(1, 'ohm^-1').equals(new Unit(1, 'S')) , true); assert.equal(new Unit(1, 'eV') .equals(new Unit(1.602176565e-19, 'J')), true); }); }); });