From a6405700d2a86dbf00d490245e26a237bc54a906 Mon Sep 17 00:00:00 2001 From: Vlad Faust Date: Sat, 25 Aug 2018 23:17:44 +0300 Subject: [PATCH] feat: support Bool as param type --- spec/params_spec.cr | 21 +++++++++++++++++++-- src/prism/ext/bool/from_param.cr | 16 ++++++++++++++++ src/prism/ext/from_param.cr | 1 + src/prism/ext/union/from_param.cr | 29 ++++++++++------------------- src/prism/params/parsing.cr | 2 +- 5 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 src/prism/ext/bool/from_param.cr diff --git a/spec/params_spec.cr b/spec/params_spec.cr index d849cb4..a761f46 100644 --- a/spec/params_spec.cr +++ b/spec/params_spec.cr @@ -22,6 +22,7 @@ module Prism::Params::Specs end type important : Array(String) | Null, validate: {size: (1..10)} + type boolean : Bool | Null? end @@last_params = uninitialized ParamsTuple @@ -36,7 +37,7 @@ module Prism::Params::Specs describe SimpleAction do context "with valid params" do - response = handle_request(SimpleAction, Req.new(method: "GET", resource: "/?id=42&value=42&time=1526120573870&kebab-param=null&nest1[nest2][bar]=null&nest1[foo]=BAR&nest1[arrayParam][]=2&nest1[arrayParam][]=3&important[]=foo&important[]=42")) + response = handle_request(SimpleAction, Req.new(method: "GET", resource: "/?id=42&value=42&time=1526120573870&kebab-param=null&nest1[nest2][bar]=null&nest1[foo]=BAR&nest1[arrayParam][]=2&nest1[arrayParam][]=3&important[]=foo&important[]=42&boolean=true")) it "doesn't halt" do response.body.should eq "ok" @@ -73,10 +74,14 @@ module Prism::Params::Specs it "has arrayParam in params" do SimpleAction.last_params[:important].should eq ["foo", "42"] end + + it "has boolean in params" do + SimpleAction.last_params[:boolean].should eq true + end end context "with missing insignificant param" do - response = handle_request(SimpleAction, Req.new(method: "GET", resource: "/?id=42&important[]=foo&important[]=42")) + response = handle_request(SimpleAction, Req.new(method: "GET", resource: "/?id=42&important[]=foo&important[]=42&boolean=false")) it "doesn't halt" do response.body.should eq "ok" @@ -85,6 +90,7 @@ module Prism::Params::Specs it "returns params" do SimpleAction.last_params[:id].should eq 42 SimpleAction.last_params[:important].should eq ["foo", "42"] + SimpleAction.last_params[:boolean].should eq false end end @@ -114,6 +120,12 @@ module Prism::Params::Specs response = handle_request(SimpleAction, Req.new(method: "GET", resource: "/?id=42&important[]=foo&nest1[arrayParam][]=foo")) end end + + it "raises" do + expect_raises(InvalidParamTypeError) do + response = handle_request(SimpleAction, Req.new(method: "GET", resource: "/?id=42&important[]=foo&boolean=unknown")) + end + end end context "with invalid params" do @@ -146,6 +158,7 @@ module Prism::Params::Specs arrayParam: [1, 2], }, important: ["foo"], + boolean: false, }.to_json, headers: HTTP::Headers{ "Content-Type" => "application/json", @@ -177,6 +190,10 @@ module Prism::Params::Specs it "has nested array params" do SimpleAction.last_params[:nest1]?.try &.[:array_param].should eq [2_u8, 4_u8] end + + it "has boolean param" do + SimpleAction.last_params[:boolean].should eq false + end end end end diff --git a/src/prism/ext/bool/from_param.cr b/src/prism/ext/bool/from_param.cr new file mode 100644 index 0000000..cf72631 --- /dev/null +++ b/src/prism/ext/bool/from_param.cr @@ -0,0 +1,16 @@ +struct Bool + # Initialize from *param*. + # + # The param value must be either `true`, `"true"`, `false` or `"false"`. + # + # ``` + # Bool.from_param(<@value="true">) # => true + # ``` + def self.from_param(param : Prism::Params::AbstractParam) + case param.value + when true, "true" then true + when false, "false" then false + else raise Prism::Params::InvalidParamTypeError.new(param, "Bool") + end + end +end diff --git a/src/prism/ext/from_param.cr b/src/prism/ext/from_param.cr index f253bf5..9aeb74d 100644 --- a/src/prism/ext/from_param.cr +++ b/src/prism/ext/from_param.cr @@ -2,6 +2,7 @@ require "../params/abstract_param" require "../params/errors" require "./array/from_param" +require "./bool/from_param" require "./float/from_param" require "./int/from_param" require "./named_tuple/from_param" diff --git a/src/prism/ext/union/from_param.cr b/src/prism/ext/union/from_param.cr index f9a959d..08bf76e 100644 --- a/src/prism/ext/union/from_param.cr +++ b/src/prism/ext/union/from_param.cr @@ -5,24 +5,15 @@ struct Union(T) # # NOTE: Types are iterated alphabetically, so `UInt8 | Null` would turn to `Null | UInt8`. That's why `Int32 | String` won't work, it will always return `String`. def self.from_param(param : Prism::Params::AbstractParam) - any = false - {% begin %} - result = ( - {% for t in T %} - ( - begin - x = {{ t.id }}.from_param(param) - any = true - x - rescue Exception - nil - end - ) || - {% end %} - nil - ) - raise Prism::Params::InvalidParamTypeError.new(param, {{@type.id.stringify}}) unless any - result.as(self) - {% end %} + result = ( + {% for t in T %} + begin + return {{ t.id }}.from_param(param).as(self) + rescue Prism::Params::InvalidParamTypeError | ArgumentError + end + {% end %} + ) + + raise Prism::Params::InvalidParamTypeError.new(param, {{@type.id.stringify}}) end end diff --git a/src/prism/params/parsing.cr b/src/prism/params/parsing.cr index b30aefb..01e2004 100644 --- a/src/prism/params/parsing.cr +++ b/src/prism/params/parsing.cr @@ -194,7 +194,7 @@ module Prism::Params raise InvalidParamTypeError.new(param.not_nil!, {{param[:type].stringify}}) end - if json_value + if json_value != nil {% if param[:parents] %} params.deep_set({{param[:parents] + [param[:name]]}}, json_value) {% else %}