diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg index 5c18e4b..17e2764 100755 --- a/.husky/prepare-commit-msg +++ b/.husky/prepare-commit-msg @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -exec < /dev/tty && node_modules/.bin/cz --hook || true +exec < /dev/tty && npx cz --hook || true diff --git a/package.json b/package.json index da649c0..2a5088a 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "config": { "commitizen": { - "path": "./node_modules/cz-conventional-changelog" + "path": "cz-conventional-changelog" } } } diff --git a/test/index.js b/test/index.js index 55f7462..2ad800a 100644 --- a/test/index.js +++ b/test/index.js @@ -1,134 +1,133 @@ // This test is for node JS var assert = require('assert') -var a = require('../src/formula_evaluator.js') +var Mexp = require('../src/formula_evaluator.js') describe('Testing Unit', function () { it('should equal 2 to check a number', function () { - assert.equal(a.lex('2').toPostfix().postfixEval(), 2) + assert.equal(Mexp.lex('2').toPostfix().postfixEval(), 2) }) it('checks a math function', function () { - assert.equal(a.lex('tan(180)').toPostfix().postfixEval(), 0) + assert.equal(Mexp.lex('tan(180)').toPostfix().postfixEval(), 0) }) it('checks a parenthesis less function', function () { - assert.equal(a.lex('sin180').toPostfix().postfixEval(), 0) + assert.equal(Mexp.lex('sin180').toPostfix().postfixEval(), 0) }) it('checks a parenthesis less function with multiplication', function () { - assert.equal(a.lex('0sin180').toPostfix().postfixEval(), 0) + assert.equal(Mexp.lex('0sin180').toPostfix().postfixEval(), 0) }) it('checks a multiplication of root function', function () { - assert.equal(a.lex('3 root 9').toPostfix().postfixEval(), 9) + assert.equal(Mexp.lex('3 root 9').toPostfix().postfixEval(), 9) }) it('checks a multiplication of root function', function () { - assert.equal(a.lex('3root9').toPostfix().postfixEval(), 9) + assert.equal(Mexp.lex('3root9').toPostfix().postfixEval(), 9) }) it('checks a parenthesis less function with multiplication by decimal', function () { - assert.equal(a.lex('0.5sin90').toPostfix().postfixEval(), 0.5) + assert.equal(Mexp.lex('0.5sin90').toPostfix().postfixEval(), 0.5) }) it('checks a parenthesis less function after a space', function () { - assert.equal(a.lex('cos 180').toPostfix().postfixEval(), -1) + assert.equal(Mexp.lex('cos 180').toPostfix().postfixEval(), -1) }) it('checks a parenthesis function with multiplication', function () { - assert.equal(a.lex('0.5sin(90)').toPostfix().postfixEval(), 0.5) + assert.equal(Mexp.lex('0.5sin(90)').toPostfix().postfixEval(), 0.5) }) it('checks a parenthesis less function after multiple spaces', function () { - assert.equal(a.lex('cos 180').toPostfix().postfixEval(), -1) + assert.equal(Mexp.lex('cos 180').toPostfix().postfixEval(), -1) }) it('checks consecutive operator', function () { - assert.equal(a.lex('0+-2').toPostfix().postfixEval(), -2) + assert.equal(Mexp.lex('0+-2').toPostfix().postfixEval(), -2) }) it('checks ^ operator', function () { - assert.equal(a.lex('2^2').toPostfix().postfixEval(), 4) + assert.equal(Mexp.lex('2^2').toPostfix().postfixEval(), 4) }) it('checks when * is omitted before parenthesis and after', function () { - assert.equal(a.lex('2(7-4)3').toPostfix().postfixEval(), 18) + assert.equal(Mexp.lex('2(7-4)3').toPostfix().postfixEval(), 18) }) it('checks multiplication and exponential in series', function () { - assert.equal(a.lex('2*7^2').toPostfix().postfixEval(), 98) + assert.equal(Mexp.lex('2*7^2').toPostfix().postfixEval(), 98) }) it('checks exponential and multiplication in series', function () { - assert.equal(a.lex('2^5*2').toPostfix().postfixEval(), 64) + assert.equal(Mexp.lex('2^5*2').toPostfix().postfixEval(), 64) }) it('-3^2=-9', function () { - assert.equal(a.lex('-3^2').toPostfix().postfixEval(), -9) + assert.equal(Mexp.lex('-3^2').toPostfix().postfixEval(), -9) }) it('3^2-2^2=5', function () { - assert.equal(a.lex('3^2-2^2').toPostfix().postfixEval(), 5) + assert.equal(Mexp.lex('3^2-2^2').toPostfix().postfixEval(), 5) assert.equal( - Math.round((a.eval('(4-(2-1)^2)^.5') + Number.EPSILON) * 100) / 100, + Math.round((Mexp.eval('(4-(2-1)^2)^.5') + Number.EPSILON) * 100) / 100, Math.round((Math.sqrt(3) + Number.EPSILON) * 100) / 100 ) }) it('formula test', function () { - assert.equal(a.lex('2').toPostfix().formulaEval(), 2) + assert.equal(Mexp.lex('2').toPostfix().formulaEval(), 2) }) it('formula test', function () { - assert.equal(a.lex('sinpi').toPostfix().formulaEval(), 'sin(π)') + assert.equal(Mexp.lex('sinpi').toPostfix().formulaEval(), 'sin(π)') }) it('formula test', function () { - assert.equal(a.lex('cos pi').toPostfix().formulaEval(), 'cos(π)') + assert.equal(Mexp.lex('cos pi').toPostfix().formulaEval(), 'cos(π)') }) it('formula test', function () { - assert.equal(a.lex('tan(pi)').toPostfix().formulaEval(), 'tan(π)') + assert.equal(Mexp.lex('tan(pi)').toPostfix().formulaEval(), 'tan(π)') }) it('formula test', function () { - assert.equal(a.lex('2(7-4)3').toPostfix().formulaEval(), '(2×(7-4))×3') + assert.equal(Mexp.lex('2(7-4)3').toPostfix().formulaEval(), '(2×(7-4))×3') }) it('test to check the bug when number contains decimal', function () { - assert.equal(a.lex('int2.3').toPostfix().postfixEval(), '2') + assert.equal(Mexp.lex('int2.3').toPostfix().postfixEval(), '2') }) it('test to check auto correct of parenthesis mismatch if opening>closing', function () { - assert.equal(a.lex('(2+(3-4').toPostfix().postfixEval(), '1') + assert.equal(Mexp.lex('(2+(3-4').toPostfix().postfixEval(), '1') }) it('check for negative of a constant', function () { - assert.equal(a.lex('-e').toPostfix().postfixEval(), -Math.E) + assert.equal(Mexp.lex('-e').toPostfix().postfixEval(), -Math.E) }) it('check for constant inside Sigma', function () { assert.equal( - a - .lex('Sigma1,3,2', [{ type: 3, value: 'x', show: 'x', token: 'x' }]) + Mexp.lex('Sigma1,3,2', [{ type: 3, value: 'x', show: 'x', token: 'x' }]) .toPostfix() .postfixEval({ x: 2 }), 6 ) }) it('check when arithmetic and n are present inside sigma', function () { - assert.equal(a.lex('Sigma1,2,n').toPostfix().postfixEval(), 3) + assert.equal(Mexp.lex('Sigma1,2,n').toPostfix().postfixEval(), 3) }) it(' should check when 4C3', function () { - assert.equal(a.lex('4C3').toPostfix().postfixEval(), 4) + assert.equal(Mexp.lex('4C3').toPostfix().postfixEval(), 4) }) it('check when arithmetic and n are present inside sigma', function () { - assert.equal(a.lex('Sigma1,2,(n*n)').toPostfix().postfixEval(), 5) + assert.equal(Mexp.lex('Sigma1,2,(n*n)').toPostfix().postfixEval(), 5) }) it('check when two parenthesis less functions are consecutive on one parameter', function () { // console.log(a.lex('int(2.6*2)*10').toPostfix().postfixEval()) - assert.equal(a.lex('sinint2').toPostfix().postfixEval(), a.lex('sin(int(2))').toPostfix().postfixEval()) + assert.equal(Mexp.lex('sinint2').toPostfix().postfixEval(), Mexp.lex('sin(int(2))').toPostfix().postfixEval()) }) it('check eval method with single argument', function () { - assert.equal(a.eval('5*3'), '15') + assert.equal(Mexp.eval('5*3'), '15') }) it('check eval method with three argument', function () { assert.equal( - a.eval('mexp*3', [{ type: 3, show: 'mexp', token: 'mexp', value: 'mexp', preced: 0 }], { + Mexp.eval('mexp*3', [{ type: 3, show: 'mexp', token: 'mexp', value: 'mexp', preced: 0 }], { mexp: 5, }), '15' ) }) it('check eval method with two argument when second one is value of constants', function () { - a.addToken([{ type: 3, show: 'mexp', value: 'mexp', token: 'mexp' }]) - assert.equal(a.eval('mexp*3', { mexp: 5 }), '15') + Mexp.addToken([{ type: 3, show: 'mexp', value: 'mexp', token: 'mexp' }]) + assert.equal(Mexp.eval('mexp*3', { mexp: 5 }), '15') }) it('check eval method with two argument when second one is value of constants', function () { - a.addToken([ + Mexp.addToken([ { type: 0, show: 'mexp', @@ -138,11 +137,11 @@ describe('Testing Unit', function () { token: 'mexp', }, ]) - assert.equal(a.lex('mexp3').toPostfix().postfixEval(), '30') + assert.equal(Mexp.lex('mexp3').toPostfix().postfixEval(), '30') }) it('check eval method with two argument when second one is token list', function () { assert.equal( - a.eval('mexp(3)', [ + Mexp.eval('mexp(3)', [ { type: 0, show: 'mexp(', @@ -156,48 +155,48 @@ describe('Testing Unit', function () { ) }) it('Pi', function () { - assert.equal(a.eval('Pi1,5,n'), '120') + assert.equal(Mexp.eval('Pi1,5,n'), '120') }) it('tan5(6+3)', function () { assert.equal( - Math.round((a.eval('tan45(6+3)') + Number.EPSILON) * 100) / 100, + Math.round((Mexp.eval('tan45(6+3)') + Number.EPSILON) * 100) / 100, Math.round((9 + Number.EPSILON) * 100) / 100 ) }) it('tan(40+5)', function () { - assert.equal(a.eval('tan(40+5)'), '1') + assert.equal(Mexp.eval('tan(40+5)'), '1') }) it('checks when a 0 is missing in a decimal number', function () { - assert.equal(a.eval('5*.8'), '4') + assert.equal(Mexp.eval('5*.8'), '4') }) it('checks root function', function () { - assert.equal(a.eval('root4'), '2') + assert.equal(Mexp.eval('root4'), '2') assert.equal( - Math.round((a.eval('root(4-1^2)') + Number.EPSILON) * 100) / 100, + Math.round((Mexp.eval('root(4-1^2)') + Number.EPSILON) * 100) / 100, Math.round((Math.sqrt(3) + Number.EPSILON) * 100) / 100 ) assert.equal( - Math.round((a.eval('root(4-(2-1)^2)') + Number.EPSILON) * 100) / 100, + Math.round((Mexp.eval('root(4-(2-1)^2)') + Number.EPSILON) * 100) / 100, Math.round((Math.sqrt(3) + Number.EPSILON) * 100) / 100 ) }) it('checks + precedence before number insise parenthesis ', function () { - assert.equal(a.eval('(-2)'), '-2') + assert.equal(Mexp.eval('(-2)'), '-2') }) it('checks multiple allowable operator', function () { - assert.equal(a.eval('2+++-++-+-+3'), '-1') - assert.equal(a.eval('2*+3'), '6') + assert.equal(Mexp.eval('2+++-++-+-+3'), '-1') + assert.equal(Mexp.eval('2*+3'), '6') }) }) describe('These expression will check for types of returned result', function () { it('should tell to compllete expression', function () { - assert.equal(typeof a.eval('0'), 'number') + assert.equal(typeof Mexp.eval('0'), 'number') }) }) describe('These expression will raise error', function () { it('should tell to compllete expression', function () { try { - a.eval('2*') + Mexp.eval('2*') assert.equal(1, 2) } catch (e) { assert.equal(e.message, 'complete the expression') @@ -205,7 +204,7 @@ describe('These expression will raise error', function () { }) it('should warn about multiple operators', function () { try { - a.eval('2**3') + Mexp.eval('2**3') assert.equal(1, 2) } catch (e) { assert.equal(e.message, '* is not allowed after *') @@ -213,7 +212,7 @@ describe('These expression will raise error', function () { }) it('should warn about multiple operators', function () { try { - a.eval('2*Mod*3') + Mexp.eval('2*Mod*3') assert.equal(1, 2) } catch (e) { assert.equal(e.message, 'Mod is not allowed after *') @@ -221,7 +220,7 @@ describe('These expression will raise error', function () { }) it('should warn about operator inside parenthesis', function () { try { - a.eval('(+)') + Mexp.eval('(+)') assert.equal(1, 2) } catch (e) { assert.equal(e.message, ') is not allowed after +') @@ -229,7 +228,7 @@ describe('These expression will raise error', function () { }) it('should warn about operator inside parenthesis', function () { try { - a.eval('(2+3+)') + Mexp.eval('(2+3+)') assert.equal(1, 2) } catch (e) { assert.equal(e.message, ') is not allowed after +') @@ -237,7 +236,7 @@ describe('These expression will raise error', function () { }) it('should warn about using space as operator', function () { try { - console.log(a.eval('1 2')) + console.log(Mexp.eval('1 2')) assert.equal(1, 2) } catch (e) { assert.equal(e.message, 'Unexpected Space') @@ -245,7 +244,7 @@ describe('These expression will raise error', function () { }) it('should warn about using space as operator', function () { try { - console.log(a.eval('1. 2')) + console.log(Mexp.eval('1. 2')) assert.equal(1, 2) } catch (e) { assert.equal(e.message, 'Unexpected Space') @@ -254,12 +253,12 @@ describe('These expression will raise error', function () { }) describe('Check autoclose of parenthesis of parser', function () { it('should tell to compllete expression', function () { - assert.equal(a.eval('((2+3*4'), '14') + assert.equal(Mexp.eval('((2+3*4'), '14') }) }) describe('Ading Token', function () { it('should tell to compllete expression', function () { - a.addToken([ + Mexp.addToken([ { type: 2, token: 'nroot', @@ -269,8 +268,8 @@ describe('Ading Token', function () { }, }, ]) - assert.equal(a.eval('27nroot3'), 3) - a.addToken([ + assert.equal(Mexp.eval('27nroot3'), 3) + Mexp.addToken([ { type: 2, token: 'nrootlongesttoken', @@ -280,8 +279,8 @@ describe('Ading Token', function () { }, }, ]) - assert.equal(a.eval('27nrootlongesttoken3'), 3) - a.addToken([ + assert.equal(Mexp.eval('27nrootlongesttoken3'), 3) + Mexp.addToken([ { type: 2, token: 'tokenwithnumber34', @@ -291,10 +290,10 @@ describe('Ading Token', function () { }, }, ]) - assert.equal(a.eval('17tokenwithnumber347'), 24) + assert.equal(Mexp.eval('17tokenwithnumber347'), 24) }) it('should evaluate to correct two functions', function () { - a.addToken([ + Mexp.addToken([ { type: 0, token: 'ceil', @@ -314,15 +313,15 @@ describe('Ading Token', function () { }, ]) // console.log("PAGAL", a.eval("min(4,ceil(0.1*10))")) - assert.equal(a.eval('min(4,ceil(0.011*100))'), 2) + assert.equal(Mexp.eval('min(4,ceil(0.011*100))'), 2) }) it('should also evaluate to correct two functions', function () { // console.log("PAGAL", a.eval("min(4,ceil(0.1*10))")) - assert.equal(a.eval('ceil(min(4, 0.0801*100))'), 4) + assert.equal(Mexp.eval('ceil(min(4, 0.0801*100))'), 4) }) it('should tell to compllete expression', function () { - a.addToken([ + Mexp.addToken([ { type: 2, token: 'nroot', @@ -332,10 +331,10 @@ describe('Ading Token', function () { }, }, ]) - assert.equal(a.eval('27nroot3'), 3) + assert.equal(Mexp.eval('27nroot3'), 3) }) it('should tell to compllete expression', function () { - a.addToken([ + Mexp.addToken([ { type: 2, token: 'nrootlongesttoken', @@ -345,10 +344,10 @@ describe('Ading Token', function () { }, }, ]) - assert.equal(a.eval('27nrootlongesttoken3'), 3) + assert.equal(Mexp.eval('27nrootlongesttoken3'), 3) }) it('should tell to compllete expression', function () { - a.addToken([ + Mexp.addToken([ { type: 2, token: 'tokenwithnumber34', @@ -358,10 +357,10 @@ describe('Ading Token', function () { }, }, ]) - assert.equal(a.eval('17tokenwithnumber347'), 24) + assert.equal(Mexp.eval('17tokenwithnumber347'), 24) }) it('maximum of 5 numbers', function () { - a.addToken([ + Mexp.addToken([ { type: 8, token: 'maxof2', @@ -371,6 +370,20 @@ describe('Ading Token', function () { }, }, ]) - assert.equal(a.eval('maxof2(1,maxof2(maxof2(maxof2(maxof2(2,3),5),6),7))'), 7) + assert.equal(Mexp.eval('maxof2(1,maxof2(maxof2(maxof2(maxof2(2,3),5),6),7))'), 7) + }) + it('maximum of 5 numbers using n arguments', function () { + Mexp.addToken([ + { + type: Mexp.tokenTypes.FUNCTION_WITH_N_ARGS, + token: 'maxof5', + show: 'maxof5', + numberOfArguments: 5, + value: function (a, b, c, d, e) { + return Math.max.apply(Math, [a, b, c, d, e]) + }, + }, + ]) + assert.equal(Mexp.eval('maxof5(7, 12, 23, 33, 2)'), 33) }) })