tilt 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/COPYING +1 -1
  2. data/Gemfile +31 -1
  3. data/HACKING +16 -0
  4. data/README.md +5 -2
  5. data/Rakefile +25 -1
  6. data/TEMPLATES.md +13 -13
  7. data/bin/tilt +8 -6
  8. data/lib/tilt.rb +15 -1
  9. data/lib/tilt/asciidoc.rb +34 -0
  10. data/lib/tilt/coffee.rb +4 -0
  11. data/lib/tilt/css.rb +10 -2
  12. data/lib/tilt/csv.rb +71 -0
  13. data/lib/tilt/erb.rb +1 -1
  14. data/lib/tilt/etanni.rb +27 -0
  15. data/lib/tilt/liquid.rb +4 -0
  16. data/lib/tilt/markdown.rb +35 -11
  17. data/lib/tilt/nokogiri.rb +4 -4
  18. data/lib/tilt/plain.rb +20 -0
  19. data/lib/tilt/radius.rb +4 -0
  20. data/lib/tilt/rdoc.rb +20 -5
  21. data/lib/tilt/template.rb +35 -74
  22. data/lib/tilt/textile.rb +5 -0
  23. data/lib/tilt/wiki.rb +8 -0
  24. data/test/tilt_asciidoctor_test.rb +44 -0
  25. data/test/tilt_blueclothtemplate_test.rb +1 -1
  26. data/test/tilt_coffeescripttemplate_test.rb +64 -11
  27. data/test/tilt_creoletemplate_test.rb +1 -1
  28. data/test/tilt_csv_test.rb +73 -0
  29. data/test/tilt_erbtemplate_test.rb +5 -0
  30. data/test/tilt_erubistemplate_test.rb +1 -1
  31. data/test/tilt_etannitemplate_test.rb +173 -0
  32. data/test/tilt_fallback_test.rb +6 -6
  33. data/test/tilt_hamltemplate_test.rb +1 -1
  34. data/test/tilt_kramdown_test.rb +1 -1
  35. data/test/tilt_lesstemplate_test.less +1 -0
  36. data/test/tilt_lesstemplate_test.rb +19 -3
  37. data/test/tilt_liquidtemplate_test.rb +1 -1
  38. data/test/tilt_markaby_test.rb +1 -1
  39. data/test/tilt_markdown_test.rb +15 -4
  40. data/test/tilt_marukutemplate_test.rb +1 -1
  41. data/test/tilt_radiustemplate_test.rb +1 -1
  42. data/test/tilt_rdiscounttemplate_test.rb +1 -1
  43. data/test/tilt_rdoctemplate_test.rb +10 -3
  44. data/test/tilt_redcarpettemplate_test.rb +15 -3
  45. data/test/tilt_redclothtemplate_test.rb +13 -1
  46. data/test/tilt_sasstemplate_test.rb +1 -1
  47. data/test/tilt_stringtemplate_test.rb +1 -1
  48. data/test/tilt_template_test.rb +13 -0
  49. data/test/tilt_wikiclothtemplate_test.rb +1 -1
  50. data/test/tilt_yajltemplate_test.rb +13 -4
  51. data/tilt.gemspec +27 -17
  52. metadata +203 -75
@@ -24,6 +24,10 @@ module Tilt
24
24
  def evaluate(scope, locals, &block)
25
25
  @output ||= @engine.to_html
26
26
  end
27
+
28
+ def allows_script?
29
+ false
30
+ end
27
31
  end
28
32
 
29
33
  # WikiCloth implementation. See:
@@ -46,5 +50,9 @@ module Tilt
46
50
  def evaluate(scope, locals, &block)
47
51
  @output ||= @engine.to_html
48
52
  end
53
+
54
+ def allows_script?
55
+ false
56
+ end
49
57
  end
50
58
  end
