| package norm |
| |
| import ( |
| "testing" |
| "utf8" |
| ) |
| |
| // Test data is located in triedata_test.go; generated by maketesttables. |
| var testdata = testdataTrie |
| |
| type rangeTest struct { |
| block uint8 |
| lookup byte |
| result uint16 |
| table []valueRange |
| offsets []uint16 |
| } |
| |
| var range1Off = []uint16{0, 2} |
| var range1 = []valueRange{ |
| {0, 1, 0}, |
| {1, 0x80, 0x80}, |
| {0, 2, 0}, |
| {1, 0x80, 0x80}, |
| {9, 0xff, 0xff}, |
| } |
| |
| var rangeTests = []rangeTest{ |
| {10, 0x80, 1, range1, range1Off}, |
| {10, 0x00, 0, range1, range1Off}, |
| {11, 0x80, 1, range1, range1Off}, |
| {11, 0xff, 9, range1, range1Off}, |
| {11, 0x00, 0, range1, range1Off}, |
| } |
| |
| func TestLookupSparse(t *testing.T) { |
| for i, test := range rangeTests { |
| n := trie{sparse: test.table, sparseOffset: test.offsets, cutoff: 10} |
| v := n.lookupValue(test.block, test.lookup) |
| if v != test.result { |
| t.Errorf("LookupSparse:%d: found %X; want %X", i, v, test.result) |
| } |
| } |
| } |
| |
| // Test cases for illegal runes. |
| type trietest struct { |
| size int |
| bytes []byte |
| } |
| |
| var tests = []trietest{ |
| // illegal runes |
| {1, []byte{0x80}}, |
| {1, []byte{0xFF}}, |
| {1, []byte{t2, tx - 1}}, |
| {1, []byte{t2, t2}}, |
| {2, []byte{t3, tx, tx - 1}}, |
| {2, []byte{t3, tx, t2}}, |
| {1, []byte{t3, tx - 1, tx}}, |
| {3, []byte{t4, tx, tx, tx - 1}}, |
| {3, []byte{t4, tx, tx, t2}}, |
| {1, []byte{t4, t2, tx, tx - 1}}, |
| {2, []byte{t4, tx, t2, tx - 1}}, |
| |
| // short runes |
| {0, []byte{t2}}, |
| {0, []byte{t3, tx}}, |
| {0, []byte{t4, tx, tx}}, |
| |
| // we only support UTF-8 up to utf8.UTFMax bytes (4 bytes) |
| {1, []byte{t5, tx, tx, tx, tx}}, |
| {1, []byte{t6, tx, tx, tx, tx, tx}}, |
| } |
| |
| func mkUtf8(rune int) ([]byte, int) { |
| var b [utf8.UTFMax]byte |
| sz := utf8.EncodeRune(b[:], rune) |
| return b[:sz], sz |
| } |
| |
| func TestLookup(t *testing.T) { |
| for i, tt := range testRunes { |
| b, szg := mkUtf8(tt) |
| v, szt := testdata.lookup(b) |
| if int(v) != i { |
| t.Errorf("lookup(%U): found value %#x, expected %#x", tt, v, i) |
| } |
| if szt != szg { |
| t.Errorf("lookup(%U): found size %d, expected %d", tt, szt, szg) |
| } |
| } |
| for i, tt := range tests { |
| v, sz := testdata.lookup(tt.bytes) |
| if int(v) != 0 { |
| t.Errorf("lookup of illegal rune, case %d: found value %#x, expected 0", i, v) |
| } |
| if sz != tt.size { |
| t.Errorf("lookup of illegal rune, case %d: found size %d, expected %d", i, sz, tt.size) |
| } |
| } |
| } |
| |
| func TestLookupUnsafe(t *testing.T) { |
| for i, tt := range testRunes { |
| b, _ := mkUtf8(tt) |
| v := testdata.lookupUnsafe(b) |
| if int(v) != i { |
| t.Errorf("lookupUnsafe(%U): found value %#x, expected %#x", i, v, i) |
| } |
| } |
| } |
| |
| func TestLookupString(t *testing.T) { |
| for i, tt := range testRunes { |
| b, szg := mkUtf8(tt) |
| v, szt := testdata.lookupString(string(b)) |
| if int(v) != i { |
| t.Errorf("lookup(%U): found value %#x, expected %#x", i, v, i) |
| } |
| if szt != szg { |
| t.Errorf("lookup(%U): found size %d, expected %d", i, szt, szg) |
| } |
| } |
| for i, tt := range tests { |
| v, sz := testdata.lookupString(string(tt.bytes)) |
| if int(v) != 0 { |
| t.Errorf("lookup of illegal rune, case %d: found value %#x, expected 0", i, v) |
| } |
| if sz != tt.size { |
| t.Errorf("lookup of illegal rune, case %d: found size %d, expected %d", i, sz, tt.size) |
| } |
| } |
| } |
| |
| func TestLookupStringUnsafe(t *testing.T) { |
| for i, tt := range testRunes { |
| b, _ := mkUtf8(tt) |
| v := testdata.lookupStringUnsafe(string(b)) |
| if int(v) != i { |
| t.Errorf("lookupUnsafe(%U): found value %#x, expected %#x", i, v, i) |
| } |
| } |
| } |