Skip to content

Commit

Permalink
Add tests for search.Expression interface implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
dstotijn committed Mar 23, 2022
1 parent 02408b5 commit 0e9fb0a
Showing 1 changed file with 212 additions and 0 deletions.
212 changes: 212 additions & 0 deletions pkg/search/ast_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package search_test

import (
"regexp"
"testing"

"github.com/dstotijn/hetty/pkg/search"
)

func TestExpressionString(t *testing.T) {
t.Parallel()

tests := []struct {
name string
expression search.Expression
expected string
}{
{
name: "string literal expression",
expression: search.StringLiteral{Value: "foobar"},
expected: `"foobar"`,
},
{
name: "boolean expression with equal operator",
expression: search.InfixExpression{
Operator: search.TokOpEq,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
expected: `("foo" = "bar")`,
},
{
name: "boolean expression with not equal operator",
expression: search.InfixExpression{
Operator: search.TokOpNotEq,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
expected: `("foo" != "bar")`,
},
{
name: "boolean expression with greater than operator",
expression: search.InfixExpression{
Operator: search.TokOpGt,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
expected: `("foo" > "bar")`,
},
{
name: "boolean expression with less than operator",
expression: search.InfixExpression{
Operator: search.TokOpLt,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
expected: `("foo" < "bar")`,
},
{
name: "boolean expression with greater than or equal operator",
expression: search.InfixExpression{
Operator: search.TokOpGtEq,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
expected: `("foo" >= "bar")`,
},
{
name: "boolean expression with less than or equal operator",
expression: search.InfixExpression{
Operator: search.TokOpLtEq,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
expected: `("foo" <= "bar")`,
},
{
name: "boolean expression with regular expression operator",
expression: search.InfixExpression{
Operator: search.TokOpRe,
Left: search.StringLiteral{Value: "foo"},
Right: search.RegexpLiteral{regexp.MustCompile("bar")},
},
expected: `("foo" =~ "bar")`,
},
{
name: "boolean expression with not regular expression operator",
expression: search.InfixExpression{
Operator: search.TokOpNotRe,
Left: search.StringLiteral{Value: "foo"},
Right: search.RegexpLiteral{regexp.MustCompile("bar")},
},
expected: `("foo" !~ "bar")`,
},
{
name: "boolean expression with AND, OR and NOT operators",
expression: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.StringLiteral{Value: "foo"},
Right: search.InfixExpression{
Operator: search.TokOpOr,
Left: search.StringLiteral{Value: "bar"},
Right: search.PrefixExpression{
Operator: search.TokOpNot,
Right: search.StringLiteral{Value: "baz"},
},
},
},
expected: `("foo" AND ("bar" OR (NOT "baz")))`,
},
{
name: "boolean expression with nested group",
expression: search.InfixExpression{
Operator: search.TokOpOr,
Left: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
Right: search.PrefixExpression{
Operator: search.TokOpNot,
Right: search.StringLiteral{Value: "baz"},
},
},
expected: `(("foo" AND "bar") OR (NOT "baz"))`,
},
{
name: "implicit boolean expression with string literal operands",
expression: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
Right: search.StringLiteral{Value: "baz"},
},
expected: `(("foo" AND "bar") AND "baz")`,
},
{
name: "implicit boolean expression nested in group",
expression: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
expected: `("foo" AND "bar")`,
},
{
name: "implicit and explicit boolean expression with string literal operands",
expression: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.StringLiteral{Value: "foo"},
Right: search.InfixExpression{
Operator: search.TokOpOr,
Left: search.StringLiteral{Value: "bar"},
Right: search.StringLiteral{Value: "baz"},
},
},
Right: search.StringLiteral{Value: "yolo"},
},
expected: `(("foo" AND ("bar" OR "baz")) AND "yolo")`,
},
{
name: "implicit boolean expression with comparison operands",
expression: search.InfixExpression{
Operator: search.TokOpAnd,
Left: search.InfixExpression{
Operator: search.TokOpEq,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
Right: search.InfixExpression{
Operator: search.TokOpRe,
Left: search.StringLiteral{Value: "baz"},
Right: search.RegexpLiteral{regexp.MustCompile("yolo")},
},
},
expected: `(("foo" = "bar") AND ("baz" =~ "yolo"))`,
},
{
name: "eq operator takes precedence over boolean ops",
expression: search.InfixExpression{
Operator: search.TokOpOr,
Left: search.InfixExpression{
Operator: search.TokOpEq,
Left: search.StringLiteral{Value: "foo"},
Right: search.StringLiteral{Value: "bar"},
},
Right: search.InfixExpression{
Operator: search.TokOpEq,
Left: search.StringLiteral{Value: "baz"},
Right: search.StringLiteral{Value: "yolo"},
},
},
expected: `(("foo" = "bar") OR ("baz" = "yolo"))`,
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := tt.expression.String()
if tt.expected != got {
t.Errorf("expected: %v, got: %v", tt.expected, got)
}
})
}
}

0 comments on commit 0e9fb0a

Please sign in to comment.