padrino-helpers 0.18.2 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 924909fe1054736b28e1ab952d79295455cb02678e634fadf70632672baaee66
4
- data.tar.gz: 53e1a1f8c8e69f4723355f0857e69196543cd72cd1d6e90b526481f446b24350
3
+ metadata.gz: 35050a53fc94cf2c43d7594e7de3cc42b18a84aef606a6f200105dd96ec0aaa3
4
+ data.tar.gz: 1d7736573b50b4eab2443e94708cb4885afbee1b551bc822c94964907838b548
5
5
  SHA512:
6
- metadata.gz: 022652651c54083698e889064b555ae5262d041e770f80880a22998f0c95c4ce30302952b51aa6e338a4b58a61de76a9a4be377e6ab1108aec53e860ff700730
7
- data.tar.gz: 14c646b16ad8a04f93f828b888de6bf2ec6dc20d6ff36d28aa2e93da3dcfdafc1fac514964be0bbe03fd451eaf8b7bab58e83fe4e41f27506ad43ec440176111
6
+ metadata.gz: d7c76cd3c24cd86eb0f74a4c13dbcb2df2146e35115c50092a45b353e5b6055ff1b249452994718a225f542b37bb0f560d5672f5d7bbb55b96e512b4954c8b64
7
+ data.tar.gz: dbb2af3ccc585f139ccbe8397e2e866a8e374674ce30363d92736cf78cf27a39d29279f011ed7baec531f72fff231093ac47d691c431d742dd3c1959dde3b0ce
@@ -52,7 +52,7 @@ module Padrino
52
52
  # it will create one and assign it to the session's `csrf` key.
53
53
  #
54
54
  def csrf_token
55
- session[:csrf] ||= SecureRandom.hex(32) if defined?(session)
55
+ session[:csrf] ||= SecureRandom.urlsafe_base64(32) if defined?(session)
56
56
  end
57
57
 
58
58
  ##
@@ -203,6 +203,7 @@ module Padrino
203
203
  # The html pattern for wrapping the highlighted words.
204
204
  #
205
205
  # @return [String] The text with the words specified wrapped with highlighted spans.
206
+ # Words inside HTML tags (tag names and attributes) are left as they are.
206
207
  #
207
208
  # @example
208
209
  # highlight('Lorem ipsum dolor sit amet', 'dolor')
@@ -217,8 +218,10 @@ module Padrino
217
218
  if text.empty? || words.empty?
218
219
  text
219
220
  else
