# frozen_string_literal: true require 'spec_helper' RSpec.describe 'Attributes rendering', type: :render do it 'parses attributes' do expect(render_string('%span{class: "x"} hello')).to eq(%Q{hello\n}) end it 'parses attributes' do expect(render_string('%span{class: "x", "old" => 2} hello')).to eq(%Q{hello\n}) end it 'renders attributes with symbol literal' do expect(render_string("%span{foo: 'baz'}")).to eq("\n") expect(render_string("%span{:foo => 'baz'}")).to eq("\n") expect(render_string("%span{:'foo-bar' => 'baz'}")).to eq("\n") end if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.2.0') it 'renders attributes with 2.2-style symbol literals' do expect(render_string(%q|%span{"foo": 'bar'}|)).to eq("\n") expect(render_string(%Q|- x = 'bar'\n%span{"foo": x}|)).to eq("\n") expect(render_string(%q|%span{'foo': 'bar'}|)).to eq("\n") expect(render_string(%Q|- x = 'bar'\n%span{'foo': x}|)).to eq("\n") end end it 'renders dynamic attributes' do expect(render_string(%q|%span#main{class: "na#{'ni'}ka"} hello|)).to eq(%Q{hello\n}) end it 'renders boolean attributes' do with_each_attribute_type(:checked, 'true', tag: 'input') do |str| expect(render_string(str)).to eq("\n") end with_each_attribute_type(:checked, 'false', tag: 'input') do |str| expect(render_string(str)).to eq("\n") end with_each_attribute_type(:checked, 'nil', tag: 'input') do |str| expect(render_string(str)).to eq("\n") end end it 'skips falsey values after merging attributes' do expect(render_string(<\n") - h1 = { foo: 'should be overwritten' } - h2 = { foo: nil } %a{h1, h2} HAML end it 'renders duplicated keys correctly' do expect(render_string("%span{foo: 1, 'foo' => 2}")).to eq("\n") expect(render_string("- v = 2\n%span{foo: 1, 'foo' => v}")).to eq("\n") expect(render_string("- h = {foo: 1, 'foo' => 2}\n%span{h}")).to eq("\n") end it 'escapes' do with_each_attribute_type(:foo, %q|"x\"y'z"|, text: 'hello') do |str| expect(render_string(str)).to eq(%Q{hello\n}) end end it 'does not escape slash' do with_each_attribute_type(:href, "'http://example.com/'", tag: 'a') do |str| expect(render_string(str)).to eq(%Q{\n}) end end it 'raises error when unparsable Ruby code is given' do expect { render_string('%span{x ==== 2}') }.to raise_error(Faml::UnparsableRubyCode) end context 'with xhtml format' do it 'renders name="name" if value is true' do with_each_attribute_type(:foo, 'true', text: 'hello') do |str| expect(render_string(str, format: :xhtml)).to eq(%Q{hello\n}) end end end it 'renders dstr attributes' do expect(render_string(<hello\n|) - data = { foo: 1 } %span{data: "x\#{data}y"} hello HAML end it 'renders __LINE__ correctly' do expect(render_string(<\n") %span{b: __LINE__, a: __LINE__} HAML end it 'allows NUL characters' do expect(render_string('%span{"foo\0bar" => "hello"}')).to eq("\n") expect(render_string(<<'HAML')).to eq("\n") - val = "hello" %span{"foo\0bar" => val} HAML expect(render_string(<<'HAML')).to eq("\n") - key = "foo\0bar" - val = "hello" %span{key => val} HAML end describe 'object reference' do it 'renders id and class attribute' do expect(render_string('%span[Faml::TestStruct.new(123)] hello')).to eq("hello\n") end it 'renders id and class attribute with prefix' do expect(render_string('%span[Faml::TestStruct.new(123), :hello] hello')).to eq("hello\n") end it 'renders id and class attribute with haml_object_ref' do expect(render_string('%span[Faml::TestRefStruct.new(123)] hello')).to eq("hello\n") end it 'renders id in correct order' do expect(render_string('%span#baz[Faml::TestStruct.new(123)]{id: "foo"} hello')).to eq("hello\n") end end context 'when old attributes and new attributes have the same key' do it 'prefers old attributes' do aggregate_failures do expect(render_string('%span{foo: 1}(foo=2)')).to eq("\n") expect(render_string('%span(foo=2){foo: 1}')).to eq("\n") expect(render_string("- v = 2\n%span{foo: v-1}(foo=v)")).to eq("\n") expect(render_string("- v = 2\n%span(foo=v){foo: v-1}")).to eq("\n") expect(render_string("- h = {foo: 1}\n%span{h}(foo=2)")).to eq("\n") expect(render_string("- h = {foo: 1}\n%span(foo=2){h}")).to eq("\n") end end it 'merges class attribute' do aggregate_failures do expect(render_string('%span{class: 1}(class=2)')).to eq("\n") expect(render_string("- v = 2\n%span{class: v-1}(class=v)")).to eq("\n") expect(render_string("- h = {class: 1}\n%span{h}(class=2)")).to eq("\n") end end it 'merges id attribute' do aggregate_failures do expect(render_string('%span{id: 1}(id=2)')).to eq("\n") expect(render_string('%span(id=2){id: 1}')).to eq("\n") expect(render_string("- v = 2\n%span{id: v-1}(id=v)")).to eq("\n") expect(render_string("- v = 2\n%span(id=v){id: v-1}")).to eq("\n") expect(render_string("- h = {id: 1}\n%span{h}(id=2)")).to eq("\n") expect(render_string("- h = {id: 1}\n%span(id=2){h}")).to eq("\n") end end end end