trpc.group/trpc-go/trpc-go@v1.0.3/internal/dat/dat_internal_test.go (about)

     1  //
     2  //
     3  // Tencent is pleased to support the open source community by making tRPC available.
     4  //
     5  // Copyright (C) 2023 THL A29 Limited, a Tencent company.
     6  // All rights reserved.
     7  //
     8  // If you have downloaded a copy of the tRPC source code from Tencent,
     9  // please note that tRPC source code is licensed under the  Apache 2.0 License,
    10  // A copy of the Apache 2.0 License is included in this file.
    11  //
    12  //
    13  
    14  package dat
    15  
    16  import (
    17  	"reflect"
    18  	"testing"
    19  )
    20  
    21  func Test_newFieldDict(t *testing.T) {
    22  	tests := []struct {
    23  		name string
    24  		fps  fieldPaths
    25  		want fieldDict
    26  	}{
    27  		{"nil", nil, fieldDict{}},
    28  		{"empty paths", [][]string{}, fieldDict{}},
    29  		{"one path with unique fields", [][]string{{"bb", "cc", "aa"}}, fieldDict{"aa": 0, "bb": 1, "cc": 2}},
    30  		{"one path with duplicated fields", [][]string{{"aa", "aa", "aa"}}, fieldDict{"aa": 0}},
    31  		{
    32  			"multiple paths with unique fields",
    33  			[][]string{
    34  				{"acb", "cab"},
    35  				{"abc", "bac"},
    36  				{"bca", "cba"},
    37  			},
    38  			fieldDict{
    39  				"abc": 0,
    40  				"acb": 1,
    41  				"bac": 2,
    42  				"bca": 3,
    43  				"cab": 4,
    44  				"cba": 5,
    45  			},
    46  		},
    47  		{
    48  			"multiple paths with duplicated fields: case 1",
    49  			[][]string{
    50  				{"acb", "bca"},
    51  				{"abc", "bac"},
    52  				{"bca", "cba"},
    53  			},
    54  			fieldDict{
    55  				"abc": 0,
    56  				"acb": 1,
    57  				"bac": 2,
    58  				"bca": 3,
    59  				"cba": 4,
    60  			},
    61  		},
    62  		{
    63  			"multiple paths with duplicated fields: case 2",
    64  			[][]string{
    65  				{"baz"},
    66  				{"foobar", "foo"},
    67  				{"foobar", "bar"},
    68  				{"foobar", "baz", "baz"},
    69  				{"foo", "bar", "baz", "qux"},
    70  			},
    71  			fieldDict{
    72  				"bar":    0,
    73  				"baz":    1,
    74  				"foo":    2,
    75  				"foobar": 3,
    76  				"qux":    4,
    77  			},
    78  		},
    79  	}
    80  	for _, tt := range tests {
    81  		t.Run(tt.name, func(t *testing.T) {
    82  			if got := newFieldDict(tt.fps); !reflect.DeepEqual(got, tt.want) {
    83  				t.Errorf("newFieldDict() = %v, want %v", got, tt.want)
    84  			}
    85  		})
    86  	}
    87  }
    88  
    89  func TestDoubleArrayTrie_fetch(t *testing.T) {
    90  	var fps = [][]string{
    91  		{"baz"},
    92  		{"foobar", "foo"},
    93  		{"foobar", "bar"},
    94  		{"foobar", "baz", "baz"},
    95  		{"foo", "bar", "baz", "qux"},
    96  	}
    97  	// trie:
    98  	//     (*root)
    99  	//    /   |    \
   100  	//  baz  foo    foobar
   101  	//        |    /   |  \
   102  	//       bar  bar baz foo
   103  	//        |        |
   104  	//       baz 	  baz
   105  	//        |
   106  	//       qux
   107  	// ------------------------------
   108  	//       (*0)
   109  	//    /   |   \
   110  	//   2    3     4
   111  	//        |   /  |  \
   112  	//        1  1   2   3
   113  	//        |      |
   114  	//        2 	 2
   115  	//        |
   116  	//        5
   117  	dat := mustBuild(t, fps)
   118  	tests := []struct {
   119  		name    string
   120  		parent  *node
   121  		want    []*node
   122  		wantErr bool
   123  	}{
   124  		{
   125  			"root",
   126  			&node{left: 0, right: len(dat.fps), depth: 0},
   127  			[]*node{
   128  				{code: 2, left: 0, right: 1, depth: 1},
   129  				{code: 3, left: 1, right: 2, depth: 1},
   130  				{code: 4, left: 2, right: 5, depth: 1}},
   131  			false,
   132  		},
   133  		{
   134  			"internal node-baz",
   135  			&node{left: 1, right: 2, depth: 2},
   136  			[]*node{
   137  				{code: 2, left: 1, right: 2, depth: 3},
   138  			},
   139  			false,
   140  		},
   141  		{
   142  			"leaf-qux",
   143  			&node{left: 1, right: 2, depth: 3},
   144  			[]*node{
   145  				{code: 5, left: 1, right: 2, depth: 4},
   146  			},
   147  			false,
   148  		},
   149  	}
   150  	for _, tt := range tests {
   151  		t.Run(tt.name, func(t *testing.T) {
   152  			got, err := dat.fetch(tt.parent)
   153  			if (err != nil) != tt.wantErr {
   154  				t.Errorf("fetch() error = %v, wantErr %v", err, tt.wantErr)
   155  				return
   156  			}
   157  			for _, item := range got {
   158  				t.Log(item.code, item.left, item.right, item.depth)
   159  			}
   160  			if !reflect.DeepEqual(got, tt.want) {
   161  				t.Errorf("fetch() got = %v, want %v", got, tt.want)
   162  			}
   163  		})
   164  	}
   165  }
   166  
   167  func mustBuild(t *testing.T, fps [][]string) *DoubleArrayTrie {
   168  	t.Helper()
   169  	trie, err := Build(fps)
   170  	if err != nil {
   171  		t.Fatalf("could not build DoubleArrayTrie under test: %v", err)
   172  	}
   173  	return trie
   174  }