github.com/aristanetworks/goarista@v0.0.0-20240514173732-cca2755bbd44/key/path_test.go (about) 1 // Copyright (c) 2018 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 package key_test 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "testing" 11 "unicode/utf8" 12 13 "github.com/aristanetworks/goarista/key" 14 "github.com/aristanetworks/goarista/path" 15 ) 16 17 func TestPath(t *testing.T) { 18 expected := path.New("leet") 19 k := key.New(expected) 20 21 keyPath, ok := k.Key().(key.Path) 22 if !ok { 23 t.Fatalf("key.Key() did not return a key.Path") 24 } 25 if !path.Equal(keyPath, expected) { 26 t.Errorf("expected path from key is %#v, got %#v", expected, keyPath) 27 } 28 29 if expected, actual := "/leet", fmt.Sprint(k); actual != expected { 30 t.Errorf("expected string from path key %q, got %q", expected, actual) 31 } 32 33 if js, err := json.Marshal(k); err != nil { 34 t.Errorf("JSON marshalling error: %v", err) 35 } else if expected, actual := `{"_path":"/leet"}`, string(js); actual != expected { 36 t.Errorf("expected json output %q, got %q", expected, actual) 37 } 38 } 39 40 func newPathKey(e ...interface{}) key.Key { 41 return key.New(path.New(e...)) 42 } 43 44 type customPath string 45 46 func (p customPath) Key() interface{} { 47 return path.FromString(string(p)) 48 } 49 50 func (p customPath) Equal(other interface{}) bool { 51 o, ok := other.(key.Key) 52 return ok && o.Equal(p) 53 } 54 55 func (p customPath) String() string { return string(p) } 56 func (p customPath) ToBuiltin() interface{} { panic("not impl") } 57 func (p customPath) MarshalJSON() ([]byte, error) { panic("not impl") } 58 59 func TestPathEqual(t *testing.T) { 60 tests := []struct { 61 a key.Key 62 b key.Key 63 result bool 64 }{{ 65 a: newPathKey(), 66 b: nil, 67 result: false, 68 }, { 69 a: newPathKey(), 70 b: newPathKey(), 71 result: true, 72 }, { 73 a: newPathKey(), 74 b: newPathKey("foo"), 75 result: false, 76 }, { 77 a: newPathKey("foo"), 78 b: newPathKey(), 79 result: false, 80 }, { 81 a: newPathKey(int16(1337)), 82 b: newPathKey(int64(1337)), 83 result: false, 84 }, { 85 a: newPathKey(path.Wildcard, "bar"), 86 b: newPathKey("foo", path.Wildcard), 87 result: false, 88 }, { 89 a: newPathKey(map[string]interface{}{"a": "x", "b": "y"}), 90 b: newPathKey(map[string]interface{}{"b": "y", "a": "x"}), 91 result: true, 92 }, { 93 a: newPathKey(map[string]interface{}{"a": "x", "b": "y"}), 94 b: newPathKey(map[string]interface{}{"x": "x", "y": "y"}), 95 result: false, 96 }, { 97 a: newPathKey("foo", "bar"), 98 b: customPath("/foo/bar"), 99 result: true, 100 }, { 101 a: customPath("/foo/bar"), 102 b: newPathKey("foo", "bar"), 103 result: true, 104 }, { 105 a: newPathKey("foo"), 106 b: key.New(customPath("/bar")), 107 result: false, 108 }, { 109 a: key.New(customPath("/foo")), 110 b: newPathKey("foo", "bar"), 111 result: false, 112 }} 113 114 for i, tc := range tests { 115 if a, b := tc.a, tc.b; a.Equal(b) != tc.result { 116 t.Errorf("result not as expected for test case %d", i) 117 } 118 } 119 } 120 121 func TestPathAsKey(t *testing.T) { 122 a := newPathKey("foo", path.Wildcard, map[string]interface{}{ 123 "bar": key.NewMap( 124 // Should be able to embed a path key and value 125 newPathKey("path", "to", "something"), path.New("else")), 126 }) 127 m := key.NewMap(a, "thats a complex key!") 128 if s, ok := m.Get(a); !ok { 129 t.Error("complex key not found in map") 130 } else if s != "thats a complex key!" { 131 t.Errorf("incorrect value in map: %s", s) 132 } 133 134 // preserve custom path implementations 135 b := key.New(customPath("/foo/bar")) 136 if _, ok := b.Key().(customPath); !ok { 137 t.Errorf("customPath implementation not preserved: %T", b.Key()) 138 } 139 } 140 141 func TestInvalidUTF8(t *testing.T) { 142 bytesAsString := string([]byte{0xFF, 0xFF, 0xFF, 0xFF}) 143 if utf8.ValidString(bytesAsString) { 144 t.Fatalf("expected %q to be invalid utf8", bytesAsString) 145 } 146 p := key.Path{key.New(bytesAsString)} 147 pathString := p.String() 148 if !utf8.ValidString(pathString) { 149 t.Errorf("expected %q to be valid utf8", pathString) 150 } 151 } 152 153 var pathStr string 154 155 func BenchmarkPathString(b *testing.B) { 156 p := path.New("foo", "bar", "baz", "qux", "corge", "grault", "garply", "waldo", "fred") 157 b.ReportAllocs() 158 b.ResetTimer() 159 for i := 0; i < b.N; i++ { 160 pathStr = p.String() 161 } 162 }