1// Copyright 2019 CUE Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package ast_test 16 17import ( 18 "strings" 19 "testing" 20 21 "github.com/stretchr/testify/assert" 22 23 "cuelang.org/go/cue/ast" 24 "cuelang.org/go/cue/errors" 25 "cuelang.org/go/cue/format" 26 "cuelang.org/go/cue/token" 27) 28 29func TestLabelName(t *testing.T) { 30 testCases := []struct { 31 in ast.Label 32 out string 33 isIdent bool 34 err bool 35 expr bool 36 }{{ 37 in: ast.NewString("foo-bar"), 38 out: "foo-bar", 39 isIdent: false, 40 }, { 41 in: ast.NewString("8ball"), 42 out: "8ball", 43 isIdent: false, 44 }, { 45 in: ast.NewString("foo bar"), 46 out: "foo bar", 47 isIdent: false, 48 }, { 49 in: &ast.Ident{Name: "`foo`"}, 50 out: "foo", 51 isIdent: true, 52 }, { 53 in: &ast.Ident{Name: ""}, 54 out: "", 55 isIdent: false, 56 err: true, 57 }, { 58 in: &ast.Ident{Name: "#"}, 59 out: "#", 60 isIdent: true, 61 }, { 62 in: &ast.Ident{Name: "#0"}, 63 out: "", 64 isIdent: false, 65 err: true, 66 }, { 67 in: &ast.Ident{Name: "_#"}, 68 out: "_#", 69 isIdent: true, 70 err: false, 71 }, { 72 in: &ast.Ident{Name: "_"}, 73 out: "_", 74 isIdent: true, 75 }, { 76 in: &ast.Ident{Name: "8ball"}, 77 out: "", 78 isIdent: false, 79 err: true, 80 }, { 81 in: &ast.Ident{Name: "_hidden"}, 82 out: "_hidden", 83 isIdent: true, 84 }, { 85 in: &ast.Ident{Name: "#A"}, 86 out: "#A", 87 isIdent: true, 88 }, { 89 in: &ast.Ident{Name: "#Def"}, 90 out: "#Def", 91 isIdent: true, 92 }, { 93 in: &ast.Ident{Name: "_#Def"}, 94 out: "_#Def", 95 isIdent: true, 96 }, { 97 in: &ast.Ident{Name: "#_Def"}, 98 out: "#_Def", 99 isIdent: true, 100 }, { 101 in: &ast.Ident{Name: "`foo-bar`"}, 102 out: "foo-bar", 103 isIdent: true, 104 }, { 105 in: &ast.Ident{Name: "`foo-bar\x00`"}, 106 out: "", 107 isIdent: false, 108 err: true, 109 }, { 110 in: &ast.Ident{Name: "`foo-bar\x00`"}, 111 out: "", 112 isIdent: false, 113 err: true, 114 }, { 115 in: ast.NewBool(true), 116 out: "true", 117 isIdent: true, 118 }, { 119 in: &ast.BasicLit{Kind: token.STRING, Value: `"foo`}, 120 out: "", 121 isIdent: false, 122 err: true, 123 }, { 124 in: &ast.Interpolation{Elts: []ast.Expr{ast.NewString("foo")}}, 125 out: "", 126 isIdent: false, 127 err: true, 128 expr: true, 129 }} 130 for _, tc := range testCases { 131 b, _ := format.Node(tc.in) 132 t.Run(string(b), func(t *testing.T) { 133 if id, ok := tc.in.(*ast.Ident); ok && !strings.HasPrefix(id.Name, "`") { 134 assert.Equal(t, tc.isIdent, ast.IsValidIdent(id.Name)) 135 } 136 137 str, isIdent, err := ast.LabelName(tc.in) 138 assert.Equal(t, tc.out, str, "value") 139 assert.Equal(t, tc.isIdent, isIdent, "isIdent") 140 assert.Equal(t, tc.err, err != nil, "err") 141 assert.Equal(t, tc.expr, errors.Is(err, ast.ErrIsExpression), "expr") 142 }) 143 } 144} 145