@@ -0,0 +1,44 @@
1
+ require 'contest'
2
+ require 'tilt'
3
+
4
+ begin
5
+ require 'asciidoctor'
6
+
7
+ class AsciidoctorTemplateTest < Test::Unit::TestCase
8
+ HTML5_OUTPUT = "<div class=\"sect1\"><h2 id=\"_hello_world\">Hello World!</h2><div class=\"sectionbody\"></div></div>"
9
+ DOCBOOK_OUTPUT = "<section id=\"_hello_world\"><title>Hello World!</title></section>"
10
+
11
+ def strip_space(str)
12
+ str.gsub(/>\s+</, '><').strip
13
+ end
14
+
15
+ test "registered for '.ad' files" do
16
+ assert Tilt.mappings['ad'].include?(Tilt::AsciidoctorTemplate)
17
+ end
18
+
19
+ test "registered for '.adoc' files" do
20
+ assert Tilt.mappings['adoc'].include?(Tilt::AsciidoctorTemplate)
21
+ end
22
+
23
+ test "registered for '.asciidoc' files" do
24
+ assert Tilt.mappings['asciidoc'].include?(Tilt::AsciidoctorTemplate)
25
+ end
26
+
27
+ test "preparing and evaluating html5 templates on #render" do
28
+ template = Tilt::AsciidoctorTemplate.new(:attributes => {"backend" => 'html5'}) { |t| "== Hello World!" }
29
+ assert_equal HTML5_OUTPUT, strip_space(template.render)
30
+ end
31
+
32
+ test "preparing and evaluating docbook templates on #render" do
33
+ template = Tilt::AsciidoctorTemplate.new(:attributes => {"backend" => 'docbook'}) { |t| "== Hello World!" }
34
+ assert_equal DOCBOOK_OUTPUT, strip_space(template.render)
35
+ end
36
+
37
+ test "can be rendered more than once" do
38
+ template = Tilt::AsciidoctorTemplate.new(:attributes => {"backend" => 'html5'}) { |t| "== Hello World!" }
39
+ 3.times { assert_equal HTML5_OUTPUT, strip_space(template.render) }
40
+ end
41
+ end
42
+ rescue LoadError => boom
43
+ warn "Tilt::AsciidoctorTemplate (disabled)"
44
+ end
@@ -41,5 +41,5 @@ begin
41
41
  end
42
42
  end
43
43
  rescue LoadError => boom
44
- warn "Tilt::BlueClothTemplate (disabled)\n"
44
+ warn "Tilt::BlueClothTemplate (disabled)"
45
45
  end
@@ -5,10 +5,25 @@ begin
5
5
  require 'coffee_script'
6
6
 
7
7
  class CoffeeScriptTemplateTest < Test::Unit::TestCase
8
+
9
+ unless method_defined?(:assert_not_match)
10
+ # assert_not_match is missing on 1.8.7, which uses assert_no_match
11
+ def assert_not_match(a, b)
12
+ unless a.kind_of?(Regexp)
13
+ a = Regexp.new(Regexp.escape(a))
14
+ end
15
+ assert_no_match(a,b)
16
+ end
17
+ end
18
+
8
19
  test "is registered for '.coffee' files" do
9
20
  assert_equal Tilt::CoffeeScriptTemplate, Tilt['test.coffee']
10
21
  end
11
22
 
23
+ test "bare is disabled by default" do
24
+ assert_equal false, Tilt::CoffeeScriptTemplate.default_bare
25
+ end
26
+
12
27
  test "compiles and evaluates the template on #render" do
13
28
  template = Tilt::CoffeeScriptTemplate.new { |t| "puts 'Hello, World!'\n" }
14
29
  assert_match "puts('Hello, World!');", template.render
@@ -20,18 +35,25 @@ begin
20
35
  end
21
36
 
22
37
  test "disabling coffee-script wrapper" do
23
- str = "puts 'Hello, World!'\n"
38
+ str = 'name = "Josh"; puts "Hello #{name}"'
39
+
40
+ template = Tilt::CoffeeScriptTemplate.new { str }
41
+ assert_match "(function() {", template.render
42
+ assert_match "puts(\"Hello \" + name);\n", template.render
24
43
 
