Skip to content

Commit df7037d

Browse files
committed
fix: nullable values in models #deploy_branch
1 parent 2670940 commit df7037d

File tree

4 files changed

+60
-14
lines changed

4 files changed

+60
-14
lines changed

js-enumerable.code-workspace

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
}
6868
},
6969
"editor.codeActionsOnSave": {
70-
"source.fixAll.eslint": false
70+
"source.fixAll.eslint": "never"
7171
},
7272
"eslint.validate": [
7373
"typescript",

src/linq/peg/odatavisitor.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ export class ODataVisitor extends ReducerVisitor {
3333
let getParams = (expression: IMethodExpression, ...typeofs: Array<string>) => {
3434
let params: Array<any> | undefined,
3535
getType = (t: any) => {
36-
if(typeof t == 'object') {
36+
if(t == null)
37+
return 'undefined'
38+
39+
if(t != null && typeof t == 'object') {
3740
if(t.getTime && t.getTime() >= 0)
3841
return 'date'
3942
}
@@ -45,7 +48,7 @@ export class ODataVisitor extends ReducerVisitor {
4548
if(parameters.every(expression => expression.type == ExpressionType.Literal) == true) {
4649
params = parameters.map(expr => (<LiteralExpression>expr).value)
4750

48-
if(new RegExp('^' + typeofs.map(t => t.endsWith('?') ? '(' + t.slice(0, -1) + ')?' : t).join(';') + ';?$').test(params.map(p => getType(p)).join(';') + ';') == false)
51+
if(new RegExp('^' + typeofs.map(t => t.endsWith('?') ? `(${t.slice(0, -1)})?` : `(${t})`).join(';') + ';?$').test(params.map(p => getType(p)).join(';') + ';') == false)
4952
throw new TypeError(params.map(p => getType(p)).join(', '))
5053
}
5154
else if((parameters.length == typeofs.length) == false) {
@@ -62,28 +65,44 @@ export class ODataVisitor extends ReducerVisitor {
6265
switch(expression.name) {
6366
// String Functions
6467
case 'substringof': // bool substringof(string po, string p1)
65-
if((params = getParams(expression, 'string', 'string')) != null)
68+
if((params = getParams(expression, 'string|undefined', 'string')) != null) {
69+
if(params[0] == null)
70+
return new LiteralExpression(false)
71+
6672
return new LiteralExpression(String(params[0]).indexOf(String(params[1])) >= 0)
73+
}
6774

6875
break
6976

7077
case 'endswith': // bool endswith(string p0, string p1)
71-
if((params = getParams(expression, 'string', 'string')) != null)
78+
if((params = getParams(expression, 'string|undefined', 'string')) != null) {
79+
if(params[0] == null)
80+
return new LiteralExpression(false)
81+
7282
return new LiteralExpression(String(params[0]).endsWith(String(params[1])))
73-
83+
}
7484
break
7585

7686
case 'startswith': // bool startswith(string p0, string p1)
77-
if((params = getParams(expression, 'string', 'string')) != null)
87+
if((params = getParams(expression, 'string|undefined', 'string')) != null) {
88+
if(params[0] == null)
89+
return new LiteralExpression(false)
90+
7891
return new LiteralExpression(String(params[0]).startsWith(String(params[1])))
92+
}
7993

8094
break
8195

8296
case 'contains': // bool contains(string p0, string p1)
83-
if((params = getParams(expression, 'string', 'string')) != null)
97+
if((params = getParams(expression, 'string|undefined', 'string')) != null) {
98+
if(params[0] == null)
99+
return new LiteralExpression(false)
100+
84101
return new LiteralExpression(String(params[0]).indexOf(String(params[1])) >= 0)
85-
102+
}
103+
86104
break
105+
87106
case 'length': // int length(string p0)
88107
if((params = getParams(expression, 'string')) != null)
89108
return new LiteralExpression(String(params[0]).length)
@@ -109,14 +128,22 @@ export class ODataVisitor extends ReducerVisitor {
109128
break
110129

111130
case 'tolower': // string tolower(string p0)
112-
if((params = getParams(expression, 'string')) != null)
131+
if((params = getParams(expression, 'string|undefined')) != null) {
132+
if(params[0] == null)
133+
return new LiteralExpression(params[0])
134+
113135
return new LiteralExpression(String(params[0]).toLowerCase())
136+
}
114137

115138
break
116139

117140
case 'toupper': // string toupper(string p0)
118-
if((params = getParams(expression, 'string')) != null)
141+
if((params = getParams(expression, 'string|undefined')) != null) {
142+
if(params[0] == null)
143+
return new LiteralExpression(params[0])
144+
119145
return new LiteralExpression(String(params[0]).toUpperCase())
146+
}
120147

121148
break
122149

src/linq/peg/reducervisitor.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,10 @@ export class ReducerVisitor extends ExpressionVisitor {
245245
let identifier = (<IIdentifierExpression>expression),
246246
currentScope = Object.assign({}, global ?? {}, scope ?? {})
247247

248-
249248
// this object
250-
if(isRecord(currentScope) && identifier.name in currentScope && (value = currentScope[identifier.name]) !== undefined) {
249+
if(isRecord(currentScope) && identifier.name in currentScope) {
250+
value = currentScope[identifier.name]
251+
251252
if(value == null)
252253
return new LiteralExpression(null)
253254

src/test/odatavisitor.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ describe('When using OData for ExpressionVisitor', () => {
77
vars = {
88
number: 5,
99
stringhavingdate: '2018-05-30Z',
10+
stringthatisnull: '' || null,
11+
stringthatisundefined: '' || undefined,
1012
string: 'abc',
1113
decimal: 5.50,
1214
dateonly: new Date('2020-01-28Z'),
@@ -89,7 +91,23 @@ describe('When using OData for ExpressionVisitor', () => {
8991

9092
assert.equal(expr.type, Expr.ExpressionType.Literal)
9193
assert.equal((<Expr.LiteralExpression>expr).value, false)
92-
})
94+
})
95+
96+
it('should evaluate a expression with contains where property may be null', () => {
97+
let reduced = reducer.parseOData('contains(stringthatisnull, \'bc\')'),
98+
expr = reducer.evaluate(reduced, vars)
99+
100+
assert.equal(expr.type, Expr.ExpressionType.Literal)
101+
assert.equal((<Expr.LiteralExpression>expr).value, false)
102+
})
103+
104+
it('should evaluate a expression with contains where property may be undefined', () => {
105+
let reduced = reducer.parseOData('contains(stringthatisundefined, \'bc\')'),
106+
expr = reducer.evaluate(reduced, vars)
107+
108+
assert.equal(expr.type, Expr.ExpressionType.Literal)
109+
assert.equal((<Expr.LiteralExpression>expr).value, false)
110+
})
93111

94112
it('should evaluate a expression with date as type (v4)', () => {
95113
let reduced = reducer.parseOData('date ge 2017-05-01Z'),

0 commit comments

Comments
 (0)