erubi 1.8.0 → 1.11.0

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: 30bbae115393cc4d2ff05acd506ebd7616aad0797454c91766b379bfbfecef8b
4
- data.tar.gz: 4dd7876504af9f3a17674875daad4233b9731c7bd3f195ecdf2e2507a2fa33b1
3
+ metadata.gz: 0424c43d37611204a83153f9cffb1e259027a0f1a1edd16b3b5cfef09ec7b137
4
+ data.tar.gz: 796b2b90f46c80297fdf05b3070f9bad10fc9199946878c0bfbfe7435ce5466c
5
5
  SHA512:
6
- metadata.gz: 380753f81d65b28686ccc285bb77ed998fe95ef179fea87b28c74701c833182225ba22f544fbc2276cad1f5d1c8309a3c837e5e78ba120806b49b8b675d2ba30
7
- data.tar.gz: 006365ddcb013ebb47789055993e176640ba8f285b4bb718c85d9a0793d7ba428587adab203976dc068dcb7fc0d466e76362f6fbcab7832d7463dfc05a7e3934
6
+ metadata.gz: 8833bc8ec00db215ef73c71271c97e668861f920c339de7df658f1cf464761b62b2811845a062b681bb30966b7797beec708674929aa9400159e1bfdce3c31dd
7
+ data.tar.gz: 74fa7a9107f056dbcb3bb2efedb858a7f120d8c36d378da1eb425783c75e2a398ffd4b301c1e300cc684b98155d9b67abb07d1589f1be9786282756a0140449b
data/CHANGELOG CHANGED
@@ -1,3 +1,23 @@
1
+ === 1.11.0 (2022-08-02)
2
+
3
+ * Support :freeze_template_literals option for configuring whether to add .freeze to template literal strings (casperisfine) (#33)
4
+
5
+ * Support :chain_appends option for chaining appends to the buffer variable (casperisfine, jeremyevans) (#32)
6
+
7
+ * Avoid unnecessary defined? usage on Ruby 3+ when using the :ensure option (jeremyevans)
8
+
9
+ === 1.10.0 (2020-11-13)
10
+
11
+ * Improve template parsing, mostly by reducing allocations (jeremyevans)
12
+
13
+ * Do not ship tests in the gem, reducing gem size about 20% (jeremyevans)
14
+
15
+ * Support :literal_prefix and :literal_postfix options for how to output literal tags (e.g. <%% code %>) (jaredcwhite) (#26, #27)
16
+
17
+ === 1.9.0 (2019-09-25)
18
+
19
+ * Change default :bufvar from 'String.new' to '::String.new' to work with BasicObject (jeremyevans)
20
+
1
21
  === 1.8.0 (2018-12-18)
2
22
 
3
23
  * Support :yield_returns_buffer option in capture_end for always returning the (potentially modified) buffer in <%|= tags (evanleck) (#15)
data/MIT-LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
2
- copyright(c) 2016-2018 Jeremy Evans
2
+ copyright(c) 2016-2021 Jeremy Evans
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -5,9 +5,9 @@ the same basic algorithm, with the following differences:
5
5
 
6
6
  * Handles postfix conditionals when using escaping (e.g. <tt><%= foo if bar %></tt>)
7
7
  * Supports frozen_string_literal: true in templates via :freeze option
8
- * Works with ruby's --enable-frozen-string-literal option
8
+ * Works with ruby's <tt>--enable-frozen-string-literal</tt> option
9
9
  * Automatically freezes strings for template text when ruby optimizes it (on ruby 2.1+)
10
- * Escapes ' (apostrophe) when escaping for better XSS protection
10
+ * Escapes <tt>'</tt> (apostrophe) when escaping for better XSS protection
11
11
  * Has 6x faster escaping on ruby 2.3+ by using cgi/escape
12
12
  * Has 86% smaller memory footprint
13
13
  * Does no monkey patching (Erubis adds a method to Kernel)
@@ -92,7 +92,7 @@ instance variable. Example:
92
92
  # </form>
93
93
  # after
94
94
 
95
- Alternatively, passing the option +:yield_returns_buffer => true+ will return the
95
+ Alternatively, passing the option <tt>:yield_returns_buffer => true</tt> will return the
96
96
  buffer captured by the block instead of the last expression in the block.
97
97
 
98
98
  = Reporting Bugs
data/Rakefile CHANGED
@@ -42,7 +42,7 @@ end
42
42
 
43
43
  spec = proc do |env|
44
44
  env.each{|k,v| ENV[k] = v}
45
- sh "#{FileUtils::RUBY} test/test.rb"
45
+ sh "#{FileUtils::RUBY} #{'-w' if RUBY_VERSION >= '3'} test/test.rb"
46
46
  env.each{|k,v| ENV.delete(k)}
47
47
  end
48
48
 
@@ -57,13 +57,6 @@ desc "Run specs with coverage"
57
57
  task "spec_cov" do
58
58
  spec.call('COVERAGE'=>'1')
59
59
  end
60
-
61
- desc "Run specs with -w, some warnings filtered"
62
- task "spec_w" do
63
- ENV['RUBYOPT'] ? (ENV['RUBYOPT'] += " -w") : (ENV['RUBYOPT'] = '-w')
64
- rake = ENV['RAKE'] || "#{FileUtils::RUBY} -S rake"
65
- sh %{#{rake} 2>&1 | egrep -v \": warning: instance variable @.* not initialized|: warning: method redefined; discarding old|: warning: previous definition of|: warning: statement not reached"}
66
- end
67
60
 
68
61
  ### Other
69
62
 
@@ -3,15 +3,15 @@
3
3
  require 'erubi'
4
4
 
5
5
  module Erubi
6
- # An engine class that supports capturing blocks via the <%|= and <%|== tags,
7
- # explicitly ending the captures using <%| end %> blocks.
6
+ # An engine class that supports capturing blocks via the <tt><%|=</tt> and <tt><%|==</tt> tags,
7
+ # explicitly ending the captures using <tt><%|</tt> end <tt>%></tt> blocks.
8
8
  class CaptureEndEngine < Engine
9
9
  # Initializes the engine. Accepts the same arguments as ::Erubi::Engine, and these
10
10
  # additional options:
11
- # :escape_capture :: Whether to make <%|= escape by default, and <%|== not escape by default,
11
+ # :escape_capture :: Whether to make <tt><%|=</tt> escape by default, and <tt><%|==</tt> not escape by default,
12
12
  # defaults to the same value as :escape.
13
- # :yield_returns_buffer :: Whether to have <%| tags insert the buffer as an expression, so that
14
- # <%| end %> tags will have the buffer be the last expression inside
13
+ # :yield_returns_buffer :: Whether to have <tt><%|</tt> tags insert the buffer as an expression, so that
14
+ # <tt><%| end %></tt> tags will have the buffer be the last expression inside
15
15
  # the block, and therefore have the buffer be returned by the yield
16
16
  # expression. Normally the buffer will be returned anyway, but there
17
17
  # are cases where the last expression will not be the buffer,
@@ -21,7 +21,7 @@ module Erubi
21
21
  escape = properties.fetch(:escape){properties.fetch(:escape_html, false)}
22
22
  @escape_capture = properties.fetch(:escape_capture, escape)
23
23
  @yield_returns_buffer = properties.fetch(:yield_returns_buffer, false)
24
- @bufval = properties[:bufval] ||= 'String.new'
24
+ @bufval = properties[:bufval] ||= '::String.new'
25
25
  @bufstack = '__erubi_stack'
26
26
  properties[:regexp] ||= /<%(\|?={1,2}|-|\#|%|\|)?(.*?)([-=])?%>([ \t]*\r?\n)?/m
27
27
  super
@@ -36,13 +36,19 @@ module Erubi
36
36
  rspace = nil if tailch && !tailch.empty?
37
37
  add_text(lspace) if lspace
38
38
  escape_capture = !((indicator == '|=') ^ @escape_capture)
39
- src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
39
+ terminate_expression
40
+ @src << "begin; (#{@bufstack} ||= []) << #{@bufvar}; #{@bufvar} = #{@bufval}; #{@bufstack}.last << #{@escapefunc if escape_capture}((" << code
41
+ @buffer_on_stack = false
40
42
  add_text(rspace) if rspace
41
43
  when '|'
42
44
  rspace = nil if tailch && !tailch.empty?
43
45
  add_text(lspace) if lspace
44
- result = @yield_returns_buffer ? " #{@bufvar}; " : ""
45
- src << result << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
46
+ if @yield_returns_buffer
47
+ terminate_expression
48
+ @src << " #{@bufvar}; "
49
+ end
50
+ @src << code << ")).to_s; ensure; #{@bufvar} = #{@bufstack}.pop; end;"
51
+ @buffer_on_stack = false
46
52
  add_text(rspace) if rspace
47
53
  else
48
54
  super
data/lib/erubi.rb CHANGED
@@ -1,34 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Erubi
4
- VERSION = '1.8.0'
5
- RANGE_ALL = 0..-1
4
+ VERSION = '1.11.0'
6
5
 
6
+ # :nocov:
7
7
  if RUBY_VERSION >= '1.9'
8
8
  RANGE_FIRST = 0
9
9
  RANGE_LAST = -1
10
- TEXT_END = RUBY_VERSION >= '2.1' ? "'.freeze;" : "';"
11
10
  else
12
- # :nocov:
13
11
  RANGE_FIRST = 0..0
14
12
  RANGE_LAST = -1..-1
15
- TEXT_END = "';"
16
13
  end
17
14
 
15
+ MATCH_METHOD = RUBY_VERSION >= '2.4' ? :match? : :match
16
+ SKIP_DEFINED_FOR_INSTANCE_VARIABLE = RUBY_VERSION > '3'
17
+ # :nocov:
18
+
18
19
  begin
19
20
  require 'cgi/escape'
21
+ # :nocov:
20
22
  unless CGI.respond_to?(:escapeHTML) # work around for JRuby 9.1
21
23
  CGI = Object.new
22
24
  CGI.extend(defined?(::CGI::Escape) ? ::CGI::Escape : ::CGI::Util)
23
25
  end
26
+ # :nocov:
27
+ # Escape characters with their HTML/XML equivalents.
24
28
  def self.h(value)
25
29
  CGI.escapeHTML(value.to_s)
26
30
  end
27
31
  rescue LoadError
32
+ # :nocov:
28
33
  ESCAPE_TABLE = {'&' => '&amp;'.freeze, '<' => '&lt;'.freeze, '>' => '&gt;'.freeze, '"' => '&quot;'.freeze, "'" => '&#39;'.freeze}.freeze
29
34
  if RUBY_VERSION >= '1.9'
30
- # Escape the following characters with their HTML/XML
31
- # equivalents.
32
35
  def self.h(value)
33
36
  value.to_s.gsub(/[&<>"']/, ESCAPE_TABLE)
34
37
  end
@@ -37,9 +40,13 @@ module Erubi
37
40
  value.to_s.gsub(/[&<>"']/){|s| ESCAPE_TABLE[s]}
38
41
  end
39
42
  end
43
+ # :nocov:
40
44
  end
41
45
 
42
46
  class Engine
47
+ # The default regular expression used for scanning.
48
+ DEFAULT_REGEXP = /<%(={1,2}|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m
49
+
43
50
  # The frozen ruby source code generated from the template, which can be evaled.
44
51
  attr_reader :src
45
52
 
@@ -50,38 +57,66 @@ module Erubi
50
57
  attr_reader :bufvar
51
58
 
52
59
  # Initialize a new Erubi::Engine. Options:
53
- # :bufval :: The value to use for the buffer variable, as a string.
54
- # :bufvar :: The variable name to use for the buffer variable, as a string.
55
- # :ensure :: Wrap the template in a begin/ensure block restoring the previous value of bufvar.
56
- # :escapefunc :: The function to use for escaping, as a string (default: ::Erubi.h).
57
- # :escape :: Whether to make <%= escape by default, and <%== not escape by default.
58
- # :escape_html :: Same as :escape, with lower priority.
59
- # :filename :: The filename for the template.
60
- # :freeze :: Whether to enable frozen string literals in the resulting source code.
61
- # :outvar :: Same as bufvar, with lower priority.
62
- # :postamble :: The postamble for the template, by default returns the resulting source code.
63
- # :preamble :: The preamble for the template, by default initializes up the buffer variable.
64
- # :regexp :: The regexp to use for scanning.
65
- # :src :: The initial value to use for the source code
66
- # :trim :: Whether to trim leading and trailing whitespace, true by default.
60
+ # +:bufval+ :: The value to use for the buffer variable, as a string (default <tt>'::String.new'</tt>).
61
+ # +:bufvar+ :: The variable name to use for the buffer variable, as a string.
62
+ # +:chain_appends+ :: Whether to chain <tt><<</t> calls to the buffer variable. Offers better
63
+ # performance, but can cause issues when the buffer variable is reassigned during
64
+ # template rendering (default +false+).
65
+ # +:ensure+ :: Wrap the template in a begin/ensure block restoring the previous value of bufvar.
66
+ # +:escapefunc+ :: The function to use for escaping, as a string (default: <tt>'::Erubi.h'</tt>).
67
+ # +:escape+ :: Whether to make <tt><%=</tt> escape by default, and <tt><%==</tt> not escape by default.
68
+ # +:escape_html+ :: Same as +:escape+, with lower priority.
69
+ # +:filename+ :: The filename for the template.
70
+ # +:freeze+ :: Whether to enable add a <tt>frozen_string_literal: true</tt> magic comment at the top of
71
+ # the resulting source code. Note this may cause problems if you are wrapping the resulting
72
+ # source code in other code, because the magic comment only has an effect at the beginning of
73
+ # the file, and having the magic comment later in the file can trigger warnings.
74
+ # +:freeze_template_literals+ :: Whether to suffix all literal strings for template code with <tt>.freeze</tt>
75
+ # (default: +true+ on Ruby 2.1+, +false+ on Ruby 2.0 and older).
76
+ # Can be set to +false+ on Ruby 2.3+ when frozen string literals are enabled
77
+ # in order to improve performance.
78
+ # +:literal_prefix+ :: The prefix to output when using escaped tag delimiters (default <tt>'<%'</tt>).
79
+ # +:literal_postfix+ :: The postfix to output when using escaped tag delimiters (default <tt>'%>'</tt>).
80
+ # +:outvar+ :: Same as +:bufvar+, with lower priority.
81
+ # +:postamble+ :: The postamble for the template, by default returns the resulting source code.
82
+ # +:preamble+ :: The preamble for the template, by default initializes the buffer variable.
83
+ # +:regexp+ :: The regexp to use for scanning.
84
+ # +:src+ :: The initial value to use for the source code, an empty string by default.
85
+ # +:trim+ :: Whether to trim leading and trailing whitespace, true by default.
67
86
  def initialize(input, properties={})
68
87
  @escape = escape = properties.fetch(:escape){properties.fetch(:escape_html, false)}
69
88
  trim = properties[:trim] != false
70
89
  @filename = properties[:filename]
71
90
  @bufvar = bufvar = properties[:bufvar] || properties[:outvar] || "_buf"
72
- bufval = properties[:bufval] || 'String.new'
73
- regexp = properties[:regexp] || /<%(={1,2}|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m
91
+ bufval = properties[:bufval] || '::String.new'
92
+ regexp = properties[:regexp] || DEFAULT_REGEXP
93
+ literal_prefix = properties[:literal_prefix] || '<%'
94
+ literal_postfix = properties[:literal_postfix] || '%>'
74
95
  preamble = properties[:preamble] || "#{bufvar} = #{bufval};"
75
96
  postamble = properties[:postamble] || "#{bufvar}.to_s\n"
97
+ @chain_appends = properties[:chain_appends]
98
+ @text_end = if properties.fetch(:freeze_template_literals, RUBY_VERSION >= '2.1')
99
+ "'.freeze"
100
+ else
101
+ "'"
102
+ end
76
103
 
104
+ @buffer_on_stack = false
77
105
  @src = src = properties[:src] || String.new
78
106
  src << "# frozen_string_literal: true\n" if properties[:freeze]
79
- src << "begin; __original_outvar = #{bufvar} if defined?(#{bufvar}); " if properties[:ensure]
107
+ if properties[:ensure]
108
+ src << "begin; __original_outvar = #{bufvar}"
109
+ if SKIP_DEFINED_FOR_INSTANCE_VARIABLE && /\A@[^@]/ =~ bufvar
110
+ src << "; "
111
+ else
112
+ src << " if defined?(#{bufvar}); "
113
+ end
114
+ end
80
115
 
81
116
  unless @escapefunc = properties[:escapefunc]
82
117
  if escape
83
118
  @escapefunc = '__erubi.h'
84
- src << "__erubi = ::Erubi;"
119
+ src << "__erubi = ::Erubi; "
85
120
  else
86
121
  @escapefunc = '::Erubi.h'
87
122
  end
@@ -110,46 +145,45 @@ module Erubi
110
145
  if rindex
111
146
  range = rindex+1..-1
112
147
  s = text[range]
113
- if s =~ /\A[ \t]*\z/
148
+ if /\A[ \t]*\z/.send(MATCH_METHOD, s)
114
149
  lspace = s
115
150
  text[range] = ''
116
151
  end
117
152
  else
118
- if is_bol && text =~ /\A[ \t]*\z/
119
- lspace = text.dup
120
- text[RANGE_ALL] = ''
153
+ if is_bol && /\A[ \t]*\z/.send(MATCH_METHOD, text)
154
+ lspace = text
155
+ text = ''
121
156
  end
122
157
  end
123
158
  end
124
159
  end
125
160
 
126
161
  is_bol = rspace
127
- add_text(text) if text && !text.empty?
162
+ add_text(text)
128
163
  case ch
129
164
  when '='
130
165
  rspace = nil if tailch && !tailch.empty?
131
- add_text(lspace) if lspace
132
166
  add_expression(indicator, code)
133
167
  add_text(rspace) if rspace
134
- when '#'
135
- n = code.count("\n") + (rspace ? 1 : 0)
168
+ when nil, '-'
136
169
  if trim && lspace && rspace
137
- add_code("\n" * n)
170
+ add_code("#{lspace}#{code}#{rspace}")
138
171
  else
139
172
  add_text(lspace) if lspace
140
- add_code("\n" * n)
173
+ add_code(code)
141
174
  add_text(rspace) if rspace
142
175
  end
143
- when '%'
144
- add_text("#{lspace}#{prefix||='<%'}#{code}#{tailch}#{postfix||='%>'}#{rspace}")
145
- when nil, '-'
176
+ when '#'
177
+ n = code.count("\n") + (rspace ? 1 : 0)
146
178
  if trim && lspace && rspace
147
- add_code("#{lspace}#{code}#{rspace}")
179
+ add_code("\n" * n)
148
180
  else
149
181
  add_text(lspace) if lspace
150
- add_code(code)
182
+ add_code("\n" * n)
151
183
  add_text(rspace) if rspace
152
184
  end
185
+ when '%'
186
+ add_text("#{lspace}#{literal_prefix}#{code}#{tailch}#{literal_postfix}#{rspace}")
153
187
  else
154
188
  handle(indicator, code, tailch, rspace, lspace)
155
189
  end
@@ -159,22 +193,33 @@ module Erubi
159
193
 
160
194
  src << "\n" unless src[RANGE_LAST] == "\n"
161
195
  add_postamble(postamble)
162
- src << "; ensure\n #{bufvar} = __original_outvar\nend\n" if properties[:ensure]
196
+ src << "; ensure\n " << bufvar << " = __original_outvar\nend\n" if properties[:ensure]
163
197
  src.freeze
164
198
  freeze
165
199
  end
166
200
 
167
201
  private
168
202
 
169
- # Add raw text to the template
203
+ # Add raw text to the template. Modifies argument if argument is mutable as a memory optimization.
204
+ # Must be called with a string, cannot be called with nil (Rails's subclass depends on it).
170
205
  def add_text(text)
171
- @src << " #{@bufvar} << '" << text.gsub(/['\\]/, '\\\\\&') << TEXT_END unless text.empty?
206
+ return if text.empty?
207
+
208
+ if text.frozen?
209
+ text = text.gsub(/['\\]/, '\\\\\&')
210
+ else
211
+ text.gsub!(/['\\]/, '\\\\\&')
212
+ end
213
+
214
+ with_buffer{@src << " << '" << text << @text_end}
172
215
  end
173
216
 
174
217
  # Add ruby code to the template
175
218
  def add_code(code)
219
+ terminate_expression
176
220
  @src << code
177
221
  @src << ';' unless code[RANGE_LAST] == "\n"
222
+ @buffer_on_stack = false
178
223
  end
179
224
 
180
225
  # Add the given ruby expression result to the template,
@@ -189,23 +234,52 @@ module Erubi
189
234
 
190
235
  # Add the result of Ruby expression to the template
191
236
  def add_expression_result(code)
192
- @src << " #{@bufvar} << (" << code << ').to_s;'
237
+ with_buffer{@src << ' << (' << code << ').to_s'}
193
238
  end
194
239
 
195
240
  # Add the escaped result of Ruby expression to the template
196
241
  def add_expression_result_escaped(code)
197
- @src << " #{@bufvar} << #{@escapefunc}((" << code << '));'
242
+ with_buffer{@src << ' << ' << @escapefunc << '((' << code << '))'}
198
243
  end
199
244
 
200
245
  # Add the given postamble to the src. Can be overridden in subclasses
201
246
  # to make additional changes to src that depend on the current state.
202
247
  def add_postamble(postamble)
203
- src << postamble
248
+ terminate_expression
249
+ @src << postamble
204
250
  end
205
251
 
206
252
  # Raise an exception, as the base engine class does not support handling other indicators.
207
253
  def handle(indicator, code, tailch, rspace, lspace)
208
254
  raise ArgumentError, "Invalid indicator: #{indicator}"
209
255
  end
256
+
257
+ # Make sure the buffer variable is the target of the next append
258
+ # before yielding to the block. Mark that the buffer is the target
259
+ # of the next append after the block executes.
260
+ #
261
+ # This method should only be called if the block will result in
262
+ # code where << will append to the bufvar.
263
+ def with_buffer
264
+ if @chain_appends
265
+ unless @buffer_on_stack
266
+ @src << '; ' << @bufvar
267
+ end
268
+ yield
269
+ @buffer_on_stack = true
270
+ else
271
+ @src << ' ' << @bufvar
272
+ yield
273
+ @src << ';'
274
+ end
275
+ end
276
+
277
+ # Make sure that any current expression has been terminated.
278
+ # The default is to terminate all expressions, but when
279
+ # the chain_appends option is used, expressions may not be
280
+ # terminated.
281
+ def terminate_expression
282
+ @src << '; ' if @chain_appends
283
+ end
210
284
  end
211
285
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erubi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-12-18 00:00:00.000000000 Z
12
+ date: 2022-08-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: minitest-global_expectations
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
28
42
  description: Erubi is a ERB template engine for ruby. It is a simplified fork of Erubis
29
43
  email: code@jeremyevans.net
30
44
  executables: []
@@ -40,11 +54,13 @@ files:
40
54
  - Rakefile
41
55
  - lib/erubi.rb
42
56
  - lib/erubi/capture_end.rb
43
- - test/test.rb
44
57
  homepage: https://github.com/jeremyevans/erubi
45
58
  licenses:
46
59
  - MIT
47
- metadata: {}
60
+ metadata:
61
+ bug_tracker_uri: https://github.com/jeremyevans/erubi/issues
62
+ changelog_uri: https://github.com/jeremyevans/erubi/blob/master/CHANGELOG
63
+ source_code_uri: https://github.com/jeremyevans/erubi
48
64
  post_install_message:
49
65
  rdoc_options:
50
66
  - "--quiet"
@@ -67,8 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
83
  - !ruby/object:Gem::Version
68
84
  version: '0'
69
85
  requirements: []
70
- rubyforge_project:
71
- rubygems_version: 2.7.6
86
+ rubygems_version: 3.3.7
72
87
  signing_key:
73
88
  specification_version: 4
74
89
  summary: Small ERB Implementation
data/test/test.rb DELETED
@@ -1,774 +0,0 @@
1
- require 'rubygems'
2
-
3
- unless defined?(TESTDIR)
4
- TESTDIR = File.dirname(__FILE__)
5
- LIBDIR = TESTDIR == '.' ? '../lib' : File.dirname(TESTDIR) + '/lib'
6
- $: << TESTDIR
7
- $: << LIBDIR
8
- end
9
-
10
- if ENV['COVERAGE']
11
- require 'coverage'
12
- require 'simplecov'
13
-
14
- ENV.delete('COVERAGE')
15
- SimpleCov.instance_eval do
16
- start do
17
- add_filter "/test/"
18
- add_group('Missing'){|src| src.covered_percent < 100}
19
- add_group('Covered'){|src| src.covered_percent == 100}
20
- end
21
- end
22
- end
23
-
24
- require 'erubi'
25
- require 'erubi/capture_end'
26
-
27
- ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
28
- require 'minitest/spec'
29
- require 'minitest/autorun'
30
-
31
- describe Erubi::Engine do
32
- before do
33
- @options = {}
34
- end
35
-
36
- def check_output(input, src, result, &block)
37
- t = (@options[:engine] || Erubi::Engine).new(input, @options)
38
- tsrc = t.src
39
- eval(tsrc, block.binding).must_equal result
40
- tsrc = tsrc.gsub("'.freeze;", "';") if RUBY_VERSION >= '2.1'
41
- tsrc.must_equal src
42
- end
43
-
44
- def setup_foo
45
- @foo = Object.new
46
- @foo.instance_variable_set(:@t, self)
47
- def self.a; @a; end
48
- def @foo.bar
49
- @t.a << "a"
50
- yield
51
- @t.a << 'b'
52
- @t.a.buffer.upcase!
53
- end
54
- end
55
-
56
- def setup_bar
57
- def self.bar
58
- @a << "a"
59
- yield
60
- @a << 'b'
61
- @a.upcase
62
- end
63
- def self.baz
64
- @a << "c"
65
- yield
66
- @a << 'd'
67
- @a * 2
68
- end
69
- def self.quux
70
- @a << "a"
71
- 3.times do |i|
72
- @a << "c#{i}"
73
- yield i
74
- @a << "d#{i}"
75
- end
76
- @a << "b"
77
- @a.upcase
78
- end
79
- end
80
-
81
- it "should handle no options" do
82
- list = ['&\'<>"2']
83
- check_output(<<END1, <<END2, <<END3){}
84
- <table>
85
- <tbody>
86
- <% i = 0
87
- list.each_with_index do |item, i| %>
88
- <tr>
89
- <td><%= i+1 %></td>
90
- <td><%== item %></td>
91
- </tr>
92
- <% end %>
93
- </tbody>
94
- </table>
95
- <%== i+1 %>
96
- END1
97
- _buf = String.new; _buf << '<table>
98
- <tbody>
99
- '; i = 0
100
- list.each_with_index do |item, i|
101
- _buf << ' <tr>
102
- <td>'; _buf << ( i+1 ).to_s; _buf << '</td>
103
- <td>'; _buf << ::Erubi.h(( item )); _buf << '</td>
104
- </tr>
105
- '; end
106
- _buf << ' </tbody>
107
- </table>
108
- '; _buf << ::Erubi.h(( i+1 )); _buf << '
109
- ';
110
- _buf.to_s
111
- END2
112
- <table>
113
- <tbody>
114
- <tr>
115
- <td>1</td>
116
- <td>&amp;&#39;&lt;&gt;&quot;2</td>
117
- </tr>
118
- </tbody>
119
- </table>
120
- 1
121
- END3
122
- end
123
-
124
- it "should strip only whitespace for <%, <%- and <%# tags" do
125
- check_output(<<END1, <<END2, <<END3){}
126
- <% 1 %>
127
- a
128
- <%- 2 %>
129
- b
130
- <%# 3 %>
131
- c
132
- /<% 1 %>
133
- a
134
- / <%- 2 %>
135
- b
136
- //<%# 3 %>
137
- c
138
- <% 1 %> /
139
- a
140
- <%- 2 %>/
141
- b
142
- <%# 3 %>//
143
- c
144
- END1
145
- _buf = String.new; 1
146
- _buf << 'a
147
- '; 2
148
- _buf << 'b
149
- ';
150
- _buf << 'c
151
- /'; 1 ; _buf << '
152
- '; _buf << 'a
153
- / '; 2 ; _buf << '
154
- '; _buf << 'b
155
- //';
156
- _buf << '
157
- '; _buf << 'c
158
- '; _buf << ' '; 1 ; _buf << ' /
159
- a
160
- '; _buf << ' '; 2 ; _buf << '/
161
- b
162
- '; _buf << ' ';; _buf << '//
163
- c
164
- ';
165
- _buf.to_s
166
- END2
167
- a
168
- b
169
- c
170
- /
171
- a
172
- /
173
- b
174
- //
175
- c
176
- /
177
- a
178
- /
179
- b
180
- //
181
- c
182
- END3
183
- end
184
-
185
- it "should handle ensure option" do
186
- list = ['&\'<>"2']
187
- @options[:ensure] = true
188
- @options[:bufvar] = '@a'
189
- @a = 'bar'
190
- check_output(<<END1, <<END2, <<END3){}
191
- <table>
192
- <tbody>
193
- <% i = 0
194
- list.each_with_index do |item, i| %>
195
- <tr>
196
- <td><%= i+1 %></td>
197
- <td><%== item %></td>
198
- </tr>
199
- <% end %>
200
- </tbody>
201
- </table>
202
- <%== i+1 %>
203
- END1
204
- begin; __original_outvar = @a if defined?(@a); @a = String.new; @a << '<table>
205
- <tbody>
206
- '; i = 0
207
- list.each_with_index do |item, i|
208
- @a << ' <tr>
209
- <td>'; @a << ( i+1 ).to_s; @a << '</td>
210
- <td>'; @a << ::Erubi.h(( item )); @a << '</td>
211
- </tr>
212
- '; end
213
- @a << ' </tbody>
214
- </table>
215
- '; @a << ::Erubi.h(( i+1 )); @a << '
216
- ';
217
- @a.to_s
218
- ; ensure
219
- @a = __original_outvar
220
- end
221
- END2
222
- <table>
223
- <tbody>
224
- <tr>
225
- <td>1</td>
226
- <td>&amp;&#39;&lt;&gt;&quot;2</td>
227
- </tr>
228
- </tbody>
229
- </table>
230
- 1
231
- END3
232
- @a.must_equal 'bar'
233
- end
234
-
235
- it "should have <%|= with CaptureEndEngine not escape by default" do
236
- eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>').src).must_equal '&'
237
- eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape=>false).src).must_equal '&'
238
- eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape_capture=>false).src).must_equal '&'
239
- eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape=>true).src).must_equal '&amp;'
240
- eval(::Erubi::CaptureEndEngine.new('<%|= "&" %><%| %>', :escape_capture=>true).src).must_equal '&amp;'
241
- end
242
-
243
- it "should have <%|== with CaptureEndEngine escape by default" do
244
- eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>').src).must_equal '&amp;'
245
- eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape=>true).src).must_equal '&'
246
- eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape_capture=>true).src).must_equal '&'
247
- eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape=>false).src).must_equal '&amp;'
248
- eval(::Erubi::CaptureEndEngine.new('<%|== "&" %><%| %>', :escape_capture=>false).src).must_equal '&amp;'
249
- end
250
-
251
- [['', false], ['=', true]].each do |ind, escape|
252
- it "should allow <%|=#{ind} and <%| for capturing with CaptureEndEngine with :escape_capture => #{escape} and :escape => #{!escape}" do
253
- @options[:bufvar] = '@a'
254
- @options[:capture] = true
255
- @options[:escape_capture] = escape
256
- @options[:escape] = !escape
257
- @options[:engine] = ::Erubi::CaptureEndEngine
258
- setup_bar
259
- check_output(<<END1, <<END2, <<END3){}
260
- <table>
261
- <tbody>
262
- <%|=#{ind} bar do %>
263
- <b><%=#{ind} '&' %></b>
264
- <%| end %>
265
- </tbody>
266
- </table>
267
- END1
268
- #{'__erubi = ::Erubi;' unless escape}@a = String.new; @a << '<table>
269
- <tbody>
270
- '; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << (( bar do @a << '
271
- '; @a << ' <b>'; @a << #{!escape ? '__erubi' : '::Erubi'}.h(( '&' )); @a << '</b>
272
- '; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
273
- '; @a << ' </tbody>
274
- </table>
275
- ';
276
- @a.to_s
277
- END2
278
- <table>
279
- <tbody>
280
- A
281
- <B>&AMP;</B>
282
- B
283
- </tbody>
284
- </table>
285
- END3
286
- end
287
- end
288
-
289
- [['', true], ['=', false]].each do |ind, escape|
290
- it "should allow <%|=#{ind} and <%| for capturing with CaptureEndEngine when with :escape => #{escape}" do
291
- @options[:bufvar] = '@a'
292
- @options[:escape] = escape
293
- @options[:engine] = ::Erubi::CaptureEndEngine
294
- setup_bar
295
- check_output(<<END1, <<END2, <<END3){}
296
- <table>
297
- <tbody>
298
- <%|=#{ind} bar do %>
299
- <b><%=#{ind} '&' %></b>
300
- <%| end %>
301
- </tbody>
302
- </table>
303
- END1
304
- #{'__erubi = ::Erubi;' if escape}@a = String.new; @a << '<table>
305
- <tbody>
306
- '; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( bar do @a << '
307
- '; @a << ' <b>'; @a << #{escape ? '__erubi' : '::Erubi'}.h(( '&' )); @a << '</b>
308
- '; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
309
- '; @a << ' </tbody>
310
- </table>
311
- ';
312
- @a.to_s
313
- END2
314
- <table>
315
- <tbody>
316
- A
317
- &lt;B&gt;&amp;AMP;&lt;/B&gt;
318
- B
319
- </tbody>
320
- </table>
321
- END3
322
- end
323
-
324
- it "should handle loops in <%|=#{ind} and <%| for capturing with CaptureEndEngine when with :escape => #{escape}" do
325
- @options[:bufvar] = '@a'
326
- @options[:escape] = escape
327
- @options[:engine] = ::Erubi::CaptureEndEngine
328
- setup_bar
329
- check_output(<<END1, <<END2, <<END3){}
330
- <table>
331
- <tbody>
332
- <%|=#{ind} quux do |i| %>
333
- <b><%=#{ind} "\#{i}&" %></b>
334
- <%| end %>
335
- </tbody>
336
- </table>
337
- END1
338
- #{'__erubi = ::Erubi;' if escape}@a = String.new; @a << '<table>
339
- <tbody>
340
- '; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( quux do |i| @a << '
341
- '; @a << ' <b>'; @a << #{escape ? '__erubi' : '::Erubi'}.h(( "\#{i}&" )); @a << '</b>
342
- '; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
343
- '; @a << ' </tbody>
344
- </table>
345
- ';
346
- @a.to_s
347
- END2
348
- <table>
349
- <tbody>
350
- AC0
351
- &lt;B&gt;0&amp;AMP;&lt;/B&gt;
352
- D0C1
353
- &lt;B&gt;1&amp;AMP;&lt;/B&gt;
354
- D1C2
355
- &lt;B&gt;2&amp;AMP;&lt;/B&gt;
356
- D2B
357
- </tbody>
358
- </table>
359
- END3
360
- end
361
-
362
- it "should allow <%|=#{ind} and <%| for nested capturing with CaptureEndEngine when with :escape => #{escape}" do
363
- @options[:bufvar] = '@a'
364
- @options[:escape] = escape
365
- @options[:engine] = ::Erubi::CaptureEndEngine
366
- setup_bar
367
- check_output(<<END1, <<END2, <<END3){}
368
- <table>
369
- <tbody>
370
- <%|=#{ind} bar do %>
371
- <b><%=#{ind} '&' %></b>
372
- <%|=#{ind} baz do %>e<%| end %>
373
- <%| end %>
374
- </tbody>
375
- </table>
376
- END1
377
- #{'__erubi = ::Erubi;' if escape}@a = String.new; @a << '<table>
378
- <tbody>
379
- '; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( bar do @a << '
380
- '; @a << ' <b>'; @a << #{escape ? '__erubi' : '::Erubi'}.h(( '&' )); @a << '</b>
381
- '; @a << ' ';begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << #{escape ? '__erubi' : '::Erubi'}.h(( baz do @a << 'e'; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
382
- '; @a << ' '; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
383
- '; @a << ' </tbody>
384
- </table>
385
- ';
386
- @a.to_s
387
- END2
388
- <table>
389
- <tbody>
390
- A
391
- &lt;B&gt;&amp;AMP;&lt;/B&gt;
392
- CEDCED
393
- B
394
- </tbody>
395
- </table>
396
- END3
397
- end
398
- end
399
-
400
- [:outvar, :bufvar].each do |var|
401
- it "should handle :#{var} and :freeze options" do
402
- @options[var] = "@_out_buf"
403
- @options[:freeze] = true
404
- @items = [2]
405
- i = 0
406
- check_output(<<END1, <<END2, <<END3){}
407
- <table>
408
- <% for item in @items %>
409
- <tr>
410
- <td><%= i+1 %></td>
411
- <td><%== item %></td>
412
- </tr>
413
- <% end %>
414
- </table>
415
- END1
416
- # frozen_string_literal: true
417
- @_out_buf = String.new; @_out_buf << '<table>
418
- '; for item in @items
419
- @_out_buf << ' <tr>
420
- <td>'; @_out_buf << ( i+1 ).to_s; @_out_buf << '</td>
421
- <td>'; @_out_buf << ::Erubi.h(( item )); @_out_buf << '</td>
422
- </tr>
423
- '; end
424
- @_out_buf << '</table>
425
- ';
426
- @_out_buf.to_s
427
- END2
428
- <table>
429
- <tr>
430
- <td>1</td>
431
- <td>2</td>
432
- </tr>
433
- </table>
434
- END3
435
- end
436
- end
437
-
438
- it "should handle <%% and <%# syntax" do
439
- @items = [2]
440
- i = 0
441
- check_output(<<END1, <<END2, <<END3){}
442
- <table>
443
- <%% for item in @items %>
444
- <tr>
445
- <td><%# i+1 %></td>
446
- <td><%# item %></td>
447
- </tr>
448
- <%% end %>
449
- </table>
450
- END1
451
- _buf = String.new; _buf << '<table>
452
- '; _buf << '<% for item in @items %>
453
- '; _buf << ' <tr>
454
- <td>';; _buf << '</td>
455
- <td>';; _buf << '</td>
456
- </tr>
457
- '; _buf << ' <% end %>
458
- '; _buf << '</table>
459
- ';
460
- _buf.to_s
461
- END2
462
- <table>
463
- <% for item in @items %>
464
- <tr>
465
- <td></td>
466
- <td></td>
467
- </tr>
468
- <% end %>
469
- </table>
470
- END3
471
- end
472
-
473
- it "should handle :trim => false option" do
474
- @options[:trim] = false
475
- @items = [2]
476
- i = 0
477
- check_output(<<END1, <<END2, <<END3){}
478
- <table>
479
- <% for item in @items %>
480
- <tr>
481
- <td><%#
482
- i+1
483
- %></td>
484
- <td><%== item %></td>
485
- </tr>
486
- <% end %><%#%>
487
- <% i %>a
488
- <% i %>
489
- </table>
490
- END1
491
- _buf = String.new; _buf << '<table>
492
- '; _buf << ' '; for item in @items ; _buf << '
493
- '; _buf << ' <tr>
494
- <td>';
495
-
496
- _buf << '</td>
497
- <td>'; _buf << ::Erubi.h(( item )); _buf << '</td>
498
- </tr>
499
- '; _buf << ' '; end ;
500
- _buf << '
501
- '; _buf << ' '; i ; _buf << 'a
502
- '; _buf << ' '; i ; _buf << '
503
- '; _buf << '</table>
504
- ';
505
- _buf.to_s
506
- END2
507
- <table>
508
-
509
- <tr>
510
- <td></td>
511
- <td>2</td>
512
- </tr>
513
-
514
- a
515
-
516
- </table>
517
- END3
518
- end
519
-
520
- [:escape, :escape_html].each do |opt|
521
- it "should handle :#{opt} and :escapefunc options" do
522
- @options[opt] = true
523
- @options[:escapefunc] = 'h.call'
524
- h = proc{|s| s.to_s*2}
525
- list = ['2']
526
- check_output(<<END1, <<END2, <<END3){}
527
- <table>
528
- <tbody>
529
- <% i = 0
530
- list.each_with_index do |item, i| %>
531
- <tr>
532
- <td><%= i+1 %></td>
533
- <td><%== item %></td>
534
- </tr>
535
- <% end %>
536
- </tbody>
537
- </table>
538
- <%== i+1 %>
539
- END1
540
- _buf = String.new; _buf << '<table>
541
- <tbody>
542
- '; i = 0
543
- list.each_with_index do |item, i|
544
- _buf << ' <tr>
545
- <td>'; _buf << h.call(( i+1 )); _buf << '</td>
546
- <td>'; _buf << ( item ).to_s; _buf << '</td>
547
- </tr>
548
- '; end
549
- _buf << ' </tbody>
550
- </table>
551
- '; _buf << ( i+1 ).to_s; _buf << '
552
- ';
553
- _buf.to_s
554
- END2
555
- <table>
556
- <tbody>
557
- <tr>
558
- <td>11</td>
559
- <td>2</td>
560
- </tr>
561
- </tbody>
562
- </table>
563
- 1
564
- END3
565
- end
566
- end
567
-
568
- it "should handle :escape option without :escapefunc option" do
569
- @options[:escape] = true
570
- list = ['&\'<>"2']
571
- check_output(<<END1, <<END2, <<END3){}
572
- <table>
573
- <tbody>
574
- <% i = 0
575
- list.each_with_index do |item, i| %>
576
- <tr>
577
- <td><%== i+1 %></td>
578
- <td><%= item %></td>
579
- </tr>
580
- <% end %>
581
- </tbody>
582
- </table>
583
- END1
584
- __erubi = ::Erubi;_buf = String.new; _buf << '<table>
585
- <tbody>
586
- '; i = 0
587
- list.each_with_index do |item, i|
588
- _buf << ' <tr>
589
- <td>'; _buf << ( i+1 ).to_s; _buf << '</td>
590
- <td>'; _buf << __erubi.h(( item )); _buf << '</td>
591
- </tr>
592
- '; end
593
- _buf << ' </tbody>
594
- </table>
595
- ';
596
- _buf.to_s
597
- END2
598
- <table>
599
- <tbody>
600
- <tr>
601
- <td>1</td>
602
- <td>&amp;&#39;&lt;&gt;&quot;2</td>
603
- </tr>
604
- </tbody>
605
- </table>
606
- END3
607
- end
608
-
609
- it "should handle :preamble and :postamble options" do
610
- @options[:preamble] = '_buf = String.new("1");'
611
- @options[:postamble] = "_buf[0...18]\n"
612
- list = ['2']
613
- check_output(<<END1, <<END2, <<END3){}
614
- <table>
615
- <tbody>
616
- <% i = 0
617
- list.each_with_index do |item, i| %>
618
- <tr>
619
- <td><%= i+1 %></td>
620
- <td><%== item %></td>
621
- </tr>
622
- <% end %>
623
- </tbody>
624
- </table>
625
- <%== i+1 %>
626
- END1
627
- _buf = String.new("1"); _buf << '<table>
628
- <tbody>
629
- '; i = 0
630
- list.each_with_index do |item, i|
631
- _buf << ' <tr>
632
- <td>'; _buf << ( i+1 ).to_s; _buf << '</td>
633
- <td>'; _buf << ::Erubi.h(( item )); _buf << '</td>
634
- </tr>
635
- '; end
636
- _buf << ' </tbody>
637
- </table>
638
- '; _buf << ::Erubi.h(( i+1 )); _buf << '
639
- ';
640
- _buf[0...18]
641
- END2
642
- 1<table>
643
- <tbody>
644
- END3
645
- end
646
-
647
- it "should have working filename accessor" do
648
- Erubi::Engine.new('', :filename=>'foo.rb').filename.must_equal 'foo.rb'
649
- end
650
-
651
- it "should have working bufvar accessor" do
652
- Erubi::Engine.new('', :bufvar=>'foo').bufvar.must_equal 'foo'
653
- Erubi::Engine.new('', :outvar=>'foo').bufvar.must_equal 'foo'
654
- end
655
-
656
- it "should return frozen object" do
657
- Erubi::Engine.new('').frozen?.must_equal true
658
- end
659
-
660
- it "should have frozen src" do
661
- Erubi::Engine.new('').src.frozen?.must_equal true
662
- end
663
-
664
- it "should raise an error if a tag is not handled when a custom regexp is used" do
665
- proc{Erubi::Engine.new('<%] %>', :regexp =>/<%(={1,2}|\]|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m)}.must_raise ArgumentError
666
- proc{Erubi::CaptureEndEngine.new('<%] %>', :regexp =>/<%(={1,2}|\]|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m)}.must_raise ArgumentError
667
- end
668
-
669
- it "should respect the :yield_returns_buffer option for making templates return the (potentially modified) buffer" do
670
- @options[:engine] = ::Erubi::CaptureEndEngine
671
- @options[:bufvar] = '@a'
672
-
673
- def self.bar
674
- a = String.new
675
- a << "a"
676
- yield 'burgers'
677
- case b = (yield 'salads')
678
- when String
679
- a << b
680
- a << 'b'
681
- a.upcase
682
- end
683
- end
684
-
685
- check_output(<<END1, <<END2, <<END3){}
686
- <%|= bar do |item| %>
687
- Let's eat <%= item %>!
688
- <% nil %><%| end %>
689
- END1
690
- @a = String.new;begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << (( bar do |item| @a << '
691
- '; @a << 'Let\\'s eat '; @a << ( item ).to_s; @a << '!
692
- '; nil ; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
693
- ';
694
- @a.to_s
695
- END2
696
-
697
- END3
698
-
699
- @options[:yield_returns_buffer] = true
700
-
701
- check_output(<<END1, <<END2, <<END3) {}
702
- <%|= bar do |item| %>
703
- Let's eat <%= item %>!
704
- <% nil %><%| end %>
705
- END1
706
- @a = String.new;begin; (__erubi_stack ||= []) << @a; @a = String.new; __erubi_stack.last << (( bar do |item| @a << '
707
- '; @a << 'Let\\'s eat '; @a << ( item ).to_s; @a << '!
708
- '; nil ; @a; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
709
- ';
710
- @a.to_s
711
- END2
712
- A
713
- LET'S EAT BURGERS!
714
-
715
- LET'S EAT SALADS!
716
- B
717
- END3
718
- end
719
-
720
- it "should respect the :yield_returns_buffer option for making templates return the (potentially modified) buffer as the result of the block" do
721
- @options[:engine] = ::Erubi::CaptureEndEngine
722
- @options[:yield_returns_buffer] = true
723
-
724
- def self.bar(foo = nil)
725
- if foo.nil?
726
- yield
727
- else
728
- foo
729
- end
730
- end
731
-
732
- check_output(<<END1, <<END2, <<END3) {}
733
- <%|= bar do %>
734
- Let's eat the tacos!
735
- <%| end %>
736
-
737
- Delicious!
738
- END1
739
- _buf = String.new;begin; (__erubi_stack ||= []) << _buf; _buf = String.new; __erubi_stack.last << (( bar do _buf << '
740
- '; _buf << 'Let\\'s eat the tacos!
741
- '; _buf; end )).to_s; ensure; _buf = __erubi_stack.pop; end; _buf << '
742
- '; _buf << '
743
- Delicious!
744
- ';
745
- _buf.to_s
746
- END2
747
-
748
- Let's eat the tacos!
749
-
750
-
751
- Delicious!
752
- END3
753
-
754
- check_output(<<END1, <<END2, <<END3) {}
755
- <%|= bar("Don't eat the burgers!") do %>
756
- Let's eat burgers!
757
- <%| end %>
758
-
759
- Delicious!
760
- END1
761
- _buf = String.new;begin; (__erubi_stack ||= []) << _buf; _buf = String.new; __erubi_stack.last << (( bar(\"Don't eat the burgers!\") do _buf << '
762
- '; _buf << 'Let\\'s eat burgers!
763
- '; _buf; end )).to_s; ensure; _buf = __erubi_stack.pop; end; _buf << '
764
- '; _buf << '
765
- Delicious!
766
- ';
767
- _buf.to_s
768
- END2
769
- Don't eat the burgers!
770
-
771
- Delicious!
772
- END3
773
- end
774
- end