From 4057969bdd4d741ace671e4a420fed5546fa4ff3 Mon Sep 17 00:00:00 2001 From: Max VelDink Date: Wed, 13 Mar 2024 15:57:49 -0400 Subject: [PATCH] test: Prove booleans can be serialized and deserialized --- lib/typed/coercion/boolean_coercer.rb | 2 +- lib/typed/field.rb | 2 +- test/support/structs/city.rb | 11 +++++++++++ test/support/structs/country.rb | 10 ++++++++++ test/typed/hash_serializer_test.rb | 14 ++++++++++++++ test/typed/json_serializer_test.rb | 14 ++++++++++++++ 6 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/support/structs/city.rb create mode 100644 test/support/structs/country.rb diff --git a/lib/typed/coercion/boolean_coercer.rb b/lib/typed/coercion/boolean_coercer.rb index 08f0b74..0ed09d4 100644 --- a/lib/typed/coercion/boolean_coercer.rb +++ b/lib/typed/coercion/boolean_coercer.rb @@ -23,7 +23,7 @@ def coerce(field:, value:) else Failure.new(CoercionError.new) end - rescue TypeError => e + rescue TypeError Failure.new(CoercionError.new("Field type must be a T::Boolean.")) end end diff --git a/lib/typed/field.rb b/lib/typed/field.rb index 88349b0..b22ad28 100644 --- a/lib/typed/field.rb +++ b/lib/typed/field.rb @@ -29,7 +29,7 @@ def validate(value) sig { params(value: Value).returns(T::Boolean) } def works_with?(value) - value.class == type || T.cast(type, T::Types::Base).valid?(value) + value.class == type || T.cast(type, T::Types::Base).valid?(value) # standard:disable Style/ClassEqualityComparison rescue TypeError false end diff --git a/test/support/structs/city.rb b/test/support/structs/city.rb new file mode 100644 index 0000000..0ce275a --- /dev/null +++ b/test/support/structs/city.rb @@ -0,0 +1,11 @@ +# typed: true + +class City < T::Struct + include ActsAsComparable + + const :name, String + const :capital, T::Boolean +end + +NEW_YORK_CITY = City.new(name: "New York", capital: false) +DC_CITY = City.new(name: "DC", capital: true) diff --git a/test/support/structs/country.rb b/test/support/structs/country.rb new file mode 100644 index 0000000..e4a7e3f --- /dev/null +++ b/test/support/structs/country.rb @@ -0,0 +1,10 @@ +# typed: true + +require_relative "city" + +class Country < T::Struct + const :name, String + const :cities, T::Array[City] +end + +US_COUNTRY = Country.new(name: "US", cities: [NEW_YORK_CITY, DC_CITY]) diff --git a/test/typed/hash_serializer_test.rb b/test/typed/hash_serializer_test.rb index 0df1cde..c96702b 100644 --- a/test/typed/hash_serializer_test.rb +++ b/test/typed/hash_serializer_test.rb @@ -30,6 +30,13 @@ def test_it_can_deep_serialize assert_payload({name: "Alex", age: 31, ruby_rank: "pretty", job: {title: "Software Developer", salary: 1_000_000_00}}, result) end + def test_with_boolean_it_can_serialize + result = Typed::HashSerializer.new(schema: Typed::Schema.from_struct(City)).serialize(NEW_YORK_CITY) + + assert_success(result) + assert_payload({name: "New York", capital: false}, result) + end + def test_when_struct_given_is_not_of_target_type_returns_failure result = @serializer.serialize(Job.new(title: "Testing", salary: 90_00)) @@ -53,6 +60,13 @@ def test_it_can_simple_deserialize_from_string_keys assert_payload(MAX_PERSON, result) end + def test_with_boolean_it_can_deserialize + result = Typed::HashSerializer.new(schema: Typed::Schema.from_struct(City)).deserialize({name: "New York", capital: false}) + + assert_success(result) + assert_payload(NEW_YORK_CITY, result) + end + def test_it_can_deserialize_with_nested_object result = @serializer.deserialize({name: "Alex", age: 31, ruby_rank: RubyRank::Brilliant, job: {title: "Software Developer", salary: 1_000_000_00}}) diff --git a/test/typed/json_serializer_test.rb b/test/typed/json_serializer_test.rb index 1546abb..0954bed 100644 --- a/test/typed/json_serializer_test.rb +++ b/test/typed/json_serializer_test.rb @@ -23,6 +23,13 @@ def test_it_can_serialize_with_nested_struct assert_payload('{"name":"Alex","age":31,"ruby_rank":"pretty","job":{"title":"Software Developer","salary":100000000}}', result) end + def test_with_boolean_it_can_serialize + result = Typed::JSONSerializer.new(schema: Typed::Schema.from_struct(City)).serialize(NEW_YORK_CITY) + + assert_success(result) + assert_payload('{"name":"New York","capital":false}', result) + end + # Deserialize Tests def test_it_can_simple_deserialize @@ -32,6 +39,13 @@ def test_it_can_simple_deserialize assert_payload(MAX_PERSON, result) end + def test_with_boolean_it_can_deserialize + result = Typed::JSONSerializer.new(schema: Typed::Schema.from_struct(City)).deserialize('{"name":"New York","capital":false}') + + assert_success(result) + assert_payload(NEW_YORK_CITY, result) + end + def test_it_can_deserialize_with_nested_object result = @serializer.deserialize('{"name":"Alex","age":31,"ruby_rank":"pretty","job":{"title":"Software Developer","salary":100000000}}')