@cloudpss/expression 0.6.0-alpha.10 → 0.6.0-alpha.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/analyze.js +2 -2
  2. package/dist/analyze.js.map +1 -1
  3. package/dist/migrate.d.ts.map +1 -1
  4. package/dist/migrate.js +13 -0
  5. package/dist/migrate.js.map +1 -1
  6. package/dist/migrator/access.d.ts.map +1 -1
  7. package/dist/migrator/access.js +23 -1
  8. package/dist/migrator/access.js.map +1 -1
  9. package/dist/migrator/call.d.ts.map +1 -1
  10. package/dist/migrator/call.js +36 -25
  11. package/dist/migrator/call.js.map +1 -1
  12. package/dist/migrator/concat.d.ts.map +1 -1
  13. package/dist/migrator/concat.js +15 -2
  14. package/dist/migrator/concat.js.map +1 -1
  15. package/dist/migrator/node.d.ts.map +1 -1
  16. package/dist/migrator/node.js +18 -0
  17. package/dist/migrator/node.js.map +1 -1
  18. package/dist/migrator/operator.js +27 -27
  19. package/dist/migrator/operator.js.map +1 -1
  20. package/dist/migrator/special.d.ts.map +1 -1
  21. package/dist/migrator/special.js +31 -0
  22. package/dist/migrator/special.js.map +1 -1
  23. package/dist/migrator/state.d.ts.map +1 -1
  24. package/dist/migrator/state.js +0 -1
  25. package/dist/migrator/state.js.map +1 -1
  26. package/dist/migrator/to-type.d.ts.map +1 -1
  27. package/dist/migrator/to-type.js +4 -3
  28. package/dist/migrator/to-type.js.map +1 -1
  29. package/dist/migrator/utils.d.ts +2 -0
  30. package/dist/migrator/utils.d.ts.map +1 -1
  31. package/dist/migrator/utils.js +8 -1
  32. package/dist/migrator/utils.js.map +1 -1
  33. package/package.json +5 -2
  34. package/src/analyze.ts +3 -3
  35. package/src/migrate.ts +15 -0
  36. package/src/migrator/access.ts +29 -7
  37. package/src/migrator/call.ts +37 -25
  38. package/src/migrator/concat.ts +15 -2
  39. package/src/migrator/node.ts +17 -0
  40. package/src/migrator/operator.ts +31 -31
  41. package/src/migrator/special.ts +31 -0
  42. package/src/migrator/state.ts +0 -1
  43. package/src/migrator/to-type.ts +6 -3
  44. package/src/migrator/utils.ts +9 -1
  45. package/tests/migrate.ts +170 -45
package/tests/migrate.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { migrateMathJs } from '@cloudpss/expression/migrate';
2
2
  import type { ExpressionSource } from '../dist/expression.js';
3
3
  import { Scope } from '../dist/scope.js';
4
+ import { Evaluator, Expression } from '../dist/index.js';
5
+ import dedent from 'dedent';
4
6
 
