Skip to content

Commit

Permalink
Merge branch 'master' into amber-exec
Browse files Browse the repository at this point in the history
  • Loading branch information
faustinoaq committed Nov 9, 2017
2 parents 18a8bda + 6db9744 commit 78826b6
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 36 deletions.
22 changes: 11 additions & 11 deletions spec/amber/controller/base_spec.cr
Expand Up @@ -63,71 +63,71 @@ module Amber::Controller
expected_result = "<html><body><h1>Elorest <3 Amber</h1></body></html>"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "text/html"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "respond_with html" do
expected_result = "<html><body><h1>Elorest <3 Amber</h1></body></html>"
context.request.headers["Accept"] = "text/html"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "text/html"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with json" do
expected_result = %({"type":"json","name":"Amberator"})
context.request.headers["Accept"] = "application/json"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "application/json"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with xml" do
expected_result = "<xml><body><h1>Sort of xml</h1></body></xml>"
context.request.headers["Accept"] = "application/xml"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "application/xml"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with text" do
expected_result = "Hello I'm text!"
context.request.headers["Accept"] = "text/plain"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "text/plain"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with json for path.json" do
expected_result = %({"type":"json","name":"Amberator"})
context.request.path = "/response/1.json"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "application/json"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with xml for path.xml" do
expected_result = "<xml><body><h1>Sort of xml</h1></body></xml>"
context.request.path = "/response/1.xml"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "application/xml"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with text for path.txt" do
expected_result = "Hello I'm text!"
context.request.path = "/response/1.txt"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "text/plain"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with text for path.text" do
expected_result = "Hello I'm text!"
context.request.path = "/response/1.text"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "text/plain"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with 406 for path.text when text hasn't been defined" do
Expand All @@ -143,7 +143,7 @@ module Amber::Controller
context.request.headers["Accept"] = "text/html"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "text/html"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end

it "responds with or accept header request if extension is invalid" do
Expand All @@ -152,7 +152,7 @@ module Amber::Controller
context.request.path = "/response/1.texas"
ResponsesController.new(context).index.should eq expected_result
context.response.headers["Content-Type"].should eq "application/json"
context.response.status_code.should eq 200
context.response.status_code.should eq 200
end
end

Expand Down
4 changes: 2 additions & 2 deletions spec/amber/router/context_spec.cr
Expand Up @@ -153,7 +153,7 @@ describe HTTP::Server::Context do
context = create_context(request)

context.params["test"].should eq "test"
context.params["address"].as(Hash)["city"].should eq "New York"
context.params.json("address")["city"].should eq "New York"
end

it "parses json array" do
Expand All @@ -164,7 +164,7 @@ describe HTTP::Server::Context do

context = create_context(request)

context.params["_json"].should eq %w(test test2)
context.params.json("_json").should eq %w(test test2)
end

it "parses files from multipart forms" do
Expand Down
2 changes: 1 addition & 1 deletion spec/amber/validations/params_spec.cr
Expand Up @@ -221,7 +221,7 @@ module Amber::Validators
end

def params_builder(body = "")
params = {} of String | Symbol => Amber::Router::ParamsType
params = Amber::Router::Params.new
return params if body.empty?

body.tr("?", "").split("&").each_with_object(params) do |item, params|
Expand Down
8 changes: 8 additions & 0 deletions src/amber/cli/templates/app/shard.yml.ecr
Expand Up @@ -23,28 +23,36 @@ dependencies:
<% case @model when "crecto" -%>
crecto:
github: Crecto/crecto
version: ~> 0.7.1
<% else -%>
granite_orm:
github: amberframework/granite-orm
version: ~> 0.7.6
<% end -%>

quartz_mailer:
github: amberframework/quartz-mailer
version: 0.2.0

jasper_helpers:
github: amberframework/jasper-helpers
version: ~> 0.1.6

<% case @database when "pg" -%>
pg:
github: will/crystal-pg
version: ~> 0.13.4
<% when "mysql" -%>
mysql:
github: crystal-lang/crystal-mysql
version: ~> 0.3.3
<% when "sqlite" -%>
sqlite3:
github: crystal-lang/crystal-sqlite3
version: ~> 0.8.3
<% end -%>

development_dependencies:
amber_spec:
github: amberframework/amber-spec
version: ~> 0.1.2
1 change: 0 additions & 1 deletion src/amber/controller/base.cr
Expand Up @@ -10,7 +10,6 @@ module Amber::Controller
include Helpers::Render
include Helpers::Responders
include Helpers::Route

include Callbacks

protected getter context : HTTP::Server::Context
Expand Down
26 changes: 26 additions & 0 deletions src/amber/router/params.cr
@@ -0,0 +1,26 @@
module Amber::Router
# The Parameters module will parse parameters from a URL, a form post or a JSON
# post and provide them in the self params hash. This unifies access to
# parameters into one place to simplify access to them.
# Note: other params from the router will be handled in the router handler
# instead of here. This removes a dependency on the router in case it is
# replaced or not needed.

