tilt 1.3.3 → 1.3.5

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 (54) hide show
  1. checksums.yaml +15 -0
  2. data/CHANGELOG.md +26 -0
  3. data/COPYING +1 -1
  4. data/Gemfile +31 -1
  5. data/HACKING +16 -0
  6. data/README.md +5 -2
  7. data/Rakefile +25 -1
  8. data/TEMPLATES.md +13 -13
  9. data/bin/tilt +8 -6
  10. data/lib/tilt/asciidoc.rb +34 -0
  11. data/lib/tilt/coffee.rb +4 -0
  12. data/lib/tilt/css.rb +10 -2
  13. data/lib/tilt/csv.rb +71 -0
  14. data/lib/tilt/erb.rb +1 -1
  15. data/lib/tilt/etanni.rb +27 -0
  16. data/lib/tilt/liquid.rb +4 -0
  17. data/lib/tilt/markdown.rb +35 -11
  18. data/lib/tilt/nokogiri.rb +4 -4
  19. data/lib/tilt/plain.rb +20 -0
  20. data/lib/tilt/radius.rb +4 -0
  21. data/lib/tilt/rdoc.rb +20 -5
  22. data/lib/tilt/template.rb +35 -74
  23. data/lib/tilt/textile.rb +5 -0
  24. data/lib/tilt/wiki.rb +8 -0
  25. data/lib/tilt.rb +15 -1
  26. data/test/tilt_asciidoctor_test.rb +44 -0
  27. data/test/tilt_blueclothtemplate_test.rb +1 -1
  28. data/test/tilt_coffeescripttemplate_test.rb +64 -11
  29. data/test/tilt_creoletemplate_test.rb +1 -1
  30. data/test/tilt_csv_test.rb +73 -0
  31. data/test/tilt_erbtemplate_test.rb +5 -0
  32. data/test/tilt_erubistemplate_test.rb +1 -1
  33. data/test/tilt_etannitemplate_test.rb +173 -0
  34. data/test/tilt_fallback_test.rb +6 -6
  35. data/test/tilt_hamltemplate_test.rb +1 -1
  36. data/test/tilt_kramdown_test.rb +1 -1
  37. data/test/tilt_lesstemplate_test.less +1 -0
  38. data/test/tilt_lesstemplate_test.rb +19 -3
  39. data/test/tilt_liquidtemplate_test.rb +1 -1
  40. data/test/tilt_markaby_test.rb +1 -1
  41. data/test/tilt_markdown_test.rb +15 -4
  42. data/test/tilt_marukutemplate_test.rb +1 -1
  43. data/test/tilt_radiustemplate_test.rb +1 -1
  44. data/test/tilt_rdiscounttemplate_test.rb +1 -1
  45. data/test/tilt_rdoctemplate_test.rb +10 -3
  46. data/test/tilt_redcarpettemplate_test.rb +15 -3
  47. data/test/tilt_redclothtemplate_test.rb +13 -1
  48. data/test/tilt_sasstemplate_test.rb +1 -1
  49. data/test/tilt_stringtemplate_test.rb +1 -1
  50. data/test/tilt_template_test.rb +14 -0
  51. data/test/tilt_wikiclothtemplate_test.rb +1 -1
  52. data/test/tilt_yajltemplate_test.rb +13 -4
  53. data/tilt.gemspec +28 -17
  54. metadata +182 -101
data/lib/tilt/rdoc.rb CHANGED
@@ -4,23 +4,34 @@ module Tilt
4
4
  # RDoc template. See:
5
5
  # http://rdoc.rubyforge.org/
6
6
  #
7
- # It's suggested that your program require 'rdoc/markup' and
8
- # 'rdoc/markup/to_html' at load time when using this template
9
- # engine.
7
+ # It's suggested that your program `require 'rdoc/markup'` and
8
+ # `require 'rdoc/markup/to_html'` at load time when using this template
9
+ # engine in a threaded environment.
10
10
  class RDocTemplate < Template
11
11
  self.default_mime_type = 'text/html'
12
12
 
13
13
  def self.engine_initialized?
14
- defined? ::RDoc::Markup
14
+ defined? ::RDoc::Markup::ToHtml
15
15
  end
16
16
 
17
17
  def initialize_engine
18
+ require_template_library 'rdoc'
18
19
  require_template_library 'rdoc/markup'
19
20
  require_template_library 'rdoc/markup/to_html'
20
21
  end
21
22
 
23
+ def markup
24
+ begin
25
+ # RDoc 4.0
26
+ require 'rdoc/options'
27
+ RDoc::Markup::ToHtml.new(RDoc::Options.new, nil)
28
+ rescue ArgumentError
29
+ # RDoc < 4.0
30
+ RDoc::Markup::ToHtml.new
31
+ end
32
+ end
33
+
22
34
  def prepare
23
- markup = RDoc::Markup::ToHtml.new
24
35
  @engine = markup.convert(data)
25
36
  @output = nil
26
37
  end
@@ -28,5 +39,9 @@ module Tilt
28
39
  def evaluate(scope, locals, &block)
