Skip to content

Commit

Permalink
WIP: added in a new fallback route feature. Fixes #728
Browse files Browse the repository at this point in the history
  • Loading branch information
jwoertink committed Mar 18, 2019
1 parent 580b28d commit 7fdc461
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 9 deletions.
12 changes: 12 additions & 0 deletions spec/lucky/action_rendering_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ class Rendering::File::Missing < Lucky::Action
end
end

class Rendering::FallbackRoute < Lucky::Action
fallback do
text "Hey, you found me!"
end
end

describe Lucky::Action do
describe "rendering HTML pages" do
it "render assigns" do
Expand Down Expand Up @@ -206,4 +212,10 @@ describe Lucky::Action do
response.status.should eq 200
response.content_type.should eq "text/html"
end

it "renders from a fallback" do
response = Rendering::FallbackRoute.new(build_context, params).call
response.body.should eq "Hey, you found me!"
response.status.should eq 200
end
end
15 changes: 15 additions & 0 deletions spec/lucky/router_spec.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
require "../../spec_helper"

describe Lucky::Router do
# TODO: use this once there's a way to scope to just this block
#Spec.before_each do
# Lucky::Router.reset!
#end

it "routes based on the method name and path" do
Lucky::Router.reset!
Lucky::Router.add :get, "/test", Lucky::Action

Lucky::Router.find_action(:get, "/test").should_not be_nil
Expand All @@ -10,9 +16,18 @@ describe Lucky::Router do
end

it "finds the associated get route by a head method" do
Lucky::Router.reset!
Lucky::Router.add :get, "/test", Lucky::Action

Lucky::Router.find_action(:head, "/test").should_not be_nil
Lucky::Router.find_action("head", "/test").should_not be_nil
end

it "finds a fallback route" do
Lucky::Router.reset!
Lucky::Router.add_fallback(Lucky::Action)

Lucky::Router.find_action(:get, "/test").should_not be_nil
Lucky::Router.find_action(:get, "/test").should be_a Lucky::FallbackRoute
end
end
6 changes: 6 additions & 0 deletions src/lucky/fallback_route.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Lucky::FallbackRoute
getter :payload, :params

def initialize(@payload : Lucky::Action.class, @params = {} of String => String)
end
end
5 changes: 5 additions & 0 deletions src/lucky/routeable.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Methods for routing HTTP requests and their parameters to actions.
module Lucky::Routeable
macro fallback
Lucky::Router.add_fallback({{ @type.name.id }})
setup_call_method({{ yield }})
end

{% for http_method in [:get, :put, :post, :patch, :trace, :delete] %}
# Define a route that responds to a {{ http_method.id.upcase }} request
#
Expand Down
35 changes: 26 additions & 9 deletions src/lucky/router.cr
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
class Lucky::Router
INSTANCE = new
alias RouteMatch = LuckyRouter::Match(Lucky::Action.class) | Lucky::FallbackRoute | Nil
private class_property instance = new

getter :routes
getter fallback : Lucky::FallbackRoute?

def initialize
@matcher = LuckyRouter::Matcher(Lucky::Action.class).new
@routes = [] of Lucky::Route
@fallback = nil
end

def self.add(method, path, action) : Nil
INSTANCE.add(method, path, action)
instance.add(method, path, action)
end

def self.add_fallback(action) : Lucky::FallbackRoute
instance.add_fallback(action)
end

def self.routes : Array(Lucky::Route)
INSTANCE.routes
instance.routes
end

# :nodoc:
def self.reset! : Nil
@@instance = new
nil
end

def add(method, path, action) : Nil
Expand All @@ -22,15 +35,19 @@ class Lucky::Router
@matcher.add(route.method.to_s, route.path, route.action)
end

def find_action(method, path) : LuckyRouter::Match(Lucky::Action.class)?
@matcher.match method.to_s.downcase, path
def add_fallback(action) : Lucky::FallbackRoute
@fallback = Lucky::FallbackRoute.new(action)
end

def find_action(method, path) : RouteMatch
@matcher.match(method.to_s.downcase, path) || fallback
end

def self.find_action(method, path) : LuckyRouter::Match(Lucky::Action.class)?
INSTANCE.find_action(method, path)
def self.find_action(method, path) : RouteMatch
instance.find_action(method, path)
end

def self.find_action(request) : LuckyRouter::Match(Lucky::Action.class)?
INSTANCE.find_action(request.method, request.path)
def self.find_action(request) : RouteMatch
instance.find_action(request.method, request.path)
end
end

0 comments on commit 7fdc461

Please sign in to comment.