class Params < Hash(String, String)
alias KeyType = String | Symbol

def json(key : KeyType)
JSON.parse(self[key]?.to_s)
rescue JSON::ParseException
raise "Value of params.json(#{key.inspect}) is not JSON!"
end

def []=(key : KeyType, value : V)
super(key.to_s, value)
end

def find_entry(key : KeyType)
super(key.to_s)
end
end
end
15 changes: 8 additions & 7 deletions src/amber/router/params_parser.cr
@@ -1,9 +1,6 @@
require "json"

module Amber::Router
alias ParamsType = String | JSON::Type
alias ParamsHash = Hash(String | Symbol, Amber::Router::ParamsType)

# The Parameters module will parse parameters from a URL, a form post or a JSON
# post and provide them in the self params hash. This unifies access to
# parameters into one place to simplify access to them.
Expand All @@ -18,12 +15,12 @@ module Amber::Router
OVERRIDE_HEADER = "X-HTTP-Method-Override"
OVERRIDE_METHODS = %w(PATCH PUT DELETE)

property params = Hash(String | Symbol, ParamsType).new
property params = Amber::Router::Params.new

@override_method : String?

def clear_params
@params = Hash(String | Symbol, ParamsType).new
@params = Router::Params.new
end

def parse_params
Expand Down Expand Up @@ -102,10 +99,14 @@ module Amber::Router
case json = JSON.parse_raw(body)
when Hash
json.each do |key, value|
params[key.as(String)] = value
if value.is_a?(String)
params[key.as(String)] = value
else
params[key.as(String)] = value.to_json
end
end
when Array
params["_json"] = json
params["_json"] = json.to_json
end
end
end
Expand Down
26 changes: 13 additions & 13 deletions src/amber/validations/params.cr
@@ -1,26 +1,26 @@
module Amber::Validators
# Holds a validation error message
record Error, param : String, value : Amber::Router::ParamsType, message : String
record Error, param : String, value : String?, message : String

# This struct holds the validation rules to be performed
class BaseRule
getter predicate : (Amber::Router::ParamsType -> Bool)
getter predicate : (String -> Bool)
getter field : String
getter value : Amber::Router::ParamsType
getter value : String?

def initialize(field : String | Symbol, @msg : String?, &block : Amber::Router::ParamsType -> Bool)
def initialize(field : String | Symbol, @msg : String?, &block : String -> Bool)
@field = field.to_s
@predicate = block
end

def apply(params : Amber::Router::ParamsHash)
def apply(params : Amber::Router::Params)
raise Exceptions::Validator::InvalidParam.new(@field) unless params.has_key? @field
@value = params[@field]
@predicate.call @value.to_s unless @predicate.nil?
@predicate.call params[@field] unless @predicate.nil?
end

def error
Error.new @field, @value, error_message
Error.new @field, @value.to_s, error_message
end

private def error_message
Expand All @@ -30,10 +30,10 @@ module Amber::Validators

# OptionalRule only validates if the key is present.
class OptionalRule < BaseRule
def apply(params : Amber::Router::ParamsHash)
def apply(params : Amber::Router::Params)
return true unless params.has_key? @field
@value = params[@field]
@predicate.call @value unless @predicate.nil?
@predicate.call params[@field] unless @predicate.nil?
end
end

Expand All @@ -42,20 +42,20 @@ module Amber::Validators
_validator.add_rule BaseRule.new(param, msg)
end

def required(param : String | Symbol, msg : String? = nil, &b : Amber::Router::ParamsType -> Bool)
def required(param : String | Symbol, msg : String? = nil, &b : String -> Bool)
_validator.add_rule BaseRule.new(param, msg, &b)
end

def optional(param : String | Symbol, msg : String? = nil, &b : Amber::Router::ParamsType -> Bool)
def optional(param : String | Symbol, msg : String? = nil, &b : String -> Bool)
_validator.add_rule OptionalRule.new(param, msg, &b)
end
end

class Params
getter raw_params = Amber::Router::ParamsHash.new
getter raw_params = Amber::Router::Params.new
getter errors = [] of Error
getter rules = [] of BaseRule
getter params = Amber::Router::ParamsHash.new
getter params = {} of String => String?
getter errors = [] of Error

def initialize(@raw_params); end
Expand Down
2 changes: 1 addition & 1 deletion src/amber/websockets/client_socket.cr
Expand Up @@ -25,7 +25,7 @@ module Amber
protected getter id : String
getter socket : HTTP::WebSocket
protected getter context : HTTP::Server::Context
protected getter raw_params : Amber::Router::ParamsHash
protected getter raw_params : Amber::Router::Params
protected getter params : Amber::Validators::Params
protected getter session : Amber::Router::Session::AbstractStore?
protected getter cookies : Amber::Router::Cookies::Store?
Expand Down

0 comments on commit 78826b6

Please sign in to comment.