diff --git a/CHANGELOG.md b/CHANGELOG.md index b23832c..45d2372 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ This project aims to comply with [Semantic Versioning](http://semver.org/), so please check *Changed* and *Removed* notes before upgrading. ## [Unreleased] +### Fixed +- Do not force adding paths with shared named parameter in an specific order (@jwoertink) ## [0.3.1] - 2016-07-29 ### Added diff --git a/spec/radix/tree_spec.cr b/spec/radix/tree_spec.cr index 4e5f942..a01085a 100644 --- a/spec/radix/tree_spec.cr +++ b/spec/radix/tree_spec.cr @@ -233,6 +233,30 @@ module Radix tree.root.children[0].children[0].key.should eq("/:subcategory") end + it "does allow same named parameter in different order of insertion" do + tree = Tree(Symbol).new + tree.add "/members/:id/edit", :member_edit + tree.add "/members/export", :members_export + tree.add "/members/:id/videos", :member_videos + + # /members/ + # +-export (:members_export) + # \-:id/ + # +-videos (:members_videos) + # \-edit (:members_edit) + tree.root.key.should eq("/members/") + tree.root.children.size.should eq(2) + + # first level children nodes + tree.root.children[0].key.should eq("export") + tree.root.children[1].key.should eq(":id/") + + # inner children + nodes = tree.root.children[1].children + nodes[0].key.should eq("videos") + nodes[1].key.should eq("edit") + end + it "does not allow different named parameters sharing same level" do tree = Tree(Symbol).new tree.add "/", :root diff --git a/src/radix/tree.cr b/src/radix/tree.cr index 5a0c736..5436c15 100644 --- a/src/radix/tree.cr +++ b/src/radix/tree.cr @@ -374,7 +374,18 @@ module Radix count end - # :nodoc: + # Internal: Compares *path* against *key* for differences until the + # following criteria is met: + # + # - End of *path* or *key* is reached. + # - A separator (`/`) is found. + # - A character between *path* or *key* differs + # + # ``` + # _same_key?("foo", "bar") # => false (mismatch at 1st character) + # _same_key?("foo/bar", "foo/baz") # => true (only `foo` is compared) + # _same_key?("zipcode", "zip") # => false (`zip` is shorter) + # ``` private def _same_key?(path, key) path_reader = Char::Reader.new(path) key_reader = Char::Reader.new(key) @@ -392,7 +403,7 @@ module Radix key_reader.next_char end - (!key_reader.has_next? && !different) && + (!different) && (path_reader.current_char == '/' || !path_reader.has_next?) end