expr_syntax_test.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // 语法兼容层的测试。这个转换是"悄悄改错也看不出来"的那类东西,
  2. // 所以边界情况都钉在测试里。
  3. import 'package:flutter_test/flutter_test.dart';
  4. import 'package:cal/expr_syntax.dart';
  5. void main() {
  6. group('函数调用', () {
  7. test('小写括号写法转成 Symja 方括号', () {
  8. expect(toSymjaSyntax('sin(x)'), 'Sin[x]');
  9. expect(toSymjaSyntax('ln(x)'), 'Log[x]');
  10. expect(toSymjaSyntax('sqrt(x)'), 'Sqrt[x]');
  11. expect(toSymjaSyntax('abs(x)'), 'Abs[x]');
  12. });
  13. test('函数名大小写不敏感', () {
  14. expect(toSymjaSyntax('SIN(x)'), 'Sin[x]');
  15. expect(toSymjaSyntax('Sin(x)'), 'Sin[x]');
  16. });
  17. test('嵌套调用', () {
  18. expect(toSymjaSyntax('sin(cos(x))'), 'Sin[Cos[x]]');
  19. expect(toSymjaSyntax('sqrt(1+x^2)'), 'Sqrt[1+x^2]');
  20. });
  21. test('多参数', () {
  22. expect(toSymjaSyntax('max(x, y)'), 'Max[x, y]');
  23. });
  24. test('已经是对的 Symja 写法原样保留', () {
  25. expect(toSymjaSyntax('Sin[x]'), 'Sin[x]');
  26. expect(toSymjaSyntax('x^2 + 1'), 'x^2 + 1');
  27. });
  28. });
  29. group('常量', () {
  30. test('pi', () {
  31. expect(toSymjaSyntax('pi'), 'Pi');
  32. expect(toSymjaSyntax('2*pi'), '2*Pi');
  33. });
  34. test('e 独立成词才转,且不与数字相邻', () {
  35. expect(toSymjaSyntax('e^x'), 'E^x');
  36. expect(toSymjaSyntax('e'), 'E');
  37. // 科学计数法不能被拆掉
  38. expect(toSymjaSyntax('1e-3'), '1e-3');
  39. expect(toSymjaSyntax('2.5e10'), '2.5e10');
  40. });
  41. });
  42. group('普通括号不能被当成函数调用', () {
  43. test('分组括号保持原样', () {
  44. expect(toSymjaSyntax('(x+1)*2'), '(x+1)*2');
  45. expect(toSymjaSyntax('((x))'), '((x))');
  46. });
  47. test('未知名字后面跟括号也不动', () {
  48. // 不是我们认识的函数名,就当它是用户自己的变量/函数,原样留着
  49. expect(toSymjaSyntax('f(x)'), 'f(x)');
  50. expect(toSymjaSyntax('myfunc(x+1)'), 'myfunc(x+1)');
  51. });
  52. test('函数与分组混在一起', () {
  53. expect(toSymjaSyntax('sin(x)*(x+1)'), 'Sin[x]*(x+1)');
  54. expect(toSymjaSyntax('sin(x)^2 + cos(x)^2'), 'Sin[x]^2 + Cos[x]^2');
  55. });
  56. });
  57. group('隐式乘法', () {
  58. test('数字紧跟字母补乘号', () {
  59. expect(toSymjaSyntax('2x'), '2*x');
  60. expect(toSymjaSyntax('3sin(x)'), '3*Sin[x]');
  61. });
  62. test('单独的系数不动', () {
  63. expect(toSymjaSyntax('2*x'), '2*x');
  64. expect(toSymjaSyntax('2'), '2');
  65. });
  66. });
  67. group('symjaRewriteOf 只在真的改了才返回', () {
  68. test('改了', () {
  69. expect(symjaRewriteOf('sin(x)'), 'Sin[x]');
  70. });
  71. test('没改', () {
  72. expect(symjaRewriteOf('Sin[x]'), isNull);
  73. expect(symjaRewriteOf('x^2'), isNull);
  74. });
  75. });
  76. group('根号(法向量工具用的老写法)', () {
  77. test('√ 后跟数字', () {
  78. expect(toSymjaSyntax('√3'), 'Sqrt[3]');
  79. expect(toSymjaSyntax('√2'), 'Sqrt[2]');
  80. });
  81. test('系数与根号之间补乘号', () {
  82. expect(toSymjaSyntax('2√3'), '2*Sqrt[3]');
  83. expect(toSymjaSyntax('3√2/2'), '3*Sqrt[2]/2');
  84. });
  85. test('√ 后跟配平的括号', () {
  86. expect(toSymjaSyntax('√(x+1)'), 'Sqrt[(x+1)]');
  87. expect(toSymjaSyntax('√(2+3)*4'), 'Sqrt[(2+3)]*4');
  88. });
  89. test('√ 后跟字母变量', () {
  90. expect(toSymjaSyntax('√x'), 'Sqrt[x]');
  91. });
  92. test('负数与分数系数', () {
  93. expect(toSymjaSyntax('-√3'), '-Sqrt[3]');
  94. expect(toSymjaSyntax('1/2√3'), '1/2*Sqrt[3]');
  95. });
  96. test('√ 后面什么都没有也不崩', () {
  97. expect(toSymjaSyntax('√'), 'Sqrt[Null]');
  98. });
  99. });
  100. group('不该崩', () {
  101. test('空串与怪输入', () {
  102. expect(toSymjaSyntax(''), '');
  103. expect(toSymjaSyntax(')'), ')'); // 多余的右括号原样留着,让 Symja 去报错
  104. expect(toSymjaSyntax('sin('), 'Sin[');
  105. });
  106. });
  107. }