From cdeb96609b17aa7c7d9bd62b3692ab41a14bad04 Mon Sep 17 00:00:00 2001 From: Ross Becker Date: Fri, 10 Feb 2023 09:16:17 -0800 Subject: [PATCH 1/2] add support for nested attribute hashes rendered as hyphen separated flat attributes --- lib/arbre/html/attributes.rb | 14 +++++- spec/arbre/unit/html/tag_attributes_spec.rb | 48 ++++++++++++++++++--- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/lib/arbre/html/attributes.rb b/lib/arbre/html/attributes.rb index d216b43d..8fd92bf6 100644 --- a/lib/arbre/html/attributes.rb +++ b/lib/arbre/html/attributes.rb @@ -5,7 +5,7 @@ module HTML class Attributes < Hash def to_s - map do |name, value| + flatten_hash.map do |name, value| next if value_empty?(value) "#{html_escape(name)}=\"#{html_escape(value)}\"" end.compact.join ' ' @@ -17,6 +17,18 @@ def any? protected + def flatten_hash(hash = self, old_path = [], accumulator = {}) + hash.each do |key, value| + path = old_path + [key] + if value.is_a? Hash + flatten_hash(value, path, accumulator) + else + accumulator[path.join('-')] = value + end + end + accumulator + end + def value_empty?(value) value.respond_to?(:empty?) ? value.empty? : !value end diff --git a/spec/arbre/unit/html/tag_attributes_spec.rb b/spec/arbre/unit/html/tag_attributes_spec.rb index b41e983e..8798a0d6 100644 --- a/spec/arbre/unit/html/tag_attributes_spec.rb +++ b/spec/arbre/unit/html/tag_attributes_spec.rb @@ -13,16 +13,50 @@ expect(tag.attributes).to eq({id: "my_id"}) end - it "should render the attributes to html" do - expect(tag.to_s).to eq "\n" + describe "#to_s" do + it "should render the attributes to html" do + expect(tag.to_s).to eq "\n" + end + + it "shouldn't render attributes that are empty" do + tag.class_list # initializes an empty ClassList + tag.set_attribute :foo, '' + tag.set_attribute :bar, nil + + expect(tag.to_s).to eq "\n" + end + + context "when there is a nested attribute" do + before { tag.build id: "my_id", data: { action: 'some_action' } } + + it "should flatten the attributes when rendering to html" do + expect(tag.to_s).to eq "\n" + end + + it "shouldn't render attributes that are empty" do + tag.class_list # initializes an empty ClassList + tag.set_attribute :foo, { bar: '' } + tag.set_attribute :bar, { baz: nil } + + expect(tag.to_s).to eq "\n" + end + end + end + + context "when there is a deeply nested attribute" do + before { tag.build id: "my_id", foo: { bar: { baz: 'foozle' } } } + + it "should flatten the attributes when rendering to html" do + expect(tag.to_s).to eq "\n" + end end - it "shouldn't render attributes that are empty" do - tag.class_list # initializes an empty ClassList - tag.set_attribute :foo, '' - tag.set_attribute :bar, nil + context "when there are multiple nested attributes" do + before { tag.build id: "my_id", foo: { bar: 'foozle1', baz: 'foozle2' } } - expect(tag.to_s).to eq "\n" + it "should flatten the attributes when rendering to html" do + expect(tag.to_s).to eq "\n" + end end it "should get an attribute value" do From faf4f99f7925d61f8424739cb2fbf8c6c5e68e0c Mon Sep 17 00:00:00 2001 From: Ross Becker Date: Fri, 10 Feb 2023 17:36:55 -0800 Subject: [PATCH 2/2] move two more tests inside #to_s context --- spec/arbre/unit/html/tag_attributes_spec.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/arbre/unit/html/tag_attributes_spec.rb b/spec/arbre/unit/html/tag_attributes_spec.rb index 8798a0d6..19b9c6d5 100644 --- a/spec/arbre/unit/html/tag_attributes_spec.rb +++ b/spec/arbre/unit/html/tag_attributes_spec.rb @@ -41,21 +41,21 @@ expect(tag.to_s).to eq "\n" end end - end - context "when there is a deeply nested attribute" do - before { tag.build id: "my_id", foo: { bar: { baz: 'foozle' } } } + context "when there is a deeply nested attribute" do + before { tag.build id: "my_id", foo: { bar: { baz: 'foozle' } } } - it "should flatten the attributes when rendering to html" do - expect(tag.to_s).to eq "\n" + it "should flatten the attributes when rendering to html" do + expect(tag.to_s).to eq "\n" + end end - end - context "when there are multiple nested attributes" do - before { tag.build id: "my_id", foo: { bar: 'foozle1', baz: 'foozle2' } } + context "when there are multiple nested attributes" do + before { tag.build id: "my_id", foo: { bar: 'foozle1', baz: 'foozle2' } } - it "should flatten the attributes when rendering to html" do - expect(tag.to_s).to eq "\n" + it "should flatten the attributes when rendering to html" do + expect(tag.to_s).to eq "\n" + end end end