Skip to content

Commit

Permalink
Merge pull request #55 from aristotelesbr/development
Browse files Browse the repository at this point in the history
Lennarb 1.0 🎉
  • Loading branch information
aristotelesbr authored Sep 29, 2024
2 parents 25ff419 + ce3d903 commit fa44a10
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 39 deletions.
3 changes: 3 additions & 0 deletions gems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
# Colorize is a Ruby gem used to color text in terminals.
gem 'colorize', '~> 1.1'

gem 'bigdecimal', '~> 3.1', '>= 3.1.8' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.4.0')

group :maintenance, optional: true do
# [https://rubygems.org/gems/bake-gem]
# Bake Gem is a Bake extension that helps you to create a new Ruby
Expand Down Expand Up @@ -71,3 +73,4 @@
# specified in standard Ruby syntax. Rake has the following features:
gem 'rake', '~> 13.1'
end

67 changes: 33 additions & 34 deletions lib/lennarb/route_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@

class Lennarb
class RouteNode
attr_accessor :children, :blocks, :param_key
attr_accessor :static_children, :dynamic_children, :blocks, :param_key

# Initialize the route node
# Initializes the RouteNode class.
#
# @return [RouteNode]
#
def initialize
@children = {}
@blocks = {}
@param_key = nil
@blocks = {}
@param_key = nil
@static_children = {}
@dynamic_children = {}
end

# Add a route to the route node
#
# @parameter [Array] parts
# @parameter [String] http_method
# @parameter [Proc] block
# @parameter parts [Array<String>] The parts of the route
# @parameter http_method [Symbol] The HTTP method of the route
# @parameter block [Proc] The block to be executed when the route is matched
#
# @return [void]
#
Expand All @@ -30,44 +31,42 @@ def add_route(parts, http_method, block)

parts.each do |part|
if part.start_with?(':')
key = :param
current_node.children[key] ||= RouteNode.new
current_node = current_node.children[key]
current_node.param_key = part[1..].to_sym
param_sym = part[1..].to_sym
current_node.dynamic_children[param_sym] ||= RouteNode.new
dynamic_node = current_node.dynamic_children[param_sym]
dynamic_node.param_key = param_sym
current_node = dynamic_node
else
key = part
current_node.children[key] ||= RouteNode.new
current_node = current_node.children[key]
current_node.static_children[part] ||= RouteNode.new
current_node = current_node.static_children[part]
end
end

current_node.blocks[http_method] = block
end

# Match a route to the route node
#
# @parameter [Array] parts
# @parameter [String] http_method
#
# @return [Array]
#
def match_route(parts, http_method)
current_node = self
params = {}
def match_route(parts, http_method, params: {})
if parts.empty?
return [blocks[http_method], params] if blocks[http_method]
else
part = parts.first
rest = parts[1..]

parts.each do |part|
return [nil, nil] unless current_node.children.key?(part) || current_node.children[:param]
if static_children.key?(part)
result_block, result_params = static_children[part].match_route(rest, http_method, params:)
return [result_block, result_params] if result_block
end

if current_node.children.key?(part)
current_node = current_node.children[part]
else
param_node = current_node.children[:param]
params[param_node.param_key] = part
current_node = param_node
dynamic_children.each_value do |dyn_node|
new_params = params.dup
new_params[dyn_node.param_key] = part
result_block, result_params = dyn_node.match_route(rest, http_method, params: new_params)

return [result_block, result_params] if result_block
end
end

[current_node.blocks[http_method], params]
[nil, nil]
end
end
end
2 changes: 1 addition & 1 deletion lib/lennarb/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Copyright, 2023-2024, by Aristóteles Coutinho.

class Lennarb
VERSION = '0.6.2'
VERSION = '1.0.0'

public_constant :VERSION
end
25 changes: 21 additions & 4 deletions test/lib/lennarb/test_route_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ class RouteNodeTest < Minitest::Test
def setup
@route_node = Lennarb::RouteNode.new

# Adicionando rotas de exemplo
@route_node.add_route(['posts'], 'GET', proc { 'List of posts' })
@route_node.add_route(['posts', ':id'], 'GET', proc { |id| "Post #{id}" })
end

def test_add_route
# Verificar se as rotas foram adicionadas corretamente
assert @route_node.children.key?('posts')
assert @route_node.children['posts'].children.key?(:param)
assert @route_node.static_children.key?('posts')
dynamic_node = @route_node.static_children['posts'].dynamic_children[:id]

refute_nil dynamic_node
end

def test_match_valid_route
Expand All @@ -41,5 +41,22 @@ def test_match_invalid_route
assert_nil block
assert_nil params
end

def test_different_variables_in_common_nested_routes
router = Lennarb::RouteNode.new
router.add_route(['foo', ':foo'], 'GET', proc { 'foo' })
router.add_route(%w[foo special], 'GET', proc { 'special' })
router.add_route(['foo', ':id', 'bar'], 'GET', proc { 'bar' })

_, params = router.match_route(%w[foo 23], 'GET')

assert_equal({ foo: '23' }, params)
_, params = router.match_route(%w[foo special], 'GET')

assert_empty(params)
_, params = router.match_route(%w[foo 24 bar], 'GET')

assert_equal({ id: '24' }, params)
end
end
end

0 comments on commit fa44a10

Please sign in to comment.