220
- match = Array(words).map { |p| Regexp.escape(p) }.join('|')
221
- text.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter])
221
+ pattern = /(#{Array(words).map { |p| Regexp.escape(p) }.join('|')})/i
222
+ text.to_str.gsub(%r{(<[A-Za-z/!?](?:=\s*+"[^"]*+"|=\s*+'[^']*+'|[^<>])*+>?)|(?:[^<]|<(?![A-Za-z/!?]))++}) do |part|
223
+ Regexp.last_match(1) || part.gsub(pattern, options[:highlighter])
224
+ end
222
225
  end
223
226
  end
224
227
 
@@ -135,14 +135,19 @@ module Padrino
135
135
  def number_with_delimiter(number, *args)
136
136
  options = args.last.is_a?(Hash) ? Utils.symbolize_keys(args.pop) : {}
137
137
 
138
- defaults = I18n.translate(:'number.format', locale: options[:locale], raise: true) rescue {}
138
+ delimiter = options[:delimiter]
139
+ separator = options[:separator]
140
+ unless delimiter && separator
141
+ defaults = I18n.translate(:'number.format', locale: options[:locale], raise: true) rescue {}
139
142
 
140
- delimiter ||= options[:delimiter] || defaults[:delimiter]
141
- separator ||= options[:separator] || defaults[:separator]
143
+ delimiter ||= defaults[:delimiter]
144
+ separator ||= defaults[:separator]
145
+ end
142
146
 
143
147
  begin
144
148
  parts = number.to_s.split('.')
145
- parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
149
+ reversed_delimiter = delimiter.to_s.reverse
150
+ parts[0].gsub!(/\d+/) { |digits| digits.reverse.scan(/\d{1,3}/).join(reversed_delimiter).reverse }
146
151
  parts.join(separator)
147
152
  rescue StandardError
148
153
  number
@@ -178,14 +183,19 @@ module Padrino
178
183
  def number_with_precision(number, *args)
179
184
  options = args.last.is_a?(Hash) ? Utils.symbolize_keys(args.pop) : {}
180
185
 
181
- defaults = I18n.translate(:'number.format', locale: options[:locale], raise: true) rescue {}
182
- precision_defaults = I18n.translate(:'number.precision.format', locale: options[:locale],
183
- raise: true) rescue {}
184
- defaults = defaults.merge(precision_defaults)
186
+ precision = options[:precision]
187
+ separator = options[:separator]
188
+ delimiter = options[:delimiter]
189
+ unless precision && separator && delimiter
190
+ defaults = I18n.translate(:'number.format', locale: options[:locale], raise: true) rescue {}
191
+ precision_defaults = I18n.translate(:'number.precision.format', locale: options[:locale],
192
+ raise: true) rescue {}
193
+ defaults = defaults.merge(precision_defaults)
185
194
 
186
- precision ||= options[:precision] || defaults[:precision]
187
- separator ||= options[:separator] || defaults[:separator]
188
- delimiter ||= options[:delimiter] || defaults[:delimiter]
195
+ precision ||= defaults[:precision]
196
+ separator ||= defaults[:separator]
197
+ delimiter ||= defaults[:delimiter]
198
+ end
189
199
 
190
200
  begin
191
201
  rounded_number = (Float(number) * (10**precision)).round.to_f / 10**precision
@@ -9,7 +9,7 @@ module Padrino
9
9
  # Outputs the given text to the templates buffer directly.
10
10
  #
11
11
  def concat_to_template(text = '', context = nil)
12
- return text if context&.eval('@__in_ruby_literal')
12
+ return text if context&.receiver&.instance_variable_get(:@__in_ruby_literal)
13
13
  output_buffer << text
14
14
  nil
15
15
  end
@@ -18,7 +18,7 @@ module Padrino
18
18
  # Returns true if the block is Erb.
19
19
  #
20
20
  def engine_matches?(block)
21
- block.binding.eval('defined? __in_erb_template')
21
+ block.binding.local_variable_defined?(:__in_erb_template)
22
22
  end
23
23
  end
24
24
  OutputHelpers.register(:erb, ErbHandler)
@@ -10,7 +10,7 @@ module Padrino
10
10
  # Returns true if the block is for Hamlit.
11
11
  #
12
12
  def engine_matches?(block)
13
- block.binding.eval('defined? __in_hamlit_template')
13
+ block.binding.local_variable_defined?(:__in_hamlit_template)
14
14
  end
15
15
  end
16
16
  OutputHelpers.register(:haml, HamlitHandler)
@@ -43,7 +43,7 @@ module Padrino
43
43
  # Returns true if the block is for Hamlit.
44
44
  #
45
45
  def engine_matches?(block)
46
- block.binding.eval('defined? __in_hamlit_template')
46
+ block.binding.local_variable_defined?(:__in_hamlit_template)
47
47
  end
48
48
  end
49
49
  OutputHelpers.register(:haml, HamlitHandler)
@@ -9,7 +9,7 @@ module Padrino
9
9
  # Returns true if the block is for Slim.
10
10
  #
11
11
  def engine_matches?(block)
12
- block.binding.eval('defined? __in_slim_template')
12
+ block.binding.local_variable_defined?(:__in_slim_template)
13
13
  end
14
14
  end
15
15
  OutputHelpers.register(:slim, SlimHandler)
@@ -41,6 +41,9 @@ module Padrino
41
41
  novalidate
42
42
  ].freeze
43
43
 
44
+ BOOLEAN_ATTRIBUTE_LOOKUP = BOOLEAN_ATTRIBUTES.to_h { |attribute| [attribute, true] }.freeze
45
+ private_constant :BOOLEAN_ATTRIBUTE_LOOKUP
46
+
44
47
  ##
45
48
  # Custom data attributes,
46
49
  # feel free to update with yours:
@@ -278,19 +281,21 @@ module Padrino
278
281
  def tag_attributes(options)
279
282
  return '' unless options
280
283
 
281
- options.inject(+'') do |all, (key, value)|
282
- next all unless value
284
+ all = +''
285
+ options.each do |key, value|
286
+ next unless value
283
287
 
284
288
  all << ' ' if all.empty?
285
289
  all <<
286
290
  if value.is_a?(Hash)
287
291
  nested_values(key, value)
288
- elsif BOOLEAN_ATTRIBUTES.include?(key)
292
+ elsif BOOLEAN_ATTRIBUTE_LOOKUP.key?(key)
289
293
  %(#{key}="#{key}" )
290
294
  else
291
295
  %(#{key}="#{escape_value(value)}" )
292
296
  end
293
- end.chomp!(' ')
297
+ end
298
+ all.chomp!(' ')
294
299
  end
295
300
 
296
301
  ##
@@ -298,7 +303,8 @@ module Padrino
298
303
  #
299
304
  def escape_value(string)
300
305
  string = string.collect(&:to_s).join(' ') if string.is_a?(Array)
301
- string.to_s.gsub(ESCAPE_REGEXP, ESCAPE_VALUES)
306
+ string = string.to_s
307
+ string.match?(ESCAPE_REGEXP) ? string.gsub(ESCAPE_REGEXP, ESCAPE_VALUES) : string
302
308
  end
303
309
 
304
310
  ##
@@ -321,6 +327,8 @@ module Padrino
321
327
  #
322
328
  def parse_data_options(tag, options)
323
329
  return unless options
330
+ return options unless DATA_ATTRIBUTES.any? { |key| options.key?(key) }
331
+
324
332
  parsed_options = options.dup
325
333
  options.each_key do |key|
326
334
  next if !DATA_ATTRIBUTES.include?(key) || (tag.to_s == 'form' && key == :method)
@@ -42,6 +42,14 @@ class MarkupDemo < Sinatra::Base
42
42
  end
43
43
  end
44
44
 
45
+ def block_is_template_value(&block)
46
+ block_is_template?(block).inspect
47
+ end
48
+
49
+ def ruby_block_is_template_value
50
+ block_is_template_value { 'This not a template block' }
51
+ end
52
+
45
53
  def content_tag_with_block
46
54
  one = content_tag(:p) do
47
55
  'one'
@@ -0,0 +1,5 @@
1
+ <% value = block_is_template_value do %>
2
+ <span>This is erb</span>
3
+ <% end %>
4
+ <p class="template"><%= value %></p>
5
+ <p class="ruby"><%= ruby_block_is_template_value %></p>
@@ -0,0 +1,4 @@
1
+ - value = block_is_template_value do
2
+ %span This is haml
3
+ %p.template= value
4
+ %p.ruby= ruby_block_is_template_value
@@ -0,0 +1,4 @@
1
+ - value = block_is_template_value do
2
+ span This is slim
3
+ p.template = value
4
+ p.ruby = ruby_block_is_template_value
@@ -113,6 +113,53 @@ describe 'FormatHelpers' do
113
113
  actual_text = highlight('Lorem ipsum dolor sit amet', 'dolor', highlighter: '<span class="custom">\1</span>')
114
114
  assert_equal 'Lorem ipsum <span class="custom">dolor</span> sit amet', actual_text
115
115
  end
116
+
117
+ it 'should leave words inside html tags alone' do
118
+ actual_text = highlight('<b class="b">bold</b> <a href="/b">b</a>', 'b')
119
+ assert_equal '<b class="b"><strong class="highlight">b</strong>old</b> <a href="/b"><strong class="highlight">b</strong></a>', actual_text
120
+ end
121
+
122
+ it 'should leave a quoted attribute alone when it holds a >' do
123
+ actual_text = highlight('<a title="x > y">y</a>', 'y')
124
+ assert_equal '<a title="x > y"><strong class="highlight">y</strong></a>', actual_text
125
+ end
126
+
127
+ it 'should leave a quoted attribute alone when it holds a <' do
128
+ actual_text = highlight(%(<a title="x < y" data-y='y < x'>y</a>), 'y')
129
+ assert_equal %(<a title="x < y" data-y='y < x'><strong class="highlight">y</strong></a>), actual_text
130
+ end
131
+
132
+ it 'should highlight text around a < that does not start a tag' do
133
+ assert_equal 'if a < b then <strong class="highlight">y</strong>', highlight('if a < b then y', 'y')
134
+ assert_equal 'if <strong class="highlight">a < b</strong> then y', highlight('if a < b then y', 'a < b')
135
+ assert_equal "<\u212A <strong class=\"highlight\">b</strong>", highlight("<\u212A b", 'b')
136
+ end
137
+
138
+ it 'should read a quote in a tag as a value only after =' do
139
+ actual_text = highlight("<img alt=it's> Ruby isn't", 'ruby')
140
+ assert_equal %(<img alt=it's> <strong class="highlight">Ruby</strong> isn't), actual_text
141
+ end
142
+
143
+ it 'should not split a tag at its closing >' do
144
+ assert_equal '<b>x</b>', highlight('<b>x</b>', '>x')
145
+ end
146
+
147
+ it 'should highlight long text in linear time' do
148
+ started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
149
+ actual_text = highlight('word ' * 20_000, 'word')
150
+ assert_operator Process.clock_gettime(Process::CLOCK_MONOTONIC) - started, :<, 2
151
+ assert_equal '<strong class="highlight">word</strong> ' * 20_000, actual_text
152
+ end
153
+
154
+ it 'should highlight html safe text' do
155
+ actual_text = highlight('<p>Lorem</p><p>ipsum dolor</p>'.html_safe, %w[lorem dolor])
156
+ assert_equal '<p><strong class="highlight">Lorem</strong></p><p>ipsum <strong class="highlight">dolor</strong></p>', actual_text
157
+ end
158
+
159
+ it 'should highlight several words across tags' do
160
+ actual_text = highlight('<p>Lorem</p><p>ipsum lorem</p>', %w[lorem ipsum])
161
+ assert_equal '<p><strong class="highlight">Lorem</strong></p><p><strong class="highlight">ipsum</strong> <strong class="highlight">lorem</strong></p>', actual_text
162
+ end
116
163
  end
117
164
 
118
165
  describe 'for #truncate method' do
data/test/test_helpers.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require_relative 'helper'
2
+ require 'padrino-core'
2
3
 
3
4
  describe 'Padrino::Helpers' do
4
5
  it 'should allow including without registering' do
@@ -15,4 +16,19 @@ describe 'Padrino::Helpers' do
15
16
  end
16
17
  assert_equal 'FancyBuilder', @app.default_builder
17
18
  end
19
+
20
+ it 'should write a form token that a later POST is accepted with' do
21
+ mock_app do
22
+ enable :sessions
23
+ disable :protection
24
+ set :protect_from_csrf, except: ['/signup']
25
+ get('/signup') { form_tag('/save') { '' } }
26
+ post('/save') { 'saved' }
27
+ end
28
+ get '/signup'
29
+ token = Nokogiri::HTML(last_response.body).at_css('input[name="authenticity_token"]')['value']
30
+ post '/save', authenticity_token: token
31
+ assert_equal 200, last_response.status
32
+ assert_equal 'saved', last_response.body
33
+ end
18
34
  end
@@ -62,10 +62,20 @@ describe 'NumberHelpers' do
62
62
  assert_equal '0.78901', number_with_delimiter(0.78901)
63
63
  assert_equal '123,456.78', number_with_delimiter('123456.78')
64
64
  assert_equal 'x', number_with_delimiter('x')
65
+ assert_equal '-1,234,567,890,123', number_with_delimiter('-1234567890123')
66
+ assert_equal '1,234x5,678', number_with_delimiter('1234x5678')
67
+ assert_equal '1\\1234\\1567', number_with_delimiter(1_234_567, delimiter: '\\1')
65
68
 
66
69
  assert_nil number_with_delimiter(nil)
67
70
  end
68
71
 
72
+ it 'should display number_with_delimiter in linear time' do
73
+ started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
74
+ actual = number_with_delimiter('1' * 100_000)
75
+ assert_operator Process.clock_gettime(Process::CLOCK_MONOTONIC) - started, :<, 2
76
+ assert_equal "1#{',111' * 33_333}", actual
77
+ end
78
+
69
79
  it 'should display number_with_delimiter with options' do
70
80
  assert_equal '12 345 678', number_with_delimiter(12_345_678, delimiter: ' ')
71
81
  assert_equal '12,345,678-05', number_with_delimiter(12_345_678.05, separator: '-')
@@ -92,6 +102,25 @@ describe 'NumberHelpers' do
92
102
  assert_equal '1.231,83', number_with_precision(1231.826, precision: 2, separator: ',', delimiter: '.')
93
103
  end
94
104
 
105
+ it 'should not look up the locale when every format option is given' do
106
+ I18n.backend.expects(:translate).never
107
+ assert_equal '1.234.567,89', number_with_precision(1_234_567.891, precision: 2, separator: ',', delimiter: '.')
108
+ assert_equal '1.234.567,891', number_with_delimiter(1_234_567.891, separator: ',', delimiter: '.')
109
+ assert_equal '1.235', number_with_precision(1234.5, precision: 0, separator: ',', delimiter: '.')
110
+ assert_equal '123457', number_with_precision(1234.567, precision: 2, separator: '', delimiter: '')
111
+ assert_equal '1234567,5', number_with_delimiter(1_234_567.5, separator: ',', delimiter: '')
112
+ assert_equal '1.234.5675', number_with_delimiter(1_234_567.5, separator: '', delimiter: '.')
113
+ end
114
+
115
+ it 'should take the format options not given from the locale' do
116
+ assert_equal '1234567,89', number_with_precision(1_234_567.891, precision: 2, locale: :de)
117
+ assert_equal '1234567.89', number_with_precision(1_234_567.891, precision: 2, separator: '.', locale: :de)
118
+ assert_equal '1 234 567,89', number_with_precision(1_234_567.891, separator: ',', delimiter: ' ', locale: :de)
119
+ assert_equal '1.234.567,891', number_with_delimiter(1_234_567.891, delimiter: '.', locale: :de)
120
+ assert_equal '1 234 567,891', number_with_delimiter(1_234_567.891, delimiter: ' ', locale: :de)
121
+ assert_equal '1.234.567;891', number_with_delimiter(1_234_567.891, separator: ';', locale: :de)
122
+ end
123
+
95
124
  it 'should display number_to_human_size' do
96
125
  assert_equal '0 Bytes', number_to_human_size(0)
97
126
  assert_equal '1 Byte', number_to_human_size(1)
@@ -93,19 +93,28 @@ describe 'OutputHelpers' do
93
93
  it 'should work for erb templates' do
94
94
  get '/erb/capture_concat'
95
95
  assert_response_has_tag 'p', content: 'The erb block passed in is a template', class: 'is_template', count: 1
96
- assert_response_has_no_tag 'p', content: 'The ruby block passed in is a template', class: 'is_template', count: 1
96
+ assert_response_has_no_tag 'p', content: 'The ruby block passed in is a template', class: 'is_template'
97
97
  end
98
98
 
99
99
  it 'should work for haml templates' do
100
100
  get '/haml/capture_concat'
101
101
  assert_response_has_tag 'p', content: 'The haml block passed in is a template', class: 'is_template', count: 1
102
- assert_response_has_no_tag 'p', content: 'The ruby block passed in is a template', class: 'is_template', count: 1
102
+ assert_response_has_no_tag 'p', content: 'The ruby block passed in is a template', class: 'is_template'
103
103
  end
104
104
 
105
105
  it 'should work for slim templates' do
106
106
  get '/slim/capture_concat'
107
107
  assert_response_has_tag 'p', content: 'The slim block passed in is a template', class: 'is_template', count: 1
108
- assert_response_has_no_tag 'p', content: 'The ruby block passed in is a template', class: 'is_template', count: 1
108
+ assert_response_has_no_tag 'p', content: 'The ruby block passed in is a template', class: 'is_template'
109
+ end
110
+
111
+ %w[erb haml slim].each do |engine|
112
+ it "should return true for a #{engine} template block and false for a Ruby block" do
113
+ get "/#{engine}/block_is_template"
114
+ html = Nokogiri::HTML(last_response.body)
115
+ assert_equal 'true', html.at_css('p.template').text
116
+ assert_equal 'false', html.at_css('p.ruby').text
117
+ end
109
118
  end
110
119
  end
111
120
 
@@ -12,7 +12,7 @@ describe 'RenderHelpers' do
12
12
  assert_response_has_tag 'h1', content: 'User name is John'
13
13
  end
14
14
  it 'should have no counter index for single item' do
15
- assert_response_has_no_tag 'p', content: 'My counter is 1', count: 1
15
+ assert_response_has_no_tag 'p', content: 'My counter is 1'
16
16
  end
17
17
  it 'should include extra locals information' do
18
18
  assert_response_has_tag 'p', content: 'Extra is bar'
@@ -47,7 +47,7 @@ describe 'RenderHelpers' do
47
47
  assert_response_has_tag 'h1', content: 'User name is John'
48
48
  end
49
49
  it 'should have no counter index for single item' do
50
- assert_response_has_no_tag 'p', content: 'My counter is 1', count: 1
50
+ assert_response_has_no_tag 'p', content: 'My counter is 1'
51
51
  end
52
52
  it 'should include extra locals information' do
53
53
  assert_response_has_tag 'p', content: 'Extra is bar'
@@ -52,6 +52,49 @@ describe 'TagHelpers' do
52
52
  actual_html = tag(:p, data: { foo: %i[bar baz] })
53
53
  assert_html_has_tag(actual_html, 'p', 'data-foo': 'bar baz')
54
54
  end
55
+
56
+ it 'should build the exact attribute string' do
57
+ assert_equal '<div class="x" />', tag(:div, data: {}, class: 'x')
58
+ assert_equal '<br />', tag(:br, id: nil, hidden: false)
59
+ assert_equal '<input checked="checked" name="a" />', tag(:input, checked: true, 'name' => 'a')
60
+ assert_equal '<a href="/x" data-method="delete" rel="nofollow" data-confirm="Sure?" />',
61
+ tag(:a, href: '/x', method: :delete, confirm: 'Sure?')
62
+ end
63
+
64
+ it 'should not change the options it is given' do
65
+ options = { class: 'btn', method: :delete }
66
+ 2.times { assert_equal '<a class="btn" data-method="delete" rel="nofollow" />', tag(:a, options) }
67
+ assert_equal({ class: 'btn', method: :delete }, options)
68
+ end
69
+
70
+ it 'should escape the values that need it and leave the others as they are' do
71
+ assert_equal '<input name="user[name]" value="Tom &amp; &lt;Jerry&gt; &quot;TJ&quot;" class="input" />',
72
+ tag(:input, name: 'user[name]', value: 'Tom & <Jerry> "TJ"', class: 'input')
73
+ end
74
+
75
+ it 'should escape a value whose only special character is a quote or an angle bracket' do
76
+ assert_equal '<a title="say &quot;hi&quot;" />', tag(:a, title: 'say "hi"')
77
+ assert_equal '<a title="&lt;b&gt;" />', tag(:a, title: '<b>')
78
+ assert_equal '<a title="a&lt;b" />', tag(:a, title: 'a<b')
79
+ assert_equal '<a title="a&gt;b" />', tag(:a, title: 'a>b')
80
+ end
81
+
82
+ it 'should write data attributes added to DATA_ATTRIBUTES' do
83
+ Padrino::Helpers::TagHelpers::DATA_ATTRIBUTES.push(:dialog)
84
+ assert_equal '<a data-dialog="true" />', tag(:a, dialog: true)
85
+ ensure
86
+ Padrino::Helpers::TagHelpers::DATA_ATTRIBUTES.delete(:dialog)
87
+ end
88
+
89
+ it 'should write Array, Symbol and Integer values' do
90
+ assert_equal '<td class="a &amp; b c" id="cell" colspan="2" />', tag(:td, class: ['a & b', :c], id: :cell, colspan: 2)
91
+ end
92
+
93
+ it 'should write data attributes only for the options that ask for them' do
94
+ assert_equal '<a href="/x" class="link" />', tag(:a, href: '/x', class: 'link')
95
+ assert_equal '<a href="/x" data-method="post" rel="nofollow" data-remote="true" data-confirm="Sure &amp; certain?" />',
96
+ tag(:a, href: '/x', method: :post, remote: true, confirm: 'Sure & certain?')
97
+ end
55
98
  end
56
99
 
57
100
  describe 'for #content_tag method' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: padrino-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.2
4
+ version: 0.18.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Padrino Team
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2026-11-01 00:00:00.000000000 Z
14
+ date: 2026-11-04 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: padrino-support
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - '='
21
21
  - !ruby/object:Gem::Version
22
- version: 0.18.2
22
+ version: 0.18.4
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.18.2
29
+ version: 0.18.4
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: tilt
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -139,6 +139,9 @@ files:
139
139
  - test/fixtures/apps/views/test/post.erb
140
140
  - test/fixtures/layouts/layout.erb
141
141
  - test/fixtures/markup_app/app.rb
142
+ - test/fixtures/markup_app/views/block_is_template.erb
143
+ - test/fixtures/markup_app/views/block_is_template.haml
144
+ - test/fixtures/markup_app/views/block_is_template.slim
142
145
  - test/fixtures/markup_app/views/button_to.erb
143
146
  - test/fixtures/markup_app/views/button_to.haml
144
147
  - test/fixtures/markup_app/views/button_to.slim