temple 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +1 -0
- data/LICENSE +20 -0
- data/README.md +246 -0
- data/Rakefile +16 -16
- data/lib/temple.rb +7 -1
- data/lib/temple/core.rb +89 -41
- data/lib/temple/engine.rb +31 -9
- data/lib/temple/engines/erb.rb +93 -0
- data/lib/temple/filters/dynamic_inliner.rb +26 -6
- data/lib/temple/filters/escapable.rb +12 -5
- data/lib/temple/filters/multi_flattener.rb +27 -0
- data/lib/temple/filters/static_merger.rb +5 -1
- data/lib/temple/generator.rb +60 -6
- data/lib/temple/parsers/erb.rb +63 -15
- data/lib/temple/utils.rb +20 -0
- data/temple.gemspec +5 -40
- data/test/engines/hello.erb +4 -0
- data/test/engines/test_erb.rb +495 -0
- data/test/engines/test_erb_m17n.rb +132 -0
- data/test/filters/test_dynamic_inliner.rb +116 -0
- data/test/filters/test_escapable.rb +28 -0
- data/test/filters/test_static_merger.rb +45 -0
- data/test/helper.rb +21 -0
- data/test/test_generator.rb +122 -0
- metadata +33 -25
- data/README +0 -7
- data/VERSION +0 -1
- data/lib/temple/filters/mustache.rb +0 -70
- data/lib/temple/parsers/mustache.rb +0 -68
- data/spec/dynamic_inliner_spec.rb +0 -79
- data/spec/escapable_spec.rb +0 -24
- data/spec/spec_helper.rb +0 -15
- data/spec/static_merger_spec.rb +0 -27
- data/spec/temple_spec.rb +0 -5
@@ -0,0 +1,132 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require File.dirname(__FILE__) + '/../helper'
|
3
|
+
|
4
|
+
if "".respond_to?(:encoding)
|
5
|
+
class TestTempleEnginesERBM17N < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
Temple::Engines::ERB.rock!
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
Temple::Engines::ERB.rock!
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_result_encoding
|
15
|
+
erb = ERB.new("hello")
|
16
|
+
assert_equal __ENCODING__, erb.result.encoding
|
17
|
+
|
18
|
+
erb = ERB.new("こんにちは".encode("EUC-JP"))
|
19
|
+
assert_equal Encoding::EUC_JP, erb.result.encoding
|
20
|
+
|
21
|
+
erb = ERB.new("\xC4\xE3\xBA\xC3".force_encoding("EUC-CN"))
|
22
|
+
assert_equal Encoding::EUC_CN, erb.result.encoding
|
23
|
+
|
24
|
+
erb = ERB.new("γεια σας".encode("ISO-8859-7"))
|
25
|
+
assert_equal Encoding::ISO_8859_7, erb.result.encoding
|
26
|
+
|
27
|
+
assert_raise(ArgumentError) {
|
28
|
+
ERB.new("こんにちは".force_encoding("ISO-2022-JP")) # dummy encoding
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_generate_magic_comment
|
33
|
+
erb = ERB.new("hello")
|
34
|
+
assert_match(/#coding:UTF-8/, erb.src)
|
35
|
+
|
36
|
+
erb = ERB.new("hello".force_encoding("EUC-JP"))
|
37
|
+
assert_match(/#coding:EUC-JP/, erb.src)
|
38
|
+
|
39
|
+
erb = ERB.new("hello".force_encoding("ISO-8859-9"))
|
40
|
+
assert_match(/#coding:ISO-8859-9/, erb.src)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_literal_encoding
|
44
|
+
erb = ERB.new("literal encoding is <%= 'hello'.encoding %>")
|
45
|
+
assert_match(/literal encoding is UTF-8/, erb.result)
|
46
|
+
|
47
|
+
erb = ERB.new("literal encoding is <%= 'こんにちは'.encoding %>".encode("EUC-JP"))
|
48
|
+
assert_match(/literal encoding is EUC-JP/, erb.result)
|
49
|
+
|
50
|
+
erb = ERB.new("literal encoding is <%= '\xC4\xE3\xBA\xC3'.encoding %>".force_encoding("EUC-CN"))
|
51
|
+
assert_match(/literal encoding is GB2312/, erb.result)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test___ENCODING__
|
55
|
+
erb = ERB.new("__ENCODING__ is <%= __ENCODING__ %>")
|
56
|
+
assert_match(/__ENCODING__ is UTF-8/, erb.result)
|
57
|
+
|
58
|
+
erb = ERB.new("__ENCODING__ is <%= __ENCODING__ %>".force_encoding("EUC-JP"))
|
59
|
+
assert_match(/__ENCODING__ is EUC-JP/, erb.result)
|
60
|
+
|
61
|
+
erb = ERB.new("__ENCODING__ is <%= __ENCODING__ %>".force_encoding("Big5"))
|
62
|
+
assert_match(/__ENCODING__ is Big5/, erb.result)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_recognize_magic_comment
|
66
|
+
erb = ERB.new(<<-EOS.encode("EUC-KR"))
|
67
|
+
<%# -*- coding: EUC-KR -*- %>
|
68
|
+
안녕하세요
|
69
|
+
EOS
|
70
|
+
assert_match(/#coding:EUC-KR/, erb.src)
|
71
|
+
assert_equal Encoding::EUC_KR, erb.result.encoding
|
72
|
+
|
73
|
+
erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("ASCII-8BIT"))
|
74
|
+
<%#-*- coding: EUC-KR -*-%>
|
75
|
+
안녕하세요
|
76
|
+
EOS
|
77
|
+
assert_match(/#coding:EUC-KR/, erb.src)
|
78
|
+
assert_equal Encoding::EUC_KR, erb.result.encoding
|
79
|
+
|
80
|
+
erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("ASCII-8BIT"))
|
81
|
+
<%# vim: tabsize=8 encoding=EUC-KR shiftwidth=2 expandtab %>
|
82
|
+
안녕하세요
|
83
|
+
EOS
|
84
|
+
assert_match(/#coding:EUC-KR/, erb.src)
|
85
|
+
assert_equal Encoding::EUC_KR, erb.result.encoding
|
86
|
+
|
87
|
+
erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("ASCII-8BIT"))
|
88
|
+
<%#coding:EUC-KR %>
|
89
|
+
안녕하세요
|
90
|
+
EOS
|
91
|
+
assert_match(/#coding:EUC-KR/, erb.src)
|
92
|
+
assert_equal Encoding::EUC_KR, erb.result.encoding
|
93
|
+
|
94
|
+
erb = ERB.new(<<-EOS.encode("EUC-KR").force_encoding("EUC-JP"))
|
95
|
+
<%#coding:EUC-KR %>
|
96
|
+
안녕하세요
|
97
|
+
EOS
|
98
|
+
assert_match(/#coding:EUC-KR/, erb.src)
|
99
|
+
assert_equal Encoding::EUC_KR, erb.result.encoding
|
100
|
+
end
|
101
|
+
|
102
|
+
module M; end
|
103
|
+
def test_method_with_encoding
|
104
|
+
obj = Object.new
|
105
|
+
obj.extend(M)
|
106
|
+
|
107
|
+
erb = ERB.new(<<-EOS.encode("EUC-JP").force_encoding("ASCII-8BIT"))
|
108
|
+
<%#coding:EUC-JP %>
|
109
|
+
literal encoding is <%= 'こんにちは'.encoding %>
|
110
|
+
__ENCODING__ is <%= __ENCODING__ %>
|
111
|
+
EOS
|
112
|
+
erb.def_method(M, :m_from_magic_comment)
|
113
|
+
|
114
|
+
result = obj.m_from_magic_comment
|
115
|
+
assert_equal Encoding::EUC_JP, result.encoding
|
116
|
+
assert_match(/literal encoding is EUC-JP/, result)
|
117
|
+
assert_match(/__ENCODING__ is EUC-JP/, result)
|
118
|
+
|
119
|
+
erb = ERB.new(<<-EOS.encode("EUC-KR"))
|
120
|
+
literal encoding is <%= '안녕하세요'.encoding %>
|
121
|
+
__ENCODING__ is <%= __ENCODING__ %>
|
122
|
+
EOS
|
123
|
+
erb.def_method(M, :m_from_eval_encoding)
|
124
|
+
result = obj.m_from_eval_encoding
|
125
|
+
assert_equal Encoding::EUC_KR, result.encoding
|
126
|
+
assert_match(/literal encoding is EUC-KR/, result)
|
127
|
+
assert_match(/__ENCODING__ is EUC-KR/, result)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# vim:fileencoding=UTF-8
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../helper'
|
2
|
+
|
3
|
+
class TestTempleFiltersDynamicInliner < TestFilter(:DynamicInliner)
|
4
|
+
def test_several_statics_into_dynamic
|
5
|
+
exp = @filter.compile([:multi,
|
6
|
+
[:static, "Hello "],
|
7
|
+
[:static, "World\n "],
|
8
|
+
[:static, "Have a nice day"]
|
9
|
+
])
|
10
|
+
|
11
|
+
assert_equal([:multi,
|
12
|
+
[:dynamic, "\"Hello World\n Have a nice day\""]
|
13
|
+
], exp)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_several_dynamics_into_dynamic
|
17
|
+
exp = @filter.compile([:multi,
|
18
|
+
[:dynamic, "@hello"],
|
19
|
+
[:dynamic, "@world"],
|
20
|
+
[:dynamic, "@yeah"]
|
21
|
+
])
|
22
|
+
|
23
|
+
assert_equal([:multi,
|
24
|
+
[:dynamic, '"#{@hello}#{@world}#{@yeah}"']
|
25
|
+
], exp)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_static_and_dynamic_into_dynamic
|
29
|
+
exp = @filter.compile([:multi,
|
30
|
+
[:static, "Hello"],
|
31
|
+
[:dynamic, "@world"],
|
32
|
+
[:dynamic, "@yeah"],
|
33
|
+
[:static, "Nice"]
|
34
|
+
])
|
35
|
+
|
36
|
+
assert_equal([:multi,
|
37
|
+
[:dynamic, '"Hello#{@world}#{@yeah}Nice"']
|
38
|
+
], exp)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_static_and_dynamic_around_blocks
|
42
|
+
exp = @filter.compile([:multi,
|
43
|
+
[:static, "Hello "],
|
44
|
+
[:dynamic, "@world"],
|
45
|
+
[:block, "Oh yeah"],
|
46
|
+
[:dynamic, "@yeah"],
|
47
|
+
[:static, "Once more"]
|
48
|
+
])
|
49
|
+
|
50
|
+
assert_equal([:multi,
|
51
|
+
[:dynamic, '"Hello #{@world}"'],
|
52
|
+
[:block, "Oh yeah"],
|
53
|
+
[:dynamic, '"#{@yeah}Once more"']
|
54
|
+
], exp)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_keep_blocks_intact
|
58
|
+
exp = [:multi, [:block, 'foo']]
|
59
|
+
assert_equal(exp, @filter.compile(exp))
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_keep_single_static_intact
|
63
|
+
exp = [:multi, [:static, 'foo']]
|
64
|
+
assert_equal(exp, @filter.compile(exp))
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_keep_single_dynamic_intact
|
68
|
+
exp = [:multi, [:dynamic, 'foo']]
|
69
|
+
assert_equal(exp, @filter.compile(exp))
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_inline_inside_multi
|
73
|
+
exp = @filter.compile([:multi,
|
74
|
+
[:static, "Hello "],
|
75
|
+
[:dynamic, "@world"],
|
76
|
+
[:multi,
|
77
|
+
[:static, "Hello "],
|
78
|
+
[:dynamic, "@world"]],
|
79
|
+
[:static, "Hello "],
|
80
|
+
[:dynamic, "@world"]
|
81
|
+
])
|
82
|
+
|
83
|
+
assert_equal([:multi,
|
84
|
+
[:dynamic, '"Hello #{@world}"'],
|
85
|
+
[:multi, [:dynamic, '"Hello #{@world}"']],
|
86
|
+
[:dynamic, '"Hello #{@world}"']
|
87
|
+
], exp)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_merge_across_newlines
|
91
|
+
exp = @filter.compile([:multi,
|
92
|
+
[:static, "Hello \n"],
|
93
|
+
[:newline],
|
94
|
+
[:dynamic, "@world"],
|
95
|
+
[:newline]
|
96
|
+
])
|
97
|
+
|
98
|
+
assert_equal([:multi,
|
99
|
+
[:dynamic, ["\"Hello \n\"", '"#{@world}"', '""'].join("\\\n")],
|
100
|
+
], exp)
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_static_followed_by_newline
|
104
|
+
exp = @filter.compile([:multi,
|
105
|
+
[:static, "Hello \n"],
|
106
|
+
[:newline],
|
107
|
+
[:block, "world"]
|
108
|
+
])
|
109
|
+
|
110
|
+
assert_equal([:multi,
|
111
|
+
[:static, "Hello \n"],
|
112
|
+
[:newline],
|
113
|
+
[:block, "world"]
|
114
|
+
], exp)
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../helper'
|
2
|
+
|
3
|
+
class TestTempleFiltersEscapable < TestFilter(:Escapable)
|
4
|
+
def test_escape
|
5
|
+
exp = @filter.compile([:multi,
|
6
|
+
[:escape, [:dynamic, "@hello"]],
|
7
|
+
[:escape, [:block, "@world"]]
|
8
|
+
])
|
9
|
+
|
10
|
+
assert_equal([:multi,
|
11
|
+
[:dynamic, "CGI.escapeHTML((@hello).to_s)"],
|
12
|
+
[:block, "CGI.escapeHTML((@world).to_s)"]
|
13
|
+
], exp)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_escape_static_content
|
17
|
+
exp = @filter.compile([:multi,
|
18
|
+
[:escape, [:static, "<hello>"]],
|
19
|
+
[:escape, [:block, "@world"]]
|
20
|
+
])
|
21
|
+
|
22
|
+
assert_equal([:multi,
|
23
|
+
[:static, "<hello>"],
|
24
|
+
[:block, "CGI.escapeHTML((@world).to_s)"]
|
25
|
+
], exp)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../helper'
|
2
|
+
|
3
|
+
class TestTempleFiltersStaticMerger < TestFilter(:StaticMerger)
|
4
|
+
def test_several_statics
|
5
|
+
exp = @filter.compile([:multi,
|
6
|
+
[:static, "Hello "],
|
7
|
+
[:static, "World, "],
|
8
|
+
[:static, "Good night"]
|
9
|
+
])
|
10
|
+
|
11
|
+
assert_equal([:multi,
|
12
|
+
[:static, "Hello World, Good night"]
|
13
|
+
], exp)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_several_statics_around_block
|
17
|
+
exp = @filter.compile([:multi,
|
18
|
+
[:static, "Hello "],
|
19
|
+
[:static, "World!"],
|
20
|
+
[:block, "123"],
|
21
|
+
[:static, "Good night, "],
|
22
|
+
[:static, "everybody"]
|
23
|
+
])
|
24
|
+
|
25
|
+
assert_equal([:multi,
|
26
|
+
[:static, "Hello World!"],
|
27
|
+
[:block, "123"],
|
28
|
+
[:static, "Good night, everybody"]
|
29
|
+
], exp)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_several_statics_across_newlines
|
33
|
+
exp = @filter.compile([:multi,
|
34
|
+
[:static, "Hello "],
|
35
|
+
[:static, "World, "],
|
36
|
+
[:newline],
|
37
|
+
[:static, "Good night"]
|
38
|
+
])
|
39
|
+
|
40
|
+
assert_equal([:multi,
|
41
|
+
[:static, "Hello World, Good night"],
|
42
|
+
[:newline]
|
43
|
+
], exp)
|
44
|
+
end
|
45
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'temple'
|
4
|
+
|
5
|
+
def TestFilter(klass)
|
6
|
+
klass = Temple::Filters.const_get(klass.to_s) unless klass.is_a?(Class)
|
7
|
+
|
8
|
+
Class.new(Test::Unit::TestCase) do
|
9
|
+
define_method(:setup) do
|
10
|
+
@filter = klass.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Dummy test so Turn doesn't complain
|
14
|
+
def test_void
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.name
|
18
|
+
super || "<anonymous>"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestTempleGenerator < Test::Unit::TestCase
|
4
|
+
class Simple < Temple::Generator
|
5
|
+
def preamble
|
6
|
+
buffer " = BUFFER"
|
7
|
+
end
|
8
|
+
|
9
|
+
def postamble
|
10
|
+
buffer
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_static(s)
|
14
|
+
"S:#{s}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_dynamic(s)
|
18
|
+
"D:#{s}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_block(s)
|
22
|
+
"B:#{s}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_simple_exp
|
27
|
+
simple = Simple.new
|
28
|
+
|
29
|
+
assert_equal("S:test", simple.compile([:static, "test"]))
|
30
|
+
assert_equal("D:test", simple.compile([:dynamic, "test"]))
|
31
|
+
assert_equal("B:test", simple.compile([:block, "test"]))
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_multi
|
35
|
+
simple = Simple.new(:buffer => "VAR")
|
36
|
+
str = simple.compile([:multi,
|
37
|
+
[:static, "static"],
|
38
|
+
[:dynamic, "dynamic"],
|
39
|
+
[:block, "block"]
|
40
|
+
])
|
41
|
+
|
42
|
+
assert_match(/VAR = BUFFER/, str)
|
43
|
+
assert_match(/VAR << \(S:static\)/, str)
|
44
|
+
assert_match(/VAR << \(D:dynamic\)/, str)
|
45
|
+
assert_match(/ B:block /, str)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_capture
|
49
|
+
simple = Simple.new(:buffer => "VAR")
|
50
|
+
str = simple.compile([:capture, "foo", [:static, "test"]])
|
51
|
+
|
52
|
+
assert_match(/foo = S:test/, str)
|
53
|
+
assert_match(/VAR\Z/, str)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_capture_with_multi
|
57
|
+
simple = Simple.new(:buffer => "VAR")
|
58
|
+
str = simple.compile([:multi,
|
59
|
+
[:static, "before"],
|
60
|
+
|
61
|
+
[:capture, "foo", [:multi,
|
62
|
+
[:static, "static"],
|
63
|
+
[:dynamic, "dynamic"],
|
64
|
+
[:block, "block"]]],
|
65
|
+
|
66
|
+
[:static, "after"]
|
67
|
+
])
|
68
|
+
|
69
|
+
assert_match(/VAR << \(S:before\)/, str)
|
70
|
+
assert_match(/foo = BUFFER/, str)
|
71
|
+
assert_match(/foo << \(S:static\)/, str)
|
72
|
+
assert_match(/foo << \(D:dynamic\)/, str)
|
73
|
+
assert_match(/ B:block /, str)
|
74
|
+
assert_match(/VAR << \(S:after\)/, str)
|
75
|
+
assert_match(/VAR\Z/, str)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_newlines
|
79
|
+
simple = Simple.new(:buffer => "VAR")
|
80
|
+
str = simple.compile([:multi,
|
81
|
+
[:static, "static"],
|
82
|
+
[:newline],
|
83
|
+
[:dynamic, "dynamic"],
|
84
|
+
[:newline],
|
85
|
+
[:block, "block"]
|
86
|
+
])
|
87
|
+
|
88
|
+
lines = str.split("\n")
|
89
|
+
assert_match(/VAR << \(S:static\)/, lines[0])
|
90
|
+
assert_match(/VAR << \(D:dynamic\)/, lines[1])
|
91
|
+
assert_match(/ B:block /, lines[2])
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_to_ruby
|
95
|
+
simple = Simple.new
|
96
|
+
|
97
|
+
{
|
98
|
+
"Hello" => 'Hello',
|
99
|
+
"Hello\r\nWorld" => 'Hello\nWorld',
|
100
|
+
"Hello\nWorld" => %w|Hello World|,
|
101
|
+
"Hello\n\r\n\nWorld" => %w|Hello \n World|,
|
102
|
+
"\r\n\nHelloWorld\n" => %w|\n HelloWorld .|,
|
103
|
+
"\nHelloWorld\r\n" => %w|. HelloWorld\n|,
|
104
|
+
}.
|
105
|
+
each do |actual, expected|
|
106
|
+
if expected.is_a?(Array)
|
107
|
+
expected = expected.map do |x|
|
108
|
+
if x == "."
|
109
|
+
# Use the dot so we can easily match a newline
|
110
|
+
# at the end or the beginning.
|
111
|
+
""
|
112
|
+
else
|
113
|
+
x
|
114
|
+
end
|
115
|
+
end.join("\n")
|
116
|
+
end
|
117
|
+
|
118
|
+
expected = '"' + expected + '"'
|
119
|
+
assert_equal(expected, simple.to_ruby(actual))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|