-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: new fn fieldCalculate * chore: add debug * feat: new fn logicCalculate * chore: 补充注释 * rf: remove eval * feat: 支持混合运算符优先级 * feat: 浮点误差功能 * rf: 将小数计算单独作为一个文件 * rf: 完善 fieldCalculate 及添加测试 * feat: 完善精度控制 * chore: logicCalculate benchmark * 完善测试用例 完善测试用例 * 修改lint错误 修改lint错误 * 修改命名问题,添加额外的类型包裹 * fix: 修复整数时缺乏乘法计算的问题 * 修改assertThrows 修改assertThrows * 完善beIncludes测试 完善beIncludes测试 * test: 补充 logicCalculate 测试 * 使用 !logicCalculate 使用 !logicCalculate * fix: 避免错误数据 * fix: 调整相对值的类型, 调整代码结构 * chore: 补充函数注释说明 * 采用定长方法 采用定长方法 --------- Co-authored-by: CarrieGMM <[email protected]>
- Loading branch information
Showing
13 changed files
with
3,514 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,314 @@ | ||
import { fieldCalculate } from './calculate-field.ts'; | ||
import { assertEquals } from 'https://deno.land/[email protected]/assert/assert_equals.ts'; | ||
import { assertThrows } from 'https://deno.land/[email protected]/assert/assert_throws.ts'; | ||
Deno.test('testAddAndSub-true', () => { | ||
const data = { | ||
a: '100', | ||
a1: 1, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
}; | ||
//数值之间是否有空格,有影响? | ||
|
||
// * 字符串*字符串 | ||
assertEquals(fieldCalculate(data, 'a + b'.split(' ')), 102); | ||
// * 数字*字符串 | ||
assertEquals(fieldCalculate(data, 'a + a1'.split(' ')), 101); | ||
// * 数字*数字 | ||
assertEquals(fieldCalculate(data, 'a1 + b1'.split(' ')), 3); | ||
|
||
assertEquals(fieldCalculate(data, '1.5 + 2.5'.split(' ')), 4); | ||
|
||
assertEquals(fieldCalculate(data, '0.001 + 0.0002'.split(' ')), 0.0012); | ||
|
||
assertEquals(fieldCalculate(data, '1 + 0.0002'.split(' ')), 1.0002); | ||
|
||
// - 字符串-字符串 | ||
assertEquals(fieldCalculate(data, 'a - b'.split(' ')), 98); | ||
// - 数字-字符串 | ||
assertEquals(fieldCalculate(data, 'a - a1'.split(' ')), 99); | ||
// - 数字-数字 | ||
assertEquals(fieldCalculate(data, 'a1 - b1'.split(' ')), -1); | ||
|
||
assertEquals(fieldCalculate(data, '1.5 - 2.5'.split(' ')), -1); | ||
|
||
assertEquals(fieldCalculate(data, '2 - 0.05'.split(' ')), 1.95); | ||
|
||
assertEquals(fieldCalculate(data, '0.003 - 0.002'.split(' ')), 0.001); | ||
}); | ||
|
||
//存在bug,但是代码未处理 | ||
Deno.test('testMulAndDiv-true', () => { | ||
const data = { | ||
a: '100', | ||
a1: 1, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
}; | ||
|
||
assertEquals(fieldCalculate(data, 'a * b'.split(' ')), 200); | ||
|
||
assertEquals(fieldCalculate(data, 'a * a1'.split(' ')), 100); | ||
|
||
assertEquals(fieldCalculate(data, 'a1 * b1'.split(' ')), 2); | ||
|
||
assertEquals(fieldCalculate(data, '1.5 * 2'.split(' ')), 3); | ||
|
||
assertEquals(fieldCalculate(data, '0.5 * 0.22'.split(' ')), 0.11); | ||
|
||
assertEquals(fieldCalculate(data, '1.2 * 0.5'.split(' ')), 0.6); | ||
|
||
assertEquals(fieldCalculate(data, 'a / b'.split(' ')), 50); | ||
|
||
assertEquals(fieldCalculate(data, 'a / a1'.split(' ')), 100); | ||
|
||
assertEquals(fieldCalculate(data, 'a1 / b1'.split(' ')), 1 / 2); | ||
|
||
assertEquals(fieldCalculate(data, 'a1 / 0'.split(' ')), Infinity); | ||
|
||
assertEquals(fieldCalculate(data, '3 / 0.02'.split(' ')), 150); | ||
|
||
assertEquals(fieldCalculate(data, '3.0 / 1.5'.split(' ')), 2); | ||
|
||
assertEquals(fieldCalculate(data, '0 / 1.5'.split(' ')), 0); | ||
|
||
assertEquals(fieldCalculate(data, '0.4 / 0.02'.split(' ')), 20); | ||
}); | ||
|
||
//此处 assertEquals(fieldCalculate(data, '1.5 * 2'.split(' ')), 3); | ||
Deno.test('testMulAndDiv-true-1', () => { | ||
const data = { | ||
a: '100', | ||
a1: 1, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
d: '0.5', | ||
}; | ||
assertEquals(fieldCalculate(data, '1.5 * 2'.split(' ')), 3); | ||
assertEquals(fieldCalculate(data, 'd * 2'.split(' ')), 1); | ||
}); | ||
|
||
Deno.test('testRemain-true', () => { | ||
const data = { | ||
a: '100', | ||
a1: 3, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
}; | ||
// * 字符串*字符串 | ||
assertEquals(fieldCalculate(data, 'a % b'.split(' ')), 0); | ||
// * 数字*字符串 | ||
assertEquals(fieldCalculate(data, 'a % a1'.split(' ')), 1); | ||
// * 数字*数字 | ||
assertEquals(fieldCalculate(data, 'a1 % b1'.split(' ')), 1); | ||
}); | ||
|
||
// 测试括号 | ||
Deno.test('testBracket-true', () => { | ||
const data = { | ||
a: '100', | ||
a1: 3, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
d: 'asdf', | ||
}; | ||
|
||
// 正确使用; | ||
assertEquals(fieldCalculate(data, '( a1 % b1 ) * 10'.split(' ')), 10); | ||
assertEquals( | ||
fieldCalculate(data, '( ( 2 + 3 ) + a1 % b1 ) * 10'.split(' ')), | ||
60, | ||
); | ||
assertEquals( | ||
fieldCalculate(data, '2 + ( 2 % 3 ) - 10'.split(' ')), | ||
-6, | ||
); | ||
assertEquals( | ||
fieldCalculate(data, ' 2 + 3 % 5'.split(' ')), | ||
5, | ||
); | ||
assertEquals( | ||
fieldCalculate(data, '( 2 + 3 ) * ( 5 - 2 )'.split(' ')), | ||
15, | ||
); | ||
|
||
assertEquals( | ||
fieldCalculate(data, '( ( 2 + 3 ) * 2 ) - 1'.split(' ')), | ||
9, | ||
); | ||
|
||
assertEquals( | ||
fieldCalculate(data, '10 - ( ( 5 - 2 ) * 2 )'.split(' ')), | ||
4, | ||
); | ||
}); | ||
|
||
Deno.test('testBracket-Throws-1', () => { | ||
const data = { | ||
a: '100', | ||
a1: 3, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
d: 'asdf', | ||
}; | ||
//只有( (a undefined is not a number | ||
assertThrows(() => { | ||
const calculateField = '( a % b'.split(' '); | ||
fieldCalculate(data, calculateField); | ||
}, 'd'); | ||
}); | ||
Deno.test('testBracket-Throws-2', () => { | ||
const data = { | ||
a: '100', | ||
a1: 3, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
d: 'asdf', | ||
}; | ||
// 只有) | ||
assertThrows(() => { | ||
const calculateField = ') a % b'.split(' '); | ||
fieldCalculate(data, calculateField); | ||
}, 'd'); | ||
}); | ||
Deno.test('testBracket-Throws-3', () => { | ||
const data = { | ||
a: '100', | ||
a1: 3, | ||
b: '2', | ||
b1: 2, | ||
c: '3', | ||
c1: 3, | ||
d: 'asdf', | ||
}; | ||
//()中没有内容 | ||
assertThrows(() => { | ||
const calculateField = '() a % a1'.split(' '); | ||
fieldCalculate(data, calculateField); | ||
}, 'd'); | ||
}); | ||
|
||
//复杂运算测试用例 | ||
Deno.test('test-complex-true', () => { | ||
const data = { | ||
a: '100', | ||
a1: 33, | ||
b: '2', | ||
b1: 22, | ||
c: '3', | ||
c1: 3, | ||
d: 'asdf', | ||
}; | ||
// 正确使用 | ||
assertEquals(fieldCalculate(data, 'a + b - c'.split(' ')), 99); | ||
assertEquals(fieldCalculate(data, 'a * b / 50'.split(' ')), 4); | ||
assertEquals(fieldCalculate(data, '( a + b ) * c / 50'.split(' ')), 306 / 50); | ||
assertEquals( | ||
fieldCalculate(data, '( a + b ) * 100 / 2 + 50'.split(' ')), | ||
5150, | ||
); | ||
assertEquals( | ||
fieldCalculate(data, '( ( a + b ) * 100 / 2 + 50 ) / 25'.split(' ')), | ||
206, | ||
); | ||
|
||
assertEquals( | ||
fieldCalculate(data, '( ( a + b ) * 100 / 2 + 50 ) - 25 * 2'.split(' ')), | ||
5100, | ||
); | ||
|
||
assertEquals( | ||
fieldCalculate( | ||
data, | ||
'( ( ( a + b ) * 100 / 2 + 50 ) - 25 * 2 ) / c'.split(' '), | ||
), | ||
1700, | ||
); | ||
|
||
assertEquals( | ||
fieldCalculate( | ||
data, | ||
'( ( ( a + b ) * 100 / 2 + 50 ) - 25 * 2 ) / ( c * 5 ) % 20'.split(' '), | ||
), | ||
0, | ||
); | ||
assertEquals( | ||
fieldCalculate( | ||
data, | ||
'( ( ( ( a + b ) * 100 / 2 + 50 ) - 25 * 2 ) / c ) + 0.1'.split(' '), | ||
), | ||
1700.1, | ||
); | ||
|
||
assertEquals( | ||
fieldCalculate( | ||
data, | ||
' ( a + b ) * 100 / 2 + 50 - 25 * 2 * c + 0.111111111'.split(' '), | ||
), | ||
5000.111111111, | ||
); | ||
|
||
assertEquals( | ||
fieldCalculate( | ||
data, | ||
' ( a + b ) * 100 / 2 + 50 - 25 * 2 * c + 0.111111111 - 0.11'.split(' '), | ||
), | ||
5000.001111111, | ||
); | ||
}); | ||
|
||
//测试溢出 | ||
Deno.test('test-overflow', () => { | ||
const data = { | ||
a: '9999999999999999999999999999999999999999', | ||
}; | ||
// 溢出问题 | ||
assertEquals(fieldCalculate(data, 'a + 10'.split(' ')), 1e+40); | ||
}); | ||
|
||
//测试非法字符 | ||
Deno.test('test-error-1', () => { | ||
const data = { | ||
a: '9999999999999999999999999999999999999999', | ||
}; | ||
// 错误 | ||
assertThrows(() => { | ||
const calculateField = '2 + 2a'.split(' '); | ||
fieldCalculate(data, calculateField); | ||
}, '2a'); | ||
}); | ||
|
||
//此处连个运算符的方式,预期应提出错误,代码未修改 | ||
Deno.test('test-error-2', () => { | ||
const data = { | ||
a: '9999999999999999999999999999999999999999', | ||
}; | ||
// 错误 | ||
assertThrows(() => { | ||
const calculateField = '2 + + 3'.split(' '); | ||
fieldCalculate(data, calculateField); | ||
}, 'invalid data'); | ||
}); | ||
|
||
//测试非法字符 | ||
Deno.test('test-error', () => { | ||
// 错误 | ||
assertThrows(() => { | ||
const calculateField = 'a * 3'.split(' '); | ||
fieldCalculate({}, calculateField); | ||
}, 'not found'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { fieldCalculate, fieldCalculateEval } from './calculate-field.ts'; | ||
|
||
const data = { | ||
a: '1', | ||
b: '2', | ||
c: '3', | ||
}; | ||
|
||
Deno.bench('fieldCalculate-format', () => { | ||
fieldCalculate(data, '( a + b ) * c'.split(' ')), 9; | ||
fieldCalculate(data, 'c * ( a + b )'.split(' ')), 9; | ||
fieldCalculate(data, '( a + b ) * 5'.split(' ')), 15; | ||
fieldCalculate(data, '( a + b ) * 5 * ( a + c )'.split(' ')), 60; | ||
fieldCalculate(data, '0.1 * 0.2'.split(' ')), 0.02; | ||
fieldCalculate(data, '0.1 + 0.2'.split(' ')), 0.3; | ||
fieldCalculate(data, '10000.1 + 0.2'.split(' ')), 10000.3; | ||
fieldCalculate(data, '0.3 - 0.1'.split(' ')), 0.2; | ||
fieldCalculate(data, '0.3 / 0.1'.split(' ')), 3; | ||
fieldCalculate({ ...data, a: 10 }, '( a + b ) * 4'.split(' ')), 48; | ||
}); | ||
Deno.bench('fieldCalculate-eval', () => { | ||
fieldCalculateEval(data, '( a + b ) * c'.split(' ')), 9; | ||
fieldCalculateEval(data, 'c * ( a + b )'.split(' ')), 9; | ||
fieldCalculateEval(data, '( a + b ) * 5'.split(' ')), 15; | ||
fieldCalculateEval(data, '( a + b ) * 5 * ( a + c )'.split(' ')), 60; | ||
fieldCalculateEval(data, '0.1 * 0.2'.split(' ')), 0.02; | ||
fieldCalculateEval(data, '0.1 + 0.2'.split(' ')), 0.3; | ||
fieldCalculateEval(data, '10000.1 + 0.2'.split(' ')), 10000.3; | ||
fieldCalculateEval(data, '0.3 - 0.1'.split(' ')), 0.2; | ||
fieldCalculateEval(data, '0.3 / 0.1'.split(' ')), 3; | ||
fieldCalculateEval({ ...data, a: 10 }, '( a + b ) * 4'.split(' ')), 48; | ||
}); |
Oops, something went wrong.