haml 1.0.5 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (92) hide show
  1. data/README +229 -0
  2. data/Rakefile +56 -60
  3. data/VERSION +1 -1
  4. data/bin/haml +4 -14
  5. data/bin/html2haml +89 -0
  6. data/bin/sass +8 -0
  7. data/init.rb +5 -1
  8. data/lib/haml.rb +643 -0
  9. data/lib/haml/buffer.rb +33 -30
  10. data/lib/haml/engine.rb +258 -75
  11. data/lib/haml/error.rb +43 -0
  12. data/lib/haml/exec.rb +181 -0
  13. data/lib/haml/filters.rb +89 -0
  14. data/lib/haml/helpers.rb +19 -5
  15. data/lib/haml/helpers/action_view_mods.rb +28 -4
  16. data/lib/haml/template.rb +13 -27
  17. data/lib/sass.rb +418 -0
  18. data/lib/sass/constant.rb +190 -0
  19. data/lib/sass/constant/color.rb +77 -0
  20. data/lib/sass/constant/literal.rb +51 -0
  21. data/lib/sass/constant/number.rb +87 -0
  22. data/lib/sass/constant/operation.rb +30 -0
  23. data/lib/sass/constant/string.rb +18 -0
  24. data/lib/sass/engine.rb +179 -0
  25. data/lib/sass/error.rb +35 -0
  26. data/lib/sass/plugin.rb +119 -0
  27. data/lib/sass/tree/attr_node.rb +44 -0
  28. data/lib/sass/tree/node.rb +29 -0
  29. data/lib/sass/tree/rule_node.rb +47 -0
  30. data/lib/sass/tree/value_node.rb +12 -0
  31. data/test/benchmark.rb +16 -19
  32. data/test/haml/engine_test.rb +220 -0
  33. data/test/{helper_test.rb → haml/helper_test.rb} +9 -8
  34. data/test/{mocks → haml/mocks}/article.rb +0 -0
  35. data/test/{results → haml/results}/content_for_layout.xhtml +0 -0
  36. data/test/{results → haml/results}/eval_suppressed.xhtml +0 -0
  37. data/test/haml/results/filters.xhtml +57 -0
  38. data/test/{results → haml/results}/helpers.xhtml +10 -0
  39. data/test/haml/results/helpful.xhtml +8 -0
  40. data/test/{results → haml/results}/just_stuff.xhtml +5 -0
  41. data/test/{results → haml/results}/list.xhtml +0 -0
  42. data/test/{results → haml/results}/original_engine.xhtml +1 -1
  43. data/test/{results → haml/results}/partials.xhtml +0 -0
  44. data/test/{results → haml/results}/silent_script.xhtml +0 -0
  45. data/test/{results → haml/results}/standard.xhtml +2 -1
  46. data/test/{results → haml/results}/tag_parsing.xhtml +0 -0
  47. data/test/{results → haml/results}/very_basic.xhtml +0 -0
  48. data/test/haml/results/whitespace_handling.xhtml +104 -0
  49. data/test/{rhtml → haml/rhtml}/standard.rhtml +4 -1
  50. data/test/{runner.rb → haml/runner.rb} +1 -1
  51. data/test/{template_test.rb → haml/template_test.rb} +28 -23
  52. data/test/{templates → haml/templates}/_partial.haml +0 -0
  53. data/test/{templates → haml/templates}/_text_area.haml +0 -0
  54. data/test/haml/templates/breakage.haml +8 -0
  55. data/test/{templates → haml/templates}/content_for_layout.haml +0 -0
  56. data/test/{templates → haml/templates}/eval_suppressed.haml +0 -0
  57. data/test/haml/templates/filters.haml +53 -0
  58. data/test/{templates → haml/templates}/helpers.haml +10 -1
  59. data/test/{templates → haml/templates}/helpful.haml +3 -0
  60. data/test/{templates → haml/templates}/just_stuff.haml +7 -0
  61. data/test/{templates → haml/templates}/list.haml +0 -0
  62. data/test/haml/templates/original_engine.haml +17 -0
  63. data/test/{templates → haml/templates}/partialize.haml +0 -0
  64. data/test/{templates → haml/templates}/partials.haml +0 -0
  65. data/test/{templates → haml/templates}/silent_script.haml +0 -0
  66. data/test/{templates → haml/templates}/standard.haml +3 -1
  67. data/test/{templates → haml/templates}/tag_parsing.haml +0 -0
  68. data/test/{templates → haml/templates}/very_basic.haml +0 -0
  69. data/test/haml/templates/whitespace_handling.haml +137 -0
  70. data/test/profile.rb +36 -18
  71. data/test/sass/engine_test.rb +87 -0
  72. data/test/sass/plugin_test.rb +103 -0
  73. data/test/sass/results/basic.css +9 -0
  74. data/test/sass/results/compact.css +5 -0
  75. data/test/sass/results/complex.css +86 -0
  76. data/test/sass/results/constants.css +12 -0
  77. data/test/sass/results/expanded.css +18 -0
  78. data/test/sass/results/nested.css +14 -0
  79. data/test/sass/templates/basic.sass +23 -0
  80. data/test/sass/templates/bork.sass +2 -0
  81. data/test/sass/templates/compact.sass +15 -0
  82. data/test/sass/templates/complex.sass +291 -0
  83. data/test/sass/templates/constants.sass +80 -0
  84. data/test/sass/templates/expanded.sass +15 -0
  85. data/test/sass/templates/nested.sass +15 -0
  86. metadata +98 -48
  87. data/REFERENCE +0 -662
  88. data/test/engine_test.rb +0 -93
  89. data/test/results/helpful.xhtml +0 -5
  90. data/test/results/whitespace_handling.xhtml +0 -51
  91. data/test/templates/original_engine.haml +0 -17
  92. data/test/templates/whitespace_handling.haml +0 -66
