@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.
Files changed (45) hide show
  1. package/dist/definitions/argument.d.ts +1 -1
  2. package/dist/definitions/argument.d.ts.map +1 -1
  3. package/dist/definitions/parameter.d.ts.map +1 -1
  4. package/dist/definitions/parameter.js.map +1 -1
  5. package/dist/definitions/utils.d.ts +2 -1
  6. package/dist/definitions/utils.d.ts.map +1 -1
  7. package/dist/definitions/utils.js +24 -7
  8. package/dist/definitions/utils.js.map +1 -1
  9. package/dist/main.d.ts +1 -1
  10. package/dist/main.d.ts.map +1 -1
  11. package/dist/main.js +25 -17
  12. package/dist/main.js.map +1 -1
  13. package/dist/migrator/call.d.ts.map +1 -1
  14. package/dist/migrator/call.js +39 -13
  15. package/dist/migrator/call.js.map +1 -1
  16. package/dist/migrator/node.d.ts.map +1 -1
  17. package/dist/migrator/node.js +21 -1
  18. package/dist/migrator/node.js.map +1 -1
  19. package/dist/migrator/operator.d.ts.map +1 -1
  20. package/dist/migrator/operator.js +56 -26
  21. package/dist/migrator/operator.js.map +1 -1
  22. package/dist/migrator/symbol.js +2 -2
  23. package/dist/migrator/symbol.js.map +1 -1
  24. package/dist/migrator/to-type.js +2 -2
  25. package/dist/migrator/to-type.js.map +1 -1
  26. package/dist/type.d.ts +22 -10
  27. package/dist/type.d.ts.map +1 -1
  28. package/dist/type.js +19 -26
  29. package/dist/type.js.map +1 -1
  30. package/package.json +3 -3
  31. package/src/definitions/argument.ts +1 -1
  32. package/src/definitions/parameter.ts +15 -8
  33. package/src/definitions/utils.ts +29 -13
  34. package/src/main.ts +21 -14
  35. package/src/migrator/call.ts +37 -15
  36. package/src/migrator/node.ts +22 -1
  37. package/src/migrator/operator.ts +55 -26
  38. package/src/migrator/symbol.ts +2 -2
  39. package/src/migrator/to-type.ts +2 -2
  40. package/src/type.ts +36 -27
  41. package/tests/condition.ts +20 -12
  42. package/tests/definition.ts +12 -10
  43. package/tests/import.ts +3 -3
  44. package/tests/migrate.ts +49 -9
  45. package/tests/scope.ts +3 -3
@@ -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(0);
89
- expect(def.toArgumentValue(null, { type: 'real', key: '', name: '', description: '', value: 1 })).toBe(0);
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(0);
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(0);
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(false);
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([0]);
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([0, 1]);
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('nil');
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) => lib.to_number(x) + lib.to_number(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
- ['$a', '$a', null],
44
- ['$a + 1', 'matrix.add($a, 1)', 1],
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
- null,
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
- 1,
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
- null,
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 > 1 }
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
- expect(e.evaluate(Expression(migrated), s)).toEqual(r);
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(null);
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(null);
26
- expect(e.evaluate(Expression('toString'), s)).toBe(null);
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);