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  }