summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author(no author) <(no author)@c9e70521-770b-0410-b9ac-ce6205b42a9f>2007-03-05 02:13:12 +0000
committer(no author) <(no author)@c9e70521-770b-0410-b9ac-ce6205b42a9f>2007-03-05 02:13:12 +0000
commitacdd8b2b37dee6a5a42d8ffd74c7d31e61191563 (patch)
treedf1995ef60b5563b25b8c31d698580ec5d8f6931
parentb33d57b596fbbc1082ec3ea3d2b2b3d158241534 (diff)
downloaderubis-acdd8b2b37dee6a5a42d8ffd74c7d31e61191563.tar.gz
- [enhance] add ErboutEnhancer
- [enhance] add ExpressionInterpolationEnhancer
-rw-r--r--CHANGES32
-rw-r--r--ChangeLog.txt7
-rw-r--r--ReleaseNote.txt7
-rw-r--r--benchmark/erubybench.rb4
-rw-r--r--doc/users-guide.html77
-rw-r--r--doc/users-guide.txt91
-rw-r--r--lib/erubis/engine/enhanced.rb10
-rw-r--r--lib/erubis/engine/eruby.rb8
-rw-r--r--lib/erubis/enhancer.rb136
-rw-r--r--test/test-enhancers.rb548
-rw-r--r--test/test-erubis.rb379
-rw-r--r--test/test.rb1
12 files changed, 886 insertions, 414 deletions
diff --git a/CHANGES b/CHANGES
index 8b85999..f5fa74b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,36 @@
#
+- release: 2.3.0
+ date:
+ enhancements:
+ - |
+ New enhancer 'ErboutEnhancer' is added.
+ ErboutEnhancer set '_erbout' as well as '_buf' to be compatible with ERB.
+
+ ex.
+ --------------------
+ _erbout = _buf = ''; _buf << '<p>'; _buf << text; _buf << '</p>
+ ';
+ --------------------
+
+ - |
+ New enhancer 'ExpressionInterpolationEnhancer' is added.
+ This enhancer uses expression interpolation to eliminate method call
+ of String#<<. In the result, this enhancer makes Eruby a little faster.
+
+ --------------------
+ ## Assume that input is '<a href="<%=url%>"><%=name%></a>'.
+ ## Eruby convert input into the following code. String#<< is called 5 times.
+ _buf << '<a href="'; _buf << (url).to_s; _buf << '">'; _buf << (name).to_s; _buf << '</a>';
+
+ ## If ExpressionInterpolationEnhancer is used, String#<< is called only once.
+ _buf << %Q`<a href="#{url}">#{name}</a>`;
+ --------------------
+
+
+
+#
- release: 2.2.0
date: 2007-02-11
enhancements:
@@ -78,7 +108,7 @@
$ erubis -c '{title: Example, list: [AAA, BBB, CCC]}' example.rhtml
====================
- ex. YAML inline style
+ ex. Ruby style
====================
$ erubis -c '@title="Example"; @list=%w[AAA BBB CCC]' example.rhtml
====================
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 2310dfb..faba533 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -2,6 +2,13 @@
.?lastupdate: $Date$
.?version: $Rev$
+: Rev.69 (2007-03-05)
+ .- [enhance] add ErboutEnhancer
+ .- [enhance] add ExpressionInterpolationEnhancer
+
+: Rev.68 (2007-02-12)
+ .- [release] 2.2.0
+
: Rev.67 (2007-02-12)
.- [update] benchmark data on user's guide is updated
diff --git a/ReleaseNote.txt b/ReleaseNote.txt
index aec799a..78adfb3 100644
--- a/ReleaseNote.txt
+++ b/ReleaseNote.txt
@@ -1,4 +1,4 @@
-$ [ANN] Erubis 2.1.0 release - a fast eRuby implementation
+$ [ANN] Erubis 2.2.0 release - a fast eRuby implementation
Hi all,
@@ -48,7 +48,7 @@ $$ Enhancements
are available. Methd ActionView::Helpers::TextHelper#concat() is also available.
If Erubis::Helpers::RailsHelper.show_src is ture, Erubis prints converted
- Ruby code into log file (such as 'log/development.log').
+ Ruby code into log file (such as 'log/development.log'). This is for debug.
* Erubis::Engine.load_file(filename) creates cache file (filename +
'.cache') automatically if cache file is old or not exist.
@@ -93,7 +93,7 @@ $$ Enhancements
$ erubis -c '{title: Example, list: [AAA, BBB, CCC]}' example.rhtml
====================
- ex. YAML inline style
+ ex. Ruby style
====================
$ erubis -c '@title="Example"; @list=%w[AAA BBB CCC]' example.rhtml
====================
@@ -145,7 +145,6 @@ $$ Changes
* Embedded pattern '<%- -%>' can be handled.
-
--
regards,
kwatch
diff --git a/benchmark/erubybench.rb b/benchmark/erubybench.rb
index 663da10..88f7c22 100644
--- a/benchmark/erubybench.rb
+++ b/benchmark/erubybench.rb
@@ -490,6 +490,10 @@ __END__
class: Erubis::Eruby
return: str
+- name: ErubisFastEruby
+ class: Erubis::FastEruby
+ return: str
+
- name: ErubisEruby2
desc: print _buf #, no binding()
class: Erubis::Eruby2
diff --git a/doc/users-guide.html b/doc/users-guide.html
index 36a93ba..b9355b3 100644
--- a/doc/users-guide.html
+++ b/doc/users-guide.html
@@ -99,6 +99,8 @@ It has the following features.
</li>
<li><a href="#stringbuffer-enhancer">StringBufferEnhancer</a>
</li>
+ <li><a href="#erbout-enhancer">ErboutEnhancer</a>
+ </li>
<li><a href="#notext-enhancer">NoTextEnhancer</a>
</li>
<li><a href="#nocode-enhancer">NoCodeEnhancer</a>
@@ -111,6 +113,8 @@ It has the following features.
</li>
<li><a href="#headerfooter-enhancer">HeaderFooterEnhancer</a>
</li>
+ <li><a href="#expressioninterpolation-enhancer">ExpressionInterpolationEnhancer</a>
+ </li>
</ul>
</li>
<li><a href="#lang">Multi-Language</a>
@@ -998,12 +1002,17 @@ The following is an example to use some enhancers in command-line.
<dt class="dt1">
<a href="#arraybuffer-enhancer">ArrayBufferEnhancer</a> (only for Eruby)</dt>
<dd class="dd1">
- Use array buffer. This is included in Erubis::Eruby by default.
+ Use array buffer. It is a little slower than StringBufferEnhancer.
</dd>
<dt class="dt1">
<a href="#stringbuffer-enhancer">StringBufferEnhancer</a> (only for Eruby)</dt>
<dd class="dd1">
- Use string buffer. It is a little slower than ArrayBufferEnhancer.
+ Use string buffer. This is included in Erubis::Eruby by default.
+</dd>
+<dt class="dt1">
+<a href="#erbout-enhancer">ErboutEnhancer</a> (only for Eruby)</dt>
+<dd class="dd1">
+ Set '_erbout = _buf = "";' to be compatible with ERB.
</dd>
<dt class="dt1">
<a href="#notext-enhancer">NoTextEnhancer</a> (language-independent)</dt>
@@ -1035,6 +1044,11 @@ The following is an example to use some enhancers in command-line.
<dd class="dd1">
[experimental] Enable you to add header and footer in eRuby script.
</dd>
+<dt class="dt1">
+<a href="#expressioninterpolation-enhancer">ExpressionInterpolationEnhancer</a> (only for Eruby)</dt>
+<dd class="dd1">
+ [experimental] convert '&lt;p&gt;&lt;%= text %&gt;&lt;/p&gt;' into '_buf &lt;&lt; %Q`&lt;p&gt;#{text}&lt;/p&gt;`'.
+</dd>
</dl>
<p>If you required 'erubis/engine/enhanced', Eruby subclasses which include each enhancers are defined.
For example, class BiPatternEruby includes BiPatternEnhancer.
@@ -1156,7 +1170,8 @@ because print() method in '&lt;% ... %&gt;' invokes not Kernel#print() but Print
</p>
<div class="terminal_caption">
compiled source code</div>
-<pre class="terminal"><strong>_buf = [];</strong> _buf &lt;&lt; '&lt;div&gt;
+<pre class="terminal">$ erubis -xE Array example.eruby
+<strong>_buf = [];</strong> _buf &lt;&lt; '&lt;div&gt;
'; for item in list
_buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
&lt;p&gt;'; _buf &lt;&lt; Erubis::XmlHelper.escape_xml( item ); _buf &lt;&lt; '&lt;/p&gt;
@@ -1185,7 +1200,7 @@ Array buffer is a litte slower than String buffer.
'; end
_buf &lt;&lt; '&lt;/div&gt;
';
-<strong>_buf</strong>.join
+<strong>_buf.join</strong>
</pre>
<br>
@@ -1201,6 +1216,26 @@ Erubis::Eruby includes this enhancer by default.
<br>
+<a name="erbout-enhancer"></a>
+<h3 class="section2">ErboutEnhancer</h3>
+<p>ErboutEnhancer makes Eruby to be compatible with ERB.
+This is useful especially for Ruby on Rails.
+</p>
+<pre class="terminal">$ erubis -xE Erbout example.eruby
+<strong>_erbout = _buf = '';</strong> _buf &lt;&lt; '&lt;div&gt;
+'; for item in list
+ _buf &lt;&lt; ' &lt;p&gt;'; _buf &lt;&lt; ( item ).to_s; _buf &lt;&lt; '&lt;/p&gt;
+ &lt;p&gt;'; _buf &lt;&lt; Erubis::XmlHelper.escape_xml( item ); _buf &lt;&lt; '&lt;/p&gt;
+'; end
+ _buf &lt;&lt; '&lt;/div&gt;
+';
+_buf.to_s
+</pre>
+<p>ErboutEnhancer is only for Eruby.
+</p>
+<br>
+
+
<a name="notext-enhancer"></a>
<h3 class="section2">NoTextEnhancer</h3>
<p>NoTextEnhancer suppress output of text and prints only embedded code.
@@ -1471,6 +1506,40 @@ _buf.to_s
<br>
+<a name="expressioninterpolation-enhancer"></a>
+<h3 class="section2">ExpressionInterpolationEnhancer</h3>
+<p>[experimental]
+</p>
+<p>ExpressionInterpolationEnhancer converts "&lt;h1&gt;&lt;%= title %&gt;&lt;/h1&gt;" into
+"_buf &lt;&lt; %Q`&lt;h1&gt;#{ title }&lt;/h1&gt;`".
+This makes Eruby a litter faster because method call of String#&lt;&lt; are eliminated
+by expression interpolations.
+</p>
+<div class="program_caption">
+ExpressionInterpolationEnhancer elmininates method call of String#&lt;&lt;.</div>
+<pre class="program">## Assume that input is '&lt;a href="&lt;%=url%&gt;"&gt;&lt;%=name%&gt;&lt;/a&gt;'.
+## Eruby convert input into the following code. String#&lt;&lt; is called 5 times.
+_buf &lt;&lt; '&lt;a href="'; _buf &lt;&lt; (url).to_s; _buf &lt;&lt; '"&gt;'; _buf &lt;&lt; (name).to_s; _buf &lt;&lt; '&lt;/a&gt;';
+
+## If ExpressionInterpolationEnhancer is used, String#&lt;&lt; is called only once.
+_buf &lt;&lt; %Q`&lt;a href="#{url}"&gt;#{name}&lt;/a&gt;`;
+</pre>
+<div class="terminal_caption">
+compiled source code</div>
+<pre class="terminal">$ erubis -xE ExpressionInterpolation example.eruby
+_buf = ''; _buf &lt;&lt; <strong>%Q`</strong>&lt;div&gt;\n<strong>`</strong>
+ for item in list
+ _buf &lt;&lt; <strong>%Q`</strong> &lt;p&gt;<strong>#{ item }</strong>&lt;/p&gt;
+ &lt;p&gt;<strong>#{Erubis::XmlHelper.escape_xml( item )}</strong>&lt;/p&gt;\n<strong>`</strong>
+ end
+ _buf &lt;&lt; <strong>%Q`</strong>&lt;/div&gt;\n<strong>`</strong>
+_buf.to_s
+</pre>
+<p>ExpressionInterpolationEnhancer is only for Eruby.
+</p>
+<br>
+
+
<br>
diff --git a/doc/users-guide.txt b/doc/users-guide.txt
index fd766d0..e129044 100644
--- a/doc/users-guide.txt
+++ b/doc/users-guide.txt
@@ -735,9 +735,11 @@ The following is the list of enhancers.
.: {{<ArrayEnhancer|#array-enhancer>}} (only for Eruby)
Return array of string instead of returning string.
.: {{<ArrayBufferEnhancer|#arraybuffer-enhancer>}} (only for Eruby)
- Use array buffer. This is included in Erubis::Eruby by default.
+ Use array buffer. It is a little slower than StringBufferEnhancer.
.: {{<StringBufferEnhancer|#stringbuffer-enhancer>}} (only for Eruby)
- Use string buffer. It is a little slower than ArrayBufferEnhancer.
+ Use string buffer. This is included in Erubis::Eruby by default.
+.: {{<ErboutEnhancer|#erbout-enhancer>}} (only for Eruby)
+ Set '_erbout = _buf = "";' to be compatible with ERB.
.: {{<NoTextEnhancer|#notext-enhancer>}} (language-independent)
Print embedded code only and ignore normal text.
.: {{<NoCodeEnhancer|#nocode-enhancer>}} (language-independent)
@@ -750,6 +752,8 @@ The following is the list of enhancers.
Regard lines starting with '%' as Ruby code. This is for compatibility with eruby and ERB.
.: {{<HeaderFooterEnhancer|#headerfooter-enhancer>}} (language-independent)
[experimental] Enable you to add header and footer in eRuby script.
+.: {{<ExpressionInterpolationEnhancer|#expressioninterpolation-enhancer>}} (only for Eruby)
+ [experimental] convert '<p><%= text %></p>' into '_buf << %Q`<p>#{text}</p>`'.
If you required 'erubis/engine/enhanced', Eruby subclasses which include each enhancers are defined.
@@ -926,6 +930,7 @@ ArrayEnhancer makes Eruby to return an array of strings.
.? compiled source code
.====================
+$ erubis -xE Array example.eruby
.<<<:! erubis -xE Array guide.d/example.eruby | ruby -pe 'sub! /^_buf( = \[\];)?/, "{{*\\&*}}"'
.====================
@@ -942,7 +947,7 @@ ArrayBufferEnhancer is only for Eruby.
.====================
$ erubis -xE ArrayBuffer example.eruby
-.<<<:! erubis -xE ArrayBuffer guide.d/example.eruby | ruby -pe 'sub!(/^_buf( = ..;|\.to_s)?/,"{{*\\&*}}")'
+.<<<:! erubis -xE ArrayBuffer guide.d/example.eruby | ruby -pe 'sub!(/^_buf( = .*?;|\.join)?/,"{{*\\&*}}")'
.====================
@@ -972,7 +977,7 @@ Erubis::Eruby includes this enhancer by default.
.#.====================
.#$ erubis -xE StringBuffer example.eruby
-.#.<<<:! erubis -xE StringBuffer guide.d/example.eruby | ruby -pe 'sub!(/^_buf( = ..;)?/,"{{*\\&*}}")'
+.#.<<<:! erubis -xE StringBuffer guide.d/example.eruby | ruby -pe 'sub!(/^_buf( = .*?;)?/,"{{*\\&*}}")'
.#.====================
@@ -980,6 +985,37 @@ StringBufferEnhancer is only for Eruby.
+.$$ ErboutEnhancer | erbout-enhancer
+
+ErboutEnhancer makes Eruby to be compatible with ERB.
+This is useful especially for Ruby on Rails.
+
+.#.? erbout-example.rb
+.#.-------------------- erbout-example.rb
+.#require 'erubis'
+.#class ErboutEruby < Erubis::Eruby
+.# include Erubis::ErboutEnhancer
+.#end
+.#eruby = ErboutEruby.new(File.read('example.eruby'))
+.#print eruby.src
+.#.--------------------
+.#
+.#.? compiled source code
+.#.====================
+.#$ ruby erbout-example.rb
+.#.<<<:! (cd guide.d; ruby erbout-example.rb)
+.#.====================
+
+.====================
+$ erubis -xE Erbout example.eruby
+.<<<:! erubis -xE Erbout guide.d/example.eruby | ruby -pe 'sub! /^_erbout = _buf = .*?;/,"{{*\\&*}}"'
+.====================
+
+
+ErboutEnhancer is only for Eruby.
+
+
+
.$$ NoTextEnhancer | notext-enhancer
NoTextEnhancer suppress output of text and prints only embedded code.
@@ -1269,6 +1305,53 @@ HeaderFooterEnhancer is experimental and is language-independent.
+.$$ ExpressionInterpolationEnhancer | expressioninterpolation-enhancer
+
+[experimental]
+
+ExpressionInterpolationEnhancer converts "<h1><%= title %></h1>" into
+"_buf << %Q`<h1>#{ title }</h1>`".
+This makes Eruby a litter faster because method call of String#<< are eliminated
+by expression interpolations.
+
+.? ExpressionInterpolationEnhancer elmininates method call of String#<<.
+.--------------------
+## Assume that input is '<a href="<%=url%>"><%=name%></a>'.
+## Eruby convert input into the following code. String#<< is called 5 times.
+_buf << '<a href="'; _buf << (url).to_s; _buf << '">'; _buf << (name).to_s; _buf << '</a>';
+
+## If ExpressionInterpolationEnhancer is used, String#<< is called only once.
+_buf << %Q`<a href="#{url}">#{name}</a>`;
+.--------------------
+
+.#.? expressioninterpolation-example.rb
+.#.-------------------- expressioninterpolation-example.rb
+.#require 'erubis'
+.#class ExpressionInterpolationEruby < Erubis::Eruby
+.# include Erubis::ExpressionInterpolationEnhancer
+.#end
+.#eruby = ExpressionInterpolationEruby.new(File.read('example.eruby'))
+.### or
+.##eruby = Erubis::FastEruby.new(File.read('example.eruby'))
+.#print eruby.src
+.#.--------------------
+.#
+.#.? compiled source code
+.#.====================
+.#$ ruby expressioninterpolation-example.rb
+.#.<<<:! (cd guide.d; ruby expressioninterpolation-example.rb)
+.#.====================
+
+.? compiled source code
+.====================
+$ erubis -xE ExpressionInterpolation example.eruby
+.<<<:! erubis -xE ExpressionInterpolation guide.d/example.eruby | ruby -pe 'gsub! /(%Q`|`|\#\{.*?\})/, "{{*\\&*}}"'
+.====================
+
+ExpressionInterpolationEnhancer is only for Eruby.
+
+
+
.$ Multi-Language | lang
Erubis supports the following language currently:
diff --git a/lib/erubis/engine/enhanced.rb b/lib/erubis/engine/enhanced.rb
index 122bc88..5ee34fb 100644
--- a/lib/erubis/engine/enhanced.rb
+++ b/lib/erubis/engine/enhanced.rb
@@ -62,6 +62,11 @@ module Erubis
end
+ class ErboutEruby < Eruby
+ include ErboutEnhancer
+ end
+
+
class NoTextEruby < Eruby
include NoTextEnhancer
end
@@ -104,4 +109,9 @@ module Erubis
end
+ class ExpressionInterpolationEruby < Eruby
+ include ExpressionInterpolationEnhancer
+ end
+
+
end
diff --git a/lib/erubis/engine/eruby.rb b/lib/erubis/engine/eruby.rb
index 50ee07b..c39f03c 100644
--- a/lib/erubis/engine/eruby.rb
+++ b/lib/erubis/engine/eruby.rb
@@ -85,6 +85,14 @@ module Erubis
##
+ ## fast engine for Ruby
+ ##
+ class FastEruby < Eruby
+ include ExpressionInterpolationEnhancer
+ end
+
+
+ ##
## swtich '<%= %>' to escaped and '<%== %>' to not escaped
##
class EscapedEruby < Eruby
diff --git a/lib/erubis/enhancer.rb b/lib/erubis/enhancer.rb
index f5b9eb4..0497278 100644
--- a/lib/erubis/enhancer.rb
+++ b/lib/erubis/enhancer.rb
@@ -243,29 +243,27 @@ module Erubis
end
- #--
- ###
- ### set buffer variable name to '_erbout' as well as '_buf'
- ###
- ### this is only for Eruby.
- ###
- #module ErboutEnhancer
- #
- # def self.desc # :nodoc:
- # "set buffer name '_erbout' as well as '_buf'"
- # end
- #
- # def add_preamble(src)
- # src << "_erbout = _buf = '';"
- # end
- #
- # def add_postamble(src)
- # src << "\n" unless src[-1] == ?\n
- # src << "_buf.to_s\n"
- # end
- #
- #end
- #++
+ ##
+ ## set buffer variable name to '_erbout' as well as '_buf'
+ ##
+ ## this is only for Eruby.
+ ##
+ module ErboutEnhancer
+
+ def self.desc # :nodoc:
+ "set '_erbout = _buf = \"\";' to be compatible with ERB."
+ end
+
+ def add_preamble(src)
+ src << "_erbout = _buf = '';"
+ end
+
+ def add_postamble(src)
+ src << "\n" unless src[-1] == ?\n
+ src << "_buf.to_s\n"
+ end
+
+ end
##
@@ -544,4 +542,96 @@ module Erubis
end
+ ##
+ ## convert "<h1><%= title %></h1>" into "_buf << %Q`<h1>#{ title }</h1>`"
+ ##
+ ## this is only for Eruby.
+ ##
+ module ExpressionInterpolationEnhancer
+
+ def self.desc # :nodoc:
+ "convert '<p><%= text %></p>' into '_buf << %Q`<p>#{text}</p>`'"
+ end
+
+ def convert_input(src, input)
+ pat = @pattern
+ regexp = pat.nil? || pat == '<% %>' ? Basic::Converter::DEFAULT_REGEXP : pattern_regexp(pat)
+ pos = 0
+ is_bol = true # is beginning of line
+ str = ''
+ input.scan(regexp) do |indicator, code, rspace|
+ match = Regexp.last_match()
+ len = match.begin(0) - pos
+ text = input[pos, len]
+ pos = match.end(0)
+ ch = indicator ? indicator[0] : nil
+ lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
+ is_bol = rspace ? true : false
+ _add_text_to_str(str, text)
+ ## * when '<%= %>', do nothing
+ ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
+ if ch == ?= # <%= %>
+ str << lspace if lspace
+ add_expr(str, code, indicator)
+ str << rspace if rspace
+ elsif ch == ?\# # <%# %>
+ n = code.count("\n") + (rspace ? 1 : 0)
+ if @trim && lspace && rspace
+ add_text(src, str)
+ str = ''
+ add_stmt(src, "\n" * n)
+ else
+ str << lspace if lspace
+ add_text(src, str)
+ str = ''
+ add_stmt(src, "\n" * n)
+ str << rspace if rspace
+ end
+ else # <% %>
+ if @trim && lspace && rspace
+ add_text(src, str)
+ str = ''
+ add_stmt(src, "#{lspace}#{code}#{rspace}")
+ else
+ str << lspace if lspace
+ add_text(src, str)
+ str = ''
+ add_stmt(src, code)
+ str << rspace if rspace
+ end
+ end
+ end
+ rest = $' || input # add input when no matched
+ _add_text_to_str(str, rest)
+ add_text(src, str)
+ end
+
+ def add_text(src, text)
+ return if !text || text.empty?
+ #src << " _buf << %Q`" << text << "`;"
+ if text[-1] == ?\n
+ text[-1] = "\\n"
+ src << " _buf << %Q`" << text << "`\n"
+ else
+ src << " _buf << %Q`" << text << "`;"
+ end
+ end
+
+ def _add_text_to_str(str, text)
+ return if !text || text.empty?
+ text.gsub!(/['\#\\]/, '\\\\\&')
+ str << text
+ end
+
+ def add_expr_escaped(str, code)
+ str << "\#{#{escaped_expr(code)}}"
+ end
+
+ def add_expr_literal(str, code)
+ str << "\#{#{code}}"
+ end
+
+ end
+
+
end
diff --git a/test/test-enhancers.rb b/test/test-enhancers.rb
new file mode 100644
index 0000000..870c01e
--- /dev/null
+++ b/test/test-enhancers.rb
@@ -0,0 +1,548 @@
+##
+## $Rev$
+## $Release$
+## $Copyright$
+##
+
+require "#{File.dirname(__FILE__)}/test.rb"
+
+require 'stringio'
+
+require 'erubis'
+require 'erubis/engine/enhanced'
+require 'erubis/engine/optimized'
+
+
+class EnhancersTest < Test::Unit::TestCase
+
+ testdata_list = load_yaml_datafile(__FILE__)
+ define_testmethods(testdata_list)
+
+
+ def _test()
+ @src.gsub!(/\^/, ' ')
+ @output.gsub!(/\^/, ' ') if @output.is_a?(String)
+ if @class
+ k = Erubis
+ @class.split('::').each do |name| k = k.const_get(name) end
+ @klass = k
+ else
+ @klass = Erubis::Eruby
+ end
+ @options ||= {}
+ @chomp.each do |target|
+ case target
+ when 'src' ; @src.chomp!
+ when 'input' ; @input.chomp!
+ when 'expected' ; @expected.chomp!
+ else
+ raise "#{@name}: invalid chomp value: #{@chomp.inspect}"
+ end
+ end if @chomp
+
+ if @testopt == 'load_file'
+ filename = "tmp.#{@name}.eruby"
+ begin
+ File.open(filename, 'w') { |f| f.write(@input) }
+ eruby = @klass.load_file(filename, @options)
+ ensure
+ cachename = filename + '.cache'
+ File.unlink(cachename) if test(?f, cachename)
+ File.unlink(filename) if test(?f, filename)
+ end
+ else
+ #if @klass == Erubis::TinyEruby
+ # eruby = @klass.new(@input)
+ #else
+ eruby = @klass.new(@input, @options)
+ #end
+ end
+ assert_text_equal(@src, eruby.src)
+
+ return if @testopt == 'skip_output'
+
+ list = ['<aaa>', 'b&b', '"ccc"']
+ context = @testopt == 'context' ? Erubis::Context.new : {}
+ context[:list] = list
+
+ case @testopt
+ when /\Aeval\(/
+ eval eruby.src
+ actual = eval @testopt
+ assert_text_equal(@output, actual)
+ when 'stdout', 'print'
+ begin
+ orig = $stdout
+ $stdout = stringio = StringIO.new
+ #actual = eruby.evaluate(context)
+ actual = eruby.result(context)
+ ensure
+ $stdout = orig
+ end
+ if @testopt == 'stdout'
+ assert_equal("", actual)
+ else
+ assert_nil(actual)
+ end
+ assert_text_equal(@output, stringio.string)
+ when 'evaluate', 'context'
+ actual = eruby.evaluate(context)
+ assert_text_equal(@output, actual)
+ when 'binding'
+ actual = eruby.result(binding())
+ assert_text_equal(@output, actual)
+ else
+ actual = eruby.result(context)
+ assert_text_equal(@output, actual)
+ end
+ end
+
+
+end
+
+__END__
+
+##
+- name: basic1
+ class: Eruby
+ input: &basic1_input|
+ <ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <% end %>
+ </ul>
+ src: &basic1_src|
+ _buf = ''; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ _buf.to_s
+ output: &basic1_output|
+ <ul>
+ <li><aaa></li>
+ <li>b&b</li>
+ <li>"ccc"</li>
+ </ul>
+
+- name: xml1
+ class: XmlEruby
+ input: |
+ <pre>
+ <% for item in list %>
+ <%= item %>
+ <%== item %>
+ <% end %>
+ </pre>
+ src: |
+ _buf = ''; _buf << '<pre>
+ '; for item in list
+ _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
+ '; _buf << ' '; _buf << ( item ).to_s; _buf << '
+ '; end
+ _buf << '</pre>
+ ';
+ _buf.to_s
+ output: |
+ <pre>
+ &lt;aaa&gt;
+ <aaa>
+ b&amp;b
+ b&b
+ &quot;ccc&quot;
+ "ccc"
+ </pre>
+
+##
+- name: xml2
+ class: XmlEruby
+ testopt: skip_output
+ input: |
+ <% for item in list %>
+ <%= item["var#{n}"] %>
+ <%== item["var#{n}"] %>
+ <%=== item["var#{n}"] %>
+ <%==== item["var#{n}"] %>
+ <% end %>
+ src: |
+ _buf = ''; for item in list
+ _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item["var#{n}"] ); _buf << '
+ '; _buf << ' '; _buf << ( item["var#{n}"] ).to_s; _buf << '
+ '; _buf << ' '; $stderr.puts("*** debug: item[\"var\#{n}\"]=#{(item["var#{n}"]).inspect}"); _buf << '
+ '; _buf << ' '; _buf << '
+ '; end
+ _buf.to_s
+ output: |
+
+##
+- name: printout1
+ class: PrintOutEruby
+ testopt: print
+ input: *basic1_input
+ src: |4
+ print '<ul>
+ '; for item in list
+ print ' <li>'; print(( item ).to_s); print '</li>
+ '; end
+ print '</ul>
+ ';
+ output: *basic1_output
+
+##
+- name: printenabled1
+ class: PrintEnabledEruby
+ input: &printenabled1_input|
+ <ul>
+ <% for item in list %>
+ <li><% print item %></li>
+ <% end %>
+ </ul>
+ src: |
+ @_buf = _buf = ''; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; print item ; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ _buf.to_s
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
+
+##
+- name: stdout1
+ class: StdoutEruby
+ testopt: stdout
+ input: *basic1_input
+# <ul>
+# <% for item in list %>
+# <li><%= item %></li>
+# <% end %>
+# </ul>
+ src: |
+ _buf = $stdout; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ ''
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
+
+##
+- name: array1
+ class: ArrayEruby
+ input: |
+ <ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <% end %>
+ </ul>
+ src: |
+ _buf = []; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ _buf
+ output:
+ - "<ul>\n"
+ - " <li>"
+ - "<aaa>"
+ - "</li>\n"
+ - " <li>"
+ - "b&b"
+ - "</li>\n"
+ - " <li>"
+ - "\"ccc\""
+ - "</li>\n"
+ - "</ul>\n"
+
+##
+- name: arraybuffer1
+ class: ArrayBufferEruby
+ input: *basic1_input
+ src: |
+ _buf = []; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ _buf.join
+ output: *basic1_output
+
+- name: stringbuffer1
+ class: StringBufferEruby
+ input: *basic1_input
+# <ul>
+# <% for item in list %>
+# <li><%= item %></li>
+# <% end %>
+# </ul>
+ src: |
+ _buf = ''; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ _buf.to_s
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
+
+##
+- name: erbout1
+ class: ErboutEruby
+ input: *basic1_input
+ src: |
+ _erbout = _buf = ''; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ _buf.to_s
+ output: *basic1_output
+
+##
+- name: stringio1
+ class: StringIOEruby
+ input: *basic1_input
+ src: |
+ _buf = StringIO.new; _buf << '<ul>
+ '; for item in list
+ _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
+ '; end
+ _buf << '</ul>
+ ';
+ _buf.string
+ output: *basic1_output
+
+##
+- name: notext1
+ class: NoTextEruby
+ input: *basic1_input
+ src: |
+ _buf = '';
+ for item in list
+ _buf << ( item ).to_s;
+ end
+
+ _buf.to_s
+ output: '<aaa>b&b"ccc"'
+
+
+##
+- name: nocode1
+ class: NoCodeEruby
+ testopt: skip_output
+ input: *basic1_input
+ src: |
+ <ul>
+
+ <li></li>
+
+ </ul>
+ output:
+
+##
+- name: simplified
+ class: SimplifiedEruby
+ input: |
+ <ul>
+ <% for item in list %>
+ <li>
+ <%= item %>
+ </li>
+ <% end %>
+ </ul>
+ src: |
+ _buf = ''; _buf << '<ul>
+ '; for item in list ; _buf << '
+ <li>
+ '; _buf << ( item ).to_s; _buf << '
+ </li>
+ '; end ; _buf << '
+ </ul>
+ ';
+ _buf.to_s
+ output: |
+ <ul>
+ ^
+ <li>
+ <aaa>
+ </li>
+ ^
+ <li>
+ b&b
+ </li>
+ ^
+ <li>
+ "ccc"
+ </li>
+ ^
+ </ul>
+
+##
+- name: bipattern1
+ class: BiPatternEruby
+ #options: { :bipattern : '\[= =\]' }
+ input: |
+ <% for item in list %>
+ <%= item %> % <%== item %>
+ [= item =] = [== item =]
+ <% end %>
+ src: |
+ _buf = ''; for item in list
+ _buf << ' '; _buf << ( item ).to_s; _buf << ' % '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
+ '; _buf << ' '; _buf << ( item ).to_s; _buf << ' = '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
+ '; end
+ _buf.to_s
+ output: |4
+ <aaa> % &lt;aaa&gt;
+ <aaa> = &lt;aaa&gt;
+ b&b % b&amp;b
+ b&b = b&amp;b
+ "ccc" % &quot;ccc&quot;
+ "ccc" = &quot;ccc&quot;
+
+##
+- name: bipattern2
+ class: BiPatternEruby
+ options: { :bipattern: '\$\{ \}' }
+ input: |
+ <% for item in list %>
+ <%=item%> % <%==item%>
+ ${item} = ${=item}
+ <% end %>
+ src: |
+ _buf = ''; for item in list
+ _buf << ' '; _buf << (item).to_s; _buf << ' % '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
+ '; _buf << ' '; _buf << (item).to_s; _buf << ' = '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
+ '; end
+ _buf.to_s
+ output: |4
+ <aaa> % &lt;aaa&gt;
+ <aaa> = &lt;aaa&gt;
+ b&b % b&amp;b
+ b&b = b&amp;b
+ "ccc" % &quot;ccc&quot;
+ "ccc" = &quot;ccc&quot;
+
+##
+- name: percentline1
+ class: PercentLineEruby
+ options:
+ input: |
+ <table>
+ % for item in list
+ <tr>
+ <td><%= item %></td>
+ <td><%== item %></td>
+ </tr>
+ % end
+ </table>
+ <pre>
+ %% double percent
+ % spaced percent
+ </pre>
+ src: |
+ _buf = ''; _buf << '<table>
+ '; for item in list
+ _buf << ' <tr>
+ <td>'; _buf << ( item ).to_s; _buf << '</td>
+ <td>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</td>
+ </tr>
+ '; end
+ _buf << '</table>
+ <pre>
+ '; _buf << '% double percent
+ '; _buf << ' % spaced percent
+ </pre>
+ ';
+ _buf.to_s
+ output: |
+ <table>
+ <tr>
+ <td><aaa></td>
+ <td>&lt;aaa&gt;</td>
+ </tr>
+ <tr>
+ <td>b&b</td>
+ <td>b&amp;b</td>
+ </tr>
+ <tr>
+ <td>"ccc"</td>
+ <td>&quot;ccc&quot;</td>
+ </tr>
+ </table>
+ <pre>
+ % double percent
+ % spaced percent
+ </pre>
+
+##
+- name: headerfooter1
+ class: HeaderFooterEruby
+ options:
+ testopt: eval('ordered_list(list)')
+ input: |
+ <!--#header:
+ def ordered_list(list)
+ #-->
+ <ol>
+ <% for item in list %>
+ <li><%==item%></li>
+ <% end %>
+ </ol>
+ <!--#footer: end #-->
+ src: |4
+
+ def ordered_list(list)
+
+ _buf = ''; _buf << '<ol>
+ '; for item in list
+ _buf << ' <li>'; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '</li>
+ '; end
+ _buf << '</ol>
+ ';
+ _buf.to_s
+ end
+ output: |
+ <ol>
+ <li>&lt;aaa&gt;</li>
+ <li>b&amp;b</li>
+ <li>&quot;ccc&quot;</li>
+ </ol>
+
+##
+- name: expressioninterpolation1
+ class: ExpressionInterpolationEruby
+ options:
+ testopt:
+ input: *basic1_input
+ src: |
+ _buf = ''; _buf << %Q`<ul>\n`
+ for item in list
+ _buf << %Q` <li>#{ item }</li>\n`
+ end
+ _buf << %Q`</ul>\n`
+ _buf.to_s
+ output: *basic1_output
+
+
diff --git a/test/test-erubis.rb b/test/test-erubis.rb
index a99d5ba..3fea2f9 100644
--- a/test/test-erubis.rb
+++ b/test/test-erubis.rb
@@ -399,7 +399,7 @@ __END__
_buf << '</ul>
';
chomp: [src]
- expected: null
+ expected: null
##
- name: loadfile1
@@ -464,383 +464,6 @@ __END__
<>&"
##
-- name: xml1
- class: XmlEruby
- input: |
- <pre>
- <% for item in list %>
- <%= item %>
- <%== item %>
- <% end %>
- </pre>
- src: |
- _buf = ''; _buf << '<pre>
- '; for item in list
- _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
- '; _buf << ' '; _buf << ( item ).to_s; _buf << '
- '; end
- _buf << '</pre>
- ';
- _buf.to_s
- output: |
- <pre>
- &lt;aaa&gt;
- <aaa>
- b&amp;b
- b&b
- &quot;ccc&quot;
- "ccc"
- </pre>
-
-##
-- name: xml2
- class: XmlEruby
- testopt: skip_output
- input: |
- <% for item in list %>
- <%= item["var#{n}"] %>
- <%== item["var#{n}"] %>
- <%=== item["var#{n}"] %>
- <%==== item["var#{n}"] %>
- <% end %>
- src: |
- _buf = ''; for item in list
- _buf << ' '; _buf << Erubis::XmlHelper.escape_xml( item["var#{n}"] ); _buf << '
- '; _buf << ' '; _buf << ( item["var#{n}"] ).to_s; _buf << '
- '; _buf << ' '; $stderr.puts("*** debug: item[\"var\#{n}\"]=#{(item["var#{n}"]).inspect}"); _buf << '
- '; _buf << ' '; _buf << '
- '; end
- _buf.to_s
- output: |
-
-##
-- name: printout1
- class: PrintOutEruby
- testopt: print
- input: *basic1_input
- src: |4
- print '<ul>
- '; for item in list
- print ' <li>'; print(( item ).to_s); print '</li>
- '; end
- print '</ul>
- ';
- output: *basic1_output
-
-##
-- name: printenabled1
- class: PrintEnabledEruby
- input: &printenabled1_input|
- <ul>
- <% for item in list %>
- <li><% print item %></li>
- <% end %>
- </ul>
- src: |
- @_buf = _buf = ''; _buf << '<ul>
- '; for item in list
- _buf << ' <li>'; print item ; _buf << '</li>
- '; end
- _buf << '</ul>
- ';
- _buf.to_s
- output: *basic1_output
-# <ul>
-# <li><aaa></li>
-# <li>b&b</li>
-# <li>"ccc"</li>
-# </ul>
-
-##
-- name: stdout1
- class: StdoutEruby
- testopt: stdout
- input: *basic1_input
-# <ul>
-# <% for item in list %>
-# <li><%= item %></li>
-# <% end %>
-# </ul>
- src: |
- _buf = $stdout; _buf << '<ul>
- '; for item in list
- _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
- '; end
- _buf << '</ul>
- ';
- ''
- output: *basic1_output
-# <ul>
-# <li><aaa></li>
-# <li>b&b</li>
-# <li>"ccc"</li>
-# </ul>
-
-##
-- name: array1
- class: ArrayEruby
- input: |
- <ul>
- <% for item in list %>
- <li><%= item %></li>
- <% end %>
- </ul>
- src: |
- _buf = []; _buf << '<ul>
- '; for item in list
- _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
- '; end
- _buf << '</ul>
- ';
- _buf
- output:
- - "<ul>\n"
- - " <li>"
- - "<aaa>"
- - "</li>\n"
- - " <li>"
- - "b&b"
- - "</li>\n"
- - " <li>"
- - "\"ccc\""
- - "</li>\n"
- - "</ul>\n"
-
-##
-- name: arraybuffer1
- class: ArrayBufferEruby
- input: *basic1_input
- src: |
- _buf = []; _buf << '<ul>
- '; for item in list
- _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
- '; end
- _buf << '</ul>
- ';
- _buf.join
- output: *basic1_output
-
-- name: stringbuffer1
- class: StringBufferEruby
- input: *basic1_input
-# <ul>
-# <% for item in list %>
-# <li><%= item %></li>
-# <% end %>
-# </ul>
- src: |
- _buf = ''; _buf << '<ul>
- '; for item in list
- _buf << ' <li>'; _buf << ( item ).to_s; _buf << '</li>
- '; end
- _buf << '</ul>
- ';
- _buf.to_s
- output: *basic1_output
-# <ul>
-# <li><aaa></li>
-# <li>b&b</li>
-# <li>"ccc"</li>
-# </ul>
-
-##
-- name: notext1
- class: NoTextEruby
- input: *basic1_input
- src: |
- _buf = '';
- for item in list
- _buf << ( item ).to_s;
- end
-
- _buf.to_s
- output: '<aaa>b&b"ccc"'
-
-
-##
-- name: nocode1
- class: NoCodeEruby
- testopt: skip_output
- input: *basic1_input
- src: |
- <ul>
-
- <li></li>
-
- </ul>
- output:
-
-##
-- name: simplified
- class: SimplifiedEruby
- input: |
- <ul>
- <% for item in list %>
- <li>
- <%= item %>
- </li>
- <% end %>
- </ul>
- src: |
- _buf = ''; _buf << '<ul>
- '; for item in list ; _buf << '
- <li>
- '; _buf << ( item ).to_s; _buf << '
- </li>
- '; end ; _buf << '
- </ul>
- ';
- _buf.to_s
- output: |
- <ul>
- ^
- <li>
- <aaa>
- </li>
- ^
- <li>
- b&b
- </li>
- ^
- <li>
- "ccc"
- </li>
- ^
- </ul>
-
-##
-- name: bipattern1
- class: BiPatternEruby
- #options: { :bipattern : '\[= =\]' }
- input: |
- <% for item in list %>
- <%= item %> % <%== item %>
- [= item =] = [== item =]
- <% end %>
- src: |
- _buf = ''; for item in list
- _buf << ' '; _buf << ( item ).to_s; _buf << ' % '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
- '; _buf << ' '; _buf << ( item ).to_s; _buf << ' = '; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '
- '; end
- _buf.to_s
- output: |4
- <aaa> % &lt;aaa&gt;
- <aaa> = &lt;aaa&gt;
- b&b % b&amp;b
- b&b = b&amp;b
- "ccc" % &quot;ccc&quot;
- "ccc" = &quot;ccc&quot;
-
-##
-- name: bipattern2
- class: BiPatternEruby
- options: { :bipattern: '\$\{ \}' }
- input: |
- <% for item in list %>
- <%=item%> % <%==item%>
- ${item} = ${=item}
- <% end %>
- src: |
- _buf = ''; for item in list
- _buf << ' '; _buf << (item).to_s; _buf << ' % '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
- '; _buf << ' '; _buf << (item).to_s; _buf << ' = '; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '
- '; end
- _buf.to_s
- output: |4
- <aaa> % &lt;aaa&gt;
- <aaa> = &lt;aaa&gt;
- b&b % b&amp;b
- b&b = b&amp;b
- "ccc" % &quot;ccc&quot;
- "ccc" = &quot;ccc&quot;
-
-##
-- name: percentline1
- class: PercentLineEruby
- options:
- input: |
- <table>
- % for item in list
- <tr>
- <td><%= item %></td>
- <td><%== item %></td>
- </tr>
- % end
- </table>
- <pre>
- %% double percent
- % spaced percent
- </pre>
- src: |
- _buf = ''; _buf << '<table>
- '; for item in list
- _buf << ' <tr>
- <td>'; _buf << ( item ).to_s; _buf << '</td>
- <td>'; _buf << Erubis::XmlHelper.escape_xml( item ); _buf << '</td>
- </tr>
- '; end
- _buf << '</table>
- <pre>
- '; _buf << '% double percent
- '; _buf << ' % spaced percent
- </pre>
- ';
- _buf.to_s
- output: |
- <table>
- <tr>
- <td><aaa></td>
- <td>&lt;aaa&gt;</td>
- </tr>
- <tr>
- <td>b&b</td>
- <td>b&amp;b</td>
- </tr>
- <tr>
- <td>"ccc"</td>
- <td>&quot;ccc&quot;</td>
- </tr>
- </table>
- <pre>
- % double percent
- % spaced percent
- </pre>
-
-##
-- name: headerfooter1
- class: HeaderFooterEruby
- options:
- testopt: eval('ordered_list(list)')
- input: |
- <!--#header:
- def ordered_list(list)
- #-->
- <ol>
- <% for item in list %>
- <li><%==item%></li>
- <% end %>
- </ol>
- <!--#footer: end #-->
- src: |4
-
- def ordered_list(list)
-
- _buf = ''; _buf << '<ol>
- '; for item in list
- _buf << ' <li>'; _buf << Erubis::XmlHelper.escape_xml(item); _buf << '</li>
- '; end
- _buf << '</ol>
- ';
- _buf.to_s
- end
- output: |
- <ol>
- <li>&lt;aaa&gt;</li>
- <li>b&amp;b</li>
- <li>&quot;ccc&quot;</li>
- </ol>
-
-##
- name: optimized1
class: OptimizedEruby
input: &optimized1_input|
diff --git a/test/test.rb b/test/test.rb
index b625ada..3831917 100644
--- a/test/test.rb
+++ b/test/test.rb
@@ -24,6 +24,7 @@ require 'erubis'
if $0 == __FILE__
require "#{TESTDIR}/test-erubis.rb"
require "#{TESTDIR}/test-engines.rb"
+ require "#{TESTDIR}/test-enhancers.rb"
require "#{TESTDIR}/test-main.rb"
require "#{TESTDIR}/test-notext.rb"
end