flowquery 1.0.43 → 1.0.44
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/flowquery.min.js +1 -1
- package/dist/parsing/functions/join.d.ts.map +1 -1
- package/dist/parsing/functions/join.js +6 -3
- package/dist/parsing/functions/join.js.map +1 -1
- package/dist/parsing/functions/keys.d.ts.map +1 -1
- package/dist/parsing/functions/keys.js +3 -5
- package/dist/parsing/functions/keys.js.map +1 -1
- package/dist/parsing/functions/range.d.ts.map +1 -1
- package/dist/parsing/functions/range.js +11 -3
- package/dist/parsing/functions/range.js.map +1 -1
- package/dist/parsing/functions/replace.d.ts.map +1 -1
- package/dist/parsing/functions/replace.js +8 -3
- package/dist/parsing/functions/replace.js.map +1 -1
- package/dist/parsing/functions/round.d.ts.map +1 -1
- package/dist/parsing/functions/round.js +5 -4
- package/dist/parsing/functions/round.js.map +1 -1
- package/dist/parsing/functions/size.d.ts.map +1 -1
- package/dist/parsing/functions/size.js +5 -4
- package/dist/parsing/functions/size.js.map +1 -1
- package/dist/parsing/functions/split.d.ts.map +1 -1
- package/dist/parsing/functions/split.js +12 -4
- package/dist/parsing/functions/split.js.map +1 -1
- package/dist/parsing/functions/string_distance.d.ts.map +1 -1
- package/dist/parsing/functions/string_distance.js +3 -0
- package/dist/parsing/functions/string_distance.js.map +1 -1
- package/dist/parsing/functions/stringify.d.ts.map +1 -1
- package/dist/parsing/functions/stringify.js +7 -6
- package/dist/parsing/functions/stringify.js.map +1 -1
- package/dist/parsing/functions/substring.d.ts.map +1 -1
- package/dist/parsing/functions/substring.js +3 -0
- package/dist/parsing/functions/substring.js.map +1 -1
- package/dist/parsing/functions/to_json.d.ts.map +1 -1
- package/dist/parsing/functions/to_json.js +5 -4
- package/dist/parsing/functions/to_json.js.map +1 -1
- package/dist/parsing/functions/to_lower.d.ts.map +1 -1
- package/dist/parsing/functions/to_lower.js +3 -0
- package/dist/parsing/functions/to_lower.js.map +1 -1
- package/dist/parsing/functions/to_string.js +1 -1
- package/dist/parsing/functions/to_string.js.map +1 -1
- package/dist/parsing/functions/trim.d.ts.map +1 -1
- package/dist/parsing/functions/trim.js +3 -0
- package/dist/parsing/functions/trim.js.map +1 -1
- package/docs/flowquery.min.js +1 -1
- package/flowquery-py/pyproject.toml +1 -1
- package/flowquery-py/src/parsing/functions/join.py +2 -0
- package/flowquery-py/src/parsing/functions/keys.py +1 -1
- package/flowquery-py/src/parsing/functions/range_.py +2 -0
- package/flowquery-py/src/parsing/functions/replace.py +2 -0
- package/flowquery-py/src/parsing/functions/round_.py +2 -0
- package/flowquery-py/src/parsing/functions/size.py +2 -0
- package/flowquery-py/src/parsing/functions/split.py +2 -0
- package/flowquery-py/src/parsing/functions/string_distance.py +5 -1
- package/flowquery-py/src/parsing/functions/stringify.py +2 -0
- package/flowquery-py/src/parsing/functions/substring.py +2 -0
- package/flowquery-py/src/parsing/functions/to_json.py +2 -0
- package/flowquery-py/src/parsing/functions/to_lower.py +2 -0
- package/flowquery-py/src/parsing/functions/to_string.py +1 -1
- package/flowquery-py/src/parsing/functions/trim.py +2 -0
- package/flowquery-py/tests/compute/test_runner.py +128 -0
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/package.json +1 -1
- package/src/parsing/functions/join.ts +8 -5
- package/src/parsing/functions/keys.ts +4 -6
- package/src/parsing/functions/range.ts +12 -4
- package/src/parsing/functions/replace.ts +11 -4
- package/src/parsing/functions/round.ts +6 -5
- package/src/parsing/functions/size.ts +6 -5
- package/src/parsing/functions/split.ts +14 -6
- package/src/parsing/functions/string_distance.ts +3 -0
- package/src/parsing/functions/stringify.ts +9 -8
- package/src/parsing/functions/substring.ts +3 -0
- package/src/parsing/functions/to_json.ts +6 -5
- package/src/parsing/functions/to_lower.ts +3 -0
- package/src/parsing/functions/to_string.ts +1 -1
- package/src/parsing/functions/trim.ts +3 -0
- package/tests/compute/runner.test.ts +114 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ASTNode from "../ast_node";
|
|
2
|
-
import Function from "./function";
|
|
3
2
|
import String from "../expressions/string";
|
|
3
|
+
import Function from "./function";
|
|
4
4
|
import { FunctionDef } from "./function_metadata";
|
|
5
5
|
|
|
6
6
|
@FunctionDef({
|
|
@@ -8,10 +8,10 @@ import { FunctionDef } from "./function_metadata";
|
|
|
8
8
|
category: "scalar",
|
|
9
9
|
parameters: [
|
|
10
10
|
{ name: "array", description: "Array of values to join", type: "array" },
|
|
11
|
-
{ name: "delimiter", description: "Delimiter to join with", type: "string" }
|
|
11
|
+
{ name: "delimiter", description: "Delimiter to join with", type: "string" },
|
|
12
12
|
],
|
|
13
13
|
output: { description: "Joined string", type: "string", example: "a,b,c" },
|
|
14
|
-
examples: ["WITH ['a', 'b', 'c'] AS arr RETURN join(arr, ',')"]
|
|
14
|
+
examples: ["WITH ['a', 'b', 'c'] AS arr RETURN join(arr, ',')"],
|
|
15
15
|
})
|
|
16
16
|
class Join extends Function {
|
|
17
17
|
constructor() {
|
|
@@ -19,7 +19,7 @@ class Join extends Function {
|
|
|
19
19
|
this._expectedParameterCount = 2;
|
|
20
20
|
}
|
|
21
21
|
public set parameters(nodes: ASTNode[]) {
|
|
22
|
-
if(nodes.length === 1) {
|
|
22
|
+
if (nodes.length === 1) {
|
|
23
23
|
nodes.push(new String(""));
|
|
24
24
|
}
|
|
25
25
|
super.parameters = nodes;
|
|
@@ -27,6 +27,9 @@ class Join extends Function {
|
|
|
27
27
|
public value(): any {
|
|
28
28
|
const array = this.getChildren()[0].value();
|
|
29
29
|
const delimiter = this.getChildren()[1].value();
|
|
30
|
+
if (array === null || array === undefined) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
30
33
|
if (!Array.isArray(array) || typeof delimiter !== "string") {
|
|
31
34
|
throw new Error("Invalid arguments for join function");
|
|
32
35
|
}
|
|
@@ -34,4 +37,4 @@ class Join extends Function {
|
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
export default Join;
|
|
40
|
+
export default Join;
|
|
@@ -4,11 +4,9 @@ import { FunctionDef } from "./function_metadata";
|
|
|
4
4
|
@FunctionDef({
|
|
5
5
|
description: "Returns the keys of an object (associative array) as an array",
|
|
6
6
|
category: "scalar",
|
|
7
|
-
parameters: [
|
|
8
|
-
{ name: "object", description: "Object to extract keys from", type: "object" }
|
|
9
|
-
],
|
|
7
|
+
parameters: [{ name: "object", description: "Object to extract keys from", type: "object" }],
|
|
10
8
|
output: { description: "Array of keys", type: "array", example: "['name', 'age']" },
|
|
11
|
-
examples: ["WITH { name: 'Alice', age: 30 } AS obj RETURN keys(obj)"]
|
|
9
|
+
examples: ["WITH { name: 'Alice', age: 30 } AS obj RETURN keys(obj)"],
|
|
12
10
|
})
|
|
13
11
|
class Keys extends Function {
|
|
14
12
|
constructor() {
|
|
@@ -19,7 +17,7 @@ class Keys extends Function {
|
|
|
19
17
|
public value(): any {
|
|
20
18
|
const obj = this.getChildren()[0].value();
|
|
21
19
|
if (obj === null || obj === undefined) {
|
|
22
|
-
return
|
|
20
|
+
return null;
|
|
23
21
|
}
|
|
24
22
|
if (typeof obj !== "object" || Array.isArray(obj)) {
|
|
25
23
|
throw new Error("keys() expects an object, not an array or primitive");
|
|
@@ -28,4 +26,4 @@ class Keys extends Function {
|
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
28
|
|
|
31
|
-
export default Keys;
|
|
29
|
+
export default Keys;
|
|
@@ -6,10 +6,15 @@ import { FunctionDef } from "./function_metadata";
|
|
|
6
6
|
category: "scalar",
|
|
7
7
|
parameters: [
|
|
8
8
|
{ name: "start", description: "Starting number (inclusive)", type: "number" },
|
|
9
|
-
{ name: "end", description: "Ending number (inclusive)", type: "number" }
|
|
9
|
+
{ name: "end", description: "Ending number (inclusive)", type: "number" },
|
|
10
10
|
],
|
|
11
|
-
output: {
|
|
12
|
-
|
|
11
|
+
output: {
|
|
12
|
+
description: "Array of integers from start to end",
|
|
13
|
+
type: "array",
|
|
14
|
+
items: { type: "number" },
|
|
15
|
+
example: [1, 2, 3, 4, 5],
|
|
16
|
+
},
|
|
17
|
+
examples: ["WITH range(1, 5) AS nums RETURN nums"],
|
|
13
18
|
})
|
|
14
19
|
class Range extends Function {
|
|
15
20
|
constructor() {
|
|
@@ -19,6 +24,9 @@ class Range extends Function {
|
|
|
19
24
|
public value(): any {
|
|
20
25
|
const start = this.getChildren()[0].value();
|
|
21
26
|
const end = this.getChildren()[1].value();
|
|
27
|
+
if (start === null || start === undefined || end === null || end === undefined) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
22
30
|
if (typeof start !== "number" || typeof end !== "number") {
|
|
23
31
|
throw new Error("Invalid arguments for range function");
|
|
24
32
|
}
|
|
@@ -26,4 +34,4 @@ class Range extends Function {
|
|
|
26
34
|
}
|
|
27
35
|
}
|
|
28
36
|
|
|
29
|
-
export default Range;
|
|
37
|
+
export default Range;
|
|
@@ -7,10 +7,10 @@ import { FunctionDef } from "./function_metadata";
|
|
|
7
7
|
parameters: [
|
|
8
8
|
{ name: "text", description: "Source string", type: "string" },
|
|
9
9
|
{ name: "pattern", description: "Pattern to find", type: "string" },
|
|
10
|
-
{ name: "replacement", description: "Replacement string", type: "string" }
|
|
10
|
+
{ name: "replacement", description: "Replacement string", type: "string" },
|
|
11
11
|
],
|
|
12
12
|
output: { description: "String with replacements", type: "string", example: "hello world" },
|
|
13
|
-
examples: ["WITH 'hello there' AS s RETURN replace(s, 'there', 'world')"]
|
|
13
|
+
examples: ["WITH 'hello there' AS s RETURN replace(s, 'there', 'world')"],
|
|
14
14
|
})
|
|
15
15
|
class Replace extends Function {
|
|
16
16
|
constructor() {
|
|
@@ -21,11 +21,18 @@ class Replace extends Function {
|
|
|
21
21
|
const str = this.getChildren()[0].value();
|
|
22
22
|
const search = this.getChildren()[1].value();
|
|
23
23
|
const replacement = this.getChildren()[2].value();
|
|
24
|
-
if (
|
|
24
|
+
if (str === null || str === undefined) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (
|
|
28
|
+
typeof str !== "string" ||
|
|
29
|
+
typeof search !== "string" ||
|
|
30
|
+
typeof replacement !== "string"
|
|
31
|
+
) {
|
|
25
32
|
throw new Error("Invalid arguments for replace function");
|
|
26
33
|
}
|
|
27
34
|
return str.replace(new RegExp(search, "g"), replacement);
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
37
|
|
|
31
|
-
export default Replace;
|
|
38
|
+
export default Replace;
|
|
@@ -4,11 +4,9 @@ import { FunctionDef } from "./function_metadata";
|
|
|
4
4
|
@FunctionDef({
|
|
5
5
|
description: "Rounds a number to the nearest integer",
|
|
6
6
|
category: "scalar",
|
|
7
|
-
parameters: [
|
|
8
|
-
{ name: "value", description: "Number to round", type: "number" }
|
|
9
|
-
],
|
|
7
|
+
parameters: [{ name: "value", description: "Number to round", type: "number" }],
|
|
10
8
|
output: { description: "Rounded integer", type: "number", example: 4 },
|
|
11
|
-
examples: ["WITH 3.7 AS n RETURN round(n)"]
|
|
9
|
+
examples: ["WITH 3.7 AS n RETURN round(n)"],
|
|
12
10
|
})
|
|
13
11
|
class Round extends Function {
|
|
14
12
|
constructor() {
|
|
@@ -17,6 +15,9 @@ class Round extends Function {
|
|
|
17
15
|
}
|
|
18
16
|
public value(): any {
|
|
19
17
|
const value = this.getChildren()[0].value();
|
|
18
|
+
if (value === null || value === undefined) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
20
21
|
if (typeof value !== "number") {
|
|
21
22
|
throw new Error("Invalid argument for round function");
|
|
22
23
|
}
|
|
@@ -24,4 +25,4 @@ class Round extends Function {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export default Round;
|
|
28
|
+
export default Round;
|
|
@@ -4,11 +4,9 @@ import { FunctionDef } from "./function_metadata";
|
|
|
4
4
|
@FunctionDef({
|
|
5
5
|
description: "Returns the length of an array or string",
|
|
6
6
|
category: "scalar",
|
|
7
|
-
parameters: [
|
|
8
|
-
{ name: "value", description: "Array or string to measure", type: "array" }
|
|
9
|
-
],
|
|
7
|
+
parameters: [{ name: "value", description: "Array or string to measure", type: "array" }],
|
|
10
8
|
output: { description: "Length of the input", type: "number", example: 3 },
|
|
11
|
-
examples: ["WITH [1, 2, 3] AS arr RETURN size(arr)"]
|
|
9
|
+
examples: ["WITH [1, 2, 3] AS arr RETURN size(arr)"],
|
|
12
10
|
})
|
|
13
11
|
class Size extends Function {
|
|
14
12
|
constructor() {
|
|
@@ -17,6 +15,9 @@ class Size extends Function {
|
|
|
17
15
|
}
|
|
18
16
|
public value(): any {
|
|
19
17
|
const arr = this.getChildren()[0].value();
|
|
18
|
+
if (arr === null || arr === undefined) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
20
21
|
if (!Array.isArray(arr)) {
|
|
21
22
|
throw new Error("Invalid argument for size function");
|
|
22
23
|
}
|
|
@@ -24,4 +25,4 @@ class Size extends Function {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export default Size;
|
|
28
|
+
export default Size;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ASTNode from "../ast_node";
|
|
2
|
-
import Function from "./function";
|
|
3
2
|
import String from "../expressions/string";
|
|
3
|
+
import Function from "./function";
|
|
4
4
|
import { FunctionDef } from "./function_metadata";
|
|
5
5
|
|
|
6
6
|
@FunctionDef({
|
|
@@ -8,10 +8,15 @@ import { FunctionDef } from "./function_metadata";
|
|
|
8
8
|
category: "scalar",
|
|
9
9
|
parameters: [
|
|
10
10
|
{ name: "text", description: "String to split", type: "string" },
|
|
11
|
-
{ name: "delimiter", description: "Delimiter to split by", type: "string" }
|
|
11
|
+
{ name: "delimiter", description: "Delimiter to split by", type: "string" },
|
|
12
12
|
],
|
|
13
|
-
output: {
|
|
14
|
-
|
|
13
|
+
output: {
|
|
14
|
+
description: "Array of string parts",
|
|
15
|
+
type: "array",
|
|
16
|
+
items: { type: "string" },
|
|
17
|
+
example: ["a", "b", "c"],
|
|
18
|
+
},
|
|
19
|
+
examples: ["WITH 'a,b,c' AS s RETURN split(s, ',')"],
|
|
15
20
|
})
|
|
16
21
|
class Split extends Function {
|
|
17
22
|
constructor() {
|
|
@@ -19,7 +24,7 @@ class Split extends Function {
|
|
|
19
24
|
this._expectedParameterCount = 2;
|
|
20
25
|
}
|
|
21
26
|
public set parameters(nodes: ASTNode[]) {
|
|
22
|
-
if(nodes.length === 1) {
|
|
27
|
+
if (nodes.length === 1) {
|
|
23
28
|
nodes.push(new String(""));
|
|
24
29
|
}
|
|
25
30
|
super.parameters = nodes;
|
|
@@ -27,6 +32,9 @@ class Split extends Function {
|
|
|
27
32
|
public value(): any {
|
|
28
33
|
const str = this.getChildren()[0].value();
|
|
29
34
|
const delimiter = this.getChildren()[1].value();
|
|
35
|
+
if (str === null || str === undefined) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
30
38
|
if (typeof str !== "string" || typeof delimiter !== "string") {
|
|
31
39
|
throw new Error("Invalid arguments for split function");
|
|
32
40
|
}
|
|
@@ -34,4 +42,4 @@ class Split extends Function {
|
|
|
34
42
|
}
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
export default Split;
|
|
45
|
+
export default Split;
|
|
@@ -68,6 +68,9 @@ class StringDistance extends Function {
|
|
|
68
68
|
public value(): any {
|
|
69
69
|
const str1 = this.getChildren()[0].value();
|
|
70
70
|
const str2 = this.getChildren()[1].value();
|
|
71
|
+
if (str1 === null || str1 === undefined || str2 === null || str2 === undefined) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
71
74
|
if (typeof str1 !== "string" || typeof str2 !== "string") {
|
|
72
75
|
throw new Error(
|
|
73
76
|
"Invalid arguments for string_distance function: both arguments must be strings"
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import ASTNode from "../ast_node";
|
|
2
|
-
import Function from "./function";
|
|
3
2
|
import Number from "../expressions/number";
|
|
3
|
+
import Function from "./function";
|
|
4
4
|
import { FunctionDef } from "./function_metadata";
|
|
5
5
|
|
|
6
6
|
@FunctionDef({
|
|
7
7
|
description: "Converts a value to its JSON string representation",
|
|
8
8
|
category: "scalar",
|
|
9
|
-
parameters: [
|
|
10
|
-
|
|
11
|
-
],
|
|
12
|
-
output: { description: "JSON string", type: "string", example: "{\"a\":1}" },
|
|
13
|
-
examples: ["WITH {a: 1} AS obj RETURN stringify(obj)"]
|
|
9
|
+
parameters: [{ name: "value", description: "Value to stringify", type: "any" }],
|
|
10
|
+
output: { description: "JSON string", type: "string", example: '{"a":1}' },
|
|
11
|
+
examples: ["WITH {a: 1} AS obj RETURN stringify(obj)"],
|
|
14
12
|
})
|
|
15
13
|
class Stringify extends Function {
|
|
16
14
|
constructor() {
|
|
@@ -18,7 +16,7 @@ class Stringify extends Function {
|
|
|
18
16
|
this._expectedParameterCount = 2;
|
|
19
17
|
}
|
|
20
18
|
public set parameters(nodes: ASTNode[]) {
|
|
21
|
-
if(nodes.length === 1) {
|
|
19
|
+
if (nodes.length === 1) {
|
|
22
20
|
nodes.push(new Number("3")); // Default to 3 if only one parameter is provided
|
|
23
21
|
}
|
|
24
22
|
super.parameters = nodes;
|
|
@@ -26,6 +24,9 @@ class Stringify extends Function {
|
|
|
26
24
|
public value(): any {
|
|
27
25
|
const value = this.getChildren()[0].value();
|
|
28
26
|
const indent = parseInt(this.getChildren()[1].value());
|
|
27
|
+
if (value === null || value === undefined) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
29
30
|
if (typeof value !== "object") {
|
|
30
31
|
throw new Error("Invalid argument for stringify function");
|
|
31
32
|
}
|
|
@@ -33,4 +34,4 @@ class Stringify extends Function {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
export default Stringify;
|
|
37
|
+
export default Stringify;
|
|
@@ -37,6 +37,9 @@ class Substring extends Function {
|
|
|
37
37
|
const original = children[0].value();
|
|
38
38
|
const start = children[1].value();
|
|
39
39
|
|
|
40
|
+
if (original === null || original === undefined) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
40
43
|
if (typeof original !== "string") {
|
|
41
44
|
throw new Error(
|
|
42
45
|
"Invalid argument for substring function: expected a string as the first argument"
|
|
@@ -4,11 +4,9 @@ import { FunctionDef } from "./function_metadata";
|
|
|
4
4
|
@FunctionDef({
|
|
5
5
|
description: "Parses a JSON string into an object",
|
|
6
6
|
category: "scalar",
|
|
7
|
-
parameters: [
|
|
8
|
-
{ name: "text", description: "JSON string to parse", type: "string" }
|
|
9
|
-
],
|
|
7
|
+
parameters: [{ name: "text", description: "JSON string to parse", type: "string" }],
|
|
10
8
|
output: { description: "Parsed object or array", type: "object", example: { a: 1 } },
|
|
11
|
-
examples: ["WITH '{\"a\": 1}' AS s RETURN tojson(s)"]
|
|
9
|
+
examples: ["WITH '{\"a\": 1}' AS s RETURN tojson(s)"],
|
|
12
10
|
})
|
|
13
11
|
class ToJson extends Function {
|
|
14
12
|
constructor() {
|
|
@@ -17,6 +15,9 @@ class ToJson extends Function {
|
|
|
17
15
|
}
|
|
18
16
|
public value(): any {
|
|
19
17
|
const str = this.getChildren()[0].value();
|
|
18
|
+
if (str === null || str === undefined) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
20
21
|
if (typeof str !== "string") {
|
|
21
22
|
throw new Error("Invalid arguments for tojson function");
|
|
22
23
|
}
|
|
@@ -24,4 +25,4 @@ class ToJson extends Function {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export default ToJson;
|
|
28
|
+
export default ToJson;
|
|
@@ -15,6 +15,9 @@ class ToLower extends Function {
|
|
|
15
15
|
}
|
|
16
16
|
public value(): any {
|
|
17
17
|
const val = this.getChildren()[0].value();
|
|
18
|
+
if (val === null || val === undefined) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
18
21
|
if (typeof val !== "string") {
|
|
19
22
|
throw new Error("Invalid argument for toLower function: expected a string");
|
|
20
23
|
}
|
|
@@ -15,6 +15,9 @@ class Trim extends Function {
|
|
|
15
15
|
}
|
|
16
16
|
public value(): any {
|
|
17
17
|
const val = this.getChildren()[0].value();
|
|
18
|
+
if (val === null || val === undefined) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
18
21
|
if (typeof val !== "string") {
|
|
19
22
|
throw new Error("Invalid argument for trim function: expected a string");
|
|
20
23
|
}
|
|
@@ -758,6 +758,120 @@ test("Test substring function with zero length", async () => {
|
|
|
758
758
|
expect(results[0]).toEqual({ result: "" });
|
|
759
759
|
});
|
|
760
760
|
|
|
761
|
+
// --- Null propagation tests ---
|
|
762
|
+
|
|
763
|
+
test("Test toLower with null returns null", async () => {
|
|
764
|
+
const runner = new Runner("RETURN toLower(null) as result");
|
|
765
|
+
await runner.run();
|
|
766
|
+
const results = runner.results;
|
|
767
|
+
expect(results.length).toBe(1);
|
|
768
|
+
expect(results[0]).toEqual({ result: null });
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
test("Test trim with null returns null", async () => {
|
|
772
|
+
const runner = new Runner("RETURN trim(null) as result");
|
|
773
|
+
await runner.run();
|
|
774
|
+
const results = runner.results;
|
|
775
|
+
expect(results.length).toBe(1);
|
|
776
|
+
expect(results[0]).toEqual({ result: null });
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
test("Test replace with null returns null", async () => {
|
|
780
|
+
const runner = new Runner("RETURN replace(null, 'a', 'b') as result");
|
|
781
|
+
await runner.run();
|
|
782
|
+
const results = runner.results;
|
|
783
|
+
expect(results.length).toBe(1);
|
|
784
|
+
expect(results[0]).toEqual({ result: null });
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
test("Test substring with null returns null", async () => {
|
|
788
|
+
const runner = new Runner("RETURN substring(null, 0, 3) as result");
|
|
789
|
+
await runner.run();
|
|
790
|
+
const results = runner.results;
|
|
791
|
+
expect(results.length).toBe(1);
|
|
792
|
+
expect(results[0]).toEqual({ result: null });
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
test("Test split with null returns null", async () => {
|
|
796
|
+
const runner = new Runner("RETURN split(null, ',') as result");
|
|
797
|
+
await runner.run();
|
|
798
|
+
const results = runner.results;
|
|
799
|
+
expect(results.length).toBe(1);
|
|
800
|
+
expect(results[0]).toEqual({ result: null });
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
test("Test size with null returns null", async () => {
|
|
804
|
+
const runner = new Runner("RETURN size(null) as result");
|
|
805
|
+
await runner.run();
|
|
806
|
+
const results = runner.results;
|
|
807
|
+
expect(results.length).toBe(1);
|
|
808
|
+
expect(results[0]).toEqual({ result: null });
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
test("Test round with null returns null", async () => {
|
|
812
|
+
const runner = new Runner("RETURN round(null) as result");
|
|
813
|
+
await runner.run();
|
|
814
|
+
const results = runner.results;
|
|
815
|
+
expect(results.length).toBe(1);
|
|
816
|
+
expect(results[0]).toEqual({ result: null });
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
test("Test join with null returns null", async () => {
|
|
820
|
+
const runner = new Runner("RETURN join(null, ',') as result");
|
|
821
|
+
await runner.run();
|
|
822
|
+
const results = runner.results;
|
|
823
|
+
expect(results.length).toBe(1);
|
|
824
|
+
expect(results[0]).toEqual({ result: null });
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
test("Test string_distance with null returns null", async () => {
|
|
828
|
+
const runner = new Runner("RETURN string_distance(null, 'hello') as result");
|
|
829
|
+
await runner.run();
|
|
830
|
+
const results = runner.results;
|
|
831
|
+
expect(results.length).toBe(1);
|
|
832
|
+
expect(results[0]).toEqual({ result: null });
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
test("Test stringify with null returns null", async () => {
|
|
836
|
+
const runner = new Runner("RETURN stringify(null) as result");
|
|
837
|
+
await runner.run();
|
|
838
|
+
const results = runner.results;
|
|
839
|
+
expect(results.length).toBe(1);
|
|
840
|
+
expect(results[0]).toEqual({ result: null });
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
test("Test toJson with null returns null", async () => {
|
|
844
|
+
const runner = new Runner("RETURN tojson(null) as result");
|
|
845
|
+
await runner.run();
|
|
846
|
+
const results = runner.results;
|
|
847
|
+
expect(results.length).toBe(1);
|
|
848
|
+
expect(results[0]).toEqual({ result: null });
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
test("Test range with null returns null", async () => {
|
|
852
|
+
const runner = new Runner("RETURN range(null, 5) as result");
|
|
853
|
+
await runner.run();
|
|
854
|
+
const results = runner.results;
|
|
855
|
+
expect(results.length).toBe(1);
|
|
856
|
+
expect(results[0]).toEqual({ result: null });
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
test("Test toString with null returns null", async () => {
|
|
860
|
+
const runner = new Runner("RETURN toString(null) as result");
|
|
861
|
+
await runner.run();
|
|
862
|
+
const results = runner.results;
|
|
863
|
+
expect(results.length).toBe(1);
|
|
864
|
+
expect(results[0]).toEqual({ result: null });
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
test("Test keys with null returns null", async () => {
|
|
868
|
+
const runner = new Runner("RETURN keys(null) as result");
|
|
869
|
+
await runner.run();
|
|
870
|
+
const results = runner.results;
|
|
871
|
+
expect(results.length).toBe(1);
|
|
872
|
+
expect(results[0]).toEqual({ result: null });
|
|
873
|
+
});
|
|
874
|
+
|
|
761
875
|
test("Test associative array with key which is keyword", async () => {
|
|
762
876
|
const runner = new Runner("RETURN {return: 1} as aa");
|
|
763
877
|
await runner.run();
|