Skip to content

Commit

Permalink
test: test unknown primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
sgulseth committed Mar 5, 2024
1 parent 522bd9b commit d83871c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 46 deletions.
58 changes: 15 additions & 43 deletions src/typeEvaluator/evaluateQueryType.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import debug from 'debug'

import {
gatherText,
matchAnalyzePattern,
matchText,
matchTokenize,
Expand All @@ -28,7 +27,6 @@ import type {
ValueNode,
} from '../nodeTypes'
import {parse} from '../parser'
import {StaticValue} from '../values'
import {handleFuncCallNode} from './functions'
import {optimizeUnions} from './optimizations'
import {createContext, createScope, Scope} from './scope'
Expand Down Expand Up @@ -194,6 +192,10 @@ function handleObjectNode(node: ObjectNode, scope: Scope) {
function handleOpCallNode(node: OpCallNode, scope: Scope): TypeNode {
const left = walk({node: node.left, scope})
const right = walk({node: node.right, scope})
$trace('opCallNode "%s" %O', node.op, {left, right})
if (left.type === 'unknown' || right.type === 'unknown') {
return {type: 'unknown'} satisfies UnknownTypeNode
}

switch (node.op) {
case '==':
Expand Down Expand Up @@ -780,10 +782,7 @@ function isPrimitiveTypeNode(node: TypeNode): node is PrimitiveTypeNode {
}

function evaluateEquality(left: TypeNode, right: TypeNode): boolean | undefined {
$trace('opcall == %O', {left, right})
if (left.type === 'unknown' || right.type === 'unknown') {
return undefined
}
$trace('evaluateEquality %O', {left, right})
if (left.type === 'null' && right.type === 'null') {
return true
}
Expand Down Expand Up @@ -822,6 +821,7 @@ function evaluateEquality(left: TypeNode, right: TypeNode): boolean | undefined
// eslint-disable-next-line complexity, max-statements
function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
$trace('resolveCondition.expr %O', expr)

switch (expr.type) {
case 'Value': {
const value = walk({node: expr, scope})
Expand Down Expand Up @@ -866,34 +866,26 @@ function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
return false
}
case 'OpCall': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
$trace('opcall "%s" %O', expr.op, {left, right})

if (left.type === 'unknown' || right.type === 'unknown') {
return undefined
}

switch (expr.op) {
case '==': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
$trace('opcall == %O', {left, right})

return evaluateEquality(left, right)
}
case '!=': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
$trace('opcall != %O', {left, right})

const result = evaluateEquality(left, right)
if (result === undefined) {
return undefined
}
return !result
}
case 'in': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
$trace('opcall "in" %O', {left, right})

if (left.type === 'unknown' || right.type === 'unknown') {
return undefined
}

if (right.type === 'array') {
if (left.type === 'null' && right.of.type === 'unknown') {
return undefined
Expand Down Expand Up @@ -932,7 +924,7 @@ function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
return true
}
// eslint-disable-next-line max-depth
if (left.type === node.type) {
if (left.type === node.type && node.value === undefined) {
return undefined
}
}
Expand All @@ -943,14 +935,6 @@ function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
return false
}
case 'match': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
$trace('opcall "match" %O', {left, right})

if (left.type === 'unknown' || right.type === 'unknown') {
return undefined
}

let tokens: Token[] = []
let patterns: Pattern[] = []
if (left.type === 'string') {
Expand Down Expand Up @@ -1021,12 +1005,6 @@ function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
return matchText(tokens, patterns)
}
case '<': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
if (left.type === 'unknown' || right.type === 'unknown') {
return undefined
}

if (isPrimitiveTypeNode(left) && isPrimitiveTypeNode(right)) {
if (left.value === undefined || right.value === undefined) {
return undefined
Expand All @@ -1037,8 +1015,6 @@ function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
return undefined
}
case '<=': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
if (isPrimitiveTypeNode(left) && isPrimitiveTypeNode(right)) {
if (left.value === undefined || right.value === undefined) {
return undefined
Expand All @@ -1049,8 +1025,6 @@ function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
return undefined
}
case '>': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
if (isPrimitiveTypeNode(left) && isPrimitiveTypeNode(right)) {
if (left.value === undefined || right.value === undefined) {
return undefined
Expand All @@ -1061,8 +1035,6 @@ function resolveCondition(expr: ExprNode, scope: Scope): boolean | undefined {
return undefined
}
case '>=': {
const left = walk({node: expr.left, scope})
const right = walk({node: expr.right, scope})
if (isPrimitiveTypeNode(left) && isPrimitiveTypeNode(right)) {
if (left.value === undefined || right.value === undefined) {
return undefined
Expand Down
5 changes: 3 additions & 2 deletions test/evaluateQueryNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ function inArray(input: AnnotatedValue[]): AnnotatedValue[] {
* We have four different categories. This is mainly here so that we can exclude.
*/
enum Category {
/** primitives + unknown. */
PRIMITIVES,
/** Objects of primitives + unknown. */
OBJECTS,
Expand All @@ -178,8 +179,8 @@ const objects1InArrays = inArray(objects1)
// object values actually have different keys. This tests a bit more stuff.

const valuesForCategories: AnnotatedValue[][][] = [
[primitives, objects0, arrays, objects0InArrays],
[primitives, objects1, arrays, objects1InArrays],
[primitivesWithUnknown, objects0, arrays, objects0InArrays],
[primitivesWithUnknown, objects1, arrays, objects1InArrays],
]

const SCHEMA: [] = []
Expand Down
9 changes: 8 additions & 1 deletion test/evaluateQueryType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ const authorDocument = {
type: 'string',
},
},
age: {
type: 'objectAttribute',
value: {
type: 'number',
},
},
object: {
type: 'objectAttribute',
value: {
Expand Down Expand Up @@ -567,7 +573,7 @@ t.test('values in projection', (t) => {
"notEqualObject": 3 != {},
"plus": 3 + 2,
"plusStr": "3" + "2",
"plusVar": 3 + field,
"plusVar": 3 + age,
"minus": 3 - 2,
"mul": 3 * 3,
"div": 100 / 5,
Expand Down Expand Up @@ -650,6 +656,7 @@ t.test('values in projection', (t) => {
type: 'objectAttribute',
value: {
type: 'number',
value: undefined,
},
},
minus: {
Expand Down

0 comments on commit d83871c

Please sign in to comment.