Lowers named and glob node priority to fix lookup issue

Given two similar keys, one short and one with named parameter, lookup
was incorrectly picking up the named parameter version instead of the
specific one:

    tree = Radix::Tree(Symbol).new
    tree.add "/tag-edit/:id", :edit_tag
    tree.add "/tag-edit2", :alternate_edit_tag

    result = tree.find("/tag-edit2")
    result.found? # => false

The order of insertion (named before specific) was causing the
lookup mechanism to validate it before checking the other options.

With the changes present here, short or long keys will be affected
anymore by named or globbed keys present when sharing part of the
key.

Fixes kemalcr/kemal#293
This commit is contained in:
Luis Lavena 2017-01-17 14:30:20 -03:00
parent 40b8e26ba5
commit 9163860e4d
4 changed files with 40 additions and 15 deletions

View file

@ -46,18 +46,18 @@ module Radix
it "returns zero for catch all (globbed) key" do
node = Node(Nil).new("*filepath")
node.priority.should eq(0)
node.priority.should eq(-2)
node = Node(Nil).new("/src/*filepath")
node.priority.should eq(0)
node.priority.should eq(-2)
end
it "returns one for keys with named parameters" do
node = Node(Nil).new(":query")
node.priority.should eq(1)
node.priority.should eq(-1)
node = Node(Nil).new("/search/:query")
node.priority.should eq(1)
node.priority.should eq(-1)
end
it "changes when key changes" do
@ -68,10 +68,10 @@ module Radix
node.priority.should eq(3)
node.key = "*filepath"
node.priority.should eq(0)
node.priority.should eq(-2)
node.key = ":query"
node.priority.should eq(1)
node.priority.should eq(-1)
end
end

View file

@ -466,6 +466,28 @@ module Radix
result.params.has_key?("name").should be_true
result.params["name"].should eq("日本語")
end
it "does prefer specific path over named parameters one if both are present" do
tree = Tree(Symbol).new
tree.add "/tag-edit/:tag", :edit_tag
tree.add "/tag-edit2", :alternate_tag_edit
result = tree.find("/tag-edit2")
result.found?.should be_true
result.key.should eq("/tag-edit2")
end
it "does prefer named parameter over specific key with partially shared key" do
tree = Tree(Symbol).new
tree.add "/orders/:id", :specific_order
tree.add "/orders/closed", :closed_orders
result = tree.find("/orders/10")
result.found?.should be_true
result.key.should eq("/orders/:id")
result.params.has_key?("id").should be_true
result.params["id"].should eq("10")
end
end
context "dealing with multiple named parameters" do