29
40
  @output ||= @engine.to_s
30
41
  end
42
+
43
+ def allows_script?
44
+ false
45
+ end
31
46
  end
32
47
  end
data/lib/tilt/template.rb CHANGED
@@ -41,6 +41,7 @@ module Tilt
41
41
  [options, line, file].compact.each do |arg|
42
42
  case
43
43
  when arg.respond_to?(:to_str) ; @file = arg.to_str
44
+ when arg.respond_to?(:path) ; @file = arg.path
44
45
  when arg.respond_to?(:to_int) ; @line = arg.to_int
45
46
  when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup
46
47
  else raise TypeError
@@ -91,6 +92,15 @@ module Tilt
91
92
  file || '(__TEMPLATE__)'
92
93
  end
93
94
 
95
+ # Whether or not this template engine allows executing Ruby script
96
+ # within the template. If this is false, +scope+ and +locals+ will
97
+ # generally not be used, nor will the provided block be avaiable
98
+ # via +yield+.
99
+ # This should be overridden by template subclasses.
100
+ def allows_script?
101
+ true
102
+ end
103
+
94
104
  protected
95
105
  # Called once and only once for each template subclass the first time
96
106
  # the template class is initialized. This should be used to require the
@@ -98,7 +108,7 @@ module Tilt
98
108
  def initialize_engine
99
109
  end
100
110
 
101
- # Like Kernel::require but issues a warning urging a manual require when
111
+ # Like Kernel#require but issues a warning urging a manual require when
102
112
  # running under a threaded environment.
103
113
  def require_template_library(name)
104
114
  if Thread.list.size > 1
@@ -123,25 +133,15 @@ module Tilt
123
133
  end
124
134
  end
125
135
 
136
+ # Execute the compiled template and return the result string. Template
137
+ # evaluation is guaranteed to be performed in the scope object with the
138
+ # locals specified and with support for yielding to the block.
139
+ #
140
+ # This method is only used by source generating templates. Subclasses that
141
+ # override render() may not support all features.
126
142
  def evaluate(scope, locals, &block)
127
- cached_evaluate(scope, locals, &block)
128
- end
129
-
130
- # Process the template and return the result. The first time this
131
- # method is called, the template source is evaluated with instance_eval.
132
- # On the sequential method calls it will compile the template to an
133
- # unbound method which will lead to better performance. In any case,
134
- # template executation is guaranteed to be performed in the scope object
135
- # with the locals specified and with support for yielding to the block.
136
- def cached_evaluate(scope, locals, &block)
137
- # Redefine itself to use method compilation the next time:
138
- def self.cached_evaluate(scope, locals, &block)
139
- method = compiled_method(locals.keys)
140
- method.bind(scope).call(locals, &block)
141
- end
142
-
143
- # Use instance_eval the first time:
144
- evaluate_source(scope, locals, &block)
143
+ method = compiled_method(locals.keys)
144
+ method.bind(scope).call(locals, &block)
145
145
  end
146
146
 
147
147
  # Generates all template source by combining the preamble, template, and
@@ -186,7 +186,13 @@ module Tilt
186
186
  # source line offset, so adding code to the preamble does not effect line
187
187
  # reporting in Kernel::caller and backtraces.
188
188
  def precompiled_preamble(locals)
189
- locals.map { |k,v| "#{k} = locals[#{k.inspect}]" }.join("\n")
189
+ locals.map do |k,v|
190
+ if k.to_s =~ /\A[a-z_][a-zA-Z_0-9]*\z/
191
+ "#{k} = locals[#{k.inspect}]"
192
+ else
193
+ raise "invalid locals key: #{k.inspect} (keys must be variable names)"
194
+ end
195
+ end.join("\n")
190
196
  end
191
197
 
192
198
  # Generates postamble code for the precompiled template source. The
@@ -203,34 +209,10 @@ module Tilt
203
209
  end
204
210
 
205
211
  private
206
- # Evaluate the template source in the context of the scope object.
207
- def evaluate_source(scope, locals, &block)
208
- source, offset = precompiled(locals)
209
- scope.instance_eval(source, eval_file, line - offset)
210
- end
211
-
212
- # JRuby doesn't allow Object#instance_eval to yield to the block it's
213
- # closed over. This is by design and (ostensibly) something that will
214
- # change in MRI, though no current MRI version tested (1.8.6 - 1.9.2)
215
- # exhibits the behavior. More info here:
216
- #
217
- # http://jira.codehaus.org/browse/JRUBY-2599
218
- #
219
- # We redefine evaluate_source to work around this issues.
220
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
221
- undef evaluate_source
222
- def evaluate_source(scope, locals, &block)
223
- source, offset = precompiled(locals)
224
- file, lineno = eval_file, (line - offset)
225
- scope.instance_eval { Kernel::eval(source, binding, file, lineno) }
226
- end
227
- end
228
-
229
212
  def compile_template_method(locals)
230
213
  source, offset = precompiled(locals)
231
- offset += 5
232
214
  method_name = "__tilt_#{Thread.current.object_id.abs}"
233
- Object.class_eval <<-RUBY, eval_file, line - offset
215
+ method_source = <<-RUBY
234
216
  #{extract_magic_comment source}
235
217
  TOPOBJECT.class_eval do
236
218
  def #{method_name}(locals)
@@ -238,12 +220,11 @@ module Tilt
238
220
  class << self
239
221
  this, locals = Thread.current[:tilt_vars]
240
222
  this.instance_eval do
241
- #{source}
242
- end
243
- end
244
- end
245
- end
246
223
  RUBY
224
+ offset += method_source.count("\n")
225
+ method_source << source
226
+ method_source << "\nend;end;end;end"
227
+ Object.class_eval method_source, eval_file, line - offset
247
228
  unbind_compiled_method(method_name)
248
229
  end
249
230
 
@@ -255,30 +236,10 @@ module Tilt
255
236
 
256
237
  def extract_magic_comment(script)
257
238
  comment = script.slice(/\A[ \t]*\#.*coding\s*[=:]\s*([[:alnum:]\-_]+).*$/)
258
- return comment if comment and not %w[ascii-8bit binary].include?($1.downcase)
259
- "# coding: #{@default_encoding}" if @default_encoding
260
- end
261
-
262
- # Special case Ruby 1.9.1's broken yield.
263
- #
264
- # http://github.com/rtomayko/tilt/commit/20c01a5
265
- # http://redmine.ruby-lang.org/issues/show/3601
266
- #
267
- # Remove when 1.9.2 dominates 1.9.1 installs in the wild.
268
- if RUBY_VERSION =~ /^1.9.1/
269
- undef compile_template_method
270
- def compile_template_method(locals)
271
- source, offset = precompiled(locals)
272
- offset += 1
273
- method_name = "__tilt_#{Thread.current.object_id}"
274
- Object.class_eval <<-RUBY, eval_file, line - offset
275
- TOPOBJECT.class_eval do
276
- def #{method_name}(locals)
277
- #{source}
278
- end
279
- end
280
- RUBY
281
- unbind_compiled_method(method_name)
239
+ if comment && !%w[ascii-8bit binary].include?($1.downcase)
240
+ comment
241
+ elsif @default_encoding
242
+ "# coding: #{@default_encoding}"
282
243
  end
283
244
  end
284
245
  end
data/lib/tilt/textile.rb CHANGED
@@ -14,12 +14,17 @@ module Tilt
14
14
 
15
15
  def prepare
16
16
  @engine = RedCloth.new(data)
17
+ options.each {|k, v| @engine.send("#{k}=", v) if @engine.respond_to? "#{k}="}
17
18
  @output = nil
18
19
  end
19
20
 
20
21
  def evaluate(scope, locals, &block)
21
22
  @output ||= @engine.to_html
22
23
  end
24
+
25
+ def allows_script?
26
+ false
27
+ end
23
28
  end
24
29
  end
25
30
 
data/lib/tilt/wiki.rb CHANGED
@@ -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
data/lib/tilt.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Tilt
2
- VERSION = '1.3.3'
2
+ VERSION = '1.3.5'
3
3
 
4
4
  @preferred_mappings = Hash.new
5
5
  @template_mappings = Hash.new { |h, k| h[k] = [] }
@@ -142,6 +142,9 @@ module Tilt
142
142
  register ERBTemplate, 'erb', 'rhtml'
143
143
  register ErubisTemplate, 'erb', 'rhtml', 'erubis'
144
144
 
145
+ require 'tilt/etanni'
146
+ register EtanniTemplate, 'etn', 'etanni'
147
+
145
148
  require 'tilt/haml'
146
149
  register HamlTemplate, 'haml'
147
150
 
@@ -150,6 +153,9 @@ module Tilt
150
153
  register ScssTemplate, 'scss'
151
154
  register LessTemplate, 'less'
152
155
 
156
+ require 'tilt/csv'
157
+ register CSVTemplate, 'csv'
158
+
153
159
  require 'tilt/coffee'
154
160
  register CoffeeScriptTemplate, 'coffee'
155
161
 
@@ -173,6 +179,8 @@ module Tilt
173
179
  register KramdownTemplate, 'markdown', 'mkd', 'md'
174
180
  register BlueClothTemplate, 'markdown', 'mkd', 'md'
175
181
  register RDiscountTemplate, 'markdown', 'mkd', 'md'
182
+ register RedcarpetTemplate::Redcarpet1, 'markdown', 'mkd', 'md'
183
+ register RedcarpetTemplate::Redcarpet2, 'markdown', 'mkd', 'md'
176
184
  register RedcarpetTemplate, 'markdown', 'mkd', 'md'
177
185
 
178
186
  require 'tilt/textile'
@@ -187,4 +195,10 @@ module Tilt
187
195
 
188
196
  require 'tilt/yajl'
189
197
  register YajlTemplate, 'yajl'
198
+
199
+ require 'tilt/asciidoc'
200
+ register AsciidoctorTemplate, 'ad', 'adoc', 'asciidoc'
201
+
202
+ require 'tilt/plain'
203
+ register PlainTemplate, 'html'
190
204
  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__