Skip to content

Commit

Permalink
routes namespace support
Browse files Browse the repository at this point in the history
  • Loading branch information
tongueroo committed Jan 11, 2019
1 parent 1d468c3 commit 45337af
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 4 deletions.
33 changes: 29 additions & 4 deletions lib/jets/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Jets
class Router
autoload :Scope, 'jets/router/scope'

attr_reader :routes
def initialize
@routes = []
Expand All @@ -18,6 +20,33 @@ def draw(&block)
end
end

def create_route(options)
# Currently only using scope to add namespace
# TODO: Can use it to add additional things like authorization_type
# Would be good to add authorization_type at the controller level also
options[:path] = add_namespace(options[:path])
@routes << Route.new(options)
end

def add_namespace(path)
return path unless @scope
ns = @scope.full_namespace
return path unless ns
"#{ns}/#{path}"
end

def namespace(ns, &block)
scope(namespace: ns, &block)
end

def scope(options={})
root_level = @scope.nil?
@scope = root_level ? Scope.new(options) : @scope.new(options)
yield
ensure
@scope = @scope.parent if @scope
end

# resources macro expands to all the routes
def resources(name)
get "#{name}", to: "#{name}#index"
Expand Down Expand Up @@ -45,10 +74,6 @@ def api_mode?
api_mode
end

def create_route(options)
@routes << Route.new(options)
end

# root "posts#index"
def root(to)
@routes << Route.new(path: '', to: to, method: :get, root: true)
Expand Down
30 changes: 30 additions & 0 deletions lib/jets/router/scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Jets
class Router
class Scope
attr_reader :options, :parent, :level
def initialize(options = {}, parent = nil, level = 1)
@options = options
@parent = parent
@level = level
end

def root?
@parent.nil?
end

def new(options={})
self.class.new(options, self, level + 1)
end

def full_namespace
ns = []
current = self
while current
ns.unshift(current.options[:namespace])
current = current.parent
end
ns.empty? ? nil : ns.join('/')
end
end
end
end
33 changes: 33 additions & 0 deletions spec/lib/jets/router/scope_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
describe Jets::Router::Scope do
context "root level" do
let(:scope) do
Jets::Router::Scope.new
end
it "scope is has level 1" do
expect(scope.level).to eq 1
end
end

context "root level with namespace" do
let(:scope) do
Jets::Router::Scope.new(namespace: :admin)
end
it "scope is has level 1" do
expect(scope.level).to eq 1
expect(scope.options[:namespace]).to eq :admin
end
end

context "nested 2nd level" do
let(:root) do
Jets::Router::Scope.new
end
let(:scope) do
root.new
end
it "scope is has level 2" do
expect(scope.level).to eq 2
expect(scope.parent).to eq root
end
end
end
45 changes: 45 additions & 0 deletions spec/lib/jets/router_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,50 @@
["posts/new", "posts", "posts/:id/edit", "posts/:id", "*catchall"])
end
end

context "routes with namespaces" do
# more general scope method
it "admin namespace" do
router.draw do
scope(namespace: :admin) do
get "posts", to: "posts#index"
end
end
route = router.routes.first
expect(route.path).to eq "admin/posts"
end

it "api/v1 namespace nested" do
router.draw do
scope(namespace: :api) do
scope(namespace: :v1) do
get "posts", to: "posts#index"
end
end
end
route = router.routes.first
expect(route.path).to eq "api/v1/posts"
end
it "api/v1 namespace oneline" do
router.draw do
scope(namespace: "api/v1") do
get "posts", to: "posts#index"
end
end
route = router.routes.first
expect(route.path).to eq "api/v1/posts"
end

# prettier namespace method
it "api/v2 namespace" do
router.draw do
namespace "api/v2" do
get "posts", to: "posts#index"
end
end
route = router.routes.first
expect(route.path).to eq "api/v2/posts"
end
end
end
end

0 comments on commit 45337af

Please sign in to comment.