@@ -0,0 +1,35 @@
1
+ module Sass
2
+ # Sass::SyntaxError encapsulates information about the exception,
3
+ # such as the line of the Sass template it was raised on
4
+ # and the Sass file that was being parsed (if applicable).
5
+ # It also provides a handy way to rescue only exceptions raised
6
+ # because of a faulty template.
7
+ class SyntaxError < StandardError
8
+ # The line of the Sass template on which the exception was thrown.
9
+ attr_accessor :sass_line
10
+
11
+ # The name of the file that was being parsed when the exception was raised.
12
+ # This will be nil unless Sass is being used as an ActionView plugin.
13
+ attr_reader :sass_filename
14
+
15
+ # Creates a new SyntaxError.
16
+ # +lineno+ should be the line of the Sass template on which the error occurred.
17
+ def initialize(msg, lineno = nil)
18
+ @message = msg
19
+ @sass_line = lineno
20
+ end
21
+
22
+ # Adds a properly formatted entry to the exception's backtrace.
23
+ # +filename+ should be the file in which the error occurred,
24
+ # if applicable (defaults to "(sass)").
25
+ def add_backtrace_entry(filename) # :nodoc:
26
+ @sass_filename = filename
27
+ self.backtrace ||= []
28
+ self.backtrace.unshift "#{filename || '(sass)'}:#{@sass_line}"
29
+ end
30
+
31
+ def to_s # :nodoc:
32
+ @message
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,119 @@
1
+ require 'sass/engine'
2
+ require 'rubygems'
3
+ require 'action_controller'
4
+
5
+ RAILS_ROOT = '. 'unless self.class.const_defined?('RAILS_ROOT')
6
+ RAILS_ENV = 'production' unless self.class.const_defined?('RAILS_ENV')
7
+
8
+ module Sass
9
+ # This module contains methods that ActionController calls
10
+ # to automatically update Sass templates that need updating.
11
+ # It wasn't designed to be used outside of the context of ActionController.
12
+ module Plugin
13
+ class << self
14
+ @@options = {
15
+ :template_location => RAILS_ROOT + '/public/stylesheets/sass',
16
+ :css_location => RAILS_ROOT + '/public/stylesheets',
17
+ :always_update => false,
18
+ :always_check => RAILS_ENV != "production"
19
+ }
20
+
21
+ # Gets various options for Sass. See README for details.
22
+ #--
23
+ # TODO: *DOCUMENT OPTIONS*
24
+ #++
25
+ def options
26
+ @@options
27
+ end
28
+
29
+ # Sets various options for Sass.
30
+ def options=(value)
31
+ @@options.merge!(value)
32
+ end
33
+
34
+ # Checks each stylesheet in <tt>options[:css_location]</tt>
35
+ # to see if it needs updating,
36
+ # and updates it using the corresponding template
37
+ # from <tt>options[:templates]</tt>
38
+ # if it does.
39
+ def update_stylesheets
40
+ Dir[options[:template_location] + '/*.sass'].each do |file|
41
+ name = File.basename(file)[0...-5]
42
+
43
+ if options[:always_update] || stylesheet_needs_update?(name)
44
+ css = css_filename(name)
45
+ File.delete(css) if File.exists?(css)
46
+
47
+ filename = template_filename(name)
48
+ l_options = @@options.dup
49
+ l_options[:filename] = filename
50
+ engine = Engine.new(File.read(filename), l_options)
51
+ begin
52
+ result = engine.render
53
+ rescue Exception => e
54
+ if RAILS_ENV != "production"
55
+ e_string = "#{e.class}: #{e.message}"
56
+
57
+ if e.is_a? Sass::SyntaxError
58
+ e_string << "\non line #{e.sass_line}"
59
+
60
+ if e.sass_filename
61
+ e_string << " of #{e.sass_filename}"
62
+
63
+ if File.exists?(e.sass_filename)
64
+ e_string << "\n\n"
65
+
66
+ min = [e.sass_line - 5, 0].max
67
+ File.read(e.sass_filename).rstrip.split("\n")[
68
+ min .. e.sass_line + 5
69
+ ].each_with_index do |line, i|
70
+ e_string << "#{min + i + 1}: #{line}\n"
71
+ end
72
+ end
73
+ end
74
+ end
75
+ result = "/*\n#{e_string}\n\nBacktrace:\n#{e.backtrace.join("\n")}\n*/"
76
+ else
77
+ result = "/* Internal stylesheet error */"
78
+ end
79
+ end
80
+
81
+ Dir.mkdir(l_options[:css_location]) unless File.exist?(l_options[:css_location])
82
+ File.open(css, 'w') do |file|
83
+ file.print(result)
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ private
90
+
91
+ def template_filename(name)
92
+ "#{@@options[:template_location]}/#{name}.sass"
93
+ end
94
+
95
+ def css_filename(name)
96
+ "#{@@options[:css_location]}/#{name}.css"
97
+ end
98
+
99
+ def stylesheet_needs_update?(name)
100
+ !File.exists?(css_filename(name)) || (File.mtime(template_filename(name)) - 2) > File.mtime(css_filename(name))
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ # This module refers to the ActionController module that's part of Ruby on Rails.
107
+ # Sass can be used as an alternate templating engine for Rails,
108
+ # and includes some modifications to make this more doable.
109
+ # The documentation can be found
110
+ # here[http://rubyonrails.org/api/classes/ActionController/Base.html].
111
+ module ActionController
112
+ class Base # :nodoc:
113
+ alias_method :sass_old_process, :process
114
+ def process(*args)
115
+ Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
116
+ sass_old_process(*args)
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,44 @@
1
+ require 'sass/tree/node'
2
+
3
+ module Sass::Tree
4
+ class AttrNode < ValueNode
5
+ attr_accessor :name
6
+
7
+ def initialize(name, value, style)
8
+ @name = name
9
+ super(value, style)
10
+ end
11
+
12
+ def to_s(parent_name = nil)
13
+ if name[-1] == ?: || value[-1] == ?;
14
+ raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump} (This isn't CSS!)", @line)
15
+ end
16
+ real_name = name
17
+ real_name = "#{parent_name}-#{real_name}" if parent_name
18
+ if children.size > 0
19
+ to_return = String.new
20
+ children.each do |kid|
21
+ if @style == :compact
22
+ to_return << "#{kid.to_s(real_name)} "
23
+ else
24
+ to_return << "#{kid.to_s(real_name)}\n"
25
+ end
26
+ end
27
+ to_return << "\n" unless @style == :compact
28
+ to_return[0...-1]
29
+ else
30
+ if value.length < 1
31
+ raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump}", @line)
32
+ end
33
+
34
+ "#{real_name}: #{value};"
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def declaration
41
+ ":#{name} #{value}"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ module Sass
2
+ module Tree
3
+ class Node
4
+ attr_accessor :children
5
+ attr_accessor :line
6
+
7
+ def initialize(style)
8
+ @style = style
9
+ @children = []
10
+ end
11
+
12
+ def <<(child)
13
+ @children << child
14
+ end
15
+
16
+ def to_s
17
+ result = String.new
18
+ children.each do |child|
19
+ if child.is_a? AttrNode
20
+ raise SyntaxError.new('Attributes aren\'t allowed at the root of a document.', child.line)
21
+ end
22
+
23
+ result += "#{child.to_s(1)}\n"
24
+ end
25
+ result[0...-1]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,47 @@
1
+ require 'sass/tree/node'
2
+ require 'sass/tree/attr_node'
3
+
4
+ module Sass::Tree
5
+ class RuleNode < ValueNode
6
+ alias_method :rule, :value
7
+ alias_method :rule=, :value=
8
+
9
+ def to_s(tabs, super_rules = nil)
10
+ attributes = []
11
+ sub_rules = []
12
+ total_rule = if super_rules
13
+ super_rules.split(/,\s*/).collect! do |s|
14
+ self.rule.split(/,\s*/).collect! {|r| "#{s} #{r}"}.join(", ")
15
+ end.join(", ")
16
+ else
17
+ self.rule
18
+ end
19
+
20
+ children.each do |child|
21
+ if child.is_a? AttrNode
22
+ attributes << child
23
+ else
24
+ sub_rules << child
25
+ end
26
+ end
27
+
28
+ to_return = ''
29
+ unless attributes.empty?
30
+ if @style == :compact
31
+ to_return << "#{total_rule} { #{attributes.join(' ')} }\n"
32
+ else
33
+ spaces = (@style == :expanded ? 2 : tabs * 2)
34
+ old_spaces = ' ' * (spaces - 2)
35
+ spaces = ' ' * spaces
36
+
37
+ attributes = attributes.join("\n").gsub("\n", "\n#{spaces}").rstrip
38
+ end_attrs = (@style == :expanded ? "\n" : ' ')
39
+ to_return << "#{old_spaces}#{total_rule} {\n#{spaces}#{attributes}#{end_attrs}}\n"
40
+ end
41
+ end
42
+
43
+ sub_rules.each { |sub| to_return << sub.to_s(tabs + 1, total_rule) }
44
+ to_return
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,12 @@
1
+ require 'sass/tree/node'
2
+
3
+ module Sass::Tree
4
+ class ValueNode < Node
5
+ attr_accessor :value
6
+
7
+ def initialize(value, style)
8
+ @value = value
9
+ super(style)
10
+ end
11
+ end
12
+ end
@@ -1,4 +1,6 @@
1
- require File.dirname(__FILE__) + '/../lib/haml/template'
1
+ require File.dirname(__FILE__) + '/../lib/haml'
2
+ require 'haml/template'
3
+ require 'sass/engine'
2
4
  require 'rubygems'
