From 55316b195ad5834672ee09eafbc6e653d4e4da78 Mon Sep 17 00:00:00 2001 From: Nikita Shilnikov Date: Sun, 5 Jan 2025 20:53:57 +0100 Subject: [PATCH] Better visibility for values in enum type (fix #460) --- lib/dry/types/enum.rb | 20 +++++++++++++++++ lib/dry/types/printer.rb | 3 +-- spec/dry/types/enum_spec.rb | 44 +++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/lib/dry/types/enum.rb b/lib/dry/types/enum.rb index b6a34894..97a2d648 100644 --- a/lib/dry/types/enum.rb +++ b/lib/dry/types/enum.rb @@ -88,6 +88,26 @@ def each_value(&) alias_method :inspect, :to_s + # @return [String] + # + # @api public + def name + "#{super}(#{joined_values})" + end + + # @return [String] + # + # @api private + def joined_values + mapping.keys.map { |value| + if value.is_a?(::String) + value + else + value.inspect + end + }.join("|") + end + private # Maps a value diff --git a/lib/dry/types/printer.rb b/lib/dry/types/printer.rb index 9b758409..937cb9d9 100644 --- a/lib/dry/types/printer.rb +++ b/lib/dry/types/printer.rb @@ -114,8 +114,7 @@ def visit_enum(enum) visit_options(options) do |opts| if mapping == enum.inverted_mapping - values = mapping.values.map(&:inspect).join(", ") - yield "Enum<#{type} values={#{values}}#{opts}>" + yield "Enum(#{enum.joined_values})<#{type}#{opts}>" else mapping_str = mapping.map { |key, value| "#{key.inspect}=>#{value.inspect}" diff --git a/spec/dry/types/enum_spec.rb b/spec/dry/types/enum_spec.rb index 44e35051..0eb0f05a 100644 --- a/spec/dry/types/enum_spec.rb +++ b/spec/dry/types/enum_spec.rb @@ -155,8 +155,30 @@ it "returns string representation of the type" do expect(type.to_s).to eql( - "# " \ - "rule=[included_in?([4, 5, 6])]> values={4, 5, 6}>]>" + "# " \ + "rule=[included_in?([4, 5, 6])]>>]>" + ) + end + end + + context "symbols" do + subject(:type) { Dry::Types["nominal.symbol"].enum(:draft, :published, :archived) } + + it "returns string representation of the type" do + expect(type.to_s).to eql( + "# " \ + "rule=[included_in?([:draft, :published, :archived])]>>]>" + ) + end + end + + context "strings" do + subject(:type) { Dry::Types["nominal.string"].enum("draft", "published", "archived") } + + it "returns string representation of the type" do + expect(type.to_s).to eql( + "# " \ + "rule=[included_in?([\"draft\", \"published\", \"archived\"])]>>]>" ) end end @@ -215,4 +237,22 @@ expect(type.constructor(&:to_i).mapping).to eql(4 => 4, 5 => 5) end end + + describe "#name" do + subject(:type) { Dry::Types["nominal.integer"].enum(4, 5, 6) } + + it "returns the name of the type" do + expect(type.name).to eql("Integer(4|5|6)") + end + + context "with mapping" do + let(:mapping) { {0 => "draft", 10 => "published", 20 => "archived"} } + + subject(:type) { Dry::Types["nominal.integer"].enum(mapping) } + + it "returns the name of the type" do + expect(type.name).to eql("Integer(0|10|20)") + end + end + end end