index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. // This test is for node JS
  2. var assert = require('assert')
  3. var a = require('../src/formula_evaluator.js')
  4. describe('Testing Unit', function () {
  5. it('should equal 2 to check a number', function () {
  6. assert.equal(a.lex('2').toPostfix().postfixEval(), 2)
  7. })
  8. it('checks a math function', function () {
  9. assert.equal(a.lex('tan(180)').toPostfix().postfixEval(), 0)
  10. })
  11. it('checks a parenthesis less function', function () {
  12. assert.equal(a.lex('sin180').toPostfix().postfixEval(), 0)
  13. })
  14. it('checks a parenthesis less function with multiplication', function () {
  15. assert.equal(a.lex('0sin180').toPostfix().postfixEval(), 0)
  16. })
  17. it('checks a multiplication of root function', function () {
  18. assert.equal(a.lex('3 root 9').toPostfix().postfixEval(), 9)
  19. })
  20. it('checks a multiplication of root function', function () {
  21. assert.equal(a.lex('3root9').toPostfix().postfixEval(), 9)
  22. })
  23. it('checks a parenthesis less function with multiplication by decimal', function () {
  24. assert.equal(a.lex('0.5sin90').toPostfix().postfixEval(), 0.5)
  25. })
  26. it('checks a parenthesis less function after a space', function () {
  27. assert.equal(a.lex('cos 180').toPostfix().postfixEval(), -1)
  28. })
  29. it('checks a parenthesis function with multiplication', function () {
  30. assert.equal(a.lex('0.5sin(90)').toPostfix().postfixEval(), 0.5)
  31. })
  32. it('checks a parenthesis less function after multiple spaces', function () {
  33. assert.equal(a.lex('cos 180').toPostfix().postfixEval(), -1)
  34. })
  35. it('checks consecutive operator', function () {
  36. assert.equal(a.lex('0+-2').toPostfix().postfixEval(), -2)
  37. })
  38. it('checks ^ operator', function () {
  39. assert.equal(a.lex('2^2').toPostfix().postfixEval(), 4)
  40. })
  41. it('checks when * is omitted before parenthesis and after', function () {
  42. assert.equal(a.lex('2(7-4)3').toPostfix().postfixEval(), 18)
  43. })
  44. it('checks multiplication and exponential in series', function () {
  45. assert.equal(a.lex('2*7^2').toPostfix().postfixEval(), 98)
  46. })
  47. it('checks exponential and multiplication in series', function () {
  48. assert.equal(a.lex('2^5*2').toPostfix().postfixEval(), 64)
  49. })
  50. it('-3^2=-9', function () {
  51. assert.equal(a.lex('-3^2').toPostfix().postfixEval(), -9)
  52. })
  53. it('3^2-2^2=5', function () {
  54. assert.equal(a.lex('3^2-2^2').toPostfix().postfixEval(), 5)
  55. assert.equal(
  56. Math.round((a.eval('(4-(2-1)^2)^.5') + Number.EPSILON) * 100) / 100,
  57. Math.round((Math.sqrt(3) + Number.EPSILON) * 100) / 100
  58. )
  59. })
  60. it('formula test', function () {
  61. assert.equal(a.lex('2').toPostfix().formulaEval(), 2)
  62. })
  63. it('formula test', function () {
  64. assert.equal(a.lex('sinpi').toPostfix().formulaEval(), 'sin(π)')
  65. })
  66. it('formula test', function () {
  67. assert.equal(a.lex('cos pi').toPostfix().formulaEval(), 'cos(π)')
  68. })
  69. it('formula test', function () {
  70. assert.equal(a.lex('tan(pi)').toPostfix().formulaEval(), 'tan(π)')
  71. })
  72. it('formula test', function () {
  73. assert.equal(a.lex('2(7-4)3').toPostfix().formulaEval(), '(2×(7-4))×3')
  74. })
  75. it('test to check the bug when number contains decimal', function () {
  76. assert.equal(a.lex('int2.3').toPostfix().postfixEval(), '2')
  77. })
  78. it('test to check auto correct of parenthesis mismatch if opening>closing', function () {
  79. assert.equal(a.lex('(2+(3-4').toPostfix().postfixEval(), '1')
  80. })
  81. it('check for negative of a constant', function () {
  82. assert.equal(a.lex('-e').toPostfix().postfixEval(), -Math.E)
  83. })
  84. it('check for constant inside Sigma', function () {
  85. assert.equal(
  86. a
  87. .lex('Sigma1,3,2', [{ type: 3, preced: 0, ev: 'x', show: 'x', token: 'x' }])
  88. .toPostfix()
  89. .postfixEval({ x: 2 }),
  90. 6
  91. )
  92. })
  93. it('check when arithmetic and n are present inside sigma', function () {
  94. assert.equal(a.lex('Sigma1,2,n').toPostfix().postfixEval(), 3)
  95. })
  96. it(' should check when 4C3', function () {
  97. assert.equal(a.lex('4C3').toPostfix().postfixEval(), 4)
  98. })
  99. it('check when arithmetic and n are present inside sigma', function () {
  100. assert.equal(a.lex('Sigma1,2,(n*n)').toPostfix().postfixEval(), 5)
  101. })
  102. it('check when two parenthesis less functions are consecutive on one parameter', function () {
  103. // console.log(a.lex('int(2.6*2)*10').toPostfix().postfixEval())
  104. assert.equal(
  105. a.lex('sinint2').toPostfix().postfixEval(),
  106. a.lex('sin(int(2))').toPostfix().postfixEval()
  107. )
  108. })
  109. it('check eval method with single argument', function () {
  110. assert.equal(a.eval('5*3'), '15')
  111. })
  112. it('check eval method with three argument', function () {
  113. assert.equal(
  114. a.eval('mexp*3', [{ type: 3, show: 'mexp', token: 'mexp', value: 'mexp', preced: 0 }], {
  115. mexp: 5
  116. }),
  117. '15'
  118. )
  119. })
  120. it('check eval method with two argument when second one is value of constants', function () {
  121. a.addToken([{ type: 3, show: 'mexp', value: 'mexp', preced: 0, token: 'mexp' }])
  122. assert.equal(a.eval('mexp*3', { mexp: 5 }), '15')
  123. })
  124. it('check eval method with two argument when second one is value of constants', function () {
  125. a.addToken([
  126. {
  127. type: 0,
  128. show: 'mexp',
  129. value: function (a) {
  130. return 5 * a
  131. },
  132. preced: 11,
  133. token: 'mexp'
  134. }
  135. ])
  136. assert.equal(a.lex('mexp3').toPostfix().postfixEval(), '15')
  137. })
  138. it('check eval method with two argument when second one is token list', function () {
  139. assert.equal(
  140. a.eval('mexp(3)', [
  141. {
  142. type: 0,
  143. show: 'mexp(',
  144. value: function (a) {
  145. return 5 * a
  146. },
  147. preced: 11,
  148. token: 'mexp'
  149. }
  150. ]),
  151. '15'
  152. )
  153. })
  154. it('Pi', function () {
  155. assert.equal(a.eval('Pi1,5,n'), '120')
  156. })
  157. it('tan5(6+3)', function () {
  158. assert.equal(
  159. Math.round((a.eval('tan45(6+3)') + Number.EPSILON) * 100) / 100,
  160. Math.round((9 + Number.EPSILON) * 100) / 100
  161. )
  162. })
  163. it('tan(40+5)', function () {
  164. assert.equal(a.eval('tan(40+5)'), '1')
  165. })
  166. it('checks when a 0 is missing in a decimal number', function () {
  167. assert.equal(a.eval('5*.8'), '4')
  168. })
  169. it('checks root function', function () {
  170. assert.equal(a.eval('root4'), '2')
  171. assert.equal(
  172. Math.round((a.eval('root(4-1^2)') + Number.EPSILON) * 100) / 100,
  173. Math.round((Math.sqrt(3) + Number.EPSILON) * 100) / 100
  174. )
  175. assert.equal(
  176. Math.round((a.eval('root(4-(2-1)^2)') + Number.EPSILON) * 100) / 100,
  177. Math.round((Math.sqrt(3) + Number.EPSILON) * 100) / 100
  178. )
  179. })
  180. it('checks + precedence before number insise parenthesis ', function () {
  181. assert.equal(a.eval('(-2)'), '-2')
  182. })
  183. it('checks multiple allowable operator', function () {
  184. assert.equal(a.eval('2+++-++-+-+3'), '-1')
  185. assert.equal(a.eval('2*+3'), '6')
  186. })
  187. })
  188. describe('These expression will check for types of returned result', function () {
  189. it('should tell to compllete expression', function () {
  190. assert.equal(typeof a.eval('0'), 'number')
  191. })
  192. })
  193. describe('These expression will raise error', function () {
  194. it('should tell to compllete expression', function () {
  195. try {
  196. a.eval('2*')
  197. assert.equal(1, 2)
  198. } catch (e) {
  199. assert.equal(e.message, 'complete the expression')
  200. }
  201. })
  202. it('should warn about multiple operators', function () {
  203. try {
  204. a.eval('2**3')
  205. assert.equal(1, 2)
  206. } catch (e) {
  207. assert.equal(e.message, '* is not allowed after *')
  208. }
  209. })
  210. it('should warn about multiple operators', function () {
  211. try {
  212. a.eval('2*Mod*3')
  213. assert.equal(1, 2)
  214. } catch (e) {
  215. assert.equal(e.message, 'Mod is not allowed after *')
  216. }
  217. })
  218. it('should warn about operator inside parenthesis', function () {
  219. try {
  220. a.eval('(+)')
  221. assert.equal(1, 2)
  222. } catch (e) {
  223. assert.equal(e.message, ') is not allowed after +')
  224. }
  225. })
  226. it('should warn about operator inside parenthesis', function () {
  227. try {
  228. a.eval('(2+3+)')
  229. assert.equal(1, 2)
  230. } catch (e) {
  231. assert.equal(e.message, ') is not allowed after +')
  232. }
  233. })
  234. it('should warn about using space as operator', function () {
  235. try {
  236. console.log(a.eval('1 2'))
  237. assert.equal(1, 2)
  238. } catch (e) {
  239. assert.equal(e.message, 'Unexpected Space')
  240. }
  241. })
  242. it('should warn about using space as operator', function () {
  243. try {
  244. console.log(a.eval('1. 2'))
  245. assert.equal(1, 2)
  246. } catch (e) {
  247. assert.equal(e.message, 'Unexpected Space')
  248. }
  249. })
  250. })
  251. describe('Check autoclose of parenthesis of parser', function () {
  252. it('should tell to compllete expression', function () {
  253. assert.equal(a.eval('((2+3*4'), '14')
  254. })
  255. })
  256. describe('Ading Token', function () {
  257. it('should tell to compllete expression', function () {
  258. a.addToken([
  259. {
  260. type: 2,
  261. token: 'nroot',
  262. show: 'nroot',
  263. value: function (a, b) {
  264. return Math.pow(a, 1 / b)
  265. }
  266. }
  267. ])
  268. assert.equal(a.eval('27nroot3'), 3)
  269. a.addToken([
  270. {
  271. type: 2,
  272. token: 'nrootlongesttoken',
  273. show: 'nrootlongesttoken',
  274. value: function (a, b) {
  275. return Math.pow(a, 1 / b)
  276. }
  277. }
  278. ])
  279. assert.equal(a.eval('27nrootlongesttoken3'), 3)
  280. a.addToken([
  281. {
  282. type: 2,
  283. token: 'tokenwithnumber34',
  284. show: 'tokenwithnumber34',
  285. value: function (a, b) {
  286. return a + b
  287. }
  288. }
  289. ])
  290. assert.equal(a.eval('17tokenwithnumber347'), 24)
  291. })
  292. it('should evaluate to correct two functions', function () {
  293. a.addToken([
  294. {
  295. type: 0,
  296. token: "ceil",
  297. show: "ceil",
  298. value: function (a) {
  299. const ans = Math.ceil(a)
  300. return ans;
  301. },
  302. },
  303. {
  304. type: 8,
  305. token: "min",
  306. show: "min",
  307. value: function (a, b) {
  308. return Math.min(a, b);
  309. }}
  310. ])
  311. // console.log("PAGAL", a.eval("min(4,ceil(0.1*10))"))
  312. assert.equal(a.eval("min(4,ceil(0.011*100))"), 2)
  313. })
  314. it('should also evaluate to correct two functions', function () {
  315. // console.log("PAGAL", a.eval("min(4,ceil(0.1*10))"))
  316. assert.equal(a.eval("ceil(min(4, 0.0801*100))"), 4)
  317. })
  318. it('should tell to compllete expression', function () {
  319. a.addToken([
  320. {
  321. type: 2,
  322. token: 'nroot',
  323. show: 'nroot',
  324. value: function (a, b) {
  325. return Math.pow(a, 1 / b)
  326. }
  327. }
  328. ])
  329. assert.equal(a.eval('27nroot3'), 3)
  330. })
  331. it('should tell to compllete expression', function () {
  332. a.addToken([
  333. {
  334. type: 2,
  335. token: 'nrootlongesttoken',
  336. show: 'nrootlongesttoken',
  337. value: function (a, b) {
  338. return Math.pow(a, 1 / b)
  339. }
  340. }
  341. ])
  342. assert.equal(a.eval('27nrootlongesttoken3'), 3)
  343. })
  344. it('should tell to compllete expression', function () {
  345. a.addToken([
  346. {
  347. type: 2,
  348. token: 'tokenwithnumber34',
  349. show: 'tokenwithnumber34',
  350. value: function (a, b) {
  351. return a + b
  352. }
  353. }
  354. ])
  355. assert.equal(a.eval('17tokenwithnumber347'), 24)
  356. })
  357. it('maximum of 5 numbers', function () {
  358. a.addToken([
  359. {
  360. type: 8,
  361. token: 'maxof2',
  362. show: 'maxof2',
  363. value: function (a, b, c) {
  364. return Math.max(a, b)
  365. }
  366. }
  367. ])
  368. assert.equal(a.eval('maxof2(1,maxof2(maxof2(maxof2(maxof2(2,3),5),6),7))'), 7)
  369. })
  370. })