Skip to content

Commit

Permalink
feat: Add BooleanCoercer
Browse files Browse the repository at this point in the history
  • Loading branch information
maxveldink committed Mar 13, 2024
1 parent 9ef1cd5 commit acd220f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
31 changes: 31 additions & 0 deletions lib/typed/coercion/boolean_coercer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# typed: strict

module Typed
module Coercion
class BooleanCoercer < Coercer
extend T::Generic

Target = type_member { {fixed: T::Boolean} }

sig { override.params(type: Field::Type).returns(T::Boolean) }
def used_for_type?(type)
type == T::Utils.coerce(T::Boolean)
end

sig { override.params(field: Field, value: Value).returns(Result[Target, CoercionError]) }
def coerce(field:, value:)
if T.cast(field.type, T::Types::Base).valid?(value)
Success.new(value)
elsif value == "true"
Success.new(true)
elsif value == "false"
Success.new(false)
else
Failure.new(CoercionError.new)
end
rescue TypeError => e
Failure.new(CoercionError.new("Field type must be a T::Boolean."))
end
end
end
end
2 changes: 1 addition & 1 deletion lib/typed/coercion/coercer_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CoercerRegistry

Registry = T.type_alias { T::Array[T.class_of(Coercer)] }

DEFAULT_COERCERS = T.let([StringCoercer, IntegerCoercer, FloatCoercer, EnumCoercer, StructCoercer], Registry)
DEFAULT_COERCERS = T.let([StringCoercer, BooleanCoercer, IntegerCoercer, FloatCoercer, EnumCoercer, StructCoercer], Registry)

sig { void }
def initialize
Expand Down
41 changes: 41 additions & 0 deletions test/typed/coercion/boolean_coercer_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# typed: true

class BooleanCoercerTest < Minitest::Test
def setup
@coercer = Typed::Coercion::BooleanCoercer.new
@field = Typed::Field.new(name: :capital, type: T::Utils.coerce(T::Boolean))
end

def test_used_for_type_works
assert(@coercer.used_for_type?(T::Utils.coerce(T::Boolean)))
refute(@coercer.used_for_type?(Integer))
end

def test_when_boolean_field_given_returns_failure
result = @coercer.coerce(field: Typed::Field.new(name: :testing, type: Integer), value: "testing")

assert_failure(result)
assert_error(Typed::Coercion::CoercionError.new("Field type must be a T::Boolean."), result)
end

def test_when_true_boolean_can_be_coerced_returns_success
result = @coercer.coerce(field: @field, value: "true")

assert_success(result)
assert_payload(true, result)
end

def test_when_false_boolean_can_be_coerced_returns_success
result = @coercer.coerce(field: @field, value: "false")

assert_success(result)
assert_payload(false, result)
end

def test_when_enum_cannot_be_coerced_returns_failure
result = @coercer.coerce(field: @field, value: "bad")

assert_failure(result)
assert_error(Typed::Coercion::CoercionError.new, result)
end
end

0 comments on commit acd220f

Please sign in to comment.