@cloudpss/expression 0.6.0-alpha.15 → 0.6.0-alpha.17
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/definitions/argument.d.ts +1 -1
- package/dist/definitions/argument.d.ts.map +1 -1
- package/dist/definitions/parameter.d.ts.map +1 -1
- package/dist/definitions/parameter.js.map +1 -1
- package/dist/definitions/utils.d.ts +2 -1
- package/dist/definitions/utils.d.ts.map +1 -1
- package/dist/definitions/utils.js +24 -7
- package/dist/definitions/utils.js.map +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +25 -17
- package/dist/main.js.map +1 -1
- package/dist/migrator/call.d.ts.map +1 -1
- package/dist/migrator/call.js +39 -13
- package/dist/migrator/call.js.map +1 -1
- package/dist/migrator/node.d.ts.map +1 -1
- package/dist/migrator/node.js +21 -1
- package/dist/migrator/node.js.map +1 -1
- package/dist/migrator/operator.d.ts.map +1 -1
- package/dist/migrator/operator.js +56 -26
- package/dist/migrator/operator.js.map +1 -1
- package/dist/migrator/symbol.js +2 -2
- package/dist/migrator/symbol.js.map +1 -1
- package/dist/migrator/to-type.js +2 -2
- package/dist/migrator/to-type.js.map +1 -1
- package/dist/type.d.ts +22 -10
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +19 -26
- package/dist/type.js.map +1 -1
- package/package.json +3 -3
- package/src/definitions/argument.ts +1 -1
- package/src/definitions/parameter.ts +15 -8
- package/src/definitions/utils.ts +29 -13
- package/src/main.ts +21 -14
- package/src/migrator/call.ts +37 -15
- package/src/migrator/node.ts +22 -1
- package/src/migrator/operator.ts +55 -26
- package/src/migrator/symbol.ts +2 -2
- package/src/migrator/to-type.ts +2 -2
- package/src/type.ts +36 -27
- package/tests/condition.ts +20 -12
- package/tests/definition.ts +12 -10
- package/tests/import.ts +3 -3
- package/tests/migrate.ts +49 -9
- package/tests/scope.ts +3 -3
package/tests/definition.ts
CHANGED
|
@@ -85,8 +85,10 @@ describe('definitions', () => {
|
|
|
85
85
|
null,
|
|
86
86
|
);
|
|
87
87
|
// @ts-expect-error 测试 undefined 输入
|
|
88
|
-
expect(def.toArgumentValue(undefined, { type: 'real', key: '', name: '', description: '', value: 1 })).toBe(
|
|
89
|
-
|
|
88
|
+
expect(def.toArgumentValue(undefined, { type: 'real', key: '', name: '', description: '', value: 1 })).toBe(
|
|
89
|
+
null,
|
|
90
|
+
);
|
|
91
|
+
expect(def.toArgumentValue(null, { type: 'real', key: '', name: '', description: '', value: 1 })).toBe(null);
|
|
90
92
|
expect(def.toArgumentValue('12', { type: 'real', key: '', name: '', description: '', value: 1 })).toBe(12);
|
|
91
93
|
expect(def.toArgumentValue(null, { type: 'text', key: '', name: '', description: '', value: '1' })).toBe('');
|
|
92
94
|
expect(def.toArgumentValue(12, { type: 'text', key: '', name: '', description: '', value: '1' })).toBe('12');
|
|
@@ -96,7 +98,7 @@ describe('definitions', () => {
|
|
|
96
98
|
|
|
97
99
|
expect(
|
|
98
100
|
def.toArgumentValue(null, { type: 'choice', key: '', name: '', description: '', value: 1, choices: [] }),
|
|
99
|
-
).toBe(
|
|
101
|
+
).toBe(null);
|
|
100
102
|
expect(
|
|
101
103
|
def.toArgumentValue(null, {
|
|
102
104
|
type: 'choice',
|
|
@@ -120,7 +122,7 @@ describe('definitions', () => {
|
|
|
120
122
|
],
|
|
121
123
|
}),
|
|
122
124
|
).toBe('0');
|
|
123
|
-
expect(def.toArgumentValue(null, { type: 'logical', key: '', name: '', description: '', value: 1 })).toBe(
|
|
125
|
+
expect(def.toArgumentValue(null, { type: 'logical', key: '', name: '', description: '', value: 1 })).toBe(null);
|
|
124
126
|
expect(
|
|
125
127
|
def.toArgumentValue(null, {
|
|
126
128
|
type: 'logical',
|
|
@@ -142,7 +144,7 @@ describe('definitions', () => {
|
|
|
142
144
|
description: '',
|
|
143
145
|
value: true,
|
|
144
146
|
}),
|
|
145
|
-
).toBe(
|
|
147
|
+
).toBe(null);
|
|
146
148
|
expect(
|
|
147
149
|
def.toArgumentValue(null, {
|
|
148
150
|
type: 'logical',
|
|
@@ -194,7 +196,7 @@ describe('definitions', () => {
|
|
|
194
196
|
value: [1],
|
|
195
197
|
choices: [],
|
|
196
198
|
}),
|
|
197
|
-
).toStrictEqual([
|
|
199
|
+
).toStrictEqual([]);
|
|
198
200
|
expect(
|
|
199
201
|
def.toArgumentValue('', {
|
|
200
202
|
type: 'multiSelect',
|
|
@@ -206,7 +208,7 @@ describe('definitions', () => {
|
|
|
206
208
|
}),
|
|
207
209
|
).toStrictEqual(['']);
|
|
208
210
|
expect(
|
|
209
|
-
def.toArgumentValue(['', '1'], {
|
|
211
|
+
def.toArgumentValue(['', '1', ' 2 '], {
|
|
210
212
|
type: 'multiSelect',
|
|
211
213
|
key: '',
|
|
212
214
|
name: '',
|
|
@@ -214,9 +216,9 @@ describe('definitions', () => {
|
|
|
214
216
|
value: [1],
|
|
215
217
|
choices: [],
|
|
216
218
|
}),
|
|
217
|
-
).toStrictEqual([
|
|
219
|
+
).toStrictEqual([1, 2]);
|
|
218
220
|
expect(
|
|
219
|
-
def.toArgumentValue(['', '1'], {
|
|
221
|
+
def.toArgumentValue(['', '1', ' 2 '], {
|
|
220
222
|
type: 'multiSelect',
|
|
221
223
|
key: '',
|
|
222
224
|
name: '',
|
|
@@ -224,6 +226,6 @@ describe('definitions', () => {
|
|
|
224
226
|
value: [1],
|
|
225
227
|
choices: Expression(''),
|
|
226
228
|
}),
|
|
227
|
-
).toStrictEqual(['', '1']);
|
|
229
|
+
).toStrictEqual(['', '1', ' 2 ']);
|
|
228
230
|
});
|
|
229
231
|
});
|
package/tests/import.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VmFunction } from '@mirascript/mirascript';
|
|
2
2
|
import { Evaluator, Expression, Scope } from '../dist/index.js';
|
|
3
|
-
import { lib } from '@mirascript/mirascript/subtle';
|
|
3
|
+
import { convert, lib } from '@mirascript/mirascript/subtle';
|
|
4
4
|
|
|
5
5
|
const e = new Evaluator({
|
|
6
6
|
logger: {
|
|
@@ -26,7 +26,7 @@ describe('Import should work correctly', () => {
|
|
|
26
26
|
expect(e.evaluate(Expression('add(1,2)'), s)).toBe(3);
|
|
27
27
|
expect(e.evaluate(Expression('add::type()'), s)).toBe('extern');
|
|
28
28
|
expect(e2.evaluate(Expression('add(1,2)'), s)).toBe(null);
|
|
29
|
-
expect(e2.evaluate(Expression('add::type()'), s)).toBe(
|
|
29
|
+
expect(e2.evaluate(Expression('add::type()'), s)).toBe(null);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it('can remove modules', () => {
|
|
@@ -39,7 +39,7 @@ describe('Import should work correctly', () => {
|
|
|
39
39
|
it('can replace modules', () => {
|
|
40
40
|
e.import({ add: (x: number, y: number) => x + y });
|
|
41
41
|
expect(e.evaluate(Expression('add::type()'), s)).toBe('extern');
|
|
42
|
-
e.import({ add: VmFunction((x, y) =>
|
|
42
|
+
e.import({ add: VmFunction((x, y) => convert.toNumber(x, 0) + convert.toNumber(y, 0)) });
|
|
43
43
|
expect(e.evaluate(Expression('add::type()'), s)).toBe('function');
|
|
44
44
|
});
|
|
45
45
|
});
|
package/tests/migrate.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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';
|
|
4
|
+
import { Evaluator, Expression, VmError } from '../dist/index.js';
|
|
5
5
|
import dedent from 'dedent';
|
|
6
6
|
|
|
7
7
|
const s = new Scope({
|
|
@@ -40,8 +40,16 @@ describe('migrate', () => {
|
|
|
40
40
|
['sin(0)', 'sin(0)', 0],
|
|
41
41
|
['sin(f)', 'sin(f)', Math.sin(1)],
|
|
42
42
|
['f', 'f', 1],
|
|
43
|
-
['
|
|
44
|
-
['
|
|
43
|
+
['o == null', 'o == nil', false],
|
|
44
|
+
['o == undefined', 'o == nil', false],
|
|
45
|
+
['o == undefined', 'o == nil', false],
|
|
46
|
+
['b == false', 'b =~ 0', true],
|
|
47
|
+
['true != b', '1 !~ b', true],
|
|
48
|
+
['f == true', 'f =~ 1', true],
|
|
49
|
+
['false == f', '0 =~ f', false],
|
|
50
|
+
['0 <= f + 1 <= 2', 'f + 1 is 0..2', true],
|
|
51
|
+
['$a', '$a', VmError],
|
|
52
|
+
['$a + 1', 'matrix.add($a, 1)', VmError],
|
|
45
53
|
['size(a)[1]', 'len(a)', 3],
|
|
46
54
|
['size(s)[1]', 'len(chars(s))', 3],
|
|
47
55
|
['(a).length', 'len((a))', 3],
|
|
@@ -55,6 +63,8 @@ describe('migrate', () => {
|
|
|
55
63
|
['f >0', 'f > 0', true],
|
|
56
64
|
['f >=0', 'f >= 0', true],
|
|
57
65
|
['f <0', 'f < 0', false],
|
|
66
|
+
['f == 1', 'f =~ 1', true],
|
|
67
|
+
['f != 1', 'f !~ 1', false],
|
|
58
68
|
['1<f<2', '1 < f && f < 2', false],
|
|
59
69
|
['1 + 2 + f', '1 + 2 + f', 4],
|
|
60
70
|
['PI', '@pi', Math.PI],
|
|
@@ -78,6 +88,8 @@ describe('migrate', () => {
|
|
|
78
88
|
['- f', '-f', -1],
|
|
79
89
|
['size(f)', 'matrix.size(f)', []],
|
|
80
90
|
['size(m)', 'matrix.size(m)', [2, 2]],
|
|
91
|
+
[`[1,2,3] == f`, `[1, 2, 3]::map(fn { it =~ f })`, [true, false, false]],
|
|
92
|
+
[`$V != [1,2,3]`, `[1, 2, 3]::map(fn { $V !~ it })`, VmError],
|
|
81
93
|
[
|
|
82
94
|
'u.length',
|
|
83
95
|
dedent`
|
|
@@ -88,7 +100,7 @@ describe('migrate', () => {
|
|
|
88
100
|
// - W: 符号 'u' 未定义
|
|
89
101
|
// # 原始 math.js 表达式
|
|
90
102
|
// u.length`,
|
|
91
|
-
|
|
103
|
+
VmError,
|
|
92
104
|
],
|
|
93
105
|
['o["x"]', 'o.x', 1],
|
|
94
106
|
['o.x', 'o.x', 1],
|
|
@@ -129,7 +141,7 @@ describe('migrate', () => {
|
|
|
129
141
|
// - W: 符号 'u' 未定义
|
|
130
142
|
// # 原始 math.js 表达式
|
|
131
143
|
// a[u]`,
|
|
132
|
-
|
|
144
|
+
VmError,
|
|
133
145
|
],
|
|
134
146
|
[
|
|
135
147
|
'u[1]',
|
|
@@ -141,7 +153,7 @@ describe('migrate', () => {
|
|
|
141
153
|
// - W: 符号 'u' 未定义
|
|
142
154
|
// # 原始 math.js 表达式
|
|
143
155
|
// u[1]`,
|
|
144
|
-
|
|
156
|
+
VmError,
|
|
145
157
|
],
|
|
146
158
|
[
|
|
147
159
|
'm[1,2]',
|
|
@@ -166,11 +178,10 @@ describe('migrate', () => {
|
|
|
166
178
|
[
|
|
167
179
|
'filter(x) = x > 1; a.filter(filter)',
|
|
168
180
|
dedent`
|
|
169
|
-
fn filter(x) { x >
|
|
181
|
+
fn filter(x) { matrix.entrywise(x, 1, fn (a, b) { a > b }) }
|
|
170
182
|
a::global.filter(filter)
|
|
171
183
|
// # 转换日志
|
|
172
184
|
// - W: 使用了非精确转换的语法或函数,结果可能不准确
|
|
173
|
-
// - W: '>' 不支持矩阵,计算结果可能不一致
|
|
174
185
|
// # 原始 math.js 表达式
|
|
175
186
|
// filter(x) = x > 1; a.filter(filter)`,
|
|
176
187
|
[2, 3],
|
|
@@ -227,9 +238,38 @@ describe('migrate', () => {
|
|
|
227
238
|
['', '', null],
|
|
228
239
|
['#', '//', null],
|
|
229
240
|
['#xx', '//xx', null],
|
|
241
|
+
['(random() - 1) < 0', '(random() - 1) < 0', true],
|
|
242
|
+
[
|
|
243
|
+
're(12) + im(i)',
|
|
244
|
+
dedent`
|
|
245
|
+
/* re */(12) + /* im */(i)
|
|
246
|
+
// # 转换日志
|
|
247
|
+
// - E: 不支持复数
|
|
248
|
+
// # 原始 math.js 表达式
|
|
249
|
+
// re(12) + im(i)
|
|
250
|
+
`,
|
|
251
|
+
VmError,
|
|
252
|
+
],
|
|
253
|
+
['is(a, "number")', "type(a) == 'number'", false],
|
|
254
|
+
['is(a, "string")', "type(a) == 'string'", false],
|
|
255
|
+
['is(a, "boolean")', "type(a) == 'boolean'", false],
|
|
256
|
+
['is(a, "null")', "type(a) == 'nil'", false],
|
|
257
|
+
['is(a, "undefined")', "type(a) == 'nil'", false],
|
|
258
|
+
[`sum([a > 1])`, `sum([matrix.entrywise(a, 1, fn (a, b) { a > b })]::flatten())`, 2],
|
|
259
|
+
[`prod(1,2,3)`, `product(1, 2, 3)`, 6],
|
|
260
|
+
[`sum(true)`, `sum(true)`, 1],
|
|
261
|
+
[`sum(m)`, `sum(m::flatten())`, 10],
|
|
262
|
+
[`prod([1,2,3])`, `product([1, 2, 3])`, 6],
|
|
263
|
+
[`prod(f)`, `product(f)`, 1],
|
|
230
264
|
])('should migrate expression: %s', (f, t, r) => {
|
|
231
265
|
const migrated = migrateMathJs(f as ExpressionSource, false, s);
|
|
232
266
|
expect(migrated).toBe(t);
|
|
233
|
-
|
|
267
|
+
if (typeof r === 'function' && r.prototype instanceof Error) {
|
|
268
|
+
expect(() => {
|
|
269
|
+
e.evaluate(Expression(migrated), s);
|
|
270
|
+
}).toThrow(r);
|
|
271
|
+
} else {
|
|
272
|
+
expect(e.evaluate(Expression(migrated), s)).toEqual(r);
|
|
273
|
+
}
|
|
234
274
|
});
|
|
235
275
|
});
|
package/tests/scope.ts
CHANGED
|
@@ -10,7 +10,7 @@ describe('Scope should work correctly', () => {
|
|
|
10
10
|
it('can create from function', () => {
|
|
11
11
|
const s = new Scope((k) => (k === 'a' ? 12 : undefined), false);
|
|
12
12
|
expect(e.evaluate(Expression('a'), s)).toBe(12);
|
|
13
|
-
expect(e.evaluate(Expression('b'), s)).toBe(
|
|
13
|
+
expect(e.evaluate(Expression('`b` in global'), s)).toBe(false);
|
|
14
14
|
});
|
|
15
15
|
it('can create from object', () => {
|
|
16
16
|
const s = new Scope({ a: 12, b: Expression('a + 1') }, false);
|
|
@@ -22,8 +22,8 @@ describe('Scope should work correctly', () => {
|
|
|
22
22
|
describe('Scope should not leak dangerous objects', () => {
|
|
23
23
|
it('should not access prototype fields', () => {
|
|
24
24
|
const s = new Scope({}, false);
|
|
25
|
-
expect(e.evaluate(Expression('__proto__'), s)).toBe(
|
|
26
|
-
expect(e.evaluate(Expression('toString'), s)).toBe(
|
|
25
|
+
expect(e.evaluate(Expression('`__proto__` in global'), s)).toBe(false);
|
|
26
|
+
expect(e.evaluate(Expression('`toString` in global'), s)).toBe(false);
|
|
27
27
|
});
|
|
28
28
|
it('should access same name props', () => {
|
|
29
29
|
const s = new Scope({ ['__proto__']: 12, toString: 'x' }, false);
|