3
5
  require 'active_support'
4
6
  require 'action_view'
@@ -19,26 +21,15 @@ module Haml
19
21
  end
20
22
  end
21
23
 
22
- # Benchmarks HAML against ERb. If <tt>template_name</tt> is specified,
23
- # looks for a haml template in ./templates and an rhtml template in
24
- # ./rhtml with the name <tt>template_name</tt>. Otherwise, uses
25
- # <tt>haml_template</tt> and <tt>rhtml_template</tt> as the location of
26
- # the templates.
24
+ # Benchmarks haml against ERb, and Sass on its own.
27
25
  #
28
26
  # Returns the results of the benchmarking as a string.
29
27
  #
30
- # :call-seq:
31
- # benchmark(runs = 100, template_name = 'standard')
32
- # benchmark(runs = 100, haml_template, rhtml_template)
33
- #
34
- def benchmark(runs = 100, template_name = 'standard', other_template = nil)
35
- if other_template.nil?
36
- haml_template = "templates/#{template_name}"
37
- rhtml_template = "rhtml/#{template_name}"
38
- else
39
- haml_template = template_name
40
- rhtml_template = other_template
41
- end
28
+ def benchmark(runs = 100)
29
+ template_name = 'standard'
30
+ haml_template = "haml/templates/#{template_name}"
31
+ rhtml_template = "haml/rhtml/#{template_name}"
32
+ sass_template = File.dirname(__FILE__) + "/sass/templates/complex.sass"
42
33
 
