erubi 1.9.0 → 1.12.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: '0929d05c25dcdf116a4629c9803bbf70e4abac132acec9d831a3492a5903c5c6'
4
- data.tar.gz: d95fccdac8f5755b1137b4cd652be69f23db18729f972cd017b613e2e2b80426
3
+ metadata.gz: b0cae36e4fa5e180f0934c68f04a936a6f51df57e8ef1a4436a907ab408a85a7
4
+ data.tar.gz: ceaeb0da7540a786c6e65cf8bb1c72ad60bf7309f0a9f0cdf460c32236d80a2c
5
5
  SHA512:
6
- metadata.gz: 54b160b258687a50dfc541b9f9c59fbbe3e8cff020432003b00e7cfa950c81d1a7ae0eef978c8e53b2c49c85995f40600395ffaccb578e1e07b303f5f7bb3298
7
- data.tar.gz: 5d9a63e80b79f2afc48cdb42016ec937556dc62d98987fe0fa9d87e0bad7e744d8f710860f188e500bb0718ca0eb0d5779d6e65de7f2d3664833e86f1802e68d
6
+ metadata.gz: 3c2a45e5cbd23b6f85257fcb7139e92cd116b0854fb5386b73331b05314aa0020725ac1bd918e4156e253df1cf7f5f58e6db86874f3180dabc5d8e38d1d910d3
7
+ data.tar.gz: 54a5c8d8d72bfcc8344f9f4224d36070d90d61817deaa601f25dfee24edc4b6f408f5a00b09891075959a1a41d6fa67046594c5e5e3b65707e24f737777de716
data/CHANGELOG CHANGED
@@ -1,3 +1,25 @@
1
+ === 1.12.0 (2022-12-22)
2
+
3
+ * Use erb/escape for faster html escaping if available (jeremyevans)
4
+
5
+ * Default :freeze_template_literals option to false if running with --enable-frozen-string-literal (casperisfine) (#35)
6
+
7
+ === 1.11.0 (2022-08-02)
8
+
9
+ * Support :freeze_template_literals option for configuring whether to add .freeze to template literal strings (casperisfine) (#33)
10
+
11
+ * Support :chain_appends option for chaining appends to the buffer variable (casperisfine, jeremyevans) (#32)
12
+
13
+ * Avoid unnecessary defined? usage on Ruby 3+ when using the :ensure option (jeremyevans)
14
+
15
+ === 1.10.0 (2020-11-13)
16
+
17
+ * Improve template parsing, mostly by reducing allocations (jeremyevans)
18
+
19
+ * Do not ship tests in the gem, reducing gem size about 20% (jeremyevans)
20
+
21
+ * Support :literal_prefix and :literal_postfix options for how to output literal tags (e.g. <%% code %>) (jaredcwhite) (#26, #27)
22
+
1
23
  === 1.9.0 (2019-09-25)
2
24
 
3
25
  * Change default :bufvar from 'String.new' to '::String.new' to work with BasicObject (jeremyevans)
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,11 +5,11 @@ 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
- * Has 86% smaller memory footprint
12
+ * Has 81% smaller memory footprint (calculated using +ObjectSpace.memsize_of_all+)
13
13
  * Does no monkey patching (Erubis adds a method to Kernel)
14
14
  * Uses an immutable design (all options passed to the constructor, which returns a frozen object)
15
15
  * Has simpler internals (1 file, <150 lines of code)
@@ -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,
@@ -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,45 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Erubi
4
- VERSION = '1.9.0'
5
- RANGE_ALL = 0..-1
4
+ VERSION = '1.12.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
+ FREEZE_TEMPLATE_LITERALS = !eval("''").frozen? && RUBY_VERSION >= '2.1'
18
+ # :nocov:
19
+
18
20
  begin
19
- require 'cgi/escape'
20
- unless CGI.respond_to?(:escapeHTML) # work around for JRuby 9.1
21
- CGI = Object.new
22
- CGI.extend(defined?(::CGI::Escape) ? ::CGI::Escape : ::CGI::Util)
23
- end
24
- def self.h(value)
25
- CGI.escapeHTML(value.to_s)
26
- end
21
+ require 'erb/escape'
22
+ # :nocov:
23
+ define_singleton_method(:h, ERB::Escape.instance_method(:html_escape))
24
+ # :nocov:
27
25
  rescue LoadError
28
- ESCAPE_TABLE = {'&' => '&amp;'.freeze, '<' => '&lt;'.freeze, '>' => '&gt;'.freeze, '"' => '&quot;'.freeze, "'" => '&#39;'.freeze}.freeze
29
- if RUBY_VERSION >= '1.9'
30
- # Escape the following characters with their HTML/XML
31
- # equivalents.
32
- def self.h(value)
33
- value.to_s.gsub(/[&<>"']/, ESCAPE_TABLE)
26
+ begin
27
+ require 'cgi/escape'
28
+ # :nocov:
29
+ unless CGI.respond_to?(:escapeHTML) # work around for JRuby 9.1
30
+ CGI = Object.new
31
+ CGI.extend(defined?(::CGI::Escape) ? ::CGI::Escape : ::CGI::Util)
34
32
  end
35
- else
33
+ # :nocov:
34
+ # Escape characters with their HTML/XML equivalents.
36
35
  def self.h(value)
37
- value.to_s.gsub(/[&<>"']/){|s| ESCAPE_TABLE[s]}
36
+ CGI.escapeHTML(value.to_s)
37
+ end
38
+ rescue LoadError
39
+ # :nocov:
40
+ ESCAPE_TABLE = {'&' => '&amp;'.freeze, '<' => '&lt;'.freeze, '>' => '&gt;'.freeze, '"' => '&quot;'.freeze, "'" => '&#39;'.freeze}.freeze
41
+ if RUBY_VERSION >= '1.9'
42
+ def self.h(value)
43
+ value.to_s.gsub(/[&<>"']/, ESCAPE_TABLE)
44
+ end
45
+ else
46
+ def self.h(value)
47
+ value.to_s.gsub(/[&<>"']/){|s| ESCAPE_TABLE[s]}
48
+ end
38
49
  end
50
+ # :nocov:
39
51
  end
40
52
  end
41
53
 
42
54
  class Engine
55
+ # The default regular expression used for scanning.
56
+ DEFAULT_REGEXP = /<%(={1,2}|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m
57
+
43
58
  # The frozen ruby source code generated from the template, which can be evaled.
44
59
  attr_reader :src
45
60
 
@@ -50,38 +65,66 @@ module Erubi
50
65
  attr_reader :bufvar
51
66
 
52
67
  # 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 (default '::String.new')
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.
68
+ # +:bufval+ :: The value to use for the buffer variable, as a string (default <tt>'::String.new'</tt>).
69
+ # +:bufvar+ :: The variable name to use for the buffer variable, as a string.
70
+ # +:chain_appends+ :: Whether to chain <tt><<</t> calls to the buffer variable. Offers better
71
+ # performance, but can cause issues when the buffer variable is reassigned during
72
+ # template rendering (default +false+).
73
+ # +:ensure+ :: Wrap the template in a begin/ensure block restoring the previous value of bufvar.
74
+ # +:escapefunc+ :: The function to use for escaping, as a string (default: <tt>'::Erubi.h'</tt>).
75
+ # +:escape+ :: Whether to make <tt><%=</tt> escape by default, and <tt><%==</tt> not escape by default.
76
+ # +:escape_html+ :: Same as +:escape+, with lower priority.
77
+ # +:filename+ :: The filename for the template.
78
+ # +:freeze+ :: Whether to enable add a <tt>frozen_string_literal: true</tt> magic comment at the top of
79
+ # the resulting source code. Note this may cause problems if you are wrapping the resulting
80
+ # source code in other code, because the magic comment only has an effect at the beginning of
81
+ # the file, and having the magic comment later in the file can trigger warnings.
82
+ # +:freeze_template_literals+ :: Whether to suffix all literal strings for template code with <tt>.freeze</tt>
83
+ # (default: +true+ on Ruby 2.1+, +false+ on Ruby 2.0 and older).
84
+ # Can be set to +false+ on Ruby 2.3+ when frozen string literals are enabled
85
+ # in order to improve performance.
86
+ # +:literal_prefix+ :: The prefix to output when using escaped tag delimiters (default <tt>'<%'</tt>).
87
+ # +:literal_postfix+ :: The postfix to output when using escaped tag delimiters (default <tt>'%>'</tt>).
88
+ # +:outvar+ :: Same as +:bufvar+, with lower priority.
89
+ # +:postamble+ :: The postamble for the template, by default returns the resulting source code.
90
+ # +:preamble+ :: The preamble for the template, by default initializes the buffer variable.
91
+ # +:regexp+ :: The regexp to use for scanning.
92
+ # +:src+ :: The initial value to use for the source code, an empty string by default.
93
+ # +:trim+ :: Whether to trim leading and trailing whitespace, true by default.
67
94
  def initialize(input, properties={})
68
95
  @escape = escape = properties.fetch(:escape){properties.fetch(:escape_html, false)}
69
96
  trim = properties[:trim] != false
70
97
  @filename = properties[:filename]
71
98
  @bufvar = bufvar = properties[:bufvar] || properties[:outvar] || "_buf"
72
99
  bufval = properties[:bufval] || '::String.new'
73
- regexp = properties[:regexp] || /<%(={1,2}|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m
100
+ regexp = properties[:regexp] || DEFAULT_REGEXP
101
+ literal_prefix = properties[:literal_prefix] || '<%'
102
+ literal_postfix = properties[:literal_postfix] || '%>'
74
103
  preamble = properties[:preamble] || "#{bufvar} = #{bufval};"
75
104
  postamble = properties[:postamble] || "#{bufvar}.to_s\n"
105
+ @chain_appends = properties[:chain_appends]
106
+ @text_end = if properties.fetch(:freeze_template_literals, FREEZE_TEMPLATE_LITERALS)
107
+ "'.freeze"
108
+ else
109
+ "'"
110
+ end
76
111
 
112
+ @buffer_on_stack = false
77
113
  @src = src = properties[:src] || String.new
78
114
  src << "# frozen_string_literal: true\n" if properties[:freeze]
79
- src << "begin; __original_outvar = #{bufvar} if defined?(#{bufvar}); " if properties[:ensure]
115
+ if properties[:ensure]
116
+ src << "begin; __original_outvar = #{bufvar}"
117
+ if SKIP_DEFINED_FOR_INSTANCE_VARIABLE && /\A@[^@]/ =~ bufvar
118
+ src << "; "
119
+ else
120
+ src << " if defined?(#{bufvar}); "
121
+ end
122
+ end
80
123
 
81
124
  unless @escapefunc = properties[:escapefunc]
82
125
  if escape
83
126
  @escapefunc = '__erubi.h'
84
- src << "__erubi = ::Erubi;"
127
+ src << "__erubi = ::Erubi; "
85
128
  else
86
129
  @escapefunc = '::Erubi.h'
87
130
  end
@@ -110,46 +153,45 @@ module Erubi
110
153
  if rindex
111
154
  range = rindex+1..-1
112
155
  s = text[range]
113
- if s =~ /\A[ \t]*\z/
156
+ if /\A[ \t]*\z/.send(MATCH_METHOD, s)
114
157
  lspace = s
115
158
  text[range] = ''
116
159
  end
117
160
  else
118
- if is_bol && text =~ /\A[ \t]*\z/
119
- lspace = text.dup
120
- text[RANGE_ALL] = ''
161
+ if is_bol && /\A[ \t]*\z/.send(MATCH_METHOD, text)
162
+ lspace = text
163
+ text = ''
121
164
  end
122
165
  end
123
166
  end
124
167
  end
125
168
 
126
169
  is_bol = rspace
127
- add_text(text) if text && !text.empty?
170
+ add_text(text)
128
171
  case ch
129
172
  when '='
130
173
  rspace = nil if tailch && !tailch.empty?
131
- add_text(lspace) if lspace
132
174
  add_expression(indicator, code)
133
175
  add_text(rspace) if rspace
134
- when '#'
135
- n = code.count("\n") + (rspace ? 1 : 0)
176
+ when nil, '-'
136
177
  if trim && lspace && rspace
137
- add_code("\n" * n)
178
+ add_code("#{lspace}#{code}#{rspace}")
138
179
  else
139
180
  add_text(lspace) if lspace
140
- add_code("\n" * n)
181
+ add_code(code)
141
182
  add_text(rspace) if rspace
142
183
  end
143
- when '%'
144
- add_text("#{lspace}#{prefix||='<%'}#{code}#{tailch}#{postfix||='%>'}#{rspace}")
145
- when nil, '-'
184
+ when '#'
185
+ n = code.count("\n") + (rspace ? 1 : 0)
146
186
  if trim && lspace && rspace
147
- add_code("#{lspace}#{code}#{rspace}")
187
+ add_code("\n" * n)
148
188
  else
149
189
  add_text(lspace) if lspace
150
- add_code(code)
190
+ add_code("\n" * n)
151
191
  add_text(rspace) if rspace
152
192
  end
193
+ when '%'
194
+ add_text("#{lspace}#{literal_prefix}#{code}#{tailch}#{literal_postfix}#{rspace}")
153
195
  else
154
196
  handle(indicator, code, tailch, rspace, lspace)
155
197
  end
@@ -159,22 +201,33 @@ module Erubi
159
201
 
160
202
  src << "\n" unless src[RANGE_LAST] == "\n"
161
203
  add_postamble(postamble)
162
- src << "; ensure\n #{bufvar} = __original_outvar\nend\n" if properties[:ensure]
204
+ src << "; ensure\n " << bufvar << " = __original_outvar\nend\n" if properties[:ensure]
163
205
  src.freeze
164
206
  freeze
165
207
  end
166
208
 
167
209
  private
168
210
 
169
- # Add raw text to the template
211
+ # Add raw text to the template. Modifies argument if argument is mutable as a memory optimization.
212
+ # Must be called with a string, cannot be called with nil (Rails's subclass depends on it).
170
213
  def add_text(text)
171
- @src << " #{@bufvar} << '" << text.gsub(/['\\]/, '\\\\\&') << TEXT_END unless text.empty?
214
+ return if text.empty?
215
+
216
+ if text.frozen?
217
+ text = text.gsub(/['\\]/, '\\\\\&')
218
+ else
219
+ text.gsub!(/['\\]/, '\\\\\&')
220
+ end
221
+
222
+ with_buffer{@src << " << '" << text << @text_end}
172
223
  end
173
224
 
174
225
  # Add ruby code to the template
175
226
  def add_code(code)
227
+ terminate_expression
176
228
  @src << code
177
229
  @src << ';' unless code[RANGE_LAST] == "\n"
230
+ @buffer_on_stack = false
178
231
  end
179
232
 
180
233
  # Add the given ruby expression result to the template,
@@ -189,23 +242,52 @@ module Erubi
189
242
 
190
243
  # Add the result of Ruby expression to the template
191
244
  def add_expression_result(code)
192
- @src << " #{@bufvar} << (" << code << ').to_s;'
245
+ with_buffer{@src << ' << (' << code << ').to_s'}
193
246
  end
194
247
 
195
248
  # Add the escaped result of Ruby expression to the template
196
249
  def add_expression_result_escaped(code)
197
- @src << " #{@bufvar} << #{@escapefunc}((" << code << '));'
250
+ with_buffer{@src << ' << ' << @escapefunc << '((' << code << '))'}
198
251
  end
199
252
 
200
253
  # Add the given postamble to the src. Can be overridden in subclasses
201
254
  # to make additional changes to src that depend on the current state.
202
255
  def add_postamble(postamble)
203
- src << postamble
256
+ terminate_expression
257
+ @src << postamble
204
258
  end
205
259
 
206
260
  # Raise an exception, as the base engine class does not support handling other indicators.
207
261
  def handle(indicator, code, tailch, rspace, lspace)
208
262
  raise ArgumentError, "Invalid indicator: #{indicator}"
209
263
  end
264
+
265
+ # Make sure the buffer variable is the target of the next append
266
+ # before yielding to the block. Mark that the buffer is the target
267
+ # of the next append after the block executes.
268
+ #
269
+ # This method should only be called if the block will result in
270
+ # code where << will append to the bufvar.
271
+ def with_buffer
272
+ if @chain_appends
273
+ unless @buffer_on_stack
274
+ @src << '; ' << @bufvar
275
+ end
276
+ yield
277
+ @buffer_on_stack = true
278
+ else
279
+ @src << ' ' << @bufvar
280
+ yield
281
+ @src << ';'
282
+ end
283
+ end
284
+
285
+ # Make sure that any current expression has been terminated.
286
+ # The default is to terminate all expressions, but when
287
+ # the chain_appends option is used, expressions may not be
288
+ # terminated.
289
+ def terminate_expression
290
+ @src << '; ' if @chain_appends
291
+ end
210
292
  end
211
293
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erubi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  - kuwata-lab.com
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-09-25 00:00:00.000000000 Z
12
+ date: 2022-12-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -54,12 +54,15 @@ files:
54
54
  - Rakefile
55
55
  - lib/erubi.rb
56
56
  - lib/erubi/capture_end.rb
57
- - test/test.rb
58
57
  homepage: https://github.com/jeremyevans/erubi
59
58
  licenses:
60
59
  - MIT
61
- metadata: {}
62
- post_install_message:
60
+ metadata:
61
+ bug_tracker_uri: https://github.com/jeremyevans/erubi/issues
62
+ mailing_list_uri: https://github.com/jeremyevans/erubi/discussions
63
+ changelog_uri: https://github.com/jeremyevans/erubi/blob/master/CHANGELOG
64
+ source_code_uri: https://github.com/jeremyevans/erubi
65
+ post_install_message:
63
66
  rdoc_options:
64
67
  - "--quiet"
65
68
  - "--line-numbers"
@@ -81,8 +84,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
84
  - !ruby/object:Gem::Version
82
85
  version: '0'
83
86
  requirements: []
84
- rubygems_version: 3.0.3
85
- signing_key:
87
+ rubygems_version: 3.3.26
88
+ signing_key:
86
89
  specification_version: 4
87
90
  summary: Small ERB Implementation
88
91
  test_files: []
data/test/test.rb DELETED
@@ -1,780 +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
- gem 'minitest'
29
- require 'minitest/global_expectations/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 work with BasicObject methods" do
657
- c = Class.new(BasicObject)
658
- c.class_eval("def a; #{Erubi::Engine.new('2').src} end")
659
- c.new.a.must_equal '2'
660
- end if defined?(BasicObject)
661
-
662
- it "should return frozen object" do
663
- Erubi::Engine.new('').frozen?.must_equal true
664
- end
665
-
666
- it "should have frozen src" do
667
- Erubi::Engine.new('').src.frozen?.must_equal true
668
- end
669
-
670
- it "should raise an error if a tag is not handled when a custom regexp is used" do
671
- proc{Erubi::Engine.new('<%] %>', :regexp =>/<%(={1,2}|\]|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m)}.must_raise ArgumentError
672
- proc{Erubi::CaptureEndEngine.new('<%] %>', :regexp =>/<%(={1,2}|\]|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m)}.must_raise ArgumentError
673
- end
674
-
675
- it "should respect the :yield_returns_buffer option for making templates return the (potentially modified) buffer" do
676
- @options[:engine] = ::Erubi::CaptureEndEngine
677
- @options[:bufvar] = '@a'
678
-
679
- def self.bar
680
- a = String.new
681
- a << "a"
682
- yield 'burgers'
683
- case b = (yield 'salads')
684
- when String
685
- a << b
686
- a << 'b'
687
- a.upcase
688
- end
689
- end
690
-
691
- check_output(<<END1, <<END2, <<END3){}
692
- <%|= bar do |item| %>
693
- Let's eat <%= item %>!
694
- <% nil %><%| end %>
695
- END1
696
- @a = ::String.new;begin; (__erubi_stack ||= []) << @a; @a = ::String.new; __erubi_stack.last << (( bar do |item| @a << '
697
- '; @a << 'Let\\'s eat '; @a << ( item ).to_s; @a << '!
698
- '; nil ; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
699
- ';
700
- @a.to_s
701
- END2
702
-
703
- END3
704
-
705
- @options[:yield_returns_buffer] = true
706
-
707
- check_output(<<END1, <<END2, <<END3) {}
708
- <%|= bar do |item| %>
709
- Let's eat <%= item %>!
710
- <% nil %><%| end %>
711
- END1
712
- @a = ::String.new;begin; (__erubi_stack ||= []) << @a; @a = ::String.new; __erubi_stack.last << (( bar do |item| @a << '
713
- '; @a << 'Let\\'s eat '; @a << ( item ).to_s; @a << '!
714
- '; nil ; @a; end )).to_s; ensure; @a = __erubi_stack.pop; end; @a << '
715
- ';
716
- @a.to_s
717
- END2
718
- A
719
- LET'S EAT BURGERS!
720
-
721
- LET'S EAT SALADS!
722
- B
723
- END3
724
- end
725
-
726
- it "should respect the :yield_returns_buffer option for making templates return the (potentially modified) buffer as the result of the block" do
727
- @options[:engine] = ::Erubi::CaptureEndEngine
728
- @options[:yield_returns_buffer] = true
729
-
730
- def self.bar(foo = nil)
731
- if foo.nil?
732
- yield
733
- else
734
- foo
735
- end
736
- end
737
-
738
- check_output(<<END1, <<END2, <<END3) {}
739
- <%|= bar do %>
740
- Let's eat the tacos!
741
- <%| end %>
742
-
743
- Delicious!
744
- END1
745
- _buf = ::String.new;begin; (__erubi_stack ||= []) << _buf; _buf = ::String.new; __erubi_stack.last << (( bar do _buf << '
746
- '; _buf << 'Let\\'s eat the tacos!
747
- '; _buf; end )).to_s; ensure; _buf = __erubi_stack.pop; end; _buf << '
748
- '; _buf << '
749
- Delicious!
750
- ';
751
- _buf.to_s
752
- END2
753
-
754
- Let's eat the tacos!
755
-
756
-
757
- Delicious!
758
- END3
759
-
760
- check_output(<<END1, <<END2, <<END3) {}
761
- <%|= bar("Don't eat the burgers!") do %>
762
- Let's eat burgers!
763
- <%| end %>
764
-
765
- Delicious!
766
- END1
767
- _buf = ::String.new;begin; (__erubi_stack ||= []) << _buf; _buf = ::String.new; __erubi_stack.last << (( bar(\"Don't eat the burgers!\") do _buf << '
768
- '; _buf << 'Let\\'s eat burgers!
769
- '; _buf; end )).to_s; ensure; _buf = __erubi_stack.pop; end; _buf << '
770
- '; _buf << '
771
- Delicious!
772
- ';
773
- _buf.to_s
774
- END2
775
- Don't eat the burgers!
776
-
777
- Delicious!
778
- END3
779
- end
780
- end