25
44
  template = Tilt::CoffeeScriptTemplate.new(:bare => true) { str }
26
- assert_equal "puts('Hello, World!');", template.render
45
+ assert_not_match "(function() {", template.render
46
+ assert_equal "var name;\n\nname = \"Josh\";\n\nputs(\"Hello \" + name);\n", template.render
27
47
 
28
48
  template2 = Tilt::CoffeeScriptTemplate.new(:no_wrap => true) { str}
29
- assert_equal "puts('Hello, World!');", template.render
49
+ assert_not_match "(function() {", template.render
50
+ assert_equal "var name;\n\nname = \"Josh\";\n\nputs(\"Hello \" + name);\n", template.render
30
51
  end
31
52
 
32
- context "disabling coffee-script wrapper globally" do
53
+ context "wrapper globally enabled" do
33
54
  setup do
34
55
  @bare = Tilt::CoffeeScriptTemplate.default_bare
56
+ Tilt::CoffeeScriptTemplate.default_bare = false
35
57
  end
36
58
 
37
59
  teardown do
@@ -39,23 +61,54 @@ begin
39
61
  end
40
62
 
41
63
  test "no options" do
42
- template = Tilt::CoffeeScriptTemplate.new { |t| "puts 'Hello, World!'\n" }
43
- assert_match "puts('Hello, World!');", template.render
64
+ template = Tilt::CoffeeScriptTemplate.new { |t| 'name = "Josh"; puts "Hello, #{name}"' }
65
+ assert_match "puts(\"Hello, \" + name);", template.render
44
66
  assert_match "(function() {", template.render
45
67
  end
46
68
 
47
69
  test "overridden by :bare" do
48
- template = Tilt::CoffeeScriptTemplate.new(:bare => false) { "puts 'Hello, World!'\n" }
49
- assert_not_equal "puts('Hello, World!');", template.render
70
+ template = Tilt::CoffeeScriptTemplate.new(:bare => true) { |t| 'name = "Josh"; puts "Hello, #{name}"' }
71
+ assert_match "puts(\"Hello, \" + name);", template.render
72
+ assert_not_match "(function() {", template.render
50
73
  end
51
74
 
52
75
  test "overridden by :no_wrap" do
53
- template = Tilt::CoffeeScriptTemplate.new(:no_wrap => false) { "puts 'Hello, World!'\n" }
54
- assert_not_equal "puts('Hello, World!');", template.render
76
+ template = Tilt::CoffeeScriptTemplate.new(:no_wrap => true) { |t| 'name = "Josh"; puts "Hello, #{name}"' }
77
+ assert_match "puts(\"Hello, \" + name);", template.render
78
+ assert_not_match "(function() {", template.render
79
+ end
80
+ end
81
+
82
+ context "wrapper globally disabled" do
83
+ setup do
84
+ @bare = Tilt::CoffeeScriptTemplate.default_bare
85
+ Tilt::CoffeeScriptTemplate.default_bare = true
86
+ end
87
+
88
+ teardown do
89
+ Tilt::CoffeeScriptTemplate.default_bare = @bare
90
+ end
91
+
92
+ test "no options" do
93
+ template = Tilt::CoffeeScriptTemplate.new { |t| 'name = "Josh"; puts "Hello, #{name}"' }
94
+ assert_match "puts(\"Hello, \" + name);", template.render
95
+ assert_not_match "(function() {", template.render
96
+ end
97
+
98
+ test "overridden by :bare" do
99
+ template = Tilt::CoffeeScriptTemplate.new(:bare => false) { |t| 'name = "Josh"; puts "Hello, #{name}"' }
100
+ assert_match "puts(\"Hello, \" + name);", template.render
101
+ assert_match "(function() {", template.render
102
+ end
103
+
104
+ test "overridden by :no_wrap" do
105
+ template = Tilt::CoffeeScriptTemplate.new(:no_wrap => false) { |t| 'name = "Josh"; puts "Hello, #{name}"' }
106
+ assert_match "puts(\"Hello, \" + name);", template.render
107
+ assert_match "(function() {", template.render
55
108
  end
