erubi 1.8.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
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