1// +build go1.7 2 3package expression 4 5import ( 6 "reflect" 7 "strings" 8 "testing" 9 10 "github.com/aws/aws-sdk-go/aws" 11 "github.com/aws/aws-sdk-go/service/dynamodb" 12) 13 14// opeErrorMode will help with error cases and checking error types 15type opeErrorMode string 16 17const ( 18 noOperandError opeErrorMode = "" 19 // unsetName error will occur if an empty string is passed into NameBuilder 20 unsetName = "unset parameter: NameBuilder" 21 // invalidName error will occur if a nested name has an empty intermediary 22 // attribute name (i.e. foo.bar..baz) 23 invalidName = "invalid parameter: NameBuilder" 24 // unsetKey error will occur if an empty string is passed into KeyBuilder 25 unsetKey = "unset parameter: KeyBuilder" 26) 27 28func TestBuildOperand(t *testing.T) { 29 cases := []struct { 30 name string 31 input OperandBuilder 32 expected exprNode 33 err opeErrorMode 34 }{ 35 { 36 name: "basic name", 37 input: Name("foo"), 38 expected: exprNode{ 39 names: []string{"foo"}, 40 fmtExpr: "$n", 41 }, 42 }, 43 { 44 name: "duplicate name name", 45 input: Name("foo.foo"), 46 expected: exprNode{ 47 names: []string{"foo", "foo"}, 48 fmtExpr: "$n.$n", 49 }, 50 }, 51 { 52 name: "basic value", 53 input: Value(5), 54 expected: exprNode{ 55 values: []dynamodb.AttributeValue{ 56 { 57 N: aws.String("5"), 58 }, 59 }, 60 fmtExpr: "$v", 61 }, 62 }, 63 { 64 name: "nested name", 65 input: Name("foo.bar"), 66 expected: exprNode{ 67 names: []string{"foo", "bar"}, 68 fmtExpr: "$n.$n", 69 }, 70 }, 71 { 72 name: "nested name with index", 73 input: Name("foo.bar[0].baz"), 74 expected: exprNode{ 75 names: []string{"foo", "bar", "baz"}, 76 fmtExpr: "$n.$n[0].$n", 77 }, 78 }, 79 { 80 name: "basic size", 81 input: Name("foo").Size(), 82 expected: exprNode{ 83 names: []string{"foo"}, 84 fmtExpr: "size ($n)", 85 }, 86 }, 87 { 88 name: "key", 89 input: Key("foo"), 90 expected: exprNode{ 91 names: []string{"foo"}, 92 fmtExpr: "$n", 93 }, 94 }, 95 { 96 name: "unset key error", 97 input: Key(""), 98 expected: exprNode{}, 99 err: unsetKey, 100 }, 101 { 102 name: "empty name error", 103 input: Name(""), 104 expected: exprNode{}, 105 err: unsetName, 106 }, 107 { 108 name: "invalid name", 109 input: Name("foo..bar"), 110 expected: exprNode{}, 111 err: invalidName, 112 }, 113 { 114 name: "invalid index", 115 input: Name("[foo]"), 116 expected: exprNode{}, 117 err: invalidName, 118 }, 119 } 120 121 for _, c := range cases { 122 t.Run(c.name, func(t *testing.T) { 123 operand, err := c.input.BuildOperand() 124 125 if c.err != noOperandError { 126 if err == nil { 127 t.Errorf("expect error %q, got no error", c.err) 128 } else { 129 if e, a := string(c.err), err.Error(); !strings.Contains(a, e) { 130 t.Errorf("expect %q error message to be in %q", e, a) 131 } 132 } 133 } else { 134 if err != nil { 135 t.Errorf("expect no error, got unexpected Error %q", err) 136 } 137 138 if e, a := c.expected, operand.exprNode; !reflect.DeepEqual(a, e) { 139 t.Errorf("expect %v, got %v", e, a) 140 } 141 } 142 }) 143 } 144} 145