56
109
  end
57
110
  end
58
111
 
59
112
  rescue LoadError => boom
60
- warn "Tilt::CoffeeScriptTemplate (disabled)\n"
113
+ warn "Tilt::CoffeeScriptTemplate (disabled)"
61
114
  end
@@ -24,5 +24,5 @@ begin
24
24
  end
25
25
  end
26
26
  rescue LoadError => boom
27
- warn "Tilt::CreoleTemplate (disabled)\n"
27
+ warn "Tilt::CreoleTemplate (disabled)"
28
28
  end
@@ -0,0 +1,73 @@
1
+ require 'contest'
2
+ require 'tilt'
3
+
4
+ begin
5
+ if RUBY_VERSION >= '1.9.0'
6
+ require 'csv'
7
+ else
8
+ require 'fastercsv'
9
+ end
10
+
11
+ class CSVTemplateTest < Test::Unit::TestCase
12
+
13
+ test "is registered for '.csv' files" do
14
+ assert_equal Tilt::CSVTemplate, Tilt['test.csv']
15
+ end
16
+
17
+ test "registered for '.csv' files" do
18
+ assert Tilt.mappings['csv'].include?(Tilt::CSVTemplate)
19
+ end
20
+
21
+ test "compiles and evaluates the template on #render" do
22
+ template = Tilt::CSVTemplate.new { "csv << ['hello', 'world']" }
23
+ assert_equal "hello,world\n", template.render
24
+ end
25
+
26
+ test "can be rendered more than once" do
27
+ template = Tilt::CSVTemplate.new { "csv << [1,2,3]" }
28
+ 3.times { assert_equal "1,2,3\n", template.render }
29
+ end
30
+
31
+ test "can pass locals" do
32
+ template = Tilt::CSVTemplate.new { 'csv << [1, name]' }
33
+ assert_equal "1,Joe\n", template.render(Object.new, :name => 'Joe')
34
+ end
35
+
36
+ test "evaluating in an object scope" do
37
+ template = Tilt::CSVTemplate.new { 'csv << [1, @name]' }
38
+ scope = Object.new
39
+ scope.instance_variable_set :@name, 'Joe'
40
+ assert_equal "1,Joe\n", template.render(scope)
41
+ end
42
+
43
+ test "backtrace file and line reporting" do
44
+ data = File.read(__FILE__).split("\n__END__\n").last
45
+ template = Tilt::CSVTemplate.new('test.csv') { data }
46
+ begin
47
+ template.render
48
+ fail 'should have raised an exception'
49
+ rescue => boom
50
+ assert_kind_of NameError, boom
51
+ line = boom.backtrace.grep(/^test\.csv:/).first
52
+ assert line, "Backtrace didn't contain test.csv"
53
+ file, line, meth = line.split(":")
54
+ assert_equal '4', line
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ rescue LoadError => boom
61
+ warn "Tilt::CSVTemplate (disabled) please install 'fastercsv' if using ruby 1.8.x"
62
+ end
63
+
64
+
65
+ __END__
66
+ # header
67
+ csv << ['Type', 'Age']
68
+
69
+ raise NameError
70
+
71
+ # rows
72
+ csv << ['Frog', 2]
73
+ csv << ['Cat', 5]
@@ -89,6 +89,11 @@ class ERBTemplateTest < Test::Unit::TestCase
89
89
  end
90
90
  end
91
91
 
92
+ test "explicit disabling of trim mode" do
93
+ template = Tilt::ERBTemplate.new('test.erb', 1, :trim => false) { "\n<%= 1 + 1 %>\n" }
94
+ assert_equal "\n2\n", template.render
95
+ end
96
+
92
97
  test "default stripping trim mode" do
