//go:build go1.7 // +build go1.7 package expression import ( "reflect" "strings" "testing" ) // projErrorMode will help with error cases and checking error types type projErrorMode string const ( noProjError projErrorMode = "" // invalidProjectionOperand error will occur when an invalid OperandBuilder is // used as an argument invalidProjectionOperand = "BuildOperand error" // unsetProjection error will occur if the argument ProjectionBuilder is unset unsetProjection = "unset parameter: ProjectionBuilder" ) func TestProjectionBuilder(t *testing.T) { cases := []struct { name string input ProjectionBuilder expectedNode exprNode err projErrorMode }{ { name: "names list function call", input: NamesList(Name("foo"), Name("bar")), expectedNode: exprNode{ children: []exprNode{ { names: []string{"foo"}, fmtExpr: "$n", }, { names: []string{"bar"}, fmtExpr: "$n", }, }, fmtExpr: "$c, $c", }, }, { name: "names list method call", input: Name("foo").NamesList(Name("bar")), expectedNode: exprNode{ children: []exprNode{ { names: []string{"foo"}, fmtExpr: "$n", }, { names: []string{"bar"}, fmtExpr: "$n", }, }, fmtExpr: "$c, $c", }, }, { name: "add name", input: Name("foo").NamesList(Name("bar")).AddNames(Name("baz"), Name("qux")), expectedNode: exprNode{ children: []exprNode{ { names: []string{"foo"}, fmtExpr: "$n", }, { names: []string{"bar"}, fmtExpr: "$n", }, { names: []string{"baz"}, fmtExpr: "$n", }, { names: []string{"qux"}, fmtExpr: "$n", }, }, fmtExpr: "$c, $c, $c, $c", }, }, { name: "invalid operand", input: NamesList(Name("")), err: invalidProjectionOperand, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { actual, err := c.input.buildTree() if c.err != noProjError { if err == nil { t.Errorf("expect error %q, got no error", c.err) } else { if e, a := string(c.err), err.Error(); !strings.Contains(a, e) { t.Errorf("expect %q error message to be in %q", e, a) } } } else { if err != nil { t.Errorf("expect no error, got unexpected Error %q", err) } if e, a := c.expectedNode, actual; !reflect.DeepEqual(a, e) { t.Errorf("expect %v, got %v", e, a) } } }) } } func TestBuildProjection(t *testing.T) { cases := []struct { name string input ProjectionBuilder expected string err projErrorMode }{ { name: "build projection 3", input: NamesList(Name("foo"), Name("bar"), Name("baz")), expected: "$c, $c, $c", }, { name: "build projection 5", input: NamesList(Name("foo"), Name("bar"), Name("baz")).AddNames(Name("qux"), Name("quux")), expected: "$c, $c, $c, $c, $c", }, { name: "empty ProjectionBuilder", input: ProjectionBuilder{}, err: unsetProjection, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { actual, err := c.input.buildTree() if c.err != noProjError { if err == nil { t.Errorf("expect error %q, got no error", c.err) } else { if e, a := string(c.err), err.Error(); !strings.Contains(a, e) { t.Errorf("expect %q error message to be in %q", e, a) } } } else { if err != nil { t.Errorf("expect no error, got unexpected Error %q", err) } if e, a := c.expected, actual.fmtExpr; !reflect.DeepEqual(a, e) { t.Errorf("expect %v, got %v", e, a) } } }) } } func TestBuildProjectionChildNodes(t *testing.T) { cases := []struct { name string input ProjectionBuilder expected []exprNode err projErrorMode }{ { name: "build child nodes", input: NamesList(Name("foo"), Name("bar"), Name("baz")), expected: []exprNode{ { names: []string{"foo"}, fmtExpr: "$n", }, { names: []string{"bar"}, fmtExpr: "$n", }, { names: []string{"baz"}, fmtExpr: "$n", }, }, }, { name: "operand error", input: NamesList(Name("")), err: invalidProjectionOperand, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { actual, err := c.input.buildTree() if c.err != noProjError { if err == nil { t.Errorf("expect error %q, got no error", c.err) } else { if e, a := string(c.err), err.Error(); !strings.Contains(a, e) { t.Errorf("expect %q error message to be in %q", e, a) } } } else { if err != nil { t.Errorf("expect no error, got unexpected Error %q", err) } if e, a := c.expected, actual.children; !reflect.DeepEqual(a, e) { t.Errorf("expect %v, got %v", e, a) } } }) } }