Remove deprecation on shared named parameters

Deal with named parameters under same level (shared) and raise
proper `SharedKeyError` exception.

This is a non-backward compatible change aims to solve result
mapping issues and tree lookup.

Now README covers this under *Caveats* section and offers an
alternative organization of the paths used on the tree.

To avoid potential issues when using `master` instead of a locked
release, bump the version.
This commit is contained in:
Luis Lavena 2016-03-10 20:49:52 -03:00
parent ae814c608c
commit ca41d21294
5 changed files with 47 additions and 46 deletions

View file

@ -4,6 +4,11 @@ All notable changes to Radix project will be documented in this file.
This project aims to comply with [Semantic Versioning](http://semver.org/), This project aims to comply with [Semantic Versioning](http://semver.org/),
so please check *Changed* and *Removed* notes before upgrading. so please check *Changed* and *Removed* notes before upgrading.
## [Unreleased]
### Removed
- Attempt to use two named parameters at the same level will raise
`Radix::Tree::SharedKeyError`
## [0.1.2] - 2016-03-10 ## [0.1.2] - 2016-03-10
### Fixed ### Fixed
- No longer split named parameters that share same level (@alsm) - No longer split named parameters that share same level (@alsm)

View file

@ -48,6 +48,38 @@ end
Please see `Radix::Tree#add` documentation for more usage examples. Please see `Radix::Tree#add` documentation for more usage examples.
## Caveats
Pretty much all Radix implementations have their limitations and this project
is no exception.
When designing and adding *paths* to build a Tree, please consider that two
different named parameters cannot share the same level:
```crystal
tree.add "/", :root
tree.add "/:post", :post
tree.add "/:category/:post", :category_post # => Radix::Tree::SharedKeyError
```
This is because different named parameters at the same level will result in
incorrect `params` when lookup is performed, and sometimes the value for
`post` or `category` parameters will not be stored as expected.
To avoid this issue, usage of explicit keys that differentiate each path is
recommended.
For example, following a good SEO practice will be consider `/:post` as
absolute permalink for the post and have a list of categories which links to
the permalinks of the posts under that category:
```crystal
tree.add "/", :root
tree.add "/:post", :post # this is post permalink
tree.add "/categories", :categories # list of categories
tree.add "/categories/:category", :category # listing of posts under each category
```
## Implementation ## Implementation
This project has been inspired and adapted from This project has been inspired and adapted from

View file

@ -1,5 +1,5 @@
name: radix name: radix
version: 0.1.2 version: 0.2.0
authors: authors:
- Luis Lavena <luislavena@gmail.com> - Luis Lavena <luislavena@gmail.com>

View file

@ -209,37 +209,7 @@ module Radix
tree.root.children[0].children[0].key.should eq("/:subcategory") tree.root.children[0].children[0].key.should eq("/:subcategory")
end end
it "does not split named parameter marker when only root is shared" do it "does not allow different named parameters sharing same level" do
tree = Tree.new
tree.add "/", :root
tree.add "/:post", :post
tree.add "/:category/:post", :category_post
# / (:root)
# +-:category/:post (:category_post)
# \-:post (:post)
tree.root.children.size.should eq(2)
tree.root.children[0].key.should eq(":category/:post")
tree.root.children[1].key.should eq(":post")
end
it "displays deprecation warning when two different named parameters share same level" do
tree = Tree.new
tree.show_deprecations!
tree.add "/", :root
tree.add "/:post", :post
tree.add "/:category/:post", :category_post
stderr = tree.@stderr.not_nil!
stderr.rewind
message = stderr.gets_to_end
message.should contain("DEPRECATION WARNING")
message.should contain("Tried to place key ':category/:post' at same level as ':post'")
end
pending "does not allow different named parameters sharing same level" do
tree = Tree.new tree = Tree.new
tree.add "/", :root tree.add "/", :root
tree.add "/:post", :post tree.add "/:post", :post

View file

@ -20,6 +20,13 @@ module Radix
end end
end end
# :nodoc:
class SharedKeyError < Exception
def initialize(new_key, existing_key)
super("Tried to place key '#{new_key}' at same level as '#{existing_key}'")
end
end
# Returns the root `Node` element of the Tree. # Returns the root `Node` element of the Tree.
# #
# On a new tree instance, this will be a placeholder. # On a new tree instance, this will be a placeholder.
@ -130,20 +137,7 @@ module Radix
# Otherwise, compare just first character # Otherwise, compare just first character
if child.key[0]? == ':' && new_key[0]? == ':' if child.key[0]? == ':' && new_key[0]? == ':'
unless _same_key?(new_key, child.key) unless _same_key?(new_key, child.key)
message = <<-NOTICE raise SharedKeyError.new(new_key, child.key)
DEPRECATION WARNING: Usage of two different named parameters at same level
will result in lookup issues and misplaced values.
Tried to place key '%s' at same level as '%s'.
Future versions will raise `Radix::Tree::SharedKeyError`.
See Issue #5 for details:
https://github.com/luislavena/radix/issues/5
NOTICE
deprecation message % {new_key, child.key}
next
end end
else else
next unless child.key[0]? == new_key[0]? next unless child.key[0]? == new_key[0]?