93
98
  template = Tilt::ERBTemplate.new('test.erb', 1) { "\n<%= 1 + 1 %>\n" }
94
99
  assert_equal "\n2", template.render
@@ -137,7 +137,7 @@ begin
137
137
  end
138
138
  end
139
139
  rescue LoadError => boom
140
- warn "Tilt::ErubisTemplate (disabled)\n"
140
+ warn "Tilt::ErubisTemplate (disabled)"
141
141
  end
142
142
 
143
143
  __END__
@@ -0,0 +1,173 @@
1
+ require 'contest'
2
+ require 'tilt'
3
+
4
+ class EtanniTemplateTest < Test::Unit::TestCase
5
+ test "registered for '.etn' files" do
6
+ assert_equal Tilt::EtanniTemplate, Tilt['test.etn']
7
+ end
8
+
9
+ test "registered for '.etanni' files" do
10
+ assert_equal Tilt::EtanniTemplate, Tilt['test.etanni']
11
+ end
12
+
13
+ test "loading and evaluating templates on #render" do
14
+ template = Tilt::EtanniTemplate.new { |t| "Hello World!" }
15
+ assert_equal "Hello World!", template.render
16
+ end
17
+
18
+ test "can be rendered more than once" do
19
+ template = Tilt::EtanniTemplate.new { |t| "Hello World!" }
20
+ 3.times { assert_equal "Hello World!", template.render }
21
+ end
22
+
23
+ test "passing locals" do
24
+ template = Tilt::EtanniTemplate.new { 'Hey #{name}!' }
25
+ assert_equal "Hey Joe!", template.render(Object.new, :name => 'Joe')
26
+ end
27
+
28
+ test "evaluating in an object scope" do
29
+ template = Tilt::EtanniTemplate.new { 'Hey #{@name}!' }
30
+ scope = Object.new
31
+ scope.instance_variable_set :@name, 'Joe'
32
+ assert_equal "Hey Joe!", template.render(scope)
33
+ end
34
+
35
+ test "passing a block for yield" do
36
+ template = Tilt::EtanniTemplate.new { 'Hey #{yield}!' }
37
+ assert_equal "Hey Joe!", template.render { 'Joe' }
38
+ assert_equal "Hey Moe!", template.render { 'Moe' }
39
+ end
40
+
41
+ test "multiline templates" do
42
+ template = Tilt::EtanniTemplate.new { "Hello\nWorld!\n" }
43
+ assert_equal "Hello\nWorld!", template.render
44
+ end
45
+
46
+ test "backtrace file and line reporting without locals" do
47
+ data = File.read(__FILE__).split("\n__END__\n").last
48
+ fail unless data[0] == ?<
49
+ template = Tilt::EtanniTemplate.new('test.etn', 11) { data }
50
+ begin
51
+ template.render
52
+ fail 'should have raised an exception'
53
+ rescue => boom
54
+ assert_kind_of NameError, boom
55
+ line = boom.backtrace.grep(/^test\.etn:/).first
56
+ assert line, "Backtrace didn't contain test.etn"
57
+ file, line, meth = line.split(":")
58
+ assert_equal '13', line
59
+ end
60
+ end
61
+
62
+ test "backtrace file and line reporting with locals" do
63
+ data = File.read(__FILE__).split("\n__END__\n").last
64
+ fail unless data[0] == ?<
65
+ template = Tilt::EtanniTemplate.new('test.etn', 1) { data }
66
+ begin
67
+ template.render(nil, :name => 'Joe', :foo => 'bar')
68
+ fail 'should have raised an exception'
69
+ rescue => boom
70
+ assert_kind_of RuntimeError, boom
71
+ line = boom.backtrace.first
72
+ file, line, meth = line.split(":")
73
+ assert_equal 'test.etn', file
74
+ assert_equal '6', line
75
+ end
76
+ end
77
+ end
78
+
79
+
80
+ class CompiledEtanniTemplateTest < Test::Unit::TestCase
81
+ def teardown
82
+ GC.start
83
+ end
84
+
85
+ class Scope
86
+ end
87
+
88
+ test "compiling template source to a method" do
89
+ template = Tilt::EtanniTemplate.new { |t| "Hello World!" }
90
+ template.render(Scope.new)
91
+ method = template.send(:compiled_method, [])
92
+ assert_kind_of UnboundMethod, method
93
+ end
94
+
95
+ test "loading and evaluating templates on #render" do
96
+ template = Tilt::EtanniTemplate.new { |t| "Hello World!" }
97
+ assert_equal "Hello World!", template.render(Scope.new)
98
+ end
99
+
100
+ test "passing locals" do
101
+ template = Tilt::EtanniTemplate.new { 'Hey #{name}!' }
102
+ assert_equal "Hey Joe!", template.render(Scope.new, :name => 'Joe')
103
+ assert_equal "Hey Moe!", template.render(Scope.new, :name => 'Moe')
104
+ end
105
+
106
+ test "evaluating in an object scope" do
107
+ template = Tilt::EtanniTemplate.new { 'Hey #{@name}!' }
108
+ scope = Scope.new
109
+ scope.instance_variable_set :@name, 'Joe'
110
+ assert_equal "Hey Joe!", template.render(scope)
111
+ scope.instance_variable_set :@name, 'Moe'
112
+ assert_equal "Hey Moe!", template.render(scope)
113
+ end
114
+
115
+ test "passing a block for yield" do
116
+ template = Tilt::EtanniTemplate.new { 'Hey #{yield}!' }
117
+ assert_equal "Hey Joe!", template.render(Scope.new) { 'Joe' }
118
+ assert_equal "Hey Moe!", template.render(Scope.new) { 'Moe' }
119
+ end
120
+
121
+ test "multiline templates" do
122
+ template = Tilt::EtanniTemplate.new { "Hello\nWorld!\n" }
123
+ assert_equal "Hello\nWorld!", template.render(Scope.new)
124
+ end
125
+
126
+ test "template with '}'" do
127
+ template = Tilt::EtanniTemplate.new { "Hello }" }
128
+ assert_equal "Hello }", template.render
129
+ end
130
+
131
+ test "backtrace file and line reporting without locals" do
132
+ data = File.read(__FILE__).split("\n__END__\n").last
133
+ fail unless data[0] == ?<
134
+ template = Tilt::EtanniTemplate.new('test.etn', 11) { data }
135
+ begin
136
+ template.render(Scope.new)
137
+ fail 'should have raised an exception'
138
+ rescue => boom
139
+ assert_kind_of NameError, boom
140
+ line = boom.backtrace.first
141
+ line = boom.backtrace.grep(/^test\.etn:/).first
142
+ assert line, "Backtrace didn't contain test.etn"
143
+ file, line, meth = line.split(":")
144
+ assert_equal '13', line
145
+ end
146
+ end
147
+
148
+ test "backtrace file and line reporting with locals" do
149
+ data = File.read(__FILE__).split("\n__END__\n").last
150
+ fail unless data[0] == ?<
151
+ template = Tilt::EtanniTemplate.new('test.etn') { data }
152
+ begin
153
+ template.render(Scope.new, :name => 'Joe', :foo => 'bar')
154
+ fail 'should have raised an exception'
155
+ rescue => boom
156
+ assert_kind_of RuntimeError, boom
157
+ line = boom.backtrace.first
158
+ file, line, meth = line.split(":")
159
+ assert_equal 'test.etn', file
160
+ assert_equal '6', line
161
+ end
162
+ end
163
+ end
164
+
165
+ __END__
166
+ <html>
167
+ <body>
168
+ <h1>Hey #{name}!</h1>
169
+
170
+
171
+ <p>#{fail}</p>
172
+ </body>
173
+ </html>