@cloudpss/expression 0.6.0-alpha.10 → 0.6.0-alpha.11
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.
- package/dist/analyze.js +2 -2
- package/dist/analyze.js.map +1 -1
- package/dist/migrate.d.ts.map +1 -1
- package/dist/migrate.js +13 -0
- package/dist/migrate.js.map +1 -1
- package/dist/migrator/access.d.ts.map +1 -1
- package/dist/migrator/access.js +23 -1
- package/dist/migrator/access.js.map +1 -1
- package/dist/migrator/call.d.ts.map +1 -1
- package/dist/migrator/call.js +36 -25
- package/dist/migrator/call.js.map +1 -1
- package/dist/migrator/concat.d.ts.map +1 -1
- package/dist/migrator/concat.js +15 -2
- package/dist/migrator/concat.js.map +1 -1
- package/dist/migrator/operator.js +27 -27
- package/dist/migrator/operator.js.map +1 -1
- package/dist/migrator/to-type.d.ts.map +1 -1
- package/dist/migrator/to-type.js +4 -3
- package/dist/migrator/to-type.js.map +1 -1
- package/dist/migrator/utils.d.ts +2 -0
- package/dist/migrator/utils.d.ts.map +1 -1
- package/dist/migrator/utils.js +8 -1
- package/dist/migrator/utils.js.map +1 -1
- package/package.json +5 -2
- package/src/analyze.ts +3 -3
- package/src/migrate.ts +15 -0
- package/src/migrator/access.ts +29 -7
- package/src/migrator/call.ts +37 -25
- package/src/migrator/concat.ts +15 -2
- package/src/migrator/operator.ts +31 -31
- package/src/migrator/to-type.ts +6 -3
- package/src/migrator/utils.ts +9 -1
- 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: '
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
});
|