From fe1ebb7d76956d998ca0d7bac2a38dbad52e6241 Mon Sep 17 00:00:00 2001 From: Luis Lavena Date: Mon, 29 Feb 2016 11:35:57 -0300 Subject: [PATCH] Correctly build key from detected parameters Given a key `/:foo/:bar`, the find mechanism was incorrectly picking the separator character as part of the key name (`foo/`). This caused incorrect match between expected name (`foo`) and the one obtained. When the key name was extracted from the named parameter, the size of the returned key was not compensated, given that we move +1 positions to avoid having ':' as part of the key. This is now corrected by reducing the key size one shorter to compensate. Fixes Issue #2 --- spec/radix/tree_spec.cr | 28 ++++++++++++++++++++++++++++ src/radix/tree.cr | 4 +++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/spec/radix/tree_spec.cr b/spec/radix/tree_spec.cr index 5314ba5..f889d20 100644 --- a/spec/radix/tree_spec.cr +++ b/spec/radix/tree_spec.cr @@ -340,6 +340,34 @@ module Radix end end + context "dealing with multiple named parameters" do + it "finds matching path" do + tree = Tree.new + tree.add "/", :root + tree.add "/:section/:page", :static_page + + result = tree.find("/about/shipping") + result.found?.should be_true + result.key.should eq("/:section/:page") + result.payload.should eq(:static_page) + end + + it "returns named parameters in result" do + tree = Tree.new + tree.add "/", :root + tree.add "/:section/:page", :static_page + + result = tree.find("/about/shipping") + result.found?.should be_true + + result.params.has_key?("section").should be_true + result.params["section"].should eq("about") + + result.params.has_key?("page").should be_true + result.params["page"].should eq("shipping") + end + end + context "dealing with both catch all and named parameters" do it "finds matching path" do tree = Tree.new diff --git a/src/radix/tree.cr b/src/radix/tree.cr index b4ed6be..b335a6f 100644 --- a/src/radix/tree.cr +++ b/src/radix/tree.cr @@ -257,7 +257,9 @@ module Radix path_size = _detect_param_size(path_reader) # obtain key and value using calculated sizes - name = key_reader.string.byte_slice(key_reader.pos + 1, key_size) + # for name: skip ':' by moving one character forward and compensate + # key size. + name = key_reader.string.byte_slice(key_reader.pos + 1, key_size - 1) value = path_reader.string.byte_slice(path_reader.pos, path_size) # add this information to result