mirror of
https://github.com/dstotijn/hetty.git
synced 2025-07-01 10:37:30 -04:00
213 lines
6.1 KiB
Go
213 lines
6.1 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|
|
}
|