github.com/aristanetworks/goarista@v0.0.0-20240514173732-cca2755bbd44/key/pointer_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  
    12  	"github.com/aristanetworks/goarista/key"
    13  	"github.com/aristanetworks/goarista/path"
    14  )
    15  
    16  func TestPointer(t *testing.T) {
    17  	p := key.NewPointer(path.New("foo"))
    18  	if expected, actual := path.New("foo"), p.Pointer(); !path.Equal(expected, actual) {
    19  		t.Errorf("Expected %#v but got %#v", expected, actual)
    20  	}
    21  	if expected, actual := "{/foo}", fmt.Sprintf("%s", p); actual != expected {
    22  		t.Errorf("Expected %q but got %q", expected, actual)
    23  	}
    24  	if js, err := json.Marshal(p); err != nil {
    25  		t.Errorf("JSON marshaling failed: %s", err)
    26  	} else if expected, actual := `{"_ptr":"/foo"}`, string(js); actual != expected {
    27  		t.Errorf("Expected %q but got %q", expected, actual)
    28  	}
    29  }
    30  
    31  type pointer string
    32  
    33  func (ptr pointer) Pointer() key.Path {
    34  	return path.FromString(string(ptr))
    35  }
    36  
    37  func (ptr pointer) ToBuiltin() interface{} {
    38  	panic("NOT IMPLEMENTED")
    39  }
    40  
    41  func (ptr pointer) String() string {
    42  	panic("NOT IMPLEMENTED")
    43  }
    44  
    45  func (ptr pointer) MarshalJSON() ([]byte, error) {
    46  	panic("NOT IMPLEMENTED")
    47  }
    48  
    49  func TestPointerEqual(t *testing.T) {
    50  	tests := []struct {
    51  		a      key.Pointer
    52  		b      key.Pointer
    53  		result bool
    54  	}{{
    55  		a:      key.NewPointer(nil),
    56  		b:      key.NewPointer(path.New()),
    57  		result: true,
    58  	}, {
    59  		a:      key.NewPointer(path.New()),
    60  		b:      key.NewPointer(nil),
    61  		result: true,
    62  	}, {
    63  		a:      key.NewPointer(path.New("foo")),
    64  		b:      key.NewPointer(path.New("foo")),
    65  		result: true,
    66  	}, {
    67  		a:      key.NewPointer(path.New("foo")),
    68  		b:      key.NewPointer(path.New("bar")),
    69  		result: false,
    70  	}, {
    71  		a:      key.NewPointer(path.New(true)),
    72  		b:      key.NewPointer(path.New("true")),
    73  		result: false,
    74  	}, {
    75  		a:      key.NewPointer(path.New(int8(0))),
    76  		b:      key.NewPointer(path.New(int16(0))),
    77  		result: false,
    78  	}, {
    79  		a:      key.NewPointer(path.New(path.Wildcard, "bar")),
    80  		b:      key.NewPointer(path.New("foo", path.Wildcard)),
    81  		result: false,
    82  	}, {
    83  		a:      key.NewPointer(path.New(map[string]interface{}{"a": "x", "b": "y"})),
    84  		b:      key.NewPointer(path.New(map[string]interface{}{"b": "y", "a": "x"})),
    85  		result: true,
    86  	}, {
    87  		a:      key.NewPointer(path.New(map[string]interface{}{"a": "x", "b": "y"})),
    88  		b:      key.NewPointer(path.New(map[string]interface{}{"x": "x", "y": "y"})),
    89  		result: false,
    90  	}, {
    91  		a:      key.NewPointer(path.New("foo")),
    92  		b:      pointer("/foo"),
    93  		result: true,
    94  	}, {
    95  		a:      pointer("/foo"),
    96  		b:      key.NewPointer(path.New("foo")),
    97  		result: true,
    98  	}, {
    99  		a:      key.NewPointer(path.New("foo")),
   100  		b:      pointer("/foo/bar"),
   101  		result: false,
   102  	}, {
   103  		a:      pointer("/foo/bar"),
   104  		b:      key.NewPointer(path.New("foo")),
   105  		result: false,
   106  	}}
   107  
   108  	for i, tcase := range tests {
   109  		if key.New(tcase.a).Equal(key.New(tcase.b)) != tcase.result {
   110  			t.Errorf("Error in pointer comparison for test %d", i)
   111  		}
   112  	}
   113  }
   114  
   115  func TestPointerAsKey(t *testing.T) {
   116  	a := key.NewPointer(path.New("foo", path.Wildcard, map[string]interface{}{
   117  		"bar": key.NewMap(
   118  			// Should be able to embed pointer key.
   119  			key.New(key.NewPointer(path.New("baz"))),
   120  			// Should be able to embed pointer value.
   121  			key.NewPointer(path.New("baz"))),
   122  	}))
   123  	m := key.NewMap(key.New(a), "a")
   124  	if s, ok := m.Get(key.New(a)); !ok {
   125  		t.Error("pointer to path not keyed in map")
   126  	} else if s != "a" {
   127  		t.Errorf("pointer to path not mapped to correct value in map: %s", s)
   128  	}
   129  
   130  	// Ensure that we preserve custom pointer implementations.
   131  	b := key.New(pointer("/foo/bar"))
   132  	if _, ok := b.Key().(pointer); !ok {
   133  		t.Errorf("pointer implementation not preserved: %T", b.Key())
   134  	}
   135  }
   136  
   137  func BenchmarkPointer(b *testing.B) {
   138  	benchmarks := []key.Path{
   139  		path.New(),
   140  		path.New("foo"),
   141  		path.New("foo", "bar"),
   142  		path.New("foo", "bar", "baz"),
   143  		path.New("foo", "bar", "baz", "qux"),
   144  	}
   145  	for i, benchmark := range benchmarks {
   146  		b.Run(fmt.Sprintf("%d", i), func(b *testing.B) {
   147  			for i := 0; i < b.N; i++ {
   148  				key.NewPointer(benchmark)
   149  			}
   150  		})
   151  	}
   152  }
   153  
   154  func BenchmarkPointerAsKey(b *testing.B) {
   155  	benchmarks := []key.Pointer{
   156  		key.NewPointer(path.New()),
   157  		key.NewPointer(path.New("foo")),
   158  		key.NewPointer(path.New("foo", "bar")),
   159  		key.NewPointer(path.New("foo", "bar", "baz")),
   160  		key.NewPointer(path.New("foo", "bar", "baz", "qux")),
   161  	}
   162  	for i, benchmark := range benchmarks {
   163  		b.Run(fmt.Sprintf("%d", i), func(b *testing.B) {
   164  			for i := 0; i < b.N; i++ {
   165  				key.New(benchmark)
   166  			}
   167  		})
   168  	}
   169  }
   170  
   171  func BenchmarkEmbeddedPointerAsKey(b *testing.B) {
   172  	benchmarks := [][]interface{}{
   173  		[]interface{}{key.NewPointer(path.New())},
   174  		[]interface{}{key.NewPointer(path.New("foo"))},
   175  		[]interface{}{key.NewPointer(path.New("foo", "bar"))},
   176  		[]interface{}{key.NewPointer(path.New("foo", "bar", "baz"))},
   177  		[]interface{}{key.NewPointer(path.New("foo", "bar", "baz", "qux"))},
   178  	}
   179  	for i, benchmark := range benchmarks {
   180  		b.Run(fmt.Sprintf("%d", i), func(b *testing.B) {
   181  			for i := 0; i < b.N; i++ {
   182  				key.New(benchmark)
   183  			}
   184  		})
   185  	}
   186  }