go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/proto/structmask/parse_test.go (about) 1 // Copyright 2021 The LUCI 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 15 package structmask 16 17 import ( 18 "testing" 19 20 . "github.com/smartystreets/goconvey/convey" 21 . "go.chromium.org/luci/common/testing/assertions" 22 ) 23 24 func TestParseElement(t *testing.T) { 25 t.Parallel() 26 27 Convey("Field", t, func() { 28 elem, err := parseElement("abc.def") 29 So(err, ShouldBeNil) 30 So(elem, ShouldResemble, fieldElement{"abc.def"}) 31 32 elem, err = parseElement("abc.de\"f") 33 So(err, ShouldBeNil) 34 So(elem, ShouldResemble, fieldElement{"abc.de\"f"}) 35 36 elem, err = parseElement("\"abc.def\"") 37 So(err, ShouldBeNil) 38 So(elem, ShouldResemble, fieldElement{"abc.def"}) 39 40 elem, err = parseElement("'a'") 41 So(err, ShouldBeNil) 42 So(elem, ShouldResemble, fieldElement{"a"}) 43 44 elem, err = parseElement("\"*\"") 45 So(err, ShouldBeNil) 46 So(elem, ShouldResemble, fieldElement{"*"}) 47 48 elem, err = parseElement("\"10\"") 49 So(err, ShouldBeNil) 50 So(elem, ShouldResemble, fieldElement{"10"}) 51 52 elem, err = parseElement("`'`") 53 So(err, ShouldBeNil) 54 So(elem, ShouldResemble, fieldElement{"'"}) 55 56 elem, err = parseElement("") 57 So(err, ShouldBeNil) 58 So(elem, ShouldResemble, fieldElement{""}) 59 60 elem, err = parseElement("/") 61 So(err, ShouldBeNil) 62 So(elem, ShouldResemble, fieldElement{"/"}) 63 64 _, err = parseElement("'not closed") 65 So(err, ShouldErrLike, `bad quoted string`) 66 }) 67 68 Convey("Index", t, func() { 69 elem, err := parseElement("0") 70 So(err, ShouldBeNil) 71 So(elem, ShouldResemble, indexElement{0}) 72 73 elem, err = parseElement("+10") 74 So(err, ShouldBeNil) 75 So(elem, ShouldResemble, indexElement{10}) 76 77 _, err = parseElement("10.0") 78 So(err, ShouldErrLike, `an index must be a non-negative integer`) 79 80 _, err = parseElement("-10") 81 So(err, ShouldErrLike, `an index must be a non-negative integer`) 82 }) 83 84 Convey("Star", t, func() { 85 elem, err := parseElement("*") 86 So(err, ShouldBeNil) 87 So(elem, ShouldResemble, starElement{}) 88 89 _, err = parseElement("p*") 90 So(err, ShouldErrLike, `prefix and suffix matches are not supported`) 91 }) 92 93 Convey("/.../", t, func() { 94 _, err := parseElement("//") 95 So(err, ShouldErrLike, `regexp matches are not supported`) 96 }) 97 } 98 99 func TestParseMask(t *testing.T) { 100 t.Parallel() 101 102 Convey("OK", t, func() { 103 filter, err := NewFilter([]*StructMask{ 104 {Path: []string{"a", "b1", "c"}}, 105 {Path: []string{"a", "*", "d"}}, 106 }) 107 So(err, ShouldBeNil) 108 So(filter, ShouldNotBeNil) 109 }) 110 111 Convey("Bad selector", t, func() { 112 _, err := NewFilter([]*StructMask{ 113 {Path: []string{"*", "-10"}}, 114 }) 115 So(err, ShouldErrLike, `bad element "-10" in the mask ["*","-10"]`) 116 }) 117 118 Convey("Empty mask", t, func() { 119 _, err := NewFilter([]*StructMask{ 120 {Path: []string{"a", "b1", "c"}}, 121 {Path: []string{}}, 122 }) 123 So(err, ShouldErrLike, "bad empty mask") 124 }) 125 126 Convey("Index selector ", t, func() { 127 _, err := NewFilter([]*StructMask{ 128 {Path: []string{"a", "1", "*"}}, 129 }) 130 So(err, ShouldErrLike, "individual index selectors are not supported") 131 }) 132 }