From 3de199f632f055ea326ea53327a802ecf47a48bf Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Sun, 8 Nov 2026 01:09:18 +0530 Subject: [PATCH] fix(type): support nilable elements in ArrayOf and HashOf case equality --- lib/context_dev/internal/type/array_of.rb | 2 +- lib/context_dev/internal/type/hash_of.rb | 2 ++ .../internal/type/base_model_test.rb | 27 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/context_dev/internal/type/array_of.rb b/lib/context_dev/internal/type/array_of.rb index bc000d46..7f6d09d6 100644 --- a/lib/context_dev/internal/type/array_of.rb +++ b/lib/context_dev/internal/type/array_of.rb @@ -38,7 +38,7 @@ def self.[](...) = new(...) # @param other [Object] # # @return [Boolean] - def ===(other) = other.is_a?(Array) && other.all?(item_type) + def ===(other) = other.is_a?(Array) && other.all? { (nilable? && _1.nil?) || item_type === _1 } # @api public # diff --git a/lib/context_dev/internal/type/hash_of.rb b/lib/context_dev/internal/type/hash_of.rb index 31013889..b02ece88 100644 --- a/lib/context_dev/internal/type/hash_of.rb +++ b/lib/context_dev/internal/type/hash_of.rb @@ -46,6 +46,8 @@ def ===(other) case [key, val] in [Symbol | String, ^type] true + in [Symbol | String, nil] if nilable? + true else false end diff --git a/test/context_dev/internal/type/base_model_test.rb b/test/context_dev/internal/type/base_model_test.rb index f3de30e8..6674368a 100644 --- a/test/context_dev/internal/type/base_model_test.rb +++ b/test/context_dev/internal/type/base_model_test.rb @@ -725,3 +725,30 @@ def test_meta_retrieval assert_equal({doc: "dawg"}, ub) end end + +class ContextDev::Test::NilableCollectionCaseEqualityTest < Minitest::Test + def test_array_of_nilable_case_equality + arr_type = ContextDev::Internal::Type::ArrayOf[String, nil?: true] + assert_operator(arr_type, :===, ["hello", nil]) + assert_operator(arr_type, :===, [nil]) + assert_operator(arr_type, :===, ["hello", "world"]) + refute_operator(arr_type, :===, ["hello", 123]) + + non_nilable = ContextDev::Internal::Type::ArrayOf[String] + assert_operator(non_nilable, :===, ["hello", "world"]) + refute_operator(non_nilable, :===, ["hello", nil]) + end + + def test_hash_of_nilable_case_equality + hash_type = ContextDev::Internal::Type::HashOf[String, nil?: true] + assert_operator(hash_type, :===, {a: "hello", b: nil}) + assert_operator(hash_type, :===, {"a" => "hello", "b" => nil}) + assert_operator(hash_type, :===, {a: nil}) + assert_operator(hash_type, :===, {a: "hello"}) + refute_operator(hash_type, :===, {a: 123}) + + non_nilable = ContextDev::Internal::Type::HashOf[String] + assert_operator(non_nilable, :===, {a: "hello", b: "world"}) + refute_operator(non_nilable, :===, {a: "hello", b: nil}) + end +end