summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormakoto kuwata <kwa@kuwata-lab.com>2006-04-29 13:43:58 +0000
committermakoto kuwata <kwa@kuwata-lab.com>2006-04-29 13:43:58 +0000
commit23c96d3dcd301159dca6e60e561ab4b27e19bd58 (patch)
treed88c50b309387f52ab9afd6fc9038f53bcdb08ec
parent1a3ae7bbb18495c0d58d4c5a79de88976e086ea7 (diff)
downloaderubis-23c96d3dcd301159dca6e60e561ab4b27e19bd58.tar.gz
- [change] Eruby adopt ArrayBufferEnhancer as default
- [enhance] new module BiPatternEnhancer [experimental] - [enhance] new module SimplifiedEnhancer - [enhance] new module StringBufferEnhancer - [enhance] new module PrintStatementEnhancer - [enhance] new module PercentLineEnhancer - [enhance] new module HeaderFooterEnhancer [experimental] - [enhance] new class OutputSimplifiedEruby - [enhance] Engine.supported_properties() added - [enhance] print show_properties() when '-h' is specified - [enhance] add Eperl class (engine/perl.rb) - [enhance] add examples - [change] class Eruby includes ArrayBufferEnhancer - [change] EscapeEnhancer now overrides add_expr() - [change] module PrintEnhancer is renamed to PrintAvailableEnhancer - [change] Ejava doesn't out 'StringBuffer _buf' nor 'return _buf.toString();' - [change] subclasses of Eruby are moved to new file 'enhanced.rb'
-rw-r--r--ChangeLog.txt19
-rw-r--r--Rookbook.yaml18
-rw-r--r--benchmark/erubybench.rb101
-rw-r--r--erubis.gemspec8
-rw-r--r--examples/Makefile50
-rw-r--r--examples/example.ec24
-rw-r--r--examples/example.ejava41
-rw-r--r--examples/example.eperl16
-rw-r--r--examples/example.ephp17
-rw-r--r--examples/example.eruby15
-rw-r--r--examples/example.escheme26
-rw-r--r--lib/erubis.rb5
-rw-r--r--lib/erubis/engine.rb20
-rw-r--r--lib/erubis/engine/c.rb30
-rw-r--r--lib/erubis/engine/enhanced.rb154
-rw-r--r--lib/erubis/engine/java.rb37
-rw-r--r--lib/erubis/engine/optimized.rb114
-rw-r--r--lib/erubis/engine/perl.rb77
-rw-r--r--lib/erubis/engine/php.rb4
-rw-r--r--lib/erubis/engine/ruby.rb66
-rw-r--r--lib/erubis/engine/scheme.rb16
-rw-r--r--lib/erubis/enhancer.rb277
-rw-r--r--lib/erubis/local-setting.rb10
-rw-r--r--lib/erubis/main.rb32
-rw-r--r--misc/memo.txt373
-rw-r--r--test/test-bin.rb17
-rw-r--r--test/test-engines.rb486
-rw-r--r--test/test-erubis.rb1246
-rw-r--r--test/test.rb27
-rw-r--r--test/testutil.rb86
30 files changed, 2496 insertions, 916 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index c11eb02..cacaa9b 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -2,6 +2,25 @@
.?lastupdate: $Date$
.?version: $Rev$
+.: Rev.13 (2006-04-29)
+ .- [change] Eruby adopt ArrayBufferEnhancer as default
+ .- [enhance] new module BiPatternEnhancer [experimental]
+ .- [enhance] new module SimplifiedEnhancer
+ .- [enhance] new module StringBufferEnhancer
+ .- [enhance] new module PrintStatementEnhancer
+ .- [enhance] new module PercentLineEnhancer
+ .- [enhance] new module HeaderFooterEnhancer [experimental]
+ .- [enhance] new class OutputSimplifiedEruby
+ .- [enhance] Engine.supported_properties() added
+ .- [enhance] print show_properties() when '-h' is specified
+ .- [enhance] add Eperl class (engine/perl.rb)
+ .- [enhance] add examples
+ .- [change] class Eruby includes ArrayBufferEnhancer
+ .- [change] EscapeEnhancer now overrides add_expr()
+ .- [change] module PrintEnhancer is renamed to PrintAvailableEnhancer
+ .- [change] Ejava doesn't out 'StringBuffer _buf' nor 'return _buf.toString();'
+ .- [change] subclasses of Eruby are moved to new file 'enhanced.rb'
+
.: Rev.12 (2006-04-26)
.- [enhance] PHP, C, Java, and Scheme support
.- [enhance] new class Engine is splitted from Eruby
diff --git a/Rookbook.yaml b/Rookbook.yaml
index 4567480..011ecf1 100644
--- a/Rookbook.yaml
+++ b/Rookbook.yaml
@@ -101,8 +101,8 @@ recipes:
mkdir_p dir
#
store 'lib/**/*', 'bin/*', 'test/**/*', $text_files, dir
- #chdir 'examples' do cmd 'rook :clean' end
- #store 'examples/**/*', dir
+ chdir 'examples' do sys 'make clean' end
+ store 'examples/**/*', dir
store '$(apidocdir)/**/*', dir
mkdir_p "#{dir}/doc"
cp_r $doc_files, "#{dir}/doc"
@@ -116,3 +116,17 @@ recipes:
#
chmod 0644, "#{dir}/**/*", :filetype=>'file'
chmod 0755, "#{dir}/{bin,contrib}/*", :filetype=>'file'
+
+ - product: :duplicate
+ method: |
+ files = []
+ files += Dir.glob('lib/**/*.rb')
+ files += Dir.glob('benchmark/erubybench.{rb,rhtml,yaml}')
+ archive = "#{@product}.tar.gz"
+ tar_czf archive, files
+ dir = '/Volumes/WORKGROUP;DENEB/src/erubis/trunk'
+ cp archive, dir
+ chdir dir do
+ tar_xzf archive
+ end
+
diff --git a/benchmark/erubybench.rb b/benchmark/erubybench.rb
index e835132..bb6ec7c 100644
--- a/benchmark/erubybench.rb
+++ b/benchmark/erubybench.rb
@@ -7,13 +7,13 @@
require 'eruby'
require 'erb'
require 'erubis'
+require 'erubis/engine/enhanced'
require 'erubis/engine/optimized'
## default values
-base = __FILE__.sub(/\.rb$/, '')
-filename = base + '.rhtml'
-datafile = base + '.yaml'
+filename = 'erubybench.rhtml'
+datafile = 'erubybench.yaml'
n = 1000
@@ -21,7 +21,7 @@ n = 1000
def usage(n, filename, datafile)
s = "Usage: ruby #{$0} [-h] [-n N] [-f file] [-d file] [testname ...]\n"
s << " -h : help\n"
- s << " -n N : number of repeat (default #{n})\n"
+ s << " -n N : number of times to loop (default #{n})\n"
s << " -f file : eruby filename (default '#{filename}')\n"
s << " -d file : data filename (default '#{datafile}')\n"
return s
@@ -40,7 +40,7 @@ while !ARGV.empty? && ARGV[0][0] == ?-
when '-f' ; filename = ARGV.shift
when '-d' ; datafile = ARGV.shift
when '-h', '--help' ; flag_help = true
- when '-A' ; flag_all = true
+ when '-A' ; test_all = true
when '-C' ; compiler_name = ARGV.shift
else ; raise "#{opt}: invalid option."
end
@@ -75,7 +75,8 @@ $devnull = File.open("/dev/null", 'w')
module Erubis
class Eruby2 < Eruby
def finalize_src(src)
- src << "\nprint _out\n"
+ #src << "\nprint _out.join; nil\n"
+ src << "\n_out.join; ''\n"
end
end
end
@@ -99,7 +100,7 @@ testdefs_str = <<END
# print eruby.result(binding())
compile: |
ERB.new(str).src
- return: str
+ return: str
- name: ErubisEruby
class: Erubis::Eruby
@@ -131,6 +132,33 @@ testdefs_str = <<END
return: str
skip: yes
+#- name: ErubisArrayBuffer
+# class: Erubis::ArrayBufferEruby
+# code: |
+# Erubis::ArrayBufferEruby.new(File.read(filename)).result(binding())
+# compile: |
+# Erubis::ArrayBufferEruby.new(str).src
+# return: str
+# skip: no
+
+- name: ErubisStringBuffer
+ class: Erubis::StringBufferEruby
+ code: |
+ Erubis::StringBufferEruby.new(File.read(filename)).result(binding())
+ compile: |
+ Erubis::StringBufferEruby.new(str).src
+ return: str
+ skip: no
+
+- name: ErubisSimplified
+ class: Erubis::SimplifiedEruby
+ code: |
+ Erubis::SimplifiedEruby.new(File.read(filename)).result(binding())
+ compile: |
+ Erubis::SimplifiedEruby.new(str).src
+ return: str
+ skip: no
+
- name: ErubisStdout
class: Erubis::StdoutEruby
code: |
@@ -138,47 +166,47 @@ testdefs_str = <<END
compile: |
Erubis::StdoutEruby.new(str).src
return: null
- skip: yes
+ skip: no
-- name: ErubisArrayBuffer
- class: Erubis::ArrayBufferEruby
+- name: ErubisStdoutSimplified
+ class: Erubis::StdoutSimplifiedEruby
code: |
- Erubis::ArrayBufferEruby.new(File.read(filename)).result(binding())
+ Erubis::StdoutSimplifiedEruby.new(File.read(filename)).result(binding())
compile: |
- Erubis::ArrayBufferEruby.new(str).src
+ Erubis::StdoutSimplifiedEruby.new(str).src
return: str
- skip: yes
+ skip: no
-- name: load
- class: load
- code: |
- load($load_filename)
- compile: null
- return: null
- skip: yes
+#- name: load
+# class: load
+# code: |
+# load($load_filename)
+# compile: null
+# return: null
+# skip: yes
END
testdefs = YAML.load(testdefs_str)
-## create file for load
-if testdefs.find { |h| h['name'] == 'load' }
- $load_filename = filename + ".tmp" # for load
- $data = data
- str = File.read(filename)
- str.gsub!(/\bdata\b/, '$data')
- hash = testdefs.find { |h| h['name'] == compiler_name }
- code = eval hash['compile']
- code.sub!(/_out\s*\z/, 'print \&')
- File.open($load_filename, 'w') { |f| f.write(code) }
- at_exit do
- File.unlink $load_filename if test(?f, $load_filename)
- end
-end
+### create file for load
+#if testdefs.find { |h| h['name'] == 'load' }
+# $load_filename = filename + ".tmp" # for load
+# $data = data
+# str = File.read(filename)
+# str.gsub!(/\bdata\b/, '$data')
+# hash = testdefs.find { |h| h['name'] == compiler_name }
+# code = eval hash['compile']
+# code.sub!(/_out\s*\z/, 'print \&')
+# File.open($load_filename, 'w') { |f| f.write(code) }
+# at_exit do
+# File.unlink $load_filename if test(?f, $load_filename)
+# end
+#end
## select test target
-if flag_all
+if test_all
#testdefs.each { |h| h['skip'] = false }
elsif !ARGV.empty?
#testdefs.each { |h| h['skip'] = ARGV.include?(h['name']) }
@@ -284,6 +312,7 @@ begin
testdefs.each do |h|
title = h['class']
func = 'test_' + h['name']
+ GC.start
job.report(title) do
__send__(func, filename, data)
end
@@ -294,6 +323,7 @@ begin
next unless h['compile']
title = 'eval_' + h['name']
func = 'test_eval_' + h['name']
+ GC.start
job.report(title) do
__send__(func, filename, data)
end
@@ -304,6 +334,7 @@ begin
next unless h['compile']
title = 'func_' + h['name']
func = 'test_view_' + h['name']
+ GC.start
job.report(title) do
__send__(func, data)
end
diff --git a/erubis.gemspec b/erubis.gemspec
index 726cc20..6d327ab 100644
--- a/erubis.gemspec
+++ b/erubis.gemspec
@@ -15,21 +15,23 @@ spec = Gem::Specification.new do |s|
s.version = ("$Release$" =~ /[\.\d]+/) && $&
s.platform = Gem::Platform::RUBY
s.homepage = "http://rubyforge.org/projects/erubis"
- s.summary = "an implementation of eRuby"
+ s.summary = "a fast and extensible eRuby implementation which supports multi-language"
s.description = <<-'END'
Erubis is an implementation of eRuby and has the following features:
+ * Very fast (about three times faster than ERB)
* Auto trimming spaces around '<% %>'
* Auto sanitizing
* Change embedded pattern (default '<% %>')
* Context object available
* Easy to expand in subclass
+ * Able to output multi-language (Ruby/PHP/C/Java/Scheme/Perl)
END
## files
files = []
files += Dir.glob('lib/**/*')
files += Dir.glob('bin/*')
- #files += Dir.glob('examples/**/*')
+ files += Dir.glob('examples/**/*')
files += Dir.glob('test/test-*.rb')
#files += Dir.glob('man/**/*')
files += [ "doc/users-guide.html", "doc/docstyle.css", ]
@@ -38,7 +40,7 @@ spec = Gem::Specification.new do |s|
s.files = files
s.executables = ["erubis"]
s.bindir = "bin"
- s.test_file = 'test/test-erubis.rb'
+ s.test_file = 'test/test.rb'
end
# Quick fix for Ruby 1.8.3 / YAML bug (thanks to Ross Bamford)
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 0000000..1261f9d
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,50 @@
+all = example.rb example.php example.c example.java example.scm example.pl
+
+all: $(all)
+
+example.rb: example.eruby
+ erubis -l ruby example.eruby > example.rb
+
+
+example.php: example.ephp
+ erubis -l php example.ephp > example.php
+
+example.c: example.ec
+ erubis -l c example.ec > example.c
+
+example.java: example.ejava
+ erubis -l java example.ejava > example.java
+
+example.scm: example.escheme
+ erubis -l scheme --func=display example.escheme > example.scm
+# erubis -l scheme example.escheme > example.scm
+
+example.pl: example.eperl
+ erubis -l perl example.eperl > example.pl
+
+
+###----------
+
+src = example.eruby example.ephp example.ec example.ejava example.escheme example.eperl Makefile
+
+clean:
+ rm -f `ruby -e 'puts(Dir.glob("*.*") - %w[$(src)])'`
+# rm -f $(all)
+
+compile: a.out example.class
+
+a.out: example.c
+ cc example.c
+
+example.class: example.java
+ jikes example.java
+
+output: $(all) a.out example.class
+ erubis example.eruby > example.ruby.out
+ php example.php > example.php.out
+ ./a.out foo bar baz > example.c.out
+ java example > example.java.out
+ gosh example.scm > example.scm.out
+# guile example.scm > example.scm.out
+ perl example.pl > example.pl.out
+
diff --git a/examples/example.ec b/examples/example.ec
new file mode 100644
index 0000000..06e7961
--- /dev/null
+++ b/examples/example.ec
@@ -0,0 +1,24 @@
+<%
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ int i;
+
+%>
+<p>Hello <%= "%s", argv[0] %>!</p>
+<table>
+ <tbody>
+ <% for (i = 1; i < argc; i++) { %>
+ <tr bgcolor="<%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %>">
+ <td><%= "%d", i %></td>
+ <td><%= "%s", argv[i] %></td>
+ </tr>
+ <% } %>
+ </tbody>
+</table>
+<%
+
+ return 0;
+}
+%>
diff --git a/examples/example.ejava b/examples/example.ejava
new file mode 100644
index 0000000..21dd155
--- /dev/null
+++ b/examples/example.ejava
@@ -0,0 +1,41 @@
+<%
+import java.util.*;
+
+public class example {
+
+ public static void main(String[] args) {
+ String user = "Erubis";
+ String[] list = { "<aaa>", "b&b", "\"ccc\"" };
+ StringBuffer _out = new StringBuffer();
+%>
+<p>Hello <%= user %>!</p>
+<table>
+ <tbody>
+ <% for (int i = 0; i < list.length; i++) { %>
+ <tr bgcolor="<%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %>">
+ <td><%= i + 1 %></td>
+ <td><%== list[i] %></td>
+ </tr>
+ <% } %>
+ </tbody>
+</table>
+<%
+ System.out.print(_out.toString());
+ }
+
+ public static String escape(String s) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ switch (ch) {
+ case '<': sb.append("&lt;"); break;
+ case '>': sb.append("&gt;"); break;
+ case '&': sb.append("&amp;"); break;
+ case '"': sb.append("&quot;"); break;
+ default: sb.append(ch);
+ }
+ }
+ return sb.toString();
+ }
+}
+%>
diff --git a/examples/example.eperl b/examples/example.eperl
new file mode 100644
index 0000000..678aa21
--- /dev/null
+++ b/examples/example.eperl
@@ -0,0 +1,16 @@
+<%
+ my $user = 'Erubis';
+ my @list = ('<aaa>', 'b&b', '"ccc"');
+%>
+<p>Hello <%= $user %>!</p>
+<table>
+ <tbody>
+ <% $i = 0; %>
+ <% for $item (@list) { %>
+ <tr bgcolor=<%= ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %>">
+ <td><%= $i %></td>
+ <td><%= $item %></td>
+ </tr>
+ <% } %>
+ </tbody>
+</table>
diff --git a/examples/example.ephp b/examples/example.ephp
new file mode 100644
index 0000000..b45d62d
--- /dev/null
+++ b/examples/example.ephp
@@ -0,0 +1,17 @@
+<%
+ $user = "World";
+ $list = array('<aaa>', 'b&b', '"ccc"');
+%>
+<p>Hello <%= $user %>!</p>
+<table>
+ <tbody>
+ <% $i = 0 %>
+ <% foreach ($list as $item) { %>
+ <% $i++; %>
+ <tr bgcolor="<%= $i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %>">
+ <td><%= $i %></td>
+ <td><%== $item %></td>
+ </tr>
+ <% } %>
+ </tbody>
+</table>
diff --git a/examples/example.eruby b/examples/example.eruby
new file mode 100644
index 0000000..ee1ed13
--- /dev/null
+++ b/examples/example.eruby
@@ -0,0 +1,15 @@
+<%
+ user = 'Erubis'
+ list = ['<aaa>', 'b&b', '"ccc"']
+ %>
+<p>Hello <%= user %>!</p>
+<table>
+ <tbody>
+ <% list.each_with_index do |item, i| %>
+ <tr bgcolor="<%= i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %>">
+ <td><%= i + 1 %></td>
+ <td><%== item %></td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
diff --git a/examples/example.escheme b/examples/example.escheme
new file mode 100644
index 0000000..419ef77
--- /dev/null
+++ b/examples/example.escheme
@@ -0,0 +1,26 @@
+<%
+(let ((user "Erubis")
+ (items '("<aaa>" "b&b" "\"ccc\""))
+ (i 0))
+ %>
+<p>Hello <%= user %>!</p>
+<table>
+ <tbody>
+<%
+ (for-each
+ (lambda (item)
+ (set! i (+ i 1))
+ %>
+ <tr bgcolor="<%= (if (= (modulo i 2) 0) "#FFCCCC" "#CCCCFF") %>">
+ <td><%= i %></td>
+ <td><%= item %></td>
+ </tr>
+<%
+ ) ; lambda end
+ items) ; for-each end
+ %>
+ </tbody>
+</table>
+<%
+) ; let end
+%>
diff --git a/lib/erubis.rb b/lib/erubis.rb
index e1ec3ab..70c660c 100644
--- a/lib/erubis.rb
+++ b/lib/erubis.rb
@@ -56,8 +56,11 @@ require 'erubis/engine'
require 'erubis/helper'
require 'erubis/enhancer'
require 'erubis/engine/ruby'
-require 'erubis/engine/optimized'
+#require 'erubis/engine/enhanced' # enhanced eruby engines
+#require 'erubis/engine/optimized' # generates optimized ruby code
#require 'erubis/engine/php'
#require 'erubis/engine/c'
#require 'erubis/engine/java'
#require 'erubis/engine/scheme'
+
+require 'erubis/local-setting'
diff --git a/lib/erubis/engine.rb b/lib/erubis/engine.rb
index 7ed9d29..1482986 100644
--- a/lib/erubis/engine.rb
+++ b/lib/erubis/engine.rb
@@ -20,6 +20,14 @@ module Erubis
##
class Engine
+ def self.supported_properties # :nodoc:
+ return [
+ [:pattern, '<% %>', "embed pattern"],
+ [:filename, nil, "filename"],
+ [:trim, true, "trim spaces around <% ... %>"],
+ ]
+ end
+
def initialize(input, options={})
#@input = input
@pattern = options[:pattern] || '<% %>'
@@ -38,17 +46,13 @@ module Erubis
return eruby
end
- def result(binding=TOPLEVEL_BINDING)
- filename = @filename || '(erubis)'
- eval @src, binding, filename
+ def result(_binding=TOPLEVEL_BINDING)
+ _filename = @filename || '(erubis)'
+ eval @src, _binding, _filename
end
def evaluate(_context={})
- _evalstr = ''
- _context.keys.each do |key|
- _evalstr << "#{key.to_s} = _context[#{key.inspect}]\n"
- end
- eval _evalstr
+ eval _context.keys.inject("") { |s, k| s << "#{k.to_s} = _context[#{k.inspect}];" }
return result(binding())
end
diff --git a/lib/erubis/engine/c.rb b/lib/erubis/engine/c.rb
index 146137b..486c8c0 100644
--- a/lib/erubis/engine/c.rb
+++ b/lib/erubis/engine/c.rb
@@ -16,6 +16,13 @@ module Erubis
##
class Ec < Engine
+ def self.supported_properties() # :nodoc:
+ list = super
+ list << [:indent, '', "indent spaces (ex. ' ')"]
+ list << [:out, 'stdout', "output stream name"]
+ return list
+ end
+
def initialize(input, properties={})
@indent = properties[:indent] || ''
@out = properties[:out] || 'stdout'
@@ -23,7 +30,7 @@ module Erubis
end
def init_src(src)
- src << "# 1 \"#{self.filename}\"\n" if self.filename
+ src << "#line 1 \"#{self.filename}\"\n" if self.filename
end
def escape_text(text)
@@ -32,6 +39,15 @@ module Erubis
return text
end
+ def escaped_expr(code)
+ code.strip!
+ if code =~ /\A(\".*?\")\s*,\s*(.*)/
+ return "#{$1}, escape(#{$2})"
+ else
+ return "escape(#{code})"
+ end
+ end
+
def add_text(src, text)
return if text.empty?
src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
@@ -60,10 +76,6 @@ module Erubis
src << " fprintf(#{@out}, " << escaped_expr(code) << ');'
end
- def escaped_expr(code)
- return code.strip
- end
-
def add_expr_debug(src, code)
code.strip!
s = nil
@@ -80,11 +92,9 @@ module Erubis
end
- #--
- #class XmlEc < Ec
- # include EscapeEnhancer
- #end
- #++
+ class XmlEc < Ec
+ include EscapeEnhancer
+ end
end
diff --git a/lib/erubis/engine/enhanced.rb b/lib/erubis/engine/enhanced.rb
new file mode 100644
index 0000000..b82789e
--- /dev/null
+++ b/lib/erubis/engine/enhanced.rb
@@ -0,0 +1,154 @@
+##
+## $Rev$
+## $Release$
+## $Copyright$
+##
+
+require 'erubis/enhancer'
+require 'erubis/engine/ruby'
+
+
+module Erubis
+
+
+ ## (obsolete)
+ class FastEruby < Eruby
+ include FastEnhancer
+ end
+
+
+ class StdoutEruby < Eruby
+ include StdoutEnhancer
+ end
+
+
+ class PrintStatementEruby < Eruby
+ include PrintStatementEnhancer
+ end
+
+
+ class PrintEnabledEruby < Eruby
+ include PrintEnabledEnhancer
+ end
+
+
+ class ArrayEruby < Eruby
+ include ArrayEnhancer
+ end
+
+
+ #--
+ #class ArrayBufferEruby < Eruby
+ # include ArrayBufferEnhancer
+ #end
+ #++
+
+
+ class StringBufferEruby < Eruby
+ include StringBufferEnhancer
+ end
+
+
+ class SimplifiedEruby < Eruby
+ include SimplifiedEnhancer
+ end
+
+
+ class StdoutSimplifiedEruby < Eruby
+ include StdoutEnhancer
+ include SimplifiedEnhancer
+ end
+
+
+ class BiPatternEruby < Eruby
+ include BiPatternEnhancer
+ end
+
+
+ class PercentLineEruby < Eruby
+ include PercentLineEnhancer
+ end
+
+
+ class HeaderFooterEruby < Eruby
+ include HeaderFooterEnhancer
+ end
+
+
+ ## (obsolete)
+ class FastXmlEruby < Eruby
+ include FastEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class StdoutXmlEruby < Eruby
+ include StdoutEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class PrintStatementXmlEruby < Eruby
+ include PrintStatementEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class PrintEnabledXmlEruby < Eruby
+ include PrintEnabledEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class ArrayXmlEruby < Eruby
+ include ArrayEnhancer
+ include EscapeEnhancer
+ end
+
+
+ #--
+ #class ArrayBufferXmlEruby < Eruby
+ # include ArrayBufferEnhancer
+ # include EscapeEnhancer
+ #end
+ #++
+
+
+ class StrinBufferXmlEruby < Eruby
+ include StringBufferEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class SimplifiedXmlEruby < Eruby
+ include SimplifiedEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class StdoutSimplifiedXmlEruby < Eruby
+ include StdoutEnhancer
+ include SimplifiedEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class BiPatternXmlEruby < Eruby
+ include BiPatternEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class PercentLineXmlEruby < Eruby
+ include PercentLineEnhancer
+ include EscapeEnhancer
+ end
+
+
+ class HeaderFooterXmlEruby < Eruby
+ include HeaderFooterEnhancer
+ include EscapeEnhancer
+ end
+
+
+end
diff --git a/lib/erubis/engine/java.rb b/lib/erubis/engine/java.rb
index 6017387..7a604f5 100644
--- a/lib/erubis/engine/java.rb
+++ b/lib/erubis/engine/java.rb
@@ -16,30 +16,38 @@ module Erubis
##
class Ejava < Engine
+ def self.supported_properties() # :nodoc:
+ list = super
+ list << [:indent, '', "indent spaces (ex. ' ')"]
+ list << [:out, '_out', "output buffer name"]
+ #list << [:outclass, 'StringBuffer', "output buffer class (ex. 'StringBuilder')"]
+ return list
+ end
+
def initialize(input, properties={})
@indent = properties[:indent] || ''
- @out = properties[:out] || '_out'
- @outclass = properties[:outclass] || 'StringBuffer'
+ @out = properties[:out] || '_out'
+ #@outclass = properties[:outclass] || 'StringBuffer'
super
end
def init_src(src)
- src << "#{@indent}#{@outclass} _out = new #{@outclass}();\n"
+ #src << "#{@indent}#{@out} _out = new #{@outclass}();\n"
end
def escape_text(text)
@@table_ ||= { "\r"=>"\\r", "\n"=>"\\n", "\t"=>"\\t", '"'=>'\\"', "\\"=>"\\\\" }
- text.gsub(/[\r\n\t"\\]/) { |m| @@table_[m] }
+ return text.gsub!(/[\r\n\t"\\]/) { |m| @@table_[m] } || text
end
def escaped_expr(code)
- return code.strip
+ return "escape(#{code.strip})"
end
def add_text(src, text)
return if text.empty?
src << (src.empty? || src[-1] == ?\n ? @indent : ' ')
- src << "_out.append("
+ src << @out << ".append("
i = 0
text.each_line do |line|
src << "\n" << @indent << ' + ' if i > 0
@@ -55,12 +63,12 @@ module Erubis
def add_expr_literal(src, code)
src << @indent if src.empty? || src[-1] == ?\n
- src << ' _out.append(' << code.strip << ');'
+ src << ' ' << @out << '.append(' << code.strip << ');'
end
def add_expr_escaped(src, code)
src << @indent if src.empty? || src[-1] == ?\n
- src << ' _out.append(' << escaped_expr(code) << ');'
+ src << ' ' << @out << '.append(' << escaped_expr(code) << ');'
end
def add_expr_debug(src, code)
@@ -69,18 +77,17 @@ module Erubis
src << " System.err.println(\"*** debug: #{code}=\"+(#{code}));"
end
- def finalize_src(src)
+ def finish_src(src)
src << "\n" if src[-1] == ?;
- src << @indent << "return _out.toString();\n"
+ #src << @indent << "return " << @out << ".toString();\n"
end
end
- #--
- #class XmlEjava < Compiler
- # include EscapeEnhancer
- #end
- #++
+ class XmlEjava < Ejava
+ include EscapeEnhancer
+ end
+
end
diff --git a/lib/erubis/engine/optimized.rb b/lib/erubis/engine/optimized.rb
index 7330188..27bed18 100644
--- a/lib/erubis/engine/optimized.rb
+++ b/lib/erubis/engine/optimized.rb
@@ -12,12 +12,24 @@ module Erubis
##
- ## Eruby class which generates optimized code
+ ## Eruby class which generates optimized ruby code
##
- class OptimizedEruby < Eruby
+ class OptimizedEruby < Engine # Eruby
+
+ def self.supported_properties() # :nodoc:
+ return super
+ end
protected
+ def escape_text(text)
+ text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
+ end
+
+ def escaped_expr(code)
+ return "Erubis::XmlHelper.escape_xml(#{code})"
+ end
+
def switch_to_expr(src)
return if @prev_is_expr
@prev_is_expr = true
@@ -46,6 +58,12 @@ module Erubis
end
end
+ def add_stmt(src, code)
+ switch_to_stmt(src) if @initialized
+ #super
+ src << code << ';'
+ end
+
def add_expr_literal(src, code)
unless @initialized; src << "_out = ''"; @initialized = true; end
switch_to_expr(src)
@@ -58,20 +76,22 @@ module Erubis
src << " << " << escaped_expr(code)
end
- def add_stmt(src, code)
- switch_to_stmt(src) if @initialized
- super
+ def add_expr_debug(src, code)
+ code.strip!
+ s = (code.dump =~ /\A"(.*)"\z/) && $1
+ src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
end
def finish_src(src)
- super if @initialized
+ #super if @initialized
+ src << "\n_out\n" if @initialized
end
end # end of class OptimizedEruby
##
- ## XmlEruby class which generates optimized code
+ ## XmlEruby class which generates optimized ruby code
##
class OptimizedXmlEruby < OptimizedEruby
include EscapeEnhancer
@@ -84,4 +104,84 @@ module Erubis
end # end of class OptimizedXmlEruby
+ ## for test
+ class Optimized2Eruby < Eruby # :nodoc:
+
+ def self.supported_properties() # :nodoc:
+ return super
+ end
+
+ protected
+
+ def escape_text(text)
+ text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
+ end
+
+ def escaped_expr(code)
+ return "Erubis::XmlHelper.escape_xml(#{code})"
+ end
+
+ #def switch_to_expr(src)
+ # return if @prev_is_expr
+ # @prev_is_expr = true
+ # src << ' _out'
+ #end
+
+ #def switch_to_stmt(src)
+ # return unless @prev_is_expr
+ # @prev_is_expr = false
+ # src << ';'
+ #end
+
+ def init_src(src)
+ @initialized = false
+ #@prev_is_expr = false
+ end
+
+ def add_text(src, text)
+ return if text.empty?
+ if @initialized
+ #switch_to_expr(src)
+ #src << " << '" << escape_text(text) << "'"
+ src << "_out << '" << escape_text(text) << "';"
+ else
+ src << "_out = '" << escape_text(text) << "';"
+ @initialized = true
+ end
+ end
+
+ def add_stmt(src, code)
+ #switch_to_stmt(src) if @initialized
+ #super
+ src << code << ';'
+ end
+
+ def add_expr_literal(src, code)
+ unless @initialized; src << "_out = ''"; @initialized = true; end
+ #switch_to_expr(src)
+ #src << " << (" << code << ").to_s"
+ src << " _out << (" << code << ").to_s;"
+ end
+
+ def add_expr_escaped(src, code)
+ unless @initialized; src << "_out = ''"; @initialized = true; end
+ #switch_to_expr(src)
+ #src << " << " << escaped_expr(code)
+ src << " _out << " << escaped_expr(code) << ';'
+ end
+
+ def add_expr_debug(src, code)
+ code.strip!
+ s = (code.dump =~ /\A"(.*)"\z/) && $1
+ src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
+ end
+
+ def finish_src(src)
+ #super if @initialized
+ src << "\n_out\n" if @initialized
+ end
+
+ end
+
+
end
diff --git a/lib/erubis/engine/perl.rb b/lib/erubis/engine/perl.rb
new file mode 100644
index 0000000..60b8bbf
--- /dev/null
+++ b/lib/erubis/engine/perl.rb
@@ -0,0 +1,77 @@
+##
+## $Rev$
+## $Release$
+## $Copyright$
+##
+
+require 'erubis/engine'
+require 'erubis/enhancer'
+
+
+module Erubis
+
+
+ ##
+ ## engine for Perl
+ ##
+ class Eperl < Engine
+
+ def self.supported_properties() # :nodoc:
+ list = super
+ list << [:func, 'print', "function name"]
+ return list
+ end
+
+ def initialize(input, options={})
+ @func = options[:func] || 'print'
+ super
+ end
+
+ #--
+ #def init_src(src)
+ #end
+ #++
+
+ def escape_text(text)
+ return text.gsub!(/['\\]/, '\\\\\&') || text
+ end
+
+ def add_text(src, text)
+ src << @func << "('" << escape_text(text) << "'); " unless text.empty?
+ end
+
+ def escaped_expr(code)
+ return "escape(#{code.strip})"
+ end
+
+ def add_expr_literal(src, code)
+ src << @func << "(" << code.strip << "); "
+ end
+
+ def add_expr_escaped(src, code)
+ src << @func << "(" << escaped_expr(code) << "); "
+ end
+
+ def add_expr_debug(src, code)
+ code.strip!
+ s = code.gsub(/\'/, "\\'")
+ src << @func << "('*** debug: #{code}=', #{code}, \"\\n\");"
+ end
+
+ def add_stmt(src, code)
+ src << code
+ end
+
+ def finish_src(src)
+ src << "\n" unless src[-1] == ?\n
+ end
+
+ end
+
+
+ class XmlEperl < Eperl
+ include EscapeEnhancer
+ end
+
+
+end
diff --git a/lib/erubis/engine/php.rb b/lib/erubis/engine/php.rb
index f1b7ba2..5de3e65 100644
--- a/lib/erubis/engine/php.rb
+++ b/lib/erubis/engine/php.rb
@@ -16,8 +16,8 @@ module Erubis
##
class Ephp < Engine
- def initialize(input, properties={})
- super
+ def self.supported_properties() # :nodoc:
+ return super
end
#--
diff --git a/lib/erubis/engine/ruby.rb b/lib/erubis/engine/ruby.rb
index 3dee302..9e424f7 100644
--- a/lib/erubis/engine/ruby.rb
+++ b/lib/erubis/engine/ruby.rb
@@ -15,9 +15,11 @@ module Erubis
## engine for Ruby
##
class Eruby < Engine
+ #include StringBufferEnhancer
+ include ArrayBufferEnhancer
- def init_src(src)
- src << "_out = '';"
+ def self.supported_properties() # :nodoc:
+ return super
end
def escape_text(text)
@@ -28,6 +30,12 @@ module Erubis
return "Erubis::XmlHelper.escape_xml(#{code})"
end
+ #--
+ #def init_src(src)
+ # src << "_out = [];"
+ #end
+ #++
+
def add_text(src, text)
src << " _out << '" << escape_text(text) << "';" unless text.empty?
end
@@ -50,9 +58,11 @@ module Erubis
src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
end
- def finish_src(src)
- src << "\n_out\n"
- end
+ #--
+ #def finish_src(src)
+ # src << "\n_out.join\n"
+ #end
+ #++
end
@@ -65,50 +75,4 @@ module Erubis
end
- ## (obsolete)
- class FastEruby < Eruby
- include FastEnhancer
- end
-
-
- class StdoutEruby < Eruby
- include StdoutEnhancer
- end
-
-
- class PrintEruby < Eruby
- include PrintEnhancer
- end
-
-
- class ArrayBufferEruby < Eruby
- include ArrayBufferEnhancer
- end
-
-
- ## (obsolete)
- class FastXmlEruby < Eruby
- include FastEnhancer
- include EscapeEnhancer
- end
-
-
- class StdoutXmlEruby < Eruby
- include StdoutEnhancer
- include EscapeEnhancer
- end
-
-
- class PrintXmlEruby < Eruby
- include PrintEnhancer
- include EscapeEnhancer
- end
-
-
- class ArrayBufferXmlEruby < Eruby
- include ArrayBufferEnhancer
- include EscapeEnhancer
- end
-
-
end
diff --git a/lib/erubis/engine/scheme.rb b/lib/erubis/engine/scheme.rb
index 7989133..4b8e0de 100644
--- a/lib/erubis/engine/scheme.rb
+++ b/lib/erubis/engine/scheme.rb
@@ -16,6 +16,12 @@ module Erubis
##
class Escheme < Engine
+ def self.supported_properties() # :nodoc:
+ list = super
+ list << [:func, '_add', "function name (ex. 'display')"]
+ return list
+ end
+
def initialize(input, properties={})
@func = properties[:func] || '_add' # or 'display'
super
@@ -36,7 +42,7 @@ module Erubis
end
def escaped_expr(code)
- return code.strip! || code
+ return "(escape #{code.strip})"
end
def add_text(src, text)
@@ -69,11 +75,9 @@ module Erubis
end
- #--
- #class XmlEscheme < Escheme
- # include EscapeEnhancer
- #end
- #++
+ class XmlEscheme < Escheme
+ include EscapeEnhancer
+ end
end
diff --git a/lib/erubis/enhancer.rb b/lib/erubis/enhancer.rb
index e94733e..347a242 100644
--- a/lib/erubis/enhancer.rb
+++ b/lib/erubis/enhancer.rb
@@ -12,7 +12,7 @@ module Erubis
##
- ## switch '<%= ... %>' to escaped and '<%== ... %>' to non-escaped
+ ## switch '<%= ... %>' to escaped and '<%== ... %>' to unescaped
##
## ex.
## class XmlEruby < Eruby
@@ -21,13 +21,28 @@ module Erubis
##
module EscapeEnhancer
- def self.included(klass)
- klass.class_eval <<-END
- alias _add_expr_literal add_expr_literal
- alias _add_expr_escaped add_expr_escaped
- alias add_expr_literal _add_expr_escaped
- alias add_expr_escaped _add_expr_literal
- END
+ #--
+ #def self.included(klass)
+ # klass.class_eval <<-END
+ # alias _add_expr_literal add_expr_literal
+ # alias _add_expr_escaped add_expr_escaped
+ # alias add_expr_literal _add_expr_escaped
+ # alias add_expr_escaped _add_expr_literal
+ # END
+ #end
+ #++
+
+ def add_expr(src, code, indicator)
+ case indicator
+ when '='
+ add_expr_escaped(src, code)
+ #add_expr_literal(src, code)
+ when '=='
+ add_expr_literal(src, code)
+ #add_expr_escaped(src, code)
+ when '==='
+ add_expr_debug(src, code)
+ end
end
end
@@ -48,22 +63,54 @@ module Erubis
end
def finish_src(src)
- src << "\nnil\n"
+ src << "\n''\n"
end
end
##
- ## print function is available.
+ ## use print statement instead of '_out << ...' style
+ ##
+ module PrintStatementEnhancer
+
+ def init_src(src)
+ end
+
+ def add_text(src, text)
+ src << " print '" << escape_text(text) << "';" unless text.empty?
+ end
+
+ def add_stmt(src, code)
+ src << code << ';'
+ end
+
+ def add_expr_literal(src, code)
+ src << ' print((' << code << ').to_s);'
+ end
+
+ def add_expr_escaped(src, code)
+ src << ' print ' << escaped_expr(code) << ';'
+ end
+
+ def finish_src(src)
+ src << "\n" unless src[-1] == ?\n
+ end
+
+ end
+
+
+ ##
+ ## enable print function
##
## Notice: use Eruby#evaluate() and don't use Eruby#result()
## to be enable print function.
##
- module PrintEnhancer
+ module PrintEnabledEnhancer
def init_src(src)
- src << "@_out = _out = '';"
+ src << "@_out = "
+ super
end
def print(*args)
@@ -76,7 +123,7 @@ module Erubis
##
- ## return Array instead of String
+ ## return array instead of string
##
module ArrayEnhancer
@@ -93,7 +140,7 @@ module Erubis
##
- ## use Array instead of String as buffer
+ ## use array buffer instead of string buffer
##
module ArrayBufferEnhancer
@@ -103,7 +150,207 @@ module Erubis
def finish_src(src)
src << "\n" unless src[-1] == ?\n
- src << "_out.join()\n"
+ src << "_out.join\n"
+ end
+
+ end
+
+
+ ##
+ ## use string buffer instead of array buffer
+ ##
+ module StringBufferEnhancer
+
+ def init_src(src)
+ src << "_out = '';"
+ end
+
+ def finish_src(src)
+ src << "\n" unless src[-1] == ?\n
+ src << "_out\n"
+ end
+
+ end
+
+
+ ##
+ ## simple and minimum compiler engine
+ ##
+ ## this makes compile faster, but spaces around '<%...%>' are not trimmed.
+ ##
+ module SimplifiedEnhancer
+
+ #DEFAULT_REGEXP = /(.*?)(^[ \t]*)?<%(=+|\#)?(.*?)-?%>([ \t]*\r?\n)?/m
+ SIMPLE_REGEXP = /(.*?)<%(=+|\#)?(.*?)-?%>/m
+
+ def compile(input)
+ src = ""
+ init_src(src)
+ regexp = pattern_regexp(@pattern)
+ input.scan(SIMPLE_REGEXP) do |text, indicator, code|
+ add_text(src, text)
+ if !indicator # <% %>
+ add_stmt(src, code)
+ elsif indicator[0] == ?= # <%= %>
+ add_expr(src, code, indicator)
+ else # <%# %>
+ n = code.count("\n")
+ add_stmt(src, "\n" * n)
+ end
+ end
+ rest = $' || input
+ add_text(src, rest)
+ finish_src(src)
+ return src
+ end
+
+ end
+
+
+ ##
+ ## enable to use other embedded expression pattern (default is '\[= =\]').
+ ##
+ ## notice! this is an experimental. spec may change in the future.
+ ##
+ ## ex.
+ ## input = <<END
+ ## <% for item in list %>
+ ## <%= item %> : <%== item %>
+ ## [= item =] : [== item =]
+ ## <% end %>
+ ## END
+ ##
+ ## class BiPatternEruby
+ ## include BiPatternEnhancer
+ ## end
+ ## eruby = BiPatternEruby.new(input, :bipattern=>'\[= =\]')
+ ## list = ['<a>', 'b&b', '"c"']
+ ## print eruby.result(binding())
+ ##
+ ## ## output
+ ## <a> : &lt;a&gt;
+ ## <a> : &lt;a&gt;
+ ## b&b : b&amp;b
+ ## b&b : b&amp;b
+ ## "c" : &quot;c&quot;
+ ## "c" : &quot;c&quot;
+ ##
+ module BiPatternEnhancer
+
+ def initialize(input, properties={})
+ @bipattern = properties[:bipattern] || '\[= =\]' # or '\$\{ \}'
+ pre, post = @bipattern.split()
+ @bipattern_regexp = /(.*?)#{pre}(=*)(.*?)#{post}/m
+ super
+ end
+
+ def add_text(src, text)
+ text.scan(@bipattern_regexp) do |txt, indicator, code|
+ super(src, txt)
+ add_expr(src, code, '=' + indicator)
+ end
+ rest = $' || text
+ super(src, rest)
+ end
+
+ end
+
+
+ ##
+ ## enable to use ruby statement line starts with '%'
+ ##
+ ## this is for compatibility to eruby and ERB.
+ ##
+ module PercentLineEnhancer
+
+ PERCENT_LINE_PATTERN = /(.*?)^\%(.*?\r?\n)/m
+
+ def add_text(src, text)
+ text.scan(PERCENT_LINE_PATTERN) do |txt, line|
+ super(src, txt)
+ if line[0] == ?%
+ super(src, line)
+ else
+ add_stmt(src, line)
+ end
+ end
+ rest = $' || text
+ super(src, rest)
+ end
+
+ end
+
+
+ ##
+ ## [experimental] allow header and footer in eRuby script
+ ##
+ ## ex.
+ ## ====================
+ ## ## without header and footer
+ ## $ cat ex1.eruby
+ ## <% def list_items(list) %>
+ ## <% for item in list %>
+ ## <li><%= item %></li>
+ ## <% end %>
+ ## <% end %>
+ ##
+ ## $ erubis -s ex1.eruby
+ ## _out = []; def list_items(list)
+ ## ; for item in list
+ ## ; _out << '<li>'; _out << ( item ).to_s; _out << '</li>
+ ## '; end
+ ## ; end
+ ## ;
+ ## _out.join
+ ##
+ ## ## with header and footer
+ ## $ cat ex2.eruby
+ ## <!--#header:
+ ## def list_items(list)
+ ## #-->
+ ## <% for item in list %>
+ ## <li><%= item %></li>
+ ## <% end %>
+ ## <!--#footer:
+ ## end
+ ## #-->
+ ##
+ ## $ erubis -s -c HeaderFooterEruby ex4.eruby
+ ##
+ ## def list_items(list)
+ ## _out = []; _out << '
+ ## '; for item in list
+ ## ; _out << '<li>'; _out << ( item ).to_s; _out << '</li>
+ ## '; end
+ ## ; _out << '
+ ## ';
+ ## _out.join
+ ## end
+ ##
+ ## ====================
+ ##
+ module HeaderFooterEnhancer
+
+ HEADER_FOOTER_PATTERN = /(.*?)(^[ \t]*)?<!--\#(\w+):(.*?)\#-->([ \t]*\r?\n)?/m
+
+ def add_text(src, text)
+ text.scan(HEADER_FOOTER_PATTERN) do |txt, lspace, word, content, rspace|
+ flag_trim = @trim && lspace && rspace
+ super(src, txt)
+ content = "#{lspace}#{content}#{rspace}" if flag_trim
+ super(src, lspace) if !flag_trim && lspace
+ instance_variable_set("@#{word}", content)
+ super(src, rspace) if !flag_trim && rspace
+ end
+ rest = $' || text
+ super(src, rest)
+ end
+
+ attr_accessor :header, :footer
+
+ def compile(input)
+ source = super
+ return "#{@header}#{source}#{@footer}"
end
end
diff --git a/lib/erubis/local-setting.rb b/lib/erubis/local-setting.rb
new file mode 100644
index 0000000..747b313
--- /dev/null
+++ b/lib/erubis/local-setting.rb
@@ -0,0 +1,10 @@
+##
+## $Rev$
+## $Release$
+## $Copyright$
+##
+
+##
+## you can add site-local settings here.
+## this files is 'require'd by erubis.rb
+##
diff --git a/lib/erubis/main.rb b/lib/erubis/main.rb
index 3664938..c865867 100644
--- a/lib/erubis/main.rb
+++ b/lib/erubis/main.rb
@@ -6,11 +6,14 @@
require 'yaml'
require 'erubis'
+require 'erubis/engine/enhanced'
+require 'erubis/engine/optimized'
require 'erubis/engine/ruby'
require 'erubis/engine/php'
require 'erubis/engine/c'
require 'erubis/engine/java'
require 'erubis/engine/scheme'
+require 'erubis/engine/perl'
module Erubis
@@ -49,6 +52,7 @@ module Erubis
if options[?h] || options[?v]
puts version() if options[?v]
puts usage() if options[?h]
+ puts show_properties() if options[?h]
return
end
@@ -148,27 +152,43 @@ module Erubis
def usage
command = File.basename($0)
s = <<END
+erubis - embedded program compiler for multi-language
Usage: #{command} [..options..] [file ...]
-h, --help : help
-v : version
-s : script source
-x : script source (removed the last '_out' line)
- -T : no trimming spaces around '<% %>'
+ -T : don't trim spaces around '<% %>'
-p pattern : embedded pattern (default '<% %>')
- -l lang : compile but no execute (ruby/php/c/java/scheme)
- -c class : class name (Eruby, XmlEruby, FastEruby, ...) (default Eruby)
+ -l lang : compile but no execute (ruby/php/c/java/scheme/perl)
+ if lang is 'xmlxxx' then 'XmlExxx' class is used
+ -c class : class name (XmlEruby/PrintStatementEruby/...) (default Eruby)
-I path : library include path
- -K kanji : kanji code (euc, sjis, utf8, none) (default none)
+ -K kanji : kanji code (euc/sjis/utf8) (default none)
-f file.yaml : YAML file for context values (read stdin if filename is '-')
-t : expand tab character in YAML file
- -S : convert mapping key from string to symbol
- --name=value : context name and value
+ -S : convert mapping key from string to symbol in YAML file
+
END
# -r library : require library
# -a : action (compile/execute)
return s
end
+ def show_properties
+ s = "supported properties:\n"
+ %w[ruby php c java scheme perl].each do |lang|
+ klass = Erubis.const_get("E#{lang}")
+ s << " * #{lang}\n"
+ list = klass.supported_properties - Erubis::Engine.supported_properties
+ list.each do |name, default_val, desc|
+ s << (" --%-25s : %s\n" % ["#{name}=#{default_val.inspect}", desc])
+ end
+ end
+ s << "\n"
+ return s
+ end
+
def version
release = ('$Release: 0.0.0 $' =~ /([.\d]+)/) && $1
return release
diff --git a/misc/memo.txt b/misc/memo.txt
new file mode 100644
index 0000000..e68427c
--- /dev/null
+++ b/misc/memo.txt
@@ -0,0 +1,373 @@
+
+¡üeRuby¹â®²½·×²è
+
+¹â®¤ÊeRuby¤Î½èÍý·Ï¤ò¼ÂÁõ¤¹¤ë¥×¥í¥¸¥§¥¯¥È¡£ÌÜɸ¤ÏPure Ruby¤ÇERuby¤è¤ê¹â®¤Ë¤¹¤ë¤³¤È¡£
+
+
+¡ý¬Äê
+
+benchmark.rb¤ò»È¤¦¡£
+
+
+¡ý¹â®²½¤½¤Î1: Àµµ¬É½¸½¤Ç²òÀϤ¹¤ë
+
+¹½Ê¸²òÀϤò¤ä¤á¤Æ¡¢Àµµ¬É½¸½¤Ë¤è¤ë¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤ò»È¤¦¡£
+
+.--------------------
+def MyEruby
+
+ def initialize(input)
+ @source = compile(input)
+ end
+
+ attr_reader :source
+
+ def compile(input)
+ ## ¥Ð¥Ã¥Õ¥¡¤ò½é´ü²½¤¹¤ë¥³¡¼¥É
+ src = "_buf = '';"
+
+ ## ¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤ò·«¤êÊÖ¤·¹Ô¤¦
+ pattern = /(.*)<%(=?)(.*?)%>/m
+ input.scan(pattern) do |text, equal, code|
+
+ ## '<% ... %>' ¤è¤êÁ°¤ÎÉôʬ¤òÄɲ乤륳¡¼¥É
+ text.each_line { |line| src << " _buf << #{line.dump}\n" }
+ src[-1] = ?; if rest[-1] != ?\n
+
+ ## '<% ... %>' ¤Î½èÍý
+ if equal # '<%= ¼° %>' ¤Î¤È¤­
+ src << " _buf << (#{code}).to_s;"
+ else # '<% ʸ %>' ¤Î¤È¤­
+ src << code
+ src << ";" if code[-1] != ?\n
+ end
+
+ end
+
+ ## '<% %>' ¤è¤ê¸å¤í¤ÎÉôʬ¡Ê°ìÅÙ¤â¥Þ¥Ã¥Á¤·¤Ê¤¤¤È¤­¤Ïinput¤ò»È¤¦¡Ë
+ rest = $' || input
+ rest.each_line { |line| src << " _buf << #{line.dump}\n" }
+ src[-1] = ?; if rest[-1] != ?\n
+
+ ## ·ë²Ì¤Îʸ»úÎó¤òÊÖ¤¹¥³¡¼¥É
+ src << " _buf\n"
+ return src
+ end
+
+ def result(binding=TOPLEVEL_BINDING)
+ eval @source, binding
+ end
+
+end
+.--------------------
+
+.#.--------------------
+.#def MyEruby
+.#
+.# def initialize(input)
+.# @source = compile(input)
+.# end
+.#
+.# attr_reader :source
+.#
+.# def compile(input)
+.# src = "_buf = '';" ## ¥Ð¥Ã¥Õ¥¡¤ò½é´ü²½¤¹¤ë¥³¡¼¥É
+.# pattern = /(.*)<%(=?)(.*?)%>/m
+.# input.scan(pattern) do |text, equal, code| ## ¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á
+.# ## ¥Þ¥Ã¥Á¤·¤¿²Õ½ê¤ÎÁ°¤Î¥Æ¥­¥¹¥È
+.# text.each_line { |line| src << " _buf << #{line.dump}\n" }
+.# src[-1] = ?; if rest[-1] != ?\n
+.# if equal ## '<%= ¼° %>' ¤Î¤È¤­
+.# src << " _buf << (#{code}).to_s;"
+.# else ## '<% ʸ %>' ¤Î¤È¤­
+.# src << code
+.# src << ";" if code[-1] != ?\n
+.# end
+.# end
+.# rest = $' || input ## ¥Þ¥Ã¥Á¤·¤¿²Õ½ê¤Î»Ä¤ê¤Î¥Æ¥­¥¹¥È
+.# rest.each_line { |line| src << " _buf << #{line.dump}\n" }
+.# src[-1] = ?; if rest[-1] != ?\n
+.# src << " _buf\n" ## ·ë²Ì¤Îʸ»úÎó¤òÊÖ¤¹¥³¡¼¥É
+.# return src
+.# end
+.#
+.# def result(binding=TOPLEVEL_BINDING)
+.# eval @source, binding
+.# end
+.#
+.#end
+.#.--------------------
+
+
+¡ý¹â®²½¤½¤Î2: ʸ»úÎó¤ò·ë¹ç¤¹¤ë
+
+.--------------------
+def MyEruby
+
+ def initialize(input)
+ @input = input
+ @source = compile(input)
+ end
+
+ attr_reader :source
+
+ def escape_text(text)
+ ## ¡Ö'¡×¤È¡Ö\¡×¤ò¥¨¥¹¥±¡¼¥×¤¹¤ë
+ text.gsub!(/['\\]/, '\\\\\1')
+ text
+ end
+
+ def compile(input)
+ ## ¥Ð¥Ã¥Õ¥¡¤ò½é´ü²½¤¹¤ë¥³¡¼¥É
+ src = "_buf = '';"
+
+ ## ¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤ò·«¤êÊÖ¤·¹Ô¤¦
+ pattern = /(.*)<%(=?)(.*?)%>/m
+ input.scan(pattern) do |text, equal, code|
+
+ ## '<% ... %>' ¤è¤êÁ°¤ÎÉôʬ¤òÄɲ乤륳¡¼¥É
+ src << " _buf << '" << escape_text(text) << "'" unless text.empty?
+
+ ## '<% ... %>' ¤Î½èÍý
+ if equal # '<%= ¼° %>' ¤Î¤È¤­
+ src << " _buf << (#{code}).to_s;"
+ else # '<% ʸ %>' ¤Î¤È¤­
+ src << code
+ src << ";" if code[-1] != ?\n
+ end
+
+ end
+
+ ## '<% %>' ¤è¤ê¸å¤í¤ÎÉôʬ¡Ê°ìÅÙ¤â¥Þ¥Ã¥Á¤·¤Ê¤¤¤È¤­¤Ïinput¤ò»È¤¦¡Ë
+ rest = $' || input
+ src << " _buf << '" << escape_text(rest) << "'" unless rest.empty?
+
+ ## ·ë²Ì¤Îʸ»úÎó¤òÊÖ¤¹¥³¡¼¥É
+ src << "\n_buf\n"
+ return src
+ end
+
+ def result(binding=TOPLEVEL_BINDING)
+ eval @source, binding
+ end
+
+end
+.--------------------
+
+
+¡ý¹â®²½¤½¤Î3: $stdout¤Ë½ÐÎϤ¹¤ë
+
+.--------------------
+def MyEruby
+
+ def initialize(input)
+ @source = compile(input)
+ end
+
+ attr_reader :source
+
+ def escape_text(text)
+ ## ¡Ö'¡×¤È¡Ö\¡×¤ò¥¨¥¹¥±¡¼¥×¤¹¤ë
+ text.gsub!(/['\\]/, '\\\\\1') # "'" => "\\'", "\\" => "\\\\"
+ text
+ end
+
+ def compile(input)
+ ## ¥Ð¥Ã¥Õ¥¡¤È¤·¤Æ$stdout¤ò»È¤¦
+ src = "_buf = $stout;"
+
+ ## ¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤ò·«¤êÊÖ¤·¹Ô¤¦
+ pattern = /(.*)<%(=?)(.*?)%>/m
+ input.scan(pattern) do |text, equal, code|
+
+ ## '<% ... %>' ¤è¤êÁ°¤ÎÉôʬ¤òÄɲ乤륳¡¼¥É
+ src << " _buf << '" << escape_text(text) << "'" unless text.empty?
+
+ ## '<% ... %>' ¤Î½èÍý
+ if equal # '<%= ¼° %>' ¤Î¤È¤­
+ src << " _buf << (#{code}).to_s;"
+ else # '<% ʸ %>' ¤Î¤È¤­
+ src << code
+ src << ";" if code[-1] != ?\n
+ end
+
+ end
+
+ ## '<% %>' ¤è¤ê¸å¤í¤ÎÉôʬ¡Ê°ìÅÙ¤â¥Þ¥Ã¥Á¤·¤Ê¤¤¤È¤­¤Ïinput¤ò»È¤¦¡Ë
+ rest = $' || input
+ src << " _buf << '" << escape_text(rest) << "'" unless rest.empty?
+
+ ## nil ¤òÊÖ¤¹¥³¡¼¥É
+ src << "\nnil\n"
+ return _buf
+ end
+
+ def result(binding=TOPLEVEL_BINDING)
+ eval @source, binding
+ end
+
+end
+.--------------------
+
+¤¢¤ë¤¤¤Ï°ú¿ô¤Ç¥Ð¥Ã¥Õ¥¡¥ª¥Ö¥¸¥§¥¯¥È¤ò»ØÄꤹ¤ë¤è¤¦¤Ë¤·¤Æ¤â¤è¤¤¡£
+
+.--------------------
+class MyEruby
+
+ def initialize(input, buffer='')
+ @buffer = buffer
+ @source = compile(input)
+ end
+
+ attr_reader :source
+
+ def compile(input)
+ ## @buffer¤Ç½é´ü²½¤¹¤ë
+ src = "_buf = @buffer;"
+
+ ...
+
+ ## Ìá¤êÃÍ
+ src << "\n_buf\n"
+ return src
+ end
+
+end
+.--------------------
+
+
+¡ý¹â®²½¤½¤Î4: ÇÛÎó¥Ð¥Ã¥Õ¥¡¤ò»È¤¦
+
+$stdout¤ò»È¤¦¤Î¤Ï³Î¤«¤Ë¹â®¤Ê¤Î¤À¤¬¡¢Ê¸»úÎó¤òÊÖ¤·¤Æ¤¯¤ì¤¿¤Û¤¦¤¬½ÀÆðÀ­¤¬¤¢¤ë¡£
+ʸ»úÎó¤òÊÖ¤¹¤è¤¦¤Ë¤·¤¿¤Þ¤Þ¤Ç¹â®²½¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¤«¡£
+
+¤½¤³¤Ç¡¢¥Ð¥Ã¥Õ¥¡¤È¤·¤Æʸ»úÎó¤Ç¤Ï¤Ê¤¯ÇÛÎó¤ò»È¤¦¡£
+
+.--------------------
+def MyEruby
+
+ def initialize(input)
+ @source = compile(input)
+ end
+
+ attr_reader :source
+
+ def escape_text(text)
+ text.gsub!(/['\\]/, '\\\\\1') ## ¡Ö'¡×¤È¡Ö\¡×¤ò¥¨¥¹¥±¡¼¥×¤¹¤ë
+ text
+ end
+
+ def compile(input)
+ src = "_buf = [];" ## ¥Ð¥Ã¥Õ¥¡¤È¤·¤ÆÇÛÎó¤ò»È¤¦
+ pattern = /(.*)<%(=?)(.*?)%>/m
+ input.scan(pattern) do |text, equal, code|
+ src << " _buf << '" << escape_text(text) << "'" unless text.empty?
+ if equal ## '<%= ¼° %>' ¤Î¤È¤­
+ src << " _buf << (#{code}).to_s;"
+ else ## '<% ʸ %>' ¤Î¤È¤­
+ src << code << ";"
+ end
+ end
+ rest = $' || input ## ¥Þ¥Ã¥Á¤·¤¿²Õ½ê¤Î»Ä¤ê¤Î¥Æ¥­¥¹¥È
+ src << " _buf << '" << escape_text(rest) << "'" unless rest.empty?
+ src << "\n_buf.join\n" ## ÇÛÎó¤ÎÍ×ÁǤò·ë¹ç¤·¤ÆÊÖ¤¹¥³¡¼¥É
+ return src
+ end
+
+ def result(binding=TOPLEVEL_BINDING)
+ eval @source, binding
+ end
+
+end
+.--------------------
+
+
+¡ý¹â®²½¤½¤Î5: ¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®¤ò¸º¤é¤¹
+
+ÉÔÊѤʥª¥Ö¥¸¥§¥¯¥È¤Ï°ì²ó¤À¤±À¸À®¤·¤Æ¤½¤ì¤ò»È¤¤²ó¤¹¤è¤¦¤Ë¤¹¤ë¡£
+º£²ó¤ÏÀµµ¬É½¸½¥ª¥Ö¥¸¥§¥¯¥È¤òÄê¿ô¤Ë¤¹¤ë¤³¤È¤Ç¡¢Ëè²óÀ¸À®¤µ¤ì¤ë¤Î¤òÈò¤±¤ë¡£
+¤¢¤Þ¤ê¹â®²½¤·¤Ê¤¤¤±¤É¡£
+
+.--------------------
+def MyEruby
+
+ def initialize(input)
+ @source = compile(input)
+ end
+
+ attr_reader :source
+
+ def escape_text(text)
+ text.gsub!(/['\\]/, '\\\\\1') ## ¡Ö'¡×¤È¡Ö\¡×¤ò¥¨¥¹¥±¡¼¥×¤¹¤ë
+ text
+ end
+
+ PATTERN = /(.*)<%(=?)(.*?)%>/m
+
+ def compile(input)
+ src = "_buf = [];" ## ¥Ð¥Ã¥Õ¥¡¤È¤·¤ÆÇÛÎó¤ò»È¤¦
+ input.scan(PATTERN) do |text, equal, code|
+ src << " _buf << '" << escape_text(text) << "'" unless text.empty?
+ if equal ## '<%= ¼° %>' ¤Î¤È¤­
+ src << " _buf << (#{code}).to_s;"
+ else ## '<% ʸ %>' ¤Î¤È¤­
+ src << code << ";"
+ end
+ end
+ rest = $' || input ## ¥Þ¥Ã¥Á¤·¤¿²Õ½ê¤Î»Ä¤ê¤Î¥Æ¥­¥¹¥È
+ src << " _buf << '" << escape_text(rest) << "'" unless rest.empty?
+ src << "\n_buf.join\n" ## ÇÛÎó¤ÎÍ×ÁǤò·ë¹ç¤·¤ÆÊÖ¤¹¥³¡¼¥É
+ return src
+ end
+
+ def result(binding=TOPLEVEL_BINDING)
+ eval @source, binding
+ end
+
+end
+.--------------------
+
+
+¡ý¹â®²½¤½¤Î6: ¥³¥ó¥Ñ¥¤¥ë·ë²Ì¤ò¥­¥ã¥Ã¥·¥å¤¹¤ë
+
+Ëè²ó¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢°ìÅÙ¥³¥ó¥Ñ¥¤¥ë¤·¤¿·ë²Ì¤ò¥Õ¥¡¥¤¥ë¤Ë¥­¥ã¥Ã¥·¥å¤·¤Æ¤ª¤¯¡£
+¤Ä¤Þ¤ê
+.* eRuby¥Õ¥¡¥¤¥ë¤òRuby¥¹¥¯¥ê¥×¥È¤Ë¥³¥ó¥Ñ¥¤¥ë
+.* Ruby¥¹¥¯¥ê¥×¥È¤òeval¤Ç¼Â¹Ô
+¤¬
+.* ¡Ê¥­¥ã¥Ã¥·¥å¤µ¤ì¤¿¡ËRuby¥¹¥¯¥ê¥×¥È¤òeval¤Ç¼Â¹Ô
+¤Ë¤Ê¤ê¡¢eRuby¥Õ¥¡¥¤¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë½èÍý¤¬¾Ê¤±¤ë¡£
+
+
+¡ý¹â®²½¤½¤Î7: ¥á¥½¥Ã¥É¤Ë¤·¤Æ¤·¤Þ¤¦
+
+
+
+
+¡ý¤Þ¤È¤á
+
+.* ¡Ö¹½Ê¸²òÀϡפè¤ê¡Ö¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¡×
+.* ¡Ö¹Ô¤´¤È¤Îʬ³ä¡×¤è¤ê¡ÖÊ£¿ô¹Ô¤ÎÏ¢·ë¡×
+.* ¡Öʸ»úÎó¤Ë¤·¤Æ½ÐÎϡפè¤ê¡ÖľÀܽÐÎÏ¡×
+.* ¡Öʸ»úÎó¥Ð¥Ã¥Õ¥¡¡×¤è¤ê¡ÖÇÛÎó¥Ð¥Ã¥Õ¥¡¡×
+.* ¡Ö¥ê¥Æ¥é¥ë¡×¤è¤ê¡ÖÄê¿ô¡×
+.* ¡ÖC¤Ç³ÈÄ¥¥é¥¤¥Ö¥é¥ê¡×¤è¤ê¡Ö¥×¥í¥°¥é¥à¤Î¸«Ä¾¤·¡×
+
+¡ÖŬÅö¤Ëºî¤Ã¤¿C¥×¥í¥°¥é¥à¡×¤è¤ê¡Ö¤è¤¯¹Í¤¨¤é¤ì¤¿Ruby¥¹¥¯¥ê¥×¥È¡×¤Î¤Û¤¦¤¬¹â®¤Ê¾ì¹ç¤¬¤¢¤ë¤³¤È¤ò¼Â¾Ú¤·¤¿¡£
+¤·¤«¤·µÕ¤Ë¸À¤¨¤Ð¡¢C¤Ç½ñ¤±¤Ð¤è¤¯¹Í¤¨¤Ê¤¯¤Æ¤â¹â®¤Ë¤Ê¤ë¤ï¤±¤À¡£
+
+¤â¤Ã¤È¤¤¤¨¤Ð¡Ö¤è¤¯¹Í¤¨¤é¤ì¤¿Ruby¥¹¥¯¥ê¥×¥È¡×¤Ï¡ÖŬÅö¤Ëºî¤Ã¤¿C¥×¥í¥°¥é¥à¡×¤è¤ê¹â®¤Ë¤Ê¤ë¤³¤È¤Ï¤¢¤Ã¤Æ¤â¡¢¡Ö¤è¤¯¹Í¤¨¤é¤ì¤¿C¥×¥í¥°¥é¥à¡×¤Ë¤Ï´Ö°ã¤¤¤Ê¤¯É餱¤ë¡£
+·è¤·¤Æ¡¢C¤Ë¤è¤ë³ÈÄ¥¥×¥í¥°¥é¥à¤¬ÉÔÍפˤʤ뤳¤È¤Ï¤Ê¤¤¡£
+
+ŬÅö¤Ëºî¤Ã¤¿C¥×¥í¥°¥é¥à ¢â ¤è¤¯¹Í¤¨¤é¤ì¤¿Ruby¥¹¥¯¥ê¥×¥È ¢ã ¤è¤¯¹Í¤¨¤é¤ì¤¿C¥×¥í¥°¥é¥à
+
+
+.* httpd, ruby, mod_ruby.so¤Ïstrip¤µ¤ì¤Æ¤¤¤ë¤«¡©
+ .- MacOS X¤Ç¤Ïstrip¤¹¤ë¤ÈÆ°¤«¤Ê¤¤¤Î¤ÇÃí°Õ
+.* apache¤ÎÀßÄê¤ÏŬÀÚ¤«¡©
+ .-
+.* ƱÅù¤Î³ÈÄ¥¥×¥í¥°¥é¥à¤Ï¤Ê¤¤¤«¡©
+ .- Ruby/MySQL¤è¤êMySQL/Ruby
+.* ¤½¤Î¥×¥í¥°¥é¥à¤Ï¤Û¤ó¤È¤¦¤Ë¥Ü¥È¥ë¥Í¥Ã¥¯¤Ê¤Î¤«¡©
+
+
diff --git a/test/test-bin.rb b/test/test-bin.rb
index 35b048d..3a7c773 100644
--- a/test/test-bin.rb
+++ b/test/test-bin.rb
@@ -4,12 +4,9 @@
## $Date$
##
-testdir = File.dirname(File.expand_path(__FILE__))
-libdir = File.dirname(testdir) + '/lib'
-$: << testdir
-$: << libdir
+require "#{File.dirname(__FILE__)}/test.rb"
-bindir = File.dirname(testdir) + '/bin'
+bindir = File.dirname(TESTDIR) + '/bin'
$script = bindir + '/erubis'
if test(?f, 'bin/erubis')
$script = 'bin/erubis'
@@ -48,14 +45,14 @@ END
#_out
#END
SRC = <<'END'
-_out = ''; _out << 'list:
+_out = []; _out << 'list:
'; list = ['<aaa>', 'b&b', '"ccc"']
for item in list
; _out << ' - '; _out << ( item ).to_s; _out << '
'; end
; _out << 'user: '; _out << ( defined?(user) ? user : "(none)" ).to_s; _out << '
';
-_out
+_out.join
END
OUTPUT = <<'END'
@@ -109,7 +106,7 @@ END
def test_source2
@input = INPUT
- @expected = SRC.sub(/^_out\s*\z/, '')
+ @expected = SRC.sub(/^_out(\.join)?\s*\z/, '')
@options = '-x'
_test()
end
@@ -161,14 +158,14 @@ END
#_out
#END
@expected = <<'END'
-_out = ''; _out << 'list:
+_out = []; _out << 'list:
'; list = ['<aaa>', 'b&b', '"ccc"']
for item in list ; _out << '
'; _out << ' - '; _out << ( item ).to_s; _out << '
'; end ; _out << '
'; _out << 'user: '; _out << ( defined?(user) ? user : "(none)" ).to_s; _out << '
';
-_out
+_out.join
END
@options = "-sT"
_test()
diff --git a/test/test-engines.rb b/test/test-engines.rb
index e08095f..8dfa56e 100644
--- a/test/test-engines.rb
+++ b/test/test-engines.rb
@@ -4,237 +4,295 @@
## $Copyright$
##
-testdir = File.dirname(__FILE__)
-libdir = testdir == '.' ? '../lib' : File.dirname(testdir) + '/lib'
-$: << testdir
-$: << libdir
-
-require 'test/unit'
-#require 'test/unit/ui/console/testrunner'
-require 'assert-text-equal'
-require 'yaml'
-require 'stringio'
-require 'testutil'
+require "#{File.dirname(__FILE__)}/test.rb"
require 'erubis'
-require 'erubis/lang/ruby'
-require 'erubis/lang/php'
-require 'erubis/lang/c'
-require 'erubis/lang/java'
-require 'erubis/lang/scheme'
+require 'erubis/engine/ruby'
+require 'erubis/engine/php'
+require 'erubis/engine/c'
+require 'erubis/engine/java'
+require 'erubis/engine/scheme'
+require 'erubis/engine/perl'
-class ErubisTest < Test::Unit::TestCase
+class EnginesTest < Test::Unit::TestCase
+ extend TestEnhancer
#load_yaml_documents(__FILE__)
- load_yaml_testdata(__FILE__)
-
+ testdata_list = load_yaml_document(__FILE__)
+ define_testmethods(testdata_list)
def _test()
klass = Erubis.const_get(@class)
- eruby = klass.new(@input, @options || {})
- actual = eruby.src
+ engine = klass.new(@input, @options || {})
+ actual = engine.src
assert_text_equal(@expected, actual)
end
end
__END__
----
-name: ruby1
-lang: ruby
-class: Eruby
-options:
-input: |
- <table>
- <tbody>
- <% i = 0
- list.each_with_index do |item, i| %>
- <tr>
- <td><%= i+1 %></td>
- <td><%== list %></td>
- </tr>
- <% end %>
- </tbody>
- </table>
- <%=== i+1 %>
-expected: |
- _out = ''; _out << '<table>
- <tbody>
- '; i = 0
- list.each_with_index do |item, i|
- ; _out << ' <tr>
- <td>'; _out << ( i+1 ).to_s; _out << '</td>
- <td>'; _out << Erubis::XmlHelper.escape_xml( list ); _out << '</td>
- </tr>
- '; end
- ; _out << ' </tbody>
- </table>
- '; $stderr.puts("*** debug: i+1=#{(i+1).inspect}"); _out << '
- ';
- _out
+- name: ruby1
+ lang: ruby
+ class: Eruby
+ options:
+ input: |
+ <table>
+ <tbody>
+ <% i = 0
+ list.each_with_index do |item, i| %>
+ <tr>
+ <td><%= i+1 %></td>
+ <td><%== list %></td>
+ </tr>
+ <% end %>
+ </tbody>
+ </table>
+ <%=== i+1 %>
+ expected: |
+ _out = []; _out << '<table>
+ <tbody>
+ '; i = 0
+ list.each_with_index do |item, i|
+ ; _out << ' <tr>
+ <td>'; _out << ( i+1 ).to_s; _out << '</td>
+ <td>'; _out << Erubis::XmlHelper.escape_xml( list ); _out << '</td>
+ </tr>
+ '; end
+ ; _out << ' </tbody>
+ </table>
+ '; $stderr.puts("*** debug: i+1=#{(i+1).inspect}"); _out << '
+ ';
+ _out.join
##
----
-name: php1
-lang: php
-class: Ephp
-options:
-input: |
- <table>
- <tbody>
- <%
- $i = 0;
- foreach ($list as $item) {
- $i++;
- %>
- <tr>
- <td><%= $i %></td>
- <td><%== $item %></td>
- </tr>
- <%
- }
- %>
- </tbody>
- </table>
- <%=== $i %>
-expected: |
- <table>
- <tbody>
- <?php
- $i = 0;
- foreach ($list as $item) {
+- name: php1
+ lang: php
+ class: Ephp
+ options:
+ input: |
+ <table>
+ <tbody>
+ <%
+ $i = 0;
+ foreach ($list as $item) {
+ $i++;
+ %>
+ <tr>
+ <td><%= $i %></td>
+ <td><%== $item %></td>
+ </tr>
+ <%
+ }
+ %>
+ </tbody>
+ </table>
+ <%=== $i %>
+ expected: |
+ <table>
+ <tbody>
+ <?php
+ $i = 0;
+ foreach ($list as $item) {
$i++;
- ?>
- <tr>
- <td><?php echo $i; ?></td>
- <td><?php echo htmlspecialchars($item); ?></td>
- </tr>
- <?php
- }
- ?>
- </tbody>
- </table>
- <?php error_log('*** debug: $i='.($i), 0); ?>
+ ?>
+ <tr>
+ <td><?php echo $i; ?></td>
+ <td><?php echo htmlspecialchars($item); ?></td>
+ </tr>
+ <?php
+ }
+ ?>
+ </tbody>
+ </table>
+ <?php error_log('*** debug: $i='.($i), 0); ?>
##
----
-name: c1
-lang: c
-class: Ec
-options: { :filename: foo.html, :indent: ' ' }
-input: |4
- <table>
- <tbody>
- <% for (i = 0; i < list; i++) { %>
- <tr>
- <td><%= "%d", i %></td>
- <td><%== "%s", list[i] %></td>
- </tr>
- <% } %>
- </tbody>
- </table>
- <%=== "%d", i %>
-expected: |
- # 1 "foo.html"
- fputs("<table>\n"
- " <tbody>\n", stdout);
- for (i = 0; i < list; i++) {
- fputs(" <tr>\n"
- " <td>", stdout); fprintf(stdout, "%d", i); fputs("</td>\n"
- " <td>", stdout); fprintf(stdout, "%s", list[i]); fputs("</td>\n"
- " </tr>\n", stdout);
- }
- fputs(" </tbody>\n"
- "</table>\n", stdout);
- fprintf(stderr, "*** debug: i=" "%d", i); fputs("\n", stdout);
+- name: c1
+ lang: c
+ class: Ec
+ options: { :filename: foo.html, :indent: ' ' }
+ input: |4
+ <table>
+ <tbody>
+ <% for (i = 0; i < list; i++) { %>
+ <tr>
+ <td><%= "%d", i %></td>
+ <td><%== "%s", list[i] %></td>
+ </tr>
+ <% } %>
+ </tbody>
+ </table>
+ <%=== "%d", i %>
+ expected: |
+ #line 1 "foo.html"
+ fputs("<table>\n"
+ " <tbody>\n", stdout);
+ for (i = 0; i < list; i++) {
+ fputs(" <tr>\n"
+ " <td>", stdout); fprintf(stdout, "%d", i); fputs("</td>\n"
+ " <td>", stdout); fprintf(stdout, "%s", escape(list[i])); fputs("</td>\n"
+ " </tr>\n", stdout);
+ }
+ fputs(" </tbody>\n"
+ "</table>\n", stdout);
+ fprintf(stderr, "*** debug: i=" "%d", i); fputs("\n", stdout);
##
----
-name: java1
-lang: java
-class: Ejava
-options: { :outclass: StringBuilder, :indent: ' ' }
-input: |
- <table>
- <tbody>
- <%
- int i = 0;
- for (Iterator it = list.iterator(); it.hasNext(); ) {
- String s = (String)it.next();
- i++;
- %>
- <tr class="<%= i%2==0 ? "even" : "odd" %>">
- <td><%= i %></td>
- <td><%== s %></td>
- </tr>
- <%
- }
- %>
- <tbody>
- </table>
- <%=== i %>
-expected: |4
- StringBuilder _out = new StringBuilder();
- _out.append("<table>\n"
- + " <tbody>\n");
-
- int i = 0;
- for (Iterator it = list.iterator(); it.hasNext(); ) {
- String s = (String)it.next();
- i++;
+- name: java1
+ lang: java
+ class: Ejava
+ options: { :out: _buf, :indent: ' ' }
+ input: |
+ <table>
+ <tbody>
+ <%
+ int i = 0;
+ for (Iterator it = list.iterator(); it.hasNext(); ) {
+ String s = (String)it.next();
+ i++;
+ %>
+ <tr class="<%= i%2==0 ? "even" : "odd" %>">
+ <td><%= i %></td>
+ <td><%== s %></td>
+ </tr>
+ <%
+ }
+ %>
+ <tbody>
+ </table>
+ <%=== i %>
+ expected: |4
+ _buf.append("<table>\n"
+ + " <tbody>\n");
+
+ int i = 0;
+ for (Iterator it = list.iterator(); it.hasNext(); ) {
+ String s = (String)it.next();
+ i++;
+
+ _buf.append(" <tr class=\""); _buf.append(i%2==0 ? "even" : "odd"); _buf.append("\">\n"
+ + " <td>"); _buf.append(i); _buf.append("</td>\n"
+ + " <td>"); _buf.append(escape(s)); _buf.append("</td>\n"
+ + " </tr>\n");
- _out.append(" <tr class=\""); _out.append(i%2==0 ? "even" : "odd"); _out.append("\">\n"
- + " <td>"); _out.append(i); _out.append("</td>\n"
- + " <td>"); _out.append(s); _out.append("</td>\n"
- + " </tr>\n");
-
- }
-
- _out.append(" <tbody>\n"
- + "</table>\n");
- System.err.println("*** debug: i="+(i)); _out.append("\n");
----
-name: scheme1
-lang: scheme
-class: Escheme
-options: { :func: 'display' }
-input: |
- <% (let ((i 0)) %>
- <table>
- <tbody>
- <%
- (for-each
- (lambda (item)
- (set! i (+ i 1))
- %>
- <tr>
- <td><%= i %></td>
- <td><%= item %></td>
- </tr>
- <%
- ); lambda end
- list); for-each end
- %>
- </tbody>
- </table>
- <%=== i %>
- <% ); let end %>
-expected: |4
- (let ((i 0))
- (display "<table>
- <tbody>
- ")
- (for-each
- (lambda (item)
- (set! i (+ i 1))
-
- (display " <tr>
- <td>")(display i)(display "</td>
- <td>")(display item)(display "</td>
- </tr>
- ")
- ); lambda end
- list); for-each end
-
- (display " </tbody>
- </table>
- ")(display "*** debug: i=")(display i)(display "
- ") ); let end
+ }
+
+ _buf.append(" <tbody>\n"
+ + "</table>\n");
+ System.err.println("*** debug: i="+(i)); _buf.append("\n");
+##
+- name: scheme1
+ lang: scheme
+ class: Escheme
+ options:
+ input: &scheme1_input|
+ <% (let ((i 0)) %>
+ <table>
+ <tbody>
+ <%
+ (for-each
+ (lambda (item)
+ (set! i (+ i 1))
+ %>
+ <tr>
+ <td><%= i %></td>
+ <td><%== item %></td>
+ </tr>
+ <%
+ ); lambda end
+ list); for-each end
+ %>
+ </tbody>
+ </table>
+ <%=== i %>
+ <% ); let end %>
+ expected: |4
+ (let ((_out '())) (define (_add x) (set! _out (cons x _out))) (let ((i 0))
+ (_add "<table>
+ <tbody>
+ ")
+ (for-each
+ (lambda (item)
+ (set! i (+ i 1))
+
+ (_add " <tr>
+ <td>")(_add i)(_add "</td>
+ <td>")(_add (escape item))(_add "</td>
+ </tr>
+ ")
+ ); lambda end
+ list); for-each end
+
+ (_add " </tbody>
+ </table>
+ ")(display "*** debug: i=")(display i)(display "\n")(_add "
+ ") ); let end
+ (reverse _out))
+
+##
+- name: scheme2
+ lang: scheme
+ class: Escheme
+ options: { :func: 'display' }
+ input: *scheme1_input
+ expected: |4
+ (let ((i 0))
+ (display "<table>
+ <tbody>
+ ")
+ (for-each
+ (lambda (item)
+ (set! i (+ i 1))
+
+ (display " <tr>
+ <td>")(display i)(display "</td>
+ <td>")(display (escape item))(display "</td>
+ </tr>
+ ")
+ ); lambda end
+ list); for-each end
+
+ (display " </tbody>
+ </table>
+ ")(display "*** debug: i=")(display i)(display "\n")(display "
+ ") ); let end
+##
+- name: perl1
+ lang: perl
+ class: Eperl
+ options:
+ input: |
+ <%
+ my $user = 'Erubis';
+ my @list = ('<aaa>', 'b&b', '"ccc"');
+ %>
+ <p>Hello <%= $user %>!</p>
+ <table>
+ <tbody>
+ <% $i = 0; %>
+ <% for $item (@list) { %>
+ <tr bgcolor=<%= ++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF' %>">
+ <td><%= $i %></td>
+ <td><%== $item %></td>
+ </tr>
+ <% } %>
+ </tbody>
+ </table>
+ <%=== $i %>
+ expected: |4
+
+ my $user = 'Erubis';
+ my @list = ('<aaa>', 'b&b', '"ccc"');
+
+ print('<p>Hello '); print($user); print('!</p>
+ <table>
+ <tbody>
+ '); $i = 0;
+ for $item (@list) {
+ print(' <tr bgcolor='); print(++$i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'); print('">
+ <td>'); print($i); print('</td>
+ <td>'); print(escape($item)); print('</td>
+ </tr>
+ '); }
+ print(' </tbody>
+ </table>
+ '); print('*** debug: $i=', $i, "\n");print('
+ ');
diff --git a/test/test-erubis.rb b/test/test-erubis.rb
index 8e3aa79..3de70f7 100644
--- a/test/test-erubis.rb
+++ b/test/test-erubis.rb
@@ -4,589 +4,773 @@
## $Copyright$
##
-testdir = File.dirname(__FILE__)
-libdir = testdir == '.' ? '../lib' : File.dirname(testdir) + '/lib'
-$: << testdir
-$: << libdir
+require "#{File.dirname(__FILE__)}/test.rb"
-require 'test/unit'
-#require 'test/unit/ui/console/testrunner'
-require 'assert-text-equal'
-require 'yaml'
require 'stringio'
require 'erubis'
+require 'erubis/engine/enhanced'
require 'erubis/engine/optimized'
class ErubisTest < Test::Unit::TestCase
+ extend TestEnhancer
- #str = DATA.read()
- str = File.read(__FILE__)
- str.gsub!(/.*^__END__$/m, '')
+ testdata_list = load_yaml_document(__FILE__)
+ define_testmethods(testdata_list)
- @@ydocs = {}
- YAML.load_documents(str) do |ydoc|
- name = ydoc['name']
- raise "*** test name '#{name}' is duplicated." if @@ydocs[name]
- ydoc.each do |key, val|
- if key[-1] == ?*
- key = key.sub(/\*\z/, '')
- val = val[$target]
- ydoc[key] = val
- end
- end
- @@ydocs[name] = ydoc
- s = <<-END
- def test_#{name}
- @name = #{name.dump}
- _test()
- end
- END
- eval s
- end
def _test()
- ydoc = @@ydocs[@name]
- input = ydoc['input']
- src = ydoc['src'].gsub(/\^/, ' ')
- output = ydoc['output'].gsub(/\^/, ' ')
- klass = ydoc['class'] ? (eval "Erubis::#{ydoc['class']}") : Erubis::Eruby
- options = ydoc['options'] || {}
- testopt = ydoc['testopt']
+ @src.gsub!(/\^/, ' ')
+ @output.gsub!(/\^/, ' ') if @output.is_a?(String)
+ @klass = @class ? Erubis.const_get(@class) : Erubis::Eruby
+ @options ||= {}
- if testopt != 'load_file'
- eruby = klass.new(input, options)
+ if @testopt != 'load_file'
+ eruby = @klass.new(@input, @options)
else
- filename = "tmp.#{name}.eruby"
+ filename = "tmp.#{@name}.eruby"
begin
- File.open(filename, 'w') { |f| f.write(input) }
- eruby = klass.load_file(filename, options)
+ File.open(filename, 'w') { |f| f.write(@input) }
+ eruby = @klass.load_file(filename, @options)
ensure
File.unlink(filename) if test(?f, filename)
end
end
- assert_text_equal(src, eruby.src)
+ assert_text_equal(@src, eruby.src)
- return if testopt == 'skip_output'
+ return if @testopt == 'skip_output'
context = {}
- context[:list] = ['<aaa>', 'b&b', '"ccc"']
+ context[:list] = list = ['<aaa>', 'b&b', '"ccc"']
- if testopt != 'stdout'
- actual = eruby.evaluate(context)
- assert_text_equal(output, actual)
- else
+ 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)
ensure
- $stdout = orig if orig
+ $stdout = orig
end
- assert_nil(actual)
- assert_text_equal(output, stringio.string)
+ if @testopt == 'stdout'
+ assert_equal("", actual)
+ else
+ assert_nil(actual)
+ end
+ assert_text_equal(@output, stringio.string)
+ else
+ actual = eruby.evaluate(context)
+ assert_text_equal(@output, actual)
end
end
end
__END__
----
-name: basic1
-input: |
- <ul>
- <% for item in list %>
- <li><%= item %></li>
- <% end %>
- </ul>
-src: |
- _out = ''; _out << '<ul>
- '; for item in list
- ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
- '; end
- ; _out << '</ul>
- ';
- _out
-output: |
- <ul>
- <li><aaa></li>
- <li>b&b</li>
- <li>"ccc"</li>
- </ul>
+- name: basic1
+ input: &basic1_input|
+ <ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <% end %>
+ </ul>
+ src: |
+ _out = []; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out.join
+ output: &basic1_output|
+ <ul>
+ <li><aaa></li>
+ <li>b&b</li>
+ <li>"ccc"</li>
+ </ul>
##
----
-name: basic2
-input: |
- <ul>
- <% i = 0
- for item in list
- i += 1
- %>
- <li><%= item %></li>
- <% end %>
- </ul>
-src: |
- _out = ''; _out << '<ul>
- '; i = 0
- for item in list
+- name: basic2
+ input: |
+ <ul>
+ <% i = 0
+ for item in list
+ i += 1
+ %>
+ <li><%= item %></li>
+ <% end %>
+ </ul>
+ src: |
+ _out = []; _out << '<ul>
+ '; i = 0
+ for item in list
+ i += 1
+ ^^^
+ ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out.join
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
+##
+- name: basic3
+ input: |
+ <ul><% i = 0
+ for item in list
+ i += 1 %><li><%= item %></li><% end %>
+ </ul>
+ src: |
+ _out = []; _out << '<ul>'; i = 0
+ for item in list
+ i += 1 ; _out << '<li>'; _out << ( item ).to_s; _out << '</li>'; end ; _out << '
+ '; _out << '</ul>
+ ';
+ _out.join
+ output: |
+ <ul><li><aaa></li><li>b&b</li><li>"ccc"</li>
+ </ul>
+##
+- name: quotation1
+ desc: single quotation and backslash
+ class: Eruby
+ input: &quotation1_input|
+ a = "'"
+ b = "\""
+ c = '\''
+ src: |
+ _out = []; _out << 'a = "\'"
+ b = "\\""
+ c = \'\\\'\'
+ ';
+ _out.join
+ output: *quotation1_input
+##
+- name: pattern1
+ options:
+ :pattern : '\[@ @\]'
+ input: |
+ <ul>
+ [@ for item in list @]
+ <li>[@= item @]</li>
+ [@ end @]
+ </ul>
+ src: |
+ _out = []; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out.join
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
+##
+- name: pattern2
+ options:
+ :pattern : '<(?:!--)?% %(?:--)?>'
+ input: |
+ <ul>
+ <!--% for item in list %-->
+ <li><%= item %></li>
+ <!--% end %-->
+ </ul>
+ src: |
+ _out = []; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out.join
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
+##
+- name: trim1
+ options:
+ :trim : false
+ input: *basic1_input
+# <ul>
+# <% for item in list %>
+# <li><%= item %></li>
+# <% end %>
+# </ul>
+ src: |
+ _out = []; _out << '<ul>
+ '; _out << ' '; for item in list ; _out << '
+ '; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; _out << ' '; end ; _out << '
+ '; _out << '</ul>
+ ';
+ _out.join
+ output: |
+ <ul>
+ ^
+ <li><aaa></li>
+ ^
+ <li>b&b</li>
+ ^
+ <li>"ccc"</li>
+ ^
+ </ul>
+##
+- name: ignore1
+ input: |
+ <ul>
+ <%# i = 0 %>
+ <% for item in list %>
+ <%#
i += 1
- ^^^
- ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
- '; end
- ; _out << '</ul>
- ';
- _out
-output: |
- <ul>
- <li><aaa></li>
- <li>b&b</li>
- <li>"ccc"</li>
- </ul>
+ color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'
+ %>
+ <li> <%#= i %> : <%= item %> </li>
+ <% end %>
+ </ul>
+ src: |
+ _out = []; _out << '<ul>
+ ';
+ ; for item in list
+ ;
+
+
+
+ ; _out << ' <li> ';; _out << ' : '; _out << ( item ).to_s; _out << ' </li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out.join
+ output: |
+ <ul>
+ <li> : <aaa> </li>
+ <li> : b&b </li>
+ <li> : "ccc" </li>
+ </ul>
##
----
-name: basic3
-input: |
- <ul><% i = 0
- for item in list
- i += 1 %><li><%= item %></li><% end %>
- </ul>
-src: |
- _out = ''; _out << '<ul>'; i = 0
- for item in list
- i += 1 ; _out << '<li>'; _out << ( item ).to_s; _out << '</li>'; end ; _out << '
- '; _out << '</ul>
- ';
- _out
-output: |
- <ul><li><aaa></li><li>b&b</li><li>"ccc"</li>
- </ul>
+- name: loadfile1
+ testopt: load_file
+ #input: |
+ # <ul>
+ # <% for item in list %>
+ # <li><%= item %></li>
+ # <% end %>
+ # </ul>
+ input:
+ "<ul>\r\n <% for item in list %>\r\n <li><%= item %></li>\r\n <% end %>\r\n</ul>\r\n"
+ #src: |
+ # _out = ''; _out << "<ul>\n"
+ # for item in list
+ # _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ # end
+ # _out << "</ul>\n"
+ # _out
+ src:
+ "_out = []; _out << '<ul>\r\n'; for item in list \r\n; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>\r\n'; end \r\n; _out << '</ul>\r\n';\n_out.join\n"
+ #output: |
+ # <ul>
+ # <li><aaa></li>
+ # <li>b&b</li>
+ # <li>"ccc"</li>
+ # </ul>
+ output:
+ "<ul>\n <li><aaa></li>\n <li>b&b</li>\n <li>\"ccc\"</li>\n</ul>\n"
+ # "<ul>\r\n <li><aaa></li>\r\n <li>b&b</li>\r\n <li>\"ccc\"</li>\r\n</ul>\r\n"
##
----
-name: quotation1
-desc: single quotation and backslash
-class: Eruby
-input: |
- a = "'"
- b = "\""
- c = '\''
-src: |
- _out = ''; _out << 'a = "\'"
- b = "\\""
- c = \'\\\'\'
- ';
- _out
-output: |
- a = "'"
- b = "\""
- c = '\''
+- name: nomatch1
+ desc: bug
+ input: &nomatch1|
+ <ul>
+ <li>foo</li>
+ </ul>
+ src: |
+ _out = []; _out << '<ul>
+ <li>foo</li>
+ </ul>
+ ';
+ _out.join
+ output: *nomatch1
##
----
-name: pattern1
-options:
- :pattern : '\[@ @\]'
-input: |
- <ul>
- [@ for item in list @]
- <li>[@= item @]</li>
- [@ end @]
- </ul>
-src: |
- _out = ''; _out << '<ul>
- '; for item in list
- ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
- '; end
- ; _out << '</ul>
- ';
- _out
-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: |
+ _out = []; _out << '<pre>
+ '; for item in list
+ ; _out << ' '; _out << Erubis::XmlHelper.escape_xml( item ); _out << '
+ '; _out << ' '; _out << ( item ).to_s; _out << '
+ '; end
+ ; _out << '</pre>
+ ';
+ _out.join
+ output: |
+ <pre>
+ &lt;aaa&gt;
+ <aaa>
+ b&amp;b
+ b&b
+ &quot;ccc&quot;
+ "ccc"
+ </pre>
##
----
-name: pattern2
-options:
- :pattern : '<(?:!--)?% %(?:--)?>'
-input: |
- <ul>
- <!--% for item in list %-->
- <li><%= item %></li>
- <!--% end %-->
- </ul>
-src: |
- _out = ''; _out << '<ul>
- '; for item in list
- ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
- '; end
- ; _out << '</ul>
- ';
- _out
-output: |
- <ul>
- <li><aaa></li>
- <li>b&b</li>
- <li>"ccc"</li>
- </ul>
+- 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: |
+ _out = []; for item in list
+ ; _out << ' '; _out << Erubis::XmlHelper.escape_xml( item["var#{n}"] ); _out << '
+ '; _out << ' '; _out << ( item["var#{n}"] ).to_s; _out << '
+ '; _out << ' '; $stderr.puts("*** debug: item[\"var\#{n}\"]=#{(item["var#{n}"]).inspect}"); _out << '
+ '; _out << ' '; _out << '
+ '; end
+ ;
+ _out.join
+ output: |
##
----
-name: trim1
-options:
- :trim : false
-input: |
- <ul>
- <% for item in list %>
- <li><%= item %></li>
- <% end %>
- </ul>
-src: |
- _out = ''; _out << '<ul>
- '; _out << ' '; for item in list ; _out << '
- '; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
- '; _out << ' '; end ; _out << '
- '; _out << '</ul>
- ';
- _out
-output: |
- <ul>
- ^
- <li><aaa></li>
- ^
- <li>b&b</li>
- ^
- <li>"ccc"</li>
- ^
- </ul>
+- name: printstatement1
+ class: PrintStatementEruby
+ 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: ignore1
-input: |
- <ul>
- <%# i = 0 %>
- <% for item in list %>
- <%#
- i += 1
- color = i % 2 == 0 ? '#FFCCCC' : '#CCCCFF'
- %>
- <li> <%#= i %> : <%= item %> </li>
- <% end %>
- </ul>
-src: |
- _out = ''; _out << '<ul>
- ';
- ; for item in list
- ;
-
-
-
- ; _out << ' <li> ';; _out << ' : '; _out << ( item ).to_s; _out << ' </li>
- '; end
- ; _out << '</ul>
- ';
- _out
-output: |
- <ul>
- <li> : <aaa> </li>
- <li> : b&b </li>
- <li> : "ccc" </li>
- </ul>
+- name: printenabled1
+ class: PrintEnabledEruby
+ input: &printenabled1_input|
+ <ul>
+ <% for item in list %>
+ <li><% print item %></li>
+ <% end %>
+ </ul>
+ src: |
+ @_out = _out = []; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; print item ; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out.join
+ 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: |
- _out = ''; _out << '<pre>
- '; for item in list
- ; _out << ' '; _out << Erubis::XmlHelper.escape_xml( item ); _out << '
- '; _out << ' '; _out << ( item ).to_s; _out << '
- '; end
- ; _out << '</pre>
- ';
- _out
-output: |
- <pre>
- &lt;aaa&gt;
- <aaa>
- b&amp;b
- b&b
- &quot;ccc&quot;
- "ccc"
- </pre>
+- name: printenabled2
+ class: PrintEnabledXmlEruby
+ input: *printenabled1_input
+# <ul>
+# <% for item in list %>
+# <li><% print item %></li>
+# <% end %>
+# </ul>
+ src: |
+ @_out = _out = []; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; print item ; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out.join
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
##
----
-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: |
- _out = ''; for item in list
- ; _out << ' '; _out << Erubis::XmlHelper.escape_xml( item["var#{n}"] ); _out << '
- '; _out << ' '; _out << ( item["var#{n}"] ).to_s; _out << '
- '; _out << ' '; $stderr.puts("*** debug: item[\"var\#{n}\"]=#{(item["var#{n}"]).inspect}"); _out << '
- '; _out << ' '; _out << '
- '; end
- ;
- _out
-output: |
+- name: stdout1
+ class: StdoutEruby
+ testopt: stdout
+ input: *basic1_input
+# <ul>
+# <% for item in list %>
+# <li><%= item %></li>
+# <% end %>
+# </ul>
+ src: |
+ _out = $stdout; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ ''
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
##
----
-name: print1
-class: PrintEruby
-input: |
- <ul>
- <% for item in list %>
- <li><% print item %></li>
- <% end %>
- </ul>
-src: |
- @_out = _out = ''; _out << '<ul>
- '; for item in list
- ; _out << ' <li>'; print item ; _out << '</li>
- '; end
- ; _out << '</ul>
- ';
- _out
-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: |
+ _out = []; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out
+ output:
+ - "<ul>\n"
+ - " <li>"
+ - "<aaa>"
+ - "</li>\n"
+ - " <li>"
+ - "b&b"
+ - "</li>\n"
+ - " <li>"
+ - "\"ccc\""
+ - "</li>\n"
+ - "</ul>\n"
##
----
-name: print2
-class: PrintXmlEruby
-input: |
- <ul>
- <% for item in list %>
- <li><% print item %></li>
- <% end %>
- </ul>
-src: |
- @_out = _out = ''; _out << '<ul>
- '; for item in list
- ; _out << ' <li>'; print item ; _out << '</li>
- '; end
- ; _out << '</ul>
- ';
- _out
-output: |
- <ul>
- <li><aaa></li>
- <li>b&b</li>
- <li>"ccc"</li>
- </ul>
+- name: stringbuffer1
+ class: StringBufferEruby
+ input: *basic1_input
+# <ul>
+# <% for item in list %>
+# <li><%= item %></li>
+# <% end %>
+# </ul>
+ src: |
+ _out = ''; _out << '<ul>
+ '; for item in list
+ ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
+ '; end
+ ; _out << '</ul>
+ ';
+ _out
+ output: *basic1_output
+# <ul>
+# <li><aaa></li>
+# <li>b&b</li>
+# <li>"ccc"</li>
+# </ul>
##
----
-name: loadfile1
-testopt: load_file
-#input: |
-# <ul>
-# <% for item in list %>
-# <li><%= item %></li>
-# <% end %>
-# </ul>
-input:
- "<ul>\r\n <% for item in list %>\r\n <li><%= item %></li>\r\n <% end %>\r\n</ul>\r\n"
-#src: |
-# _out = ''; _out << "<ul>\n"
-# for item in list
-# _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
-# end
-# _out << "</ul>\n"
-# _out
-src:
- "_out = ''; _out << '<ul>\r\n'; for item in list \r\n; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>\r\n'; end \r\n; _out << '</ul>\r\n';\n_out\n"
-#output: |
-# <ul>
-# <li><aaa></li>
-# <li>b&b</li>
-# <li>"ccc"</li>
-# </ul>
-output:
- "<ul>\n <li><aaa></li>\n <li>b&b</li>\n <li>\"ccc\"</li>\n</ul>\n"
-# "<ul>\r\n <li><aaa></li>\r\n <li>b&b</li>\r\n <li>\"ccc\"</li>\r\n</ul>\r\n"
+- name: simplified
+ class: SimplifiedEruby
+ input: |
+ <ul>
+ <% for item in list %>
+ <li>
+ <%= item %>
+ </li>
+ <% end %>
+ </ul>
+ src: |
+ _out = []; _out << '<ul>
+ '; for item in list ; _out << '
+ <li>
+ '; _out << ( item ).to_s; _out << '
+ </li>
+ '; end ; _out << '
+ </ul>
+ ';
+ _out.join
+ output: |
+ <ul>
+ ^
+ <li>
+ <aaa>
+ </li>
+ ^
+ <li>
+ b&b
+ </li>
+ ^
+ <li>
+ "ccc"
+ </li>
+ ^
+ </ul>
##
----
-name: nomatch1
-desc: bug
-input: |
- <ul>
- <li>foo</li>
- </ul>
-src: |
- _out = ''; _out << '<ul>
- <li>foo</li>
- </ul>
- ';
- _out
-output: |
- <ul>
- <li>foo</li>
- </ul>
+- name: bipattern1
+ class: BiPatternEruby
+ #options: { :bipattern : '\[= =\]' }
+ input: |
+ <% for item in list %>
+ <%= item %> % <%== item %>
+ [= item =] = [== item =]
+ <% end %>
+ src: |
+ _out = []; for item in list
+ ; _out << ' '; _out << ( item ).to_s; _out << ' % '; _out << Erubis::XmlHelper.escape_xml( item ); _out << '
+ '; _out << ' '; _out << ( item ).to_s; _out << ' = '; _out << Erubis::XmlHelper.escape_xml( item ); _out << '
+ '; end
+ ;
+ _out.join
+ 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: |
+ _out = []; for item in list
+ ; _out << ' '; _out << (item).to_s; _out << ' % '; _out << Erubis::XmlHelper.escape_xml(item); _out << '
+ '; _out << ' '; _out << (item).to_s; _out << ' = '; _out << Erubis::XmlHelper.escape_xml(item); _out << '
+ '; end
+ ;
+ _out.join
+ 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: stdout1
-class: StdoutEruby
-testopt: stdout
-input: |
- <ul>
- <% for item in list %>
- <li><%= item %></li>
- <% end %>
- </ul>
-src: |
- _out = $stdout; _out << '<ul>
- '; for item in list
- ; _out << ' <li>'; _out << ( item ).to_s; _out << '</li>
- '; end
- ; _out << '</ul>
- ';
- nil
-output: |
- <ul>
- <li><aaa></li>
- <li>b&b</li>
- <li>"ccc"</li>
- </ul>
+- 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: |
+ _out = []; _out << '<table>
+ '; for item in list
+ ; _out << ' <tr>
+ <td>'; _out << ( item ).to_s; _out << '</td>
+ <td>'; _out << Erubis::XmlHelper.escape_xml( item ); _out << '</td>
+ </tr>
+ '; end
+ ; _out << '</table>
+ <pre>
+ '; _out << '% double percent
+ '; _out << ' % spaced percent
+ </pre>
+ ';
+ _out.join
+ 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: optimized1
-class: OptimizedEruby
-input: |
- <table>
- <% for item in list %>
- <tr>
- <td><%= item %></td>
- <td><%== item %></td>
- </tr>
- <% end %>
- </table>
- <ul><% for item in list %><li><%= item %></li><% end %></ul>
-src: |
- _out = '<table>
- '; for item in list
- ; _out << ' <tr>
- <td>' << ( item ).to_s << '</td>
- <td>' << Erubis::XmlHelper.escape_xml( item ) << '</td>
- </tr>
- '; end
- ; _out << '</table>
- <ul>'; for item in list ; _out << '<li>' << ( item ).to_s << '</li>'; end ; _out << '</ul>
- '
- _out
-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>
- <ul><li><aaa></li><li>b&b</li><li>"ccc"</li></ul>
+- 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)
+
+ _out = []; _out << '<ol>
+ '; for item in list
+ ; _out << ' <li>'; _out << Erubis::XmlHelper.escape_xml(item); _out << '</li>
+ '; end
+ ; _out << '</ol>
+ ';
+ _out.join
+ end
+ output: |
+ <ol>
+ <li>&lt;aaa&gt;</li>
+ <li>b&amp;b</li>
+ <li>&quot;ccc&quot;</li>
+ </ol>
##
----
-name: optimized2
-class: OptimizedXmlEruby
-input: |
- <table>
- <% for item in list %>
- <tr>
- <td><%= item %></td>
- <td><%== item %></td>
- </tr>
- <% end %>
- </table>
- <ul><% for item in list %><li><%= item %></li><% end %></ul>
-src: |
- _out = '<table>
- '; for item in list
- ; _out << ' <tr>
- <td>' << Erubis::XmlHelper.escape_xml( item ) << '</td>
- <td>' << ( item ).to_s << '</td>
- </tr>
- '; end
- ; _out << '</table>
- <ul>'; for item in list ; _out << '<li>' << Erubis::XmlHelper.escape_xml( item ) << '</li>'; end ; _out << '</ul>
- '
- _out
-output: |
- <table>
- <tr>
- <td>&lt;aaa&gt;</td>
- <td><aaa></td>
- </tr>
- <tr>
- <td>b&amp;b</td>
- <td>b&b</td>
- </tr>
- <tr>
- <td>&quot;ccc&quot;</td>
- <td>"ccc"</td>
- </tr>
- </table>
- <ul><li>&lt;aaa&gt;</li><li>b&amp;b</li><li>&quot;ccc&quot;</li></ul>
+- name: optimized1
+ class: OptimizedEruby
+ input: &optimized1_input|
+ <table>
+ <% for item in list %>
+ <tr>
+ <td><%= item %></td>
+ <td><%== item %></td>
+ </tr>
+ <% end %>
+ </table>
+ <ul><% for item in list %><li><%= item %></li><% end %></ul>
+ src: |
+ _out = '<table>
+ '; for item in list
+ ; _out << ' <tr>
+ <td>' << ( item ).to_s << '</td>
+ <td>' << Erubis::XmlHelper.escape_xml( item ) << '</td>
+ </tr>
+ '; end
+ ; _out << '</table>
+ <ul>'; for item in list ; _out << '<li>' << ( item ).to_s << '</li>'; end ; _out << '</ul>
+ '
+ _out
+ 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>
+ <ul><li><aaa></li><li>b&b</li><li>"ccc"</li></ul>
##
----
-name: optimized3
-desc: bug
-class: OptimizedEruby
-input: |
- user = <%= "Foo" %>
- <% for item in list %>
- <%= item %>
- <% end %>
-src: |
- _out = 'user = '; _out << ( "Foo" ).to_s << '
- '; for item in list
- ; _out << ' ' << ( item ).to_s << '
- '; end
- ;
- _out
-output: |
- user = Foo
- <aaa>
- b&b
- "ccc"
+- name: optimized2
+ class: OptimizedXmlEruby
+ input: *optimized1_input
+# <table>
+# <% for item in list %>
+# <tr>
+# <td><%= item %></td>
+# <td><%== item %></td>
+# </tr>
+# <% end %>
+# </table>
+# <ul><% for item in list %><li><%= item %></li><% end %></ul>
+ src: |
+ _out = '<table>
+ '; for item in list
+ ; _out << ' <tr>
+ <td>' << Erubis::XmlHelper.escape_xml( item ) << '</td>
+ <td>' << ( item ).to_s << '</td>
+ </tr>
+ '; end
+ ; _out << '</table>
+ <ul>'; for item in list ; _out << '<li>' << Erubis::XmlHelper.escape_xml( item ) << '</li>'; end ; _out << '</ul>
+ '
+ _out
+ output: |
+ <table>
+ <tr>
+ <td>&lt;aaa&gt;</td>
+ <td><aaa></td>
+ </tr>
+ <tr>
+ <td>b&amp;b</td>
+ <td>b&b</td>
+ </tr>
+ <tr>
+ <td>&quot;ccc&quot;</td>
+ <td>"ccc"</td>
+ </tr>
+ </table>
+ <ul><li>&lt;aaa&gt;</li><li>b&amp;b</li><li>&quot;ccc&quot;</li></ul>
+##
+- name: optimized3
+ desc: bug
+ class: OptimizedEruby
+ input: |
+ user = <%= "Foo" %>
+ <% for item in list %>
+ <%= item %>
+ <% end %>
+ src: |
+ _out = 'user = '; _out << ( "Foo" ).to_s << '
+ '; for item in list
+ ; _out << ' ' << ( item ).to_s << '
+ '; end
+ ;
+ _out
+ output: |
+ user = Foo
+ <aaa>
+ b&b
+ "ccc"
##
----
-name: optimized4
-desc: single quotation and backslash
-class: OptimizedEruby
-input: |
- a = "'"
- b = "\""
- c = '\''
-src: |
- _out = 'a = "\'"
- b = "\\""
- c = \'\\\'\'
- ';
- _out
-output: |
- a = "'"
- b = "\""
- c = '\''
+- name: optimized4
+ desc: single quotation and backslash
+ class: OptimizedEruby
+ input: &optimized4_input|
+ a = "'"
+ b = "\""
+ c = '\''
+ src: |
+ _out = 'a = "\'"
+ b = "\\""
+ c = \'\\\'\'
+ ';
+ _out
+ output: *optimized4_input
##
diff --git a/test/test.rb b/test/test.rb
new file mode 100644
index 0000000..243f963
--- /dev/null
+++ b/test/test.rb
@@ -0,0 +1,27 @@
+##
+## $Rev$
+## $Release$
+## $Copyright$
+##
+
+
+unless defined?(TESTDIR)
+ TESTDIR = File.dirname(__FILE__)
+ LIBDIR = TESTDIR == '.' ? '../lib' : File.dirname(TESTDIR) + '/lib'
+ $: << TESTDIR
+ $: << LIBDIR
+end
+
+
+require 'test/unit'
+#require 'test/unit/ui/console/testrunner'
+require 'assert-text-equal'
+require 'yaml'
+require 'testutil'
+
+
+if $0 == __FILE__
+ require "#{TESTDIR}/test-erubis.rb"
+ require "#{TESTDIR}/test-engines.rb"
+ require "#{TESTDIR}/test-bin.rb"
+end
diff --git a/test/testutil.rb b/test/testutil.rb
new file mode 100644
index 0000000..bbd8b4c
--- /dev/null
+++ b/test/testutil.rb
@@ -0,0 +1,86 @@
+###
+### $Rev: 103 $
+### $Release$
+### $Copyright$
+###
+
+require 'yaml'
+
+
+module TestEnhancer
+
+
+ module_function
+
+
+ def load_testdata(filename, options={}, &block)
+ _load_yaml(filename, :doc, options, &block)
+ end
+
+
+ def load_yaml_document(filename, options={}, &block)
+ _load_yaml(filename, :doc, options, &block)
+ end
+
+
+ def load_yaml_documents(filename, options={}, &block)
+ _load_yaml(filename, :docs, options, &block)
+ end
+
+
+ def _load_yaml(filename, type, options={}, &block) # :nodoc:
+ s = File.read(filename)
+ if filename =~ /\.rb$/
+ s =~ /^__END__$/ or raise "*** error: __END__ is not found in '#{filename}'."
+ s = $'
+ end
+ unless options[:tabify] == false
+ s = s.inject('') do |sb, line|
+ sb << line.gsub(/([^\t]{8})|([^\t]*)\t/n) { [$+].pack("A8") }
+ end
+ end
+ #
+ case type
+ when :docs
+ hash_list = []
+ YAML.load_documents(s) do |hash| hash_list << hash end
+ when :doc
+ hash_list = YAML.load(s)
+ else
+ raise "*** internal error"
+ end
+ #
+ identkey = options[:identkey] || 'name'
+ table = {}
+ hash_list.each do |hash|
+ ident = hash[identkey]
+ ident or raise "*** #{identkey} is not found."
+ table[ident] and raise "*** #{identkey} '#{ident}' is duplicated."
+ table[ident] = hash
+ yield(hash) if block
+ end
+ #
+ return hash_list
+ end
+
+
+ def define_testmethods(testdata_list, options={}, &block)
+ identkey = options[:identkey] || 'name'
+ testmethod = options[:testmethod] || '_test'
+ testdata_list.each do |hash|
+ yield(hash) if block
+ ident = hash[identkey]
+ s = "def test_#{ident}\n"
+ hash.each do |key, val|
+ code = " @#{key} = #{val.inspect}\n"
+ s << " @#{key} = #{val.inspect}\n"
+ end
+ s << " #{testmethod}\n"
+ s << "end\n"
+ $stderr.puts "*** load_yaml_testdata(): eval_str=<<'END'\n#{s}END" if $DEBUG
+ self.module_eval s
+ end
+ end
+
+
+end