5
7
  const s = new Scope({
6
8
  a: [1, 2, 3],
@@ -9,9 +11,14 @@ const s = new Scope({
9
11
  [3, 4],
10
12
  ],
11
13
  f: 1,
12
- s: 's',
14
+ s: 'abc',
13
15
  b: false,
16
+ o: {
17
+ x: 1,
18
+ y: 2,
19
+ },
14
20
  });
21
+ const e = new Evaluator();
15
22
 
16
23
  describe('migrate', () => {
17
24
  it('should migrate constant expressions', () => {
@@ -29,49 +36,167 @@ describe('migrate', () => {
29
36
  });
30
37
 
31
38
  it.each([
32
- ['sin(0)', 'sin(0)'],
33
- ['sin(f)', 'sin(f)'],
34
- ['f', 'f'],
35
- ['$a', '$a'],
36
- ['$a + 1', 'matrix.add($a, 1)'],
37
- ['size(a)[1]', 'len(a)'],
38
- ['size(s)[1]', 'len(chars(s))'],
39
- ['(a).length', 'len((a))'],
40
- ['(s).length', 'len(chars((s)))'],
41
- ['count(s)', 'len(chars(s))'],
42
- ['b ? true : false', 'b'],
43
- ['b ? false : true', '!b'],
44
- ['is(f, "string") ? count(f) != 0 : false', "type(f) == 'string' && f != ''"],
45
- ['is(f, "string") ? equalText(f, "xyz") : false', "f == 'xyz'"],
46
- ['b ? 1 : 2', 'if b { 1 } else { 2 }'],
47
- ['f >0', 'f > 0'],
48
- ['f >=0', 'f >= 0'],
49
- ['f <0', 'f < 0'],
50
- ['1<f<2', '1 < f && f < 2'],
51
- ['1 + 2 + f', '1 + 2 + f'],
52
- ['PI', '@pi'],
53
- ['pi', '@pi'],
54
- ['E', '@e'],
55
- ['e', '@e'],
56
- ['[1,2,3]', '[1, 2, 3]'],
57
- ['[1;2;3]', '[[1], [2], [3]]'],
58
- ['{ x: 1, y: 2 }', '(x: 1, y: 2)'],
59
- ['{ x: f, y: b }', '(x: f, y: b)'],
60
- ['equalText("a", "b")', "'a' == 'b'"],
61
- ['equalText("a", s)', "'a' == s"],
62
- ['equalText(s, "b")', "s == 'b'"],
63
- ['equalText(s, f)', 's == to_string(f)'],
64
- ['b | b', 'to_number(b || b)'],
65
- ['b & b', 'to_number(b && b)'],
66
- ['not b', '!b'],
67
- ['12!', 'factorial(12)'],
68
- ['- b', '-b'],
69
- ['+ b', '+b'],
70
- ['- f', '-f'],
71
- ['size(f)', 'matrix.size(f)'],
72
- ['size(m)', 'matrix.size(m)'],
73
- ])('should migrate expression: %s', (f, t) => {
74
- const m = (e: string) => migrateMathJs(e as ExpressionSource, false, s);
75
- expect(m(f)).toBe(t);
39
+ ['sin(0)', 'sin(0)', 0],
40
+ ['sin(f)', 'sin(f)', Math.sin(1)],
41
+ ['f', 'f', 1],
42
+ ['$a', '$a', null],
43
+ ['$a + 1', 'matrix.add($a, 1)', 1],
44
+ ['size(a)[1]', 'len(a)', 3],
45
+ ['size(s)[1]', 'len(chars(s))', 3],
46
+ ['(a).length', 'len((a))', 3],
47
+ ['(s).length', 'len(chars((s)))', 3],
48
+ ['count(s)', 'len(chars(s))', 3],
49
+ ['b ? true : false', 'b', false],
50
+ ['b ? false : true', '!b', true],
51
+ ['is(f, "string") ? count(f) != 0 : false', "type(f) == 'string' && f != ''", false],
52
+ ['is(f, "string") ? equalText(f, "xyz") : false', "f == 'xyz'", false],
53
+ ['b ? 1 : 2', 'if b { 1 } else { 2 }', 2],
54
+ ['f >0', 'f > 0', true],
55
+ ['f >=0', 'f >= 0', true],
56
+ ['f <0', 'f < 0', false],
57
+ ['1<f<2', '1 < f && f < 2', false],
58
+ ['1 + 2 + f', '1 + 2 + f', 4],
59
+ ['PI', '@pi', Math.PI],
60
+ ['pi', '@pi', Math.PI],
61
+ ['E', '@e', Math.E],
62
+ ['e', '@e', Math.E],
63
+ ['[1,2,3]', '[1, 2, 3]', [1, 2, 3]],
64
+ ['[1;2;3]', '[[1], [2], [3]]', [[1], [2], [3]]],
65
+ ['{ x: 1, y: 2 }', '(x: 1, y: 2)', { x: 1, y: 2 }],
66
+ ['{ x: f, y: b }', '(x: f, y: b)', { x: 1, y: false }],
67
+ ['equalText("a", "b")', "'a' == 'b'", false],
68
+ ['equalText("a", s)', "'a' == s", false],
69
+ ['equalText(s, "b")', "s == 'b'", false],
70
+ ['equalText(s, f)', 's == to_string(f)', false],
71
+ ['b | b', 'to_number(b || b)', 0],
72
+ ['b & b', 'to_number(b && b)', 0],
73
+ ['not b', '!b', true],
74
+ ['12!', 'factorial(12)', 479_001_600],
75
+ ['- b', '-b', -0],
76
+ ['+ b', '+b', +0],
77
+ ['- f', '-f', -1],
78
+ ['size(f)', 'matrix.size(f)', []],
79
+ ['size(m)', 'matrix.size(m)', [2, 2]],
80
+ [
81
+ 'u.length',
82
+ dedent`
83
+ return @@length(u);
84
+ // # 帮助函数
85
+ fn @@length(x) { if type(x) == 'string' { len(chars(x)) } else if type(x) == 'array' { len(x) } else { x.length } }
86
+ // # 转换日志
87
+ // - W: 符号 'u' 未定义
88
+ // # 原始 math.js 表达式
89
+ // u.length`,
90
+ null,
91
+ ],
92
+ ['o["x"]', 'o.x', 1],
93
+ ['o.x', 'o.x', 1],
94
+ [
95
+ 'o[s]',
96
+ dedent`
97
+ return o[@@index(s)];
98
+ // # 帮助函数
99
+ fn @@index(index) { if type(index) == 'number' { index - 1 } else { index } }
100
+ // # 原始 math.js 表达式
101
+ // o[s]`,
102
+ null,
103
+ ],
104
+ [
105
+ 'o[f]',
106
+ dedent`
107
+ return o[@@index(f)];
108
+ // # 帮助函数
109
+ fn @@index(index) { if type(index) == 'number' { index - 1 } else { index } }
110
+ // # 原始 math.js 表达式
111
+ // o[f]`,
112
+ null,
113
+ ],
114
+ [`{x:1,y:2}['x']`, `(x: 1, y: 2).x`, 1],
115
+ [`{x:1,y:2}[s]`, `(x: 1, y: 2)[s]`, null],
116
+ [`[1,2,3][f]`, `[1, 2, 3][f - 1]`, 1],
117
+ ['"abc"[1]', "chars('abc')[0]", 'a'],
118
+ ['s[1]', 'chars(s)[0]', 'a'],
119
+ ['[1,2,3][2]', '[1, 2, 3][1]', 2],
120
+ ['a[2]', 'a[1]', 2],
121
+ [
122
+ 'a[u]',
123
+ dedent`
124
+ return a[@@index(u)];
125
+ // # 帮助函数
126
+ fn @@index(index) { if type(index) == 'number' { index - 1 } else { index } }
127
+ // # 转换日志
128
+ // - W: 符号 'u' 未定义
129
+ // # 原始 math.js 表达式
130
+ // a[u]`,
131
+ 1,
132
+ ],
133
+ [
134
+ 'u[1]',
135
+ dedent`
136
+ return @@maybe_chars(u)[0];
137
+ // # 帮助函数
138
+ fn @@maybe_chars(x) { if type(x) == 'string' { chars(x) } else { x } }
139
+ // # 转换日志
140
+ // - W: 符号 'u' 未定义
141
+ // # 原始 math.js 表达式
142
+ // u[1]`,
143
+ null,
144
+ ],
145
+ [
146
+ 'm[1,2]',
147
+ dedent`
148
+ m[0][1]
149
+ // # 转换日志
150
+ // - W: 多维索引已拆分为多次单维索引
151
+ // # 原始 math.js 表达式
152
+ // m[1,2]`,
153
+ 2,
154
+ ],
155
+ [
156
+ 'm[f,2]',
157
+ dedent`
158
+ m[f - 1][1]
159
+ // # 转换日志
160
+ // - W: 多维索引已拆分为多次单维索引
161
+ // # 原始 math.js 表达式
162
+ // m[f,2]`,
163
+ 2,
164
+ ],
165
+ [
166
+ 'filter(x) = x > 1; a.filter(filter)',
167
+ dedent`
168
+ fn filter(x) { x > 1 }
169
+ a::global.filter(filter)
170
+ // # 转换日志
171
+ // - W: 使用了非精确转换的语法或函数,结果可能不准确
172
+ // - W: '>' 不支持矩阵,计算结果可能不一致
173
+ // # 原始 math.js 表达式
174
+ // filter(x) = x > 1; a.filter(filter)`,
175
+ [2, 3],
176
+ ],
177
+ [`print('hello world, $s!', {s:s})`, '`hello world, $(s)!`', `hello world, abc!`],
178
+ [`print('hello world, $1!', [s])`, '`hello world, $(s)!`', `hello world, abc!`],
179
+ [`concat('Value: ', f, string(1 >= 0))`, '`Value: $(f)$(1 >= 0)`', 'Value: 1true'],
180
+ [`concat(s, f, string(1 >= 0))`, '`$(s)$(f)$(1 >= 0)`', 'abc1true'],
181
+ [
182
+ String.raw`'Value: '.concat('\\x', '$', 1, f, string(1 >= 0))`,
183
+ '`Value: \\\\x\\$1$(f)$(1 >= 0)`',
184
+ String.raw`Value: \x$11true`,
185
+ ],
186
+ [
187
+ `concat([1], a)`,
188
+ dedent`
189
+ flatten([[1], a])
190
+ // # 转换日志
191
+ // - W: 矩阵连接时结果可能不一致
192
+ // # 原始 math.js 表达式
193
+ // concat([1], a)
194
+ `,
195
+ [1, 1, 2, 3],
196
+ ],
197
+ ])('should migrate expression: %s', (f, t, r) => {
198
+ const migrated = migrateMathJs(f as ExpressionSource, false, s);
199
+ expect(migrated).toBe(t);
200
+ expect(e.evaluate(Expression(migrated), s)).toEqual(r);
76
201
  });
77
202
  });