Improves support for non-ascii keys in a tree

Properly recognize and organize non-ascii keys into nodes, allowing
usage with entries in other languages.

With this change, it is possible to use 2 or 3 bytes wide characters
(Unicode) without issues:

    tree = Radix::Tree(Symbol).new
    tree.add "/", :root
    tree.add "/日本語", :japanese
    tree.add "/日本は難しい", :japanese_is_difficult

Which produces the following node hierarchy:

    # ( 1) /       (:root)
    # ( 6)  日本
    # (12)    は難しい (:japanese_is_difficult)
    # ( 3)    語    (:japanese)

And lookup works as expected:

    result = tree.find "/日本は難しい"
    puts result.found? # => true
This commit is contained in:
Luis Lavena 2017-02-18 20:30:05 -03:00
parent 7460033db3
commit 97ef407aec
3 changed files with 55 additions and 9 deletions

View file

@ -172,6 +172,38 @@ module Radix
end
end
context "dealing with unicode" do
it "inserts properly adjacent parent nodes" do
tree = Tree(Symbol).new
tree.add "/", :root
tree.add "/日本語", :japanese
tree.add "/素晴らしい", :amazing
# / (:root)
# +-素晴らしい (:amazing)
# \-日本語 (:japanese)
tree.root.children.size.should eq(2)
tree.root.children[0].key.should eq("素晴らしい")
tree.root.children[1].key.should eq("日本語")
end
it "inserts nodes with shared parent" do
tree = Tree(Symbol).new
tree.add "/", :root
tree.add "/日本語", :japanese
tree.add "/日本は難しい", :japanese_is_difficult
# / (:root)
# \-日本語 (:japanese)
# \-日本は難しい (:japanese_is_difficult)
tree.root.children.size.should eq(1)
tree.root.children[0].key.should eq("日本")
tree.root.children[0].children.size.should eq(2)
tree.root.children[0].children[0].key.should eq("は難しい")
tree.root.children[0].children[1].key.should eq("")
end
end
context "dealing with duplicates" do
it "does not allow same path be defined twice" do
tree = Tree(Symbol).new
@ -349,6 +381,19 @@ module Radix
end
end
context "unicode nodes with shared parent" do
it "finds matching path" do
tree = Tree(Symbol).new
tree.add "/", :root
tree.add "/日本語", :japanese
tree.add "/日本日本語は難しい", :japanese_is_difficult
result = tree.find("/日本日本語は難しい/")
result.found?.should be_true
result.key.should eq("/日本日本語は難しい")
end
end
context "dealing with catch all" do
it "finds matching path" do
tree = Tree(Symbol).new