github.com/go-ego/cedar@v0.10.2/cedar_test.go (about) 1 package cedar 2 3 import ( 4 "fmt" 5 "log" 6 "os" 7 "testing" 8 ) 9 10 var ( 11 cd *Cedar 12 13 words = []string{ 14 "a", "aa", "ab", "ac", "abc", "abd", 15 "abcd", "abde", "abdf", "abcdef", "abcde", 16 "abcdefghijklmn", "bcd", "b", "xyz", 17 "太阳系", "太阳系土星", "太阳系水星", "太阳系火星", 18 "新星", "新星文明", "新星军团", "新星联邦共和国", 19 "this", "this is", "this is a sentence.", 20 } 21 ) 22 23 func loadTestData() { 24 if cd != nil { 25 return 26 } 27 cd = New() 28 // cd.Ordered = false 29 30 // add the keys 31 for i, word := range words { 32 if err := cd.Insert([]byte(word), i); err != nil { 33 panic(err) 34 } 35 } 36 37 for _, word := range words { 38 if err := cd.Delete([]byte(word)); err != nil { 39 panic(err) 40 } 41 } 42 43 for i, word := range words { 44 if err := cd.Update([]byte(word), i); err != nil { 45 panic(err) 46 } 47 } 48 49 // delete some keys 50 for i := 0; i < len(words); i += 4 { 51 if err := cd.Delete([]byte(words[i])); err != nil { 52 panic(err) 53 } 54 } 55 return 56 } 57 58 func check(cd *Cedar, ids []int, keys []string, values []int) { 59 if len(ids) != len(keys) { 60 log.Panicf("wrong prefix match: %d, %d", len(ids), len(keys)) 61 } 62 63 for i, n := range ids { 64 key, _ := cd.Key(n) 65 val, _ := cd.Value(n) 66 if string(key) != keys[i] || val != values[i] { 67 log.Printf("key: %v, value: %v; val:%v, values:%v", 68 string(key), keys[i], val, values[i]) 69 70 log.Panicf("wrong prefix match: %v, %v", 71 string(key) != keys[i], val != values[i]) 72 } 73 } 74 } 75 76 func checkConsistency(cd *Cedar) { 77 for i, word := range words { 78 id, err := cd.Jump([]byte(word), 0) 79 if i%4 == 0 { 80 if err == ErrNoPath { 81 continue 82 } 83 84 _, err := cd.Value(id) 85 if err == ErrNoValue { 86 continue 87 } 88 panic("not deleted") 89 } 90 91 key, err := cd.Key(id) 92 if err != nil { 93 panic(err) 94 } 95 96 if string(key) != word { 97 panic("key error") 98 } 99 100 value, err := cd.Value(id) 101 if err != nil || value != i { 102 fmt.Println(word, i, value, err) 103 panic("value error") 104 } 105 } 106 } 107 108 func TestBasic(t *testing.T) { 109 loadTestData() 110 // check the consistency 111 checkConsistency(cd) 112 } 113 114 func TestSaveAndLoad(t *testing.T) { 115 loadTestData() 116 117 cd.SaveToFile("cedar.gob", "gob") 118 defer os.Remove("cedar.gob") 119 120 daGob := New() 121 if err := daGob.LoadFromFile("cedar.gob", "gob"); err != nil { 122 panic(err) 123 } 124 checkConsistency(daGob) 125 126 cd.SaveToFile("cedar.json", "json") 127 defer os.Remove("cedar.json") 128 129 daJson := New() 130 if err := daJson.LoadFromFile("cedar.json", "json"); err != nil { 131 panic(err) 132 } 133 checkConsistency(daJson) 134 } 135 136 func TestPrefixMatch(t *testing.T) { 137 var ( 138 ids, values []int 139 keys []string 140 ) 141 142 ids = cd.PrefixMatch([]byte("abcdefg"), 0) 143 keys = []string{"ab", "abcd", "abcde", "abcdef"} 144 values = []int{2, 6, 10, 9} 145 check(cd, ids, keys, values) 146 147 ids = cd.PrefixMatch([]byte("新星联邦共和国"), 0) 148 keys = []string{"新星", "新星联邦共和国"} 149 values = []int{19, 22} 150 check(cd, ids, keys, values) 151 152 ids = cd.PrefixMatch([]byte("this is a sentence."), 0) 153 keys = []string{"this", "this is a sentence."} 154 values = []int{23, 25} 155 check(cd, ids, keys, values) 156 } 157 158 func TestOrder(t *testing.T) { 159 c := New() 160 c.Insert([]byte("a"), 1) 161 c.Insert([]byte("b"), 3) 162 c.Insert([]byte("d"), 6) 163 164 c.Insert([]byte("ab"), 2) 165 c.Insert([]byte("c"), 5) 166 c.Insert([]byte(""), 0) 167 c.Insert([]byte("bb"), 4) 168 169 ids := c.PrefixPredict([]byte(""), 0) 170 if len(ids) != 7 { 171 panic("wrong order") 172 } 173 174 for i, n := range ids { 175 val, _ := c.Value(n) 176 if i != val { 177 panic("wrong order") 178 } 179 } 180 } 181 182 func TestPrefixPredict(t *testing.T) { 183 var ( 184 ids []int 185 keys []string 186 values []int 187 ) 188 189 ids = cd.PrefixPredict([]byte("新星"), 0) 190 keys = []string{"新星", "新星军团", "新星联邦共和国"} 191 values = []int{19, 21, 22} 192 check(cd, ids, keys, values) 193 194 ids = cd.PrefixPredict([]byte("太阳系"), 0) 195 keys = []string{"太阳系", "太阳系水星", "太阳系火星"} 196 values = []int{15, 17, 18} 197 check(cd, ids, keys, values) 198 }