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  }