43
34
  old_stdout = $stdout
44
35
  $stdout = StringIO.new
@@ -48,10 +39,16 @@ module Haml
48
39
  b.report("erb:") { runs.times { @base.render rhtml_template } }
49
40
  end
50
41
 
51
- #puts times.inspect
42
+ #puts times[0].inspect, times[1].inspect
52
43
  ratio = sprintf("%g", times[0].to_a[5] / times[1].to_a[5])
53
44
  puts "Haml/ERB: " + ratio
54
45
 
46
+ puts '', '-' * 50, 'Sass on its own', '-' * 50
47
+
48
+ Benchmark.bmbm do |b|
49
+ b.report("sass:") { runs.times { Sass::Engine.new(File.read(sass_template)).render } }
50
+ end
51
+
55
52
  $stdout.pos = 0
56
53
  to_return = $stdout.read
57
54
  $stdout = old_stdout
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require File.dirname(__FILE__) + '/../../lib/haml'
5
+ require 'haml/engine'
6
+
7
+ class EngineTest < Test::Unit::TestCase
8
+
9
+ def render(text, options = {})
10
+ Haml::Engine.new(text, options).to_html
11
+ end
12
+
13
+ def test_empty_render_should_remain_empty
14
+ assert_equal('', render(''))
15
+ end
16
+
17
+ # This is ugly because Hashes are unordered; we don't always know the order
18
+ # in which attributes will be returned.
19
+ # There is probably a better way to do this.
20
+ def test_attributes_should_render_correctly
21
+ assert_equal("<div class='atlantis' style='ugly'>\n</div>", render(".atlantis{:style => 'ugly'}").chomp)
22
+ rescue
23
+ assert_equal("<div style='ugly' class='atlantis'>\n</div>", render(".atlantis{:style => 'ugly'}").chomp)
24
+ end
25
+
26
+ def test_ruby_code_should_work_inside_attributes
27
+ author = 'hcatlin'
28
+ assert_equal("<p class='3'>foo</p>", render("%p{:class => 1+2} foo").chomp)
29
+ end
30
+
31
+ def test_nil_should_render_empty_tag
32
+ assert_equal("<div class='no_attributes'>\n</div>",
33
+ render(".no_attributes{:nil => nil}").chomp)
34
+ end
35
+
36
+ def test_strings_should_get_stripped_inside_tags
37
+ assert_equal("<div class='stripped'>This should have no spaces in front of it</div>",
38
+ render(".stripped This should have no spaces in front of it").chomp)
39
+ end
40
+
41
+ def test_one_liner_should_be_one_line
42
+ assert_equal("<p>Hello</p>", render('%p Hello').chomp)
43
+ end
44
+
45
+ def test_long_liner_should_not_print_on_one_line
46
+ assert_equal("<div>\n #{'x' * 51}\n</div>", render("%div #{'x' * 51}").chomp)
47
+ end
48
+
49
+ def test_multi_render
50
+ engine = Haml::Engine.new("%strong Hi there!")
51
+ assert_equal("<strong>Hi there!</strong>\n", engine.to_html)
52
+ assert_equal("<strong>Hi there!</strong>\n", engine.to_html)
53
+ assert_equal("<strong>Hi there!</strong>\n", engine.to_html)
54
+ end
55
+
56
+ # Options tests
57
+
58
+ def test_stop_eval
59
+ assert_equal("", render("= 'Hello'", :suppress_eval => true))
60
+ end
61
+
62
+ def test_attr_wrapper
63
+ assert_equal("<p strange=*attrs*>\n</p>\n", render("%p{ :strange => 'attrs'}", :attr_wrapper => '*'))
64
+ assert_equal("<p escaped='quo\"te'>\n</p>\n", render("%p{ :escaped => 'quo\"te'}", :attr_wrapper => '"'))
65
+ assert_equal("<p escaped=\"q'uo&quot;te\">\n</p>\n", render("%p{ :escaped => 'q\\'uo\"te'}", :attr_wrapper => '"'))
66
+ assert_equal("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n", render("!!! XML", :attr_wrapper => '"'))
67
+ end
68
+
69
+ def test_locals
70
+ assert_equal("<p>Paragraph!</p>\n", render("%p= text", :locals => { :text => "Paragraph!" }))
71
+ end
72
+
73
+ def test_precompiled
74
+ precompiled = <<-END
75
+ def _haml_render
76
+ _hamlout = @haml_stack[-1]
77
+ _erbout = _hamlout.buffer
78
+
79
+ _hamlout.open_tag("p", 0, nil, true, "", nil, nil, false)
80
+ @haml_lineno = 1
81
+ haml_temp = "Haml Rocks Socks"
82
+ haml_temp = _hamlout.push_script(haml_temp, 1, false)
83
+ _hamlout.close_tag("p", 0)
84
+ end
85
+ END
86
+
87
+ assert_equal("<p>Haml Rocks Socks</p>\n", render("%h1 I shall not be rendered", :precompiled => precompiled))
88
+ end
89
+
90
+ def test_comps
91
+ assert_equal(-1, "foo" <=> nil)
92
+ assert_equal(1, nil <=> "foo")
93
+ end
94
+
95
+ def test_rec_merge
96
+ hash1 = {1=>2, 3=>{5=>7, 8=>9}}
97
+ hash1_2 = hash1.clone
98
+ hash2 = {4=>5, 3=>{5=>2, 16=>12}}
99
+ hash3 = {1=>2, 4=>5, 3=>{5=>2, 8=>9, 16=>12}}
100
+
101
+ assert_equal(hash3, hash1.rec_merge(hash2))
102
+ assert_equal(hash1_2, hash1)
103
+ hash1.rec_merge!(hash2)
104
+ assert_equal(hash3, hash1)
105
+ end
106
+
107
+ def test_exception_type
108
+ begin
109
+ render("%p hi\n= undefined")
110
+ rescue Exception => e
111
+ assert(e.is_a?(Haml::Error))
112
+ assert_equal(2, e.haml_line)
113
+ assert_equal(nil, e.haml_filename)
114
+ assert_equal('(haml):2', e.backtrace[0])
115
+ else
116
+ # Test failed... should have raised an exception
117
+ assert(false)
118
+ end
119
+ end
120
+
121
+ def test_syntax_errors
122
+ errs = [ "!!!\n a", "a\n b", "a\n:foo\nb", "/ a\n b",
123
+ "% a", "%p a\n b", "a\n%p=\nb", "%p=\n a",
124
+ "a\n%p~\nb", "a\n~\nb", "%p/\n a", "%p\n \t%a b",
125
+ "%a\n b\nc", "%a\n b\nc",
126
+ ":notafilter\n This isn't\n a filter!",
127
+ ]
128
+ errs.each do |err|
129
+ begin
130
+ render(err)
131
+ rescue Exception => e
132
+ assert(e.is_a?(Haml::Error),
133
+ "#{err.dump} doesn't produce Haml::SyntaxError!")
134
+ else
135
+ assert(false,
136
+ "#{err.dump} doesn't produce an exception!")
137
+ end
138
+ end
139
+ end
140
+
141
+ def test_compile_error
142
+ begin
143
+ render("a\nb\n- fee do\nc")
144
+ rescue Exception => e
145
+ assert_equal(3, e.haml_line)
146
+ else
147
+ assert(false,
148
+ '"a\nb\n- fee do\nc" doesn\'t produce an exception!')
149
+ end
150
+ end
151
+
152
+ def test_no_bluecloth
153
+ old_markdown = false
154
+ if defined?(Haml::Filters::Markdown)
155
+ old_markdown = Haml::Filters::Markdown
156
+ end
157
+
158
+ Kernel.module_eval do
159
+ alias_method :haml_old_require, :gem_original_require
160
+
161
+ def gem_original_require(file)
162
+ raise LoadError if file == 'bluecloth'
163
+ haml_old_require(file)
164
+ end
165
+ end
166
+
167
+ if old_markdown
168
+ Haml::Filters.instance_eval do
169
+ remove_const 'Markdown'
170
+ end
171
+ end
172
+
173
+ # This is purposefully redundant, so it doesn't stop
174
+ # haml/filters from being required later on.
175
+ require 'haml/../haml/filters'
176
+
177
+ assert_equal("<h1>Foo</h1>\t<p>- a\n- b</p>\n",
178
+ Haml::Engine.new(":markdown\n Foo\n ===\n - a\n - b").to_html)
179
+
180
+ Haml::Filters.instance_eval do
181
+ remove_const 'Markdown'
182
+ end
183
+
184
+ Haml::Filters.const_set('Markdown', old_markdown) if old_markdown
185
+
186
+ Kernel.module_eval do
187
+ alias_method :gem_original_require, :haml_old_require
188
+ end
189
+
190
+ NOT_LOADED.delete 'bluecloth'
191
+ end
192
+
193
+ def test_no_redcloth
194
+ Kernel.module_eval do
195
+ alias_method :haml_old_require2, :gem_original_require
196
+
197
+ def gem_original_require(file)
198
+ raise LoadError if file == 'redcloth'
199
+ haml_old_require2(file)
200
+ end
201
+ end
202
+
203
+ # This is purposefully redundant, so it doesn't stop
204
+ # haml/filters from being required later on.
205
+ require 'haml/../haml/../haml/filters'
206
+
207
+ begin
208
+ Haml::Engine.new(":redcloth\n _foo_").to_html
209
+ rescue Haml::HamlError
210
+ else
211
+ assert(false, "No exception raised!")
212
+ end
213
+
214
+ Kernel.module_eval do
215
+ alias_method :gem_original_require2, :haml_old_require
216
+ end
217
+
218
+ NOT_LOADED.delete 'redcloth'
219
+ end
220
+ end