tilt 1.3.3 → 1.3.4

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.
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>