haml 2.2.5 → 2.2.6

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.

data/Rakefile CHANGED
@@ -25,6 +25,7 @@ Rake::TestTask.new do |t|
25
25
  t.libs << 'lib'
26
26
  test_files = FileList['test/**/*_test.rb']
27
27
  test_files.exclude('test/rails/*')
28
+ test_files.exclude('test/haml/spec/*')
28
29
  t.test_files = test_files
29
30
  t.verbose = true
30
31
  end
@@ -69,11 +70,10 @@ task :install => [:package] do
69
70
  sh %{#{sudo} #{gem} install --no-ri pkg/haml-#{File.read('VERSION').strip}}
70
71
  end
71
72
 
72
- desc "Release a new Haml package to Rubyforge. Requires the NAME and VERSION flags."
73
- task :release => [:package] do
73
+ desc "Release a new Haml package to Rubyforge."
74
+ task :release => [:check_release, :release_elpa, :package] do
74
75
  name = File.read("VERSION_NAME").strip
75
76
  version = File.read("VERSION").strip
76
- raise "VERSION_NAME must not be 'Bleeding Edge'" if name == "Bleeding Edge"
77
77
  sh %{rubyforge login}
78
78
  sh %{rubyforge add_release haml haml "#{name} (v#{version})" pkg/haml-#{version}.gem}
79
79
  sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.gz}
@@ -81,6 +81,87 @@ task :release => [:package] do
81
81
  sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.zip}
82
82
  end
83
83
 
84
+ # Releases haml-mode.el and sass-mode.el to ELPA.
85
+ task :release_elpa do
86
+ require 'tlsmail'
87
+ require 'time'
88
+
89
+ version = File.read("VERSION").strip
90
+
91
+ haml_unchanged = mode_unchanged?(:haml, version)
92
+ sass_unchanged = mode_unchanged?(:sass, version)
93
+ next if haml_unchanged && sass_unchanged
94
+ raise "haml-mode.el and sass-mode.el are out of sync." if haml_unchanged ^ sass_unchanged
95
+
96
+ rev = File.read('.git/HEAD').strip
97
+ if rev =~ /^ref: (.*)$/
98
+ rev = File.read(".git/#{$1}").strip
99
+ end
100
+
101
+ from = `git config user.email`.strip
102
+ raise "Don't know how to send emails except via Gmail" unless from =~ /@gmail.com$/
103
+
104
+ to = "elpa@tromey.com"
105
+ Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
106
+ Net::SMTP.start('smtp.gmail.com', 587, 'gmail.com', from, read_password("GMail Password"), :login) do |smtp|
107
+ smtp.send_message(<<CONTENT, from, to)
108
+ From: Nathan Weizenbaum <#{from}>
109
+ To: #{to}
110
+ Subject: Submitting haml-mode and sass-mode #{version}
111
+ Date: #{Time.now.rfc2822}
112
+
113
+ haml-mode and sass-mode #{version} are packaged and ready to be included in ELPA.
114
+ They can be downloaded from:
115
+
116
+ http://github.com/nex3/haml/raw/#{rev}/extra/haml-mode.el
117
+ http://github.com/nex3/haml/raw/#{rev}/extra/sass-mode.el
118
+ CONTENT
119
+ end
120
+ end
121
+
122
+ # Ensures that the version have been updated for a new release.
123
+ task :check_release do
124
+ version = File.read("VERSION").strip
125
+ raise "There have been changes since current version (#{version})" if changed_since?(version)
126
+ raise "VERSION_NAME must not be 'Bleeding Edge'" if File.read("VERSION_NAME") == "Bleeding Edge"
127
+ end
128
+
129
+ # Reads a password from the command line.
130
+ #
131
+ # @param name [String] The prompt to use to read the password
132
+ def read_password(prompt)
133
+ require 'readline'
134
+ system "stty -echo"
135
+ Readline.readline("#{prompt}: ").strip
136
+ ensure
137
+ system "stty echo"
138
+ puts
139
+ end
140
+
141
+ # Returns whether or not the repository, or specific files,
142
+ # has/have changed since a given revision.
143
+ #
144
+ # @param rev [String] The revision to check against
145
+ # @param files [Array<String>] The files to check.
146
+ # If this is empty, checks the entire repository
147
+ def changed_since?(rev, *files)
148
+ IO.popen("git diff --exit-code #{rev} #{files.join(' ')}") {}
149
+ return !$?.success?
150
+ end
151
+
152
+ # Returns whether or not the given Emacs mode file (haml or sass)
153
+ # has changed since the given version.
154
+ #
155
+ # @param mode [String, Symbol] The name of the mode
156
+ # @param version [String] The version number
157
+ def mode_unchanged?(mode, version)
158
+ mode_version = File.read("extra/#{mode}-mode.el").scan(/^;; Version: (.*)$/).first.first
159
+ return false if mode_version == version
160
+ return true unless changed_since?(mode_version, "extra/#{mode}-mode.el")
161
+ raise "#{mode}-mode.el version is #{version.inspect}, but it has changed as of #{version.inspect}"
162
+ return false
163
+ end
164
+
84
165
  task :release_edge do
85
166
  ensure_git_cleanup do
86
167
  puts "#{'=' * 50} Running rake release_edge"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.5
1
+ 2.2.6
@@ -4,8 +4,10 @@
4
4
 
5
5
  ;; Author: Nathan Weizenbaum
6
6
  ;; URL: http://github.com/nex3/haml/tree/master
7
- ;; Version: 1.0
8
- ;; Keywords: markup, language
7
+ ;; Version: 2.2.6
8
+ ;; Created: 2007-03-08
9
+ ;; By: Nathan Weizenbaum
10
+ ;; Keywords: markup, language, html
9
11
 
10
12
  ;;; Commentary:
11
13
 
@@ -41,9 +43,9 @@
41
43
  :group 'haml)
42
44
 
43
45
  (defcustom haml-backspace-backdents-nesting t
44
- "Non-nil to have `haml-electric-backspace' re-indent all code
45
- nested beneath the backspaced line be re-indented along with the
46
- line itself."
46
+ "Non-nil to have `haml-electric-backspace' re-indent blocks of code.
47
+ This means that all code nested beneath the backspaced line is
48
+ re-indented along with the line itself."
47
49
  :type 'boolean
48
50
  :group 'haml)
49
51
 
@@ -55,7 +57,8 @@ line itself."
55
57
  :group 'haml)
56
58
 
57
59
  (defvar haml-indent-function 'haml-indent-p
58
- "This function should look at the current line and return t
60
+ "A function for checking if nesting is allowed.
61
+ This function should look at the current line and return t
59
62
  if the next line could be nested within this line.
60
63
 
61
64
  The function can also return a positive integer to indicate
@@ -75,12 +78,15 @@ a specific level to which the current line could be indented.")
75
78
  "^ */\\(\\[.*\\]\\)?[ \t]*$"
76
79
  "^ *-#"
77
80
  "^ *:")
78
- "A list of regexps that match lines of Haml that could have
79
- text nested beneath them.")
81
+ "A list of regexps that match lines of Haml that open blocks.
82
+ That is, a Haml line that can have text nested beneath it should
83
+ be matched by a regexp in this list.")
80
84
 
81
85
  ;; Font lock
82
86
 
83
87
  (defun haml-nested-regexp (re)
88
+ "Create a regexp to match a block starting with RE.
89
+ The line containing RE is matched, as well as all lines indented beneath it."
84
90
  (concat "^\\( *\\)" re "\\(\n\\(?:\\(?:\\1 .*\\| *\\)\n\\)*\\(?:\\1 .*\\| *\\)?\\)?"))
85
91
 
86
92
  (defconst haml-font-lock-keywords
@@ -110,12 +116,14 @@ text nested beneath them.")
110
116
  (font-lock-fontify-region (- beg 1) end)))))
111
117
 
112
118
  (defun haml-highlight-ruby-script (limit)
113
- "Highlight a Ruby script expression (-, =, or ~)."
119
+ "Highlight a Ruby script expression (-, =, or ~).
120
+ LIMIT works as it does in `re-search-forward'."
114
121
  (when (re-search-forward "^ *\\(-\\|[&!]?[=~]\\) \\(.*\\)$" limit t)
115
122
  (haml-fontify-region-as-ruby (match-beginning 2) (match-end 2))))
116
123
 
117
124
  (defun haml-highlight-ruby-tag (limit)
118
125
  "Highlight Ruby code within a Haml tag.
126
+ LIMIT works as it does in `re-search-forward'.
119
127
 
120
128
  This highlights the tag attributes and object refs of the tag,
121
129
  as well as the script expression (-, =, or ~) following the tag.
@@ -189,13 +197,15 @@ For example, this will highlight all of the following:
189
197
  t))
190
198
 
191
199
  (defun haml-move (re)
192
- "Try matching and moving to the end of a regular expression."
200
+ "Try matching and moving to the end of regular expression RE.
201
+ Returns non-nil if the expression was sucessfully matched."
193
202
  (when (looking-at re)
194
203
  (goto-char (match-end 0))
195
204
  t))
196
205
 
197
206
  (defun haml-highlight-interpolation (limit)
198
- "Highlight Ruby interpolation (#{foo})."
207
+ "Highlight Ruby interpolation (#{foo}).
208
+ LIMIT works as it does in `re-search-forward'."
199
209
  (when (re-search-forward "\\(#{\\)" limit t)
200
210
  (save-match-data
201
211
  (forward-char -1)
@@ -209,8 +219,8 @@ For example, this will highlight all of the following:
209
219
  t)))
210
220
 
211
221
  (defun haml-limited-forward-sexp (limit &optional arg)
212
- "Move forward using `forward-sexp' or to limit,
213
- whichever comes first."
222
+ "Move forward using `forward-sexp' or to LIMIT, whichever comes first.
223
+ With ARG, do it that many times."
214
224
  (let (forward-sexp-function)
215
225
  (condition-case err
216
226
  (save-restriction
@@ -278,7 +288,7 @@ whichever comes first."
278
288
  (modify-syntax-entry ?: "." table)
279
289
  (modify-syntax-entry ?_ "w" table)
280
290
  table)
281
- "Syntax table in use in haml-mode buffers.")
291
+ "Syntax table in use in `haml-mode' buffers.")
282
292
 
283
293
  (defvar haml-mode-map
284
294
  (let ((map (make-sparse-keymap)))
@@ -337,7 +347,8 @@ whichever comes first."
337
347
  (haml-reindent-region-by (- haml-indent-offset))))
338
348
 
339
349
  (defun haml-replace-region (start end)
340
- "Replaces the current block of Haml code with the HTML equivalent."
350
+ "Replace the current block of Haml code with the HTML equivalent.
351
+ Called from a program, START and END specify the region to indent."
341
352
  (interactive "r")
342
353
  (save-excursion
343
354
  (goto-char end)
@@ -349,9 +360,10 @@ whichever comes first."
349
360
  (shell-command-on-region start end "haml" "haml-output" t)))
350
361
 
351
362
  (defun haml-output-region (start end)
352
- "Displays the HTML output for the current block of Haml code."
363
+ "Displays the HTML output for the current block of Haml code.
364
+ Called from a program, START and END specify the region to indent."
353
365
  (interactive "r")
354
- (kill-new (buffer-substring start end))
366
+ (kill-new (buffer-substring start end))
355
367
  (with-temp-buffer
356
368
  (yank)
357
369
  (haml-indent-region (point-min) (point-max))
@@ -365,10 +377,11 @@ whichever comes first."
365
377
  ;; Navigation
366
378
 
367
379
  (defun haml-forward-through-whitespace (&optional backward)
368
- "Move the point forward at least one line, until it reaches
380
+ "Move the point forward through any whitespace.
381
+ The point will move forward at least one line, until it reaches
369
382
  either the end of the buffer or a line with no whitespace.
370
383
 
371
- If `backward' is non-nil, move the point backward instead."
384
+ If BACKWARD is non-nil, move the point backward instead."
372
385
  (let ((arg (if backward -1 1))
373
386
  (endp (if backward 'bobp 'eobp)))
374
387
  (loop do (forward-line arg)
@@ -376,9 +389,7 @@ If `backward' is non-nil, move the point backward instead."
376
389
  (looking-at "^[ \t]*$")))))
377
390
 
378
391
  (defun haml-at-indent-p ()
379
- "Returns whether or not the point is at the first
380
- non-whitespace character in a line or whitespace preceding that
381
- character."
392
+ "Return non-nil if the point is before any text on the line."
382
393
  (let ((opoint (point)))
383
394
  (save-excursion
384
395
  (back-to-indentation)
@@ -386,7 +397,7 @@ character."
386
397
 
387
398
  (defun haml-forward-sexp (&optional arg)
388
399
  "Move forward across one nested expression.
389
- With `arg', do it that many times. Negative arg -N means move
400
+ With ARG, do it that many times. Negative arg -N means move
390
401
  backward across N balanced expressions.
391
402
 
392
403
  A sexp in Haml is defined as a line of Haml code as well as any
@@ -443,14 +454,14 @@ With ARG, do this that many times."
443
454
  (back-to-indentation))
444
455
 
445
456
  (defun haml-mark-sexp ()
446
- "Marks the next Haml block."
457
+ "Mark the next Haml block."
447
458
  (let ((forward-sexp-function 'haml-forward-sexp))
448
459
  (mark-sexp)))
449
460
 
450
461
  (defun haml-mark-sexp-but-not-next-line ()
451
- "Marks the next Haml block, but puts the mark at the end of the
452
- last line of the sexp rather than the first non-whitespace
453
- character of the next line."
462
+ "Mark the next Haml block, but not the next line.
463
+ Put the mark at the end of the last line of the sexp rather than
464
+ the first non-whitespace character of the next line."
454
465
  (haml-mark-sexp)
455
466
  (set-mark
456
467
  (save-excursion
@@ -507,7 +518,7 @@ beginning the hash."
507
518
  (when (eq (char-before) ?,) (return-from haml-unclosed-attr-hash-p t))
508
519
  (re-search-backward "(\\|^")
509
520
  (haml-move "(")
510
- (haml-parse-new-attr-hash)))
521
+ (haml-parse-new-attr-hash)))
511
522
 
512
523
  (defun* haml-parse-new-attr-hash (&optional (fn (lambda (type beg end) ())))
513
524
  "Parse a new-style attribute hash on this line, and returns
@@ -549,7 +560,8 @@ and BEG and END delimit that text in the buffer."
549
560
  "Indent each nonblank line in the region.
550
561
  This is done by indenting the first line based on
551
562
  `haml-compute-indentation' and preserving the relative
552
- indentation of the rest of the region.
563
+ indentation of the rest of the region. START and END specify the
564
+ region to indent.
553
565
 
554
566
  If this command is used multiple times in a row, it will cycle
555
567
  between possible indentations."
@@ -610,7 +622,8 @@ lines in the region have indentation >= that of the first line."
610
622
  "Delete characters or back-dent the current line.
611
623
  If invoked following only whitespace on a line, will back-dent
612
624
  the line and all nested lines to the immediately previous
613
- multiple of `haml-indent-offset' spaces.
625
+ multiple of `haml-indent-offset' spaces. With ARG, do it that
626
+ many times.
614
627
 
615
628
  Set `haml-backspace-backdents-nesting' to nil to just back-dent
616
629
  the current line."
@@ -4,8 +4,10 @@
4
4
 
5
5
  ;; Author: Nathan Weizenbaum
6
6
  ;; URL: http://github.com/nex3/haml/tree/master
7
- ;; Version: 1.0
8
- ;; Keywords: markup, language
7
+ ;; Version: 2.2.6
8
+ ;; Created: 2007-03-15
9
+ ;; By: Nathan Weizenbaum
10
+ ;; Keywords: markup, language, css
9
11
 
10
12
  ;;; Commentary:
11
13
 
@@ -42,8 +44,9 @@
42
44
  (defvar sass-non-block-openers
43
45
  '("^ *:[^ \t]+[ \t]+[^ \t]"
44
46
  "^ *[^ \t:]+[ \t]*[=:][ \t]*[^ \t]")
45
- "A list of regexps that match lines of Sass that couldn't have
46
- text nested beneath them.")
47
+ "A list of regexps that match lines of Sass that don't open blocks.
48
+ That is, a Sass line that can't have text nested beneath it
49
+ should be matched by a regexp in this list.")
47
50
 
48
51
  ;; Font lock
49
52
 
@@ -93,18 +96,18 @@ text nested beneath them.")
93
96
  ("\\(\\w+\\)\s*=" 1 font-lock-variable-name-face sass-highlight-script-after-match)
94
97
  ("\\(:\\w+\\)\s*=" 1 font-lock-variable-name-face sass-highlight-script-after-match)
95
98
  (".*" sass-highlight-selector))
96
- "A list of full-line Sass syntax to highlight,
97
- used by `sass-highlight-line'.
99
+ "A list of full-line Sass syntax to highlight, used by `sass-highlight-line'.
98
100
 
99
101
  Each item is either of the form (REGEXP SUBEXP FACE), (REGEXP FN),
100
- or (REGEXP SUBEXP FACE FN). Each REGEXP is run successively on the
102
+ or (REGEXP SUBEXP FACE FN). Each REGEXP is run successively on the
101
103
  beginning of non-whitespace on the current line until one matches.
102
104
  If it has SUBEXP and FACE, then SUBEXP is highlighted using FACE.
103
105
  If it has FN, FN is run.")
104
106
 
105
107
  (defun sass-highlight-line (limit)
106
- "Highlight a single line using some Sass single-line syntax,
107
- taken from `sass-line-keywords'."
108
+ "Highlight a single line using some Sass single-line syntax.
109
+ This syntax is taken from `sass-line-keywords'.
110
+ LIMIT is the limit of the search."
108
111
  (save-match-data
109
112
  (when (re-search-forward "^ *\\(.+\\)$" limit t)
110
113
  (goto-char (match-beginning 1))
@@ -121,8 +124,7 @@ taken from `sass-line-keywords'."
121
124
  (return t)))))))
122
125
 
123
126
  (defun sass-highlight-selector ()
124
- "Highlight a CSS selector starting at `point'
125
- and ending at `end-of-line'."
127
+ "Highlight a CSS selector starting at `point' and ending at `end-of-line'."
126
128
  (let ((font-lock-keywords sass-selector-font-lock-keywords)
127
129
  font-lock-multiline)
128
130
  (font-lock-fontify-region
@@ -139,10 +141,12 @@ and ending at `end-of-line'."
139
141
  (font-lock-fontify-region beg end)))))
140
142
 
141
143
  (defun sass-highlight-script-after-match ()
144
+ "Highlight a section of SassScript after the last match."
142
145
  (end-of-line)
143
146
  (sass-highlight-script (match-end 0) (point)))
144
147
 
145
148
  (defun sass-highlight-directive ()
149
+ "Highlight a Sass directive."
146
150
  (goto-char (match-end 0))
147
151
  (block nil
148
152
  (case (intern (match-string 1))
@@ -188,7 +192,7 @@ and ending at `end-of-line'."
188
192
  ;; Indentation
189
193
 
190
194
  (defun sass-indent-p ()
191
- "Returns t if the current line can have lines nested beneath it."
195
+ "Return non-nil if the current line can have lines nested beneath it."
192
196
  (loop for opener in sass-non-block-openers
193
197
  unless (looking-at opener) return t
194
198
  return nil))
@@ -73,7 +73,7 @@ module Haml
73
73
  end
74
74
 
75
75
  opts.on_tail("-v", "--version", "Print version") do
76
- puts("Haml #{::Haml.version[:string]}")
76
+ puts("Haml/Sass #{::Haml.version[:string]}")
77
77
  exit
78
78
  end
79
79
  end
@@ -364,7 +364,8 @@ END
364
364
  require 'haml/html'
365
365
  rescue LoadError => err
366
366
  dep = err.message.scan(/^no such file to load -- (.*)/)[0]
367
- puts "Required dependency #{dep} not found!"
367
+ raise err if @options[:trace] || dep.nil? || dep.empty?
368
+ $stderr.puts "Required dependency #{dep} not found!\n Use --trace for backtrace."
368
369
  exit 1
369
370
  end
370
371
  end
@@ -465,8 +465,8 @@ END
465
465
  return unless key = scanner.scan(LITERAL_VALUE_REGEX)
466
466
  return unless scanner.scan(/\s*=>\s*/)
467
467
  return unless value = scanner.scan(LITERAL_VALUE_REGEX)
468
+ return unless scanner.scan(/\s*(?:,|$)\s*/)
468
469
  attributes[eval(key).to_s] = eval(value).to_s
469
- scanner.scan(/[,\s]*/)
470
470
  end
471
471
  text.count("\n").times { newline }
472
472
  attributes
@@ -15,7 +15,7 @@ module Haml
15
15
  # @param file [String] The filename relative to the Haml root
16
16
  # @return [String] The filename relative to the the working directory
17
17
  def scope(file)
18
- File.join(File.dirname(File.dirname(File.dirname(__FILE__))), file)
18
+ File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), file)
19
19
  end
20
20
 
21
21
  # Converts an array of `[key, value]` pairs to a hash.
@@ -54,6 +54,12 @@ class EngineTest < Test::Unit::TestCase
54
54
  "%p(foo 'bar')" => "Invalid attribute list: \"(foo 'bar')\".",
55
55
  "%p(foo 'bar'\nbaz='bang')" => ["Invalid attribute list: \"(foo 'bar'\".", 1],
56
56
  "%p(foo='bar'\nbaz 'bang'\nbip='bop')" => ["Invalid attribute list: \"(foo='bar' baz 'bang'\".", 2],
57
+ "%p{:foo => 'bar' :bar => 'baz'}" => :compile,
58
+ "%p{:foo => }" => :compile,
59
+ "%p{=> 'bar'}" => :compile,
60
+ "%p{:foo => 'bar}" => :compile,
61
+ "%p{'foo => 'bar'}" => :compile,
62
+ "%p{:foo => 'bar\"}" => :compile,
57
63
 
58
64
  # Regression tests
59
65
  "- raise 'foo'\n\n\n\nbar" => ["foo", 1],
@@ -727,18 +733,22 @@ HAML
727
733
  assert_equal("<a b='2' />\nc\n", render("%a{'b' => 1 + 1}/\n= 'c'\n"))
728
734
  end
729
735
 
730
- def test_exceptions
731
- EXCEPTION_MAP.each do |key, value|
736
+ EXCEPTION_MAP.each do |key, value|
737
+ define_method("test_exception (#{key.inspect})") do
732
738
  begin
733
- render(key, :filename => "(exception test for #{key.inspect})")
739
+ render(key, :filename => __FILE__)
734
740
  rescue Exception => err
735
741
  value = [value] unless value.is_a?(Array)
736
742
  expected_message, line_no = value
737
743
  line_no ||= key.split("\n").length
738
- line_reported = err.backtrace[0].gsub(/\(.+\):/, '').to_i
739
744
 
740
- assert_equal(expected_message, err.message, "Line: #{key}")
741
- assert_equal(line_no, line_reported, "Line: #{key}")
745
+ if expected_message == :compile
746
+ assert_match(/^compile error\n/, err.message, "Line: #{key}")
747
+ else
748
+ assert_equal(expected_message, err.message, "Line: #{key}")
749
+ end
750
+
751
+ assert_match(/^#{Regexp.escape(__FILE__)}:#{line_no}/, err.backtrace[0], "Line: #{key}")
742
752
  else
743
753
  assert(false, "Exception not raised for\n#{key}")
744
754
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  Haml Spec provides a basic suite of tests for Haml interpreters.
4
4
 
5
- It is intented for developers who are creating or maintaining an
6
- implementation of the [Haml](http://haml-lang.com) markup language.
5
+ It is intented for developers who are creating or maintaining an implementation
6
+ of the [Haml](http://haml-lang.com) markup language.
7
7
 
8
8
  At the moment, there are test runners for the [original Haml](http://github.com/nex3/haml)
9
9
  in Ruby, and for [Lua Haml](http://github.com/norman/lua-haml). Support for
@@ -12,19 +12,35 @@ are interested in using it.
12
12
 
13
13
  ## The Tests ##
14
14
 
15
- The tests are kept in JSON format for portability across languages.
16
- Each test is a simple key/value pair of input and expected output.
17
- The test suite only provides tests for features which are portable,
18
- therefore no tests for script are provided, nor for external filters
19
- such as :markdown or :textile.
15
+ The tests are kept in JSON format for portability across languages. Each test
16
+ is a JSON object with expected input, output, local variables and configuration
17
+ parameters (see below). The test suite only provides tests for features which
18
+ are portable, therefore no tests for script are provided, nor for external
19
+ filters such as :markdown or :textile.
20
+
21
+ The one major exception to this are the tests for interpolation, which you may
22
+ need to modify with a regular expression to run under PHP or Perl, which
23
+ require a symbol before variable names. These tests are included despite being
24
+ less than 100% portable because interpolation is an important part of Haml and
25
+ can be tricky to implement.
20
26
 
21
27
  ## Running the Tests ##
22
28
 
23
29
  ### Ruby ###
24
30
 
25
- The Ruby test uses RSpec, so just install the gem and run `spec ruby_haml_spec.rb`.
26
- I have only tested it against Ruby 1.9; if you want to run it on an older Ruby
27
- you'll need to install the "json" gem.
31
+ In order to make it as easy as possible for non-Ruby programmers to run the
32
+ Ruby Haml tests, the Ruby test runner uses test/unit, rather than something
33
+ fancier like Rspec. To run them you probably only need to install `haml`, and
34
+ possibly `ruby` if your platform doesn't come with it by default. If you're
35
+ using Ruby 1.8.x, you'll also need to install `json`:
36
+
37
+ sudo gem install haml
38
+ # for Ruby 1.8.x; check using "ruby --version" if unsure
39
+ sudo gem install json
40
+
41
+ Then, running the Ruby test suite is easy:
42
+
43
+ ruby ruby_haml_test.rb
28
44
 
29
45
  ### Lua ###
30
46
 
@@ -35,19 +51,47 @@ run `tsc lua_haml_spec.lua`.
35
51
 
36
52
  ## Contributing ##
37
53
 
38
- You can access the Git repo at:
54
+ ### Getting it ###
39
55
 
40
- http://github.com/norman/haml-spec
56
+ You can access the [Git repository](http://github.com/norman/haml-spec) at:
41
57
 
42
- As long as any test you add run against Ruby's Haml and are not redundant,
43
- I'll be very happy to add them.
58
+ git://github.com/norman/haml-spec.git
44
59
 
45
- ## License ##
60
+ Patches are *very* welcome, as are test runners for your Haml implementation.
46
61
 
47
- This project is released under the [WTFPL](http://sam.zoy.org/wtfpl/)
48
- in order to be as usable as possible in any project, commercial or free.
62
+ As long as any test you add run against Ruby Haml and are not redundant, I'll
63
+ be very happy to add them.
64
+
65
+ ### Test JSON format ###
66
+
67
+ "test name" : {
68
+ "haml" : "haml input",
69
+ "html" : "expected html output",
70
+ "result" : "expected test result",
71
+ "locals" : "local vars",
72
+ "config" : "config params"
73
+ }
74
+
75
+ * test name: This should be a *very* brief description of what's being tested. It can
76
+ be used by the test runners to name test methods, or to exclude certain tests from being
77
+ run.
78
+ * haml: The Haml code to be evaluated. Always required.
79
+ * html: The HTML output that should be generated. Required unless "result" is "error".
80
+ * result: Can be "pass" or "error". If it's absent, then "pass" is assumed. If it's "error",
81
+ then the goal of the test is to make sure that malformed Haml code generates an error.
82
+ * locals: An object containing local variables needed for the test.
83
+ * config: An object containing configuration parameters used to run the test.
84
+ The configuration parameters should be usable directly by Ruby's Haml with no
85
+ modification. If your implementation uses config parameters with different
86
+ names, you may need to process them to make them match your implementation.
87
+ If your implementation has options that do not exist in Ruby's Haml, then you
88
+ should add tests for this in your implementation's test rather than here.
89
+
90
+ ## License ##
49
91
 
92
+ This project is released under the [WTFPL](http://sam.zoy.org/wtfpl/) in order
93
+ to be as usable as possible in any project, commercial or free.
50
94
 
51
95
  ## Author ##
52
96
 
53
- [Norman Clarke](mailto:norman@njclarke.com)
97
+ [Norman Clarke](mailto:norman@njclarke.com)
@@ -11,27 +11,20 @@ local function get_tests(filename)
11
11
  end
12
12
  end
13
13
 
14
- local fh = assert(io.open(get_tests("tests.json")))
14
+ local fh = assert(io.open(get_tests("tests-new.json")))
15
15
  local input = fh:read '*a'
16
16
  fh:close()
17
17
 
18
18
  local contexts = json.decode(input)
19
19
 
20
- local locals = {
21
- var = "value",
22
- first = "a",
23
- last = "z"
24
- }
25
-
26
- describe("The LuaHaml Renderer", function()
27
- for context, expectations in pairs(contexts) do
28
- describe("When handling " .. context, function()
29
- for input, expectation in pairs(expectations) do
30
- it(string.format("should render '%s' as '%s'", string.gsub(input, "\n", "\\n"),
31
- string.gsub(expectation, "\n", "\\n")), function()
32
- assert_equal(haml.render(input, {}, locals), expectation)
20
+ describe("LuaHaml", function()
21
+ for context, expectations in pairs(contexts) do
22
+ describe("When handling " .. context, function()
23
+ for name, exp in pairs(expectations) do
24
+ it(string.format("should correctly render %s", name), function()
25
+ assert_equal(haml.render(exp.haml, exp.config or {}, exp.locals or {}), exp.html)
33
26
  end)
34
27
  end
35
- end)
36
- end
28
+ end)
29
+ end
37
30
  end)
@@ -0,0 +1,19 @@
1
+ require "test/unit"
2
+ require "json"
3
+ require "haml"
4
+
5
+ class HamlTest < Test::Unit::TestCase
6
+ contexts = JSON.parse(File.read(File.dirname(__FILE__) + "/tests.json"))
7
+ contexts.each do |context|
8
+ context[1].each do |name, test|
9
+ class_eval(<<-EOTEST)
10
+ def test_#{name.gsub(/\s+|[^a-zA-Z0-9_]/, "_")}
11
+ locals = Hash[*(#{test}["locals"] || {}).collect {|k, v| [k.to_sym, v] }.flatten]
12
+ options = Hash[*(#{test}["config"] || {}).collect {|k, v| [k.to_sym, v.to_sym] }.flatten]
13
+ engine = Haml::Engine.new(#{test}["haml"], options)
14
+ assert_equal(engine.render(Object.new, locals).chomp, #{test}["html"])
15
+ end
16
+ EOTEST
17
+ end
18
+ end
19
+ end
@@ -1,105 +1,488 @@
1
1
  {
2
- "headers": {
3
- "!!! XML": "<?xml version='1.0' encoding='utf-8' ?>",
4
- "!!!": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">",
5
- "!!! 1.1": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">",
6
- "!!! frameset": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">",
7
- "!!! mobile": "<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd\">",
8
- "!!! basic": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" \"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">"
2
+ "headers" : {
3
+
4
+ "an XHTML XML prolog" : {
5
+ "haml" : "!!! XML",
6
+ "html" : "<?xml version='1.0' encoding='utf-8' ?>"
7
+ },
8
+
9
+ "an XHTML default (transitional) doctype" : {
10
+ "haml" : "!!!",
11
+ "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
12
+ },
13
+
14
+ "an XHTML 1.1 doctype" : {
15
+ "haml" : "!!! 1.1",
16
+ "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"
17
+ },
18
+
19
+ "an XHTML 1.2 mobile doctype" : {
20
+ "haml" : "!!! mobile",
21
+ "html" : "<!DOCTYPE html PUBLIC \"-//WAPFORUM//DTD XHTML Mobile 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd\">"
22
+ },
23
+
24
+ "an XHTML 1.1 basic doctype" : {
25
+ "haml" : "!!! basic",
26
+ "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" \"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">"
27
+ },
28
+
29
+ "an XHTML 1.0 frameset doctype" : {
30
+ "haml" : "!!! frameset",
31
+ "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">"
32
+ },
33
+
34
+ "an HTML 5 XML prolog (silent)" : {
35
+ "haml" : "!!! XML",
36
+ "html" : "",
37
+ "config" : {
38
+ "format" : "html5"
39
+ }
40
+ },
41
+
42
+ "an HTML 5 doctype" : {
43
+ "haml" : "!!!",
44
+ "html" : "<!DOCTYPE html>",
45
+ "config" : {
46
+ "format" : "html5"
47
+ }
48
+ },
49
+
50
+ "an HTML 4 XML prolog (silent)" : {
51
+ "haml" : "!!! XML",
52
+ "html" : "",
53
+ "config" : {
54
+ "format" : "html4"
55
+ }
56
+ },
57
+
58
+ "an HTML 4 default (transitional) doctype" : {
59
+ "haml" : "!!!",
60
+ "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">",
61
+ "config" : {
62
+ "format" : "html4"
63
+ }
64
+ },
65
+
66
+ "an HTML 4 frameset doctype" : {
67
+ "haml" : "!!! frameset",
68
+ "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">",
69
+ "config" : {
70
+ "format" : "html4"
71
+ }
72
+ },
73
+
74
+ "an HTML 4 strict doctype" : {
75
+ "haml" : "!!! strict",
76
+ "html" : "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">",
77
+ "config" : {
78
+ "format" : "html4"
79
+ }
80
+ }
81
+
9
82
  },
10
83
 
11
84
  "basic Haml tags and CSS": {
12
- "%p": "<p></p>",
13
- "%meta": "<meta />",
14
- "#id1": "<div id='id1'></div>",
15
- ".class1": "<div class='class1'></div>",
16
- "%p.class1": "<p class='class1'></p>",
17
- "%p.class1.class2": "<p class='class1 class2'></p>",
18
- "%p#id1": "<p id='id1'></p>",
19
- "%p#id1#id2": "<p id='id2'></p>",
20
- "%p.class1#id1": "<p class='class1' id='id1'></p>",
21
- "%p#id1.class1": "<p class='class1' id='id1'></p>"
85
+
86
+ "a simple Haml tag" : {
87
+ "haml" : "%p",
88
+ "html" : "<p></p>"
89
+ },
90
+
91
+ "a self-closing tag (XHTML)" : {
92
+ "haml" : "%meta",
93
+ "html" : "<meta />"
94
+ },
95
+
96
+ "a self-closing tag (HTML4)" : {
97
+ "haml" : "%meta",
98
+ "html" : "<meta>",
99
+ "config" : {
100
+ "format" : "html4"
101
+ }
102
+ },
103
+
104
+ "a self-closing tag (HTML5)" : {
105
+ "haml" : "%meta",
106
+ "html" : "<meta>",
107
+ "config" : {
108
+ "format" : "html5"
109
+ }
110
+ },
111
+
112
+ "a tag with a CSS class" : {
113
+ "haml" : "%p.class1",
114
+ "html" : "<p class='class1'></p>"
115
+ },
116
+
117
+ "a tag with multiple CSS classes" : {
118
+ "haml" : "%p.class1.class2",
119
+ "html" : "<p class='class1 class2'></p>"
120
+ },
121
+
122
+ "a tag with a CSS id" : {
123
+ "haml" : "%p#id1",
124
+ "html" : "<p id='id1'></p>"
125
+ },
126
+
127
+ "a tag with multiple CSS id's" : {
128
+ "haml" : "%p#id1#id2",
129
+ "html" : "<p id='id2'></p>"
130
+ },
131
+
132
+ "a tag with a class followed by an id" : {
133
+ "haml" : "%p.class1#id1",
134
+ "html" : "<p class='class1' id='id1'></p>"
135
+ },
136
+
137
+ "a tag with an id followed by a class" : {
138
+ "haml" : "%p#id1.class1",
139
+ "html" : "<p class='class1' id='id1'></p>"
140
+ },
141
+
142
+ "an implicit div with a CSS id" : {
143
+ "haml" : "#id1",
144
+ "html" : "<div id='id1'></div>"
145
+ },
146
+
147
+ "an implicit div with a CSS class" : {
148
+ "haml" : ".class1",
149
+ "html" : "<div class='class1'></div>"
150
+ }
151
+
22
152
  },
23
153
 
24
- "tags with unusual HTML characters": {
25
- "%ns:tag": "<ns:tag></ns:tag>",
26
- "%snake_case": "<snake_case></snake_case>",
27
- "%dashed-tag": "<dashed-tag></dashed-tag>",
28
- "%camelCase": "<camelCase></camelCase>",
29
- "%PascalCase": "<PascalCase></PascalCase>"
154
+ "tags with unusual HTML characters" : {
155
+
156
+ "a tag with colons" : {
157
+ "haml" : "%ns:tag",
158
+ "html" : "<ns:tag></ns:tag>"
159
+ },
160
+
161
+ "a tag with underscores" : {
162
+ "haml" : "%snake_case",
163
+ "html" : "<snake_case></snake_case>"
164
+ },
165
+
166
+ "a tag with dashes" : {
167
+ "haml" : "%dashed-tag",
168
+ "html" : "<dashed-tag></dashed-tag>"
169
+ },
170
+
171
+ "a tag with camelCase" : {
172
+ "haml" : "%camelCase",
173
+ "html" : "<camelCase></camelCase>"
174
+ },
175
+
176
+ "a tag with PascalCase" : {
177
+ "haml" : "%PascalCase",
178
+ "html" : "<PascalCase></PascalCase>"
179
+ }
30
180
  },
31
181
 
32
- "tags with unusual CSS identifiers": {
33
- ".123": "<div class='123'></div>",
34
- ".__": "<div class='__'></div>",
35
- ".--": "<div class='--'></div>"
182
+ "tags with unusual CSS identifiers" : {
183
+
184
+ "an all-numeric class" : {
185
+ "haml" : ".123",
186
+ "html" : "<div class='123'></div>"
187
+ },
188
+
189
+ "a class with underscores" : {
190
+ "haml" : ".__",
191
+ "html" : "<div class='__'></div>"
192
+ },
193
+
194
+ "a class with dashes" : {
195
+ "haml" : ".--",
196
+ "html" : "<div class='--'></div>"
197
+ }
198
+
36
199
  },
37
200
 
38
- "tags with inline content": {
39
- "%p hello": "<p>hello</p>",
40
- "%p.class1 hello": "<p class='class1'>hello</p>"
201
+ "tags with inline content" : {
202
+
203
+ "a simple tag" : {
204
+ "haml" : "%p hello",
205
+ "html" : "<p>hello</p>"
206
+ },
207
+
208
+ "a tag with CSS" : {
209
+ "haml" : "%p.class1 hello",
210
+ "html" : "<p class='class1'>hello</p>"
211
+ }
212
+
41
213
  },
42
214
 
43
- "tags with nested content": {
44
- "%p\n hello": "<p>\n hello\n</p>"
215
+ "tags with nested content" : {
216
+
217
+ "a simple tag" : {
218
+ "haml" : "%p\n hello",
219
+ "html" : "<p>\n hello\n</p>"
220
+ },
221
+
222
+ "a tag with CSS" : {
223
+ "haml" : "%p.class1\n hello",
224
+ "html" : "<p class='class1'>\n hello\n</p>"
225
+ }
226
+
45
227
  },
46
228
 
47
- "tags with portable-style attributes": {
48
- "%p(a='b')": "<p a='b'></p>",
49
- "%p(a='b' c='d')": "<p a='b' c='d'></p>",
50
- "%p(a='b'\n c='d')": "<p a='b' c='d'></p>",
51
- "%p(class='class1')": "<p class='class1'></p>",
52
- "%p.class2(class='class1')": "<p class='class1 class2'></p>",
53
- "%p#id(id='1')": "<p id='id_1'></p>",
54
- ".hello(class=var)": "<div class='hello value'></div>",
55
- ".b(class=last)": "<div class='b z'></div>",
56
- ".b(class=first)": "<div class='a b'></div>"
229
+ "tags with HTML-style attributes": {
230
+
231
+ "one attribute" : {
232
+ "haml" : "%p(a='b')",
233
+ "html" : "<p a='b'></p>"
234
+ },
235
+
236
+ "multiple attributes" : {
237
+ "haml" : "%p(a='b' c='d')",
238
+ "html" : "<p a='b' c='d'></p>"
239
+ },
240
+
241
+ "attributes separated with newlines" : {
242
+ "haml" : "%p(a='b'\n c='d')",
243
+ "html" : "<p a='b' c='d'></p>"
244
+ },
245
+
246
+ "an interpolated attribute" : {
247
+ "haml" : "%p(a=\"#{var}\")",
248
+ "html" : "<p a='value'></p>",
249
+ "locals" : {
250
+ "var" : "value"
251
+ }
252
+ },
253
+
254
+ "'class' as an attribute" : {
255
+ "haml" : "%p(class='class1')",
256
+ "html" : "<p class='class1'></p>"
257
+ },
258
+
259
+ "a tag with a CSS class and 'class' as an attribute" : {
260
+ "haml" : "%p.class2(class='class1')",
261
+ "html" : "<p class='class1 class2'></p>"
262
+ },
263
+
264
+ "a tag with 'id' as an attribute" : {
265
+ "haml" : "%p(id='1')",
266
+ "html" : "<p id='1'></p>"
267
+ },
268
+
269
+ "a tag with a CSS id and 'id' as an attribute" : {
270
+ "haml" : "%p#id(id='1')",
271
+ "html" : "<p id='id_1'></p>"
272
+ },
273
+
274
+ "a tag with a variable attribute" : {
275
+ "haml" : "%p(class=var)",
276
+ "html" : "<p class='hello'></p>",
277
+ "locals" : {
278
+ "var" : "hello"
279
+ }
280
+ },
281
+
282
+ "a tag with a CSS class and 'class' as a variable attribute" : {
283
+ "haml" : ".hello(class=var)",
284
+ "html" : "<div class='hello world'></div>",
285
+ "locals" : {
286
+ "var" : "world"
287
+ }
288
+ },
289
+
290
+ "a tag multiple CSS classes (sorted correctly)" : {
291
+ "haml" : ".z(class=var)",
292
+ "html" : "<div class='a z'></div>",
293
+ "locals" : {
294
+ "var" : "a"
295
+ }
296
+ }
297
+
57
298
  },
58
299
 
59
300
  "tags with Ruby-style attributes": {
60
- "%p{:a => 'b'}": "<p a='b'></p>",
61
- "%p{ :a => 'b' }": "<p a='b'></p>",
62
- "%p{ :a => 'b', 'c' => 'd' }": "<p a='b' c='d'></p>",
63
- "%p{ :a => 'b',\n 'c' => 'd' }": "<p a='b' c='d'></p>",
64
- "%p{ :a => var}": "<p a='value'></p>",
65
- "%p#id{ :id => '1' }": "<p id='id_1'></p>",
66
- "%p#id{ :id => 1 }": "<p id='id_1'></p>",
67
- "%p{ :a => \"#{var}\"}": "<p a='value'></p>",
68
- ".b{ :class => last }": "<div class='b z'></div>",
69
- ".b{ :class => first }": "<div class='a b'></div>"
70
- },
71
301
 
72
- "inline comments": {
73
- "-# hello\n%p": "<p></p>"
302
+ "one attribute" : {
303
+ "haml" : "%p{:a => 'b'}",
304
+ "html" : "<p a='b'></p>"
305
+ },
306
+
307
+ "attributes hash with whitespace" : {
308
+ "haml" : "%p{ :a => 'b' }",
309
+ "html" : "<p a='b'></p>"
310
+ },
311
+
312
+ "an interpolated attribute" : {
313
+ "haml" : "%p{:a =>\"#{var}\"}",
314
+ "html" : "<p a='value'></p>",
315
+ "locals" : {
316
+ "var" : "value"
317
+ }
318
+ },
319
+
320
+ "multiple attributes" : {
321
+ "haml" : "%p{ :a => 'b', 'c' => 'd' }",
322
+ "html" : "<p a='b' c='d'></p>"
323
+ },
324
+
325
+ "attributes separated with newlines" : {
326
+ "haml" : "%p{ :a => 'b',\n 'c' => 'd' }",
327
+ "html" : "<p a='b' c='d'></p>"
328
+ },
329
+
330
+ "'class' as an attribute" : {
331
+ "haml" : "%p{:class => 'class1'}",
332
+ "html" : "<p class='class1'></p>"
333
+ },
334
+
335
+ "a tag with a CSS class and 'class' as an attribute" : {
336
+ "haml" : "%p.class2{:class => 'class1'}",
337
+ "html" : "<p class='class1 class2'></p>"
338
+ },
339
+
340
+ "a tag with 'id' as an attribute" : {
341
+ "haml" : "%p{:id => '1'}",
342
+ "html" : "<p id='1'></p>"
343
+ },
344
+
345
+ "a tag with a CSS id and 'id' as an attribute" : {
346
+ "haml" : "%p#id{:id => '1'}",
347
+ "html" : "<p id='id_1'></p>"
348
+ },
349
+
350
+ "a tag with a CSS id and a numeric 'id' as an attribute" : {
351
+ "haml" : "%p#id{:id => 1}",
352
+ "html" : "<p id='id_1'></p>"
353
+ },
354
+
355
+ "a tag with a variable attribute" : {
356
+ "haml" : "%p{:class => var}",
357
+ "html" : "<p class='hello'></p>",
358
+ "locals" : {
359
+ "var" : "hello"
360
+ }
361
+ },
362
+
363
+ "a tag with a CSS class and 'class' as a variable attribute" : {
364
+ "haml" : ".hello{:class => var}",
365
+ "html" : "<div class='hello world'></div>",
366
+ "locals" : {
367
+ "var" : "world"
368
+ }
369
+ },
370
+
371
+ "a tag multiple CSS classes (sorted correctly)" : {
372
+ "haml" : ".z{:class => var}",
373
+ "html" : "<div class='a z'></div>",
374
+ "locals" : {
375
+ "var" : "a"
376
+ }
377
+ },
378
+
379
+ "an interpolated attribute" : {
380
+ "haml" : "%p{:a =>\"#{var}\"}",
381
+ "html" : "<p a='value'></p>",
382
+ "locals" : {
383
+ "var" : "value"
384
+ }
385
+ }
386
+
74
387
  },
75
388
 
76
- "silent comments": {
77
- "-# nothing\n%p": "<p></p>",
78
- "-# nothing\n nested\n%p": "<p></p>"
389
+ "silent comments" : {
390
+
391
+ "an inline comment" : {
392
+ "haml" : "-# hello",
393
+ "html" : ""
394
+ },
395
+
396
+ "a nested comment" : {
397
+ "haml" : "-#\n hello",
398
+ "html" : ""
399
+ }
400
+
79
401
  },
80
402
 
81
- "markup comments": {
82
- "/ comment": "<!-- comment -->",
83
- "/\n comment\n comment2": "<!--\n comment\n comment2\n-->"
403
+ "markup comments" : {
404
+
405
+ "an inline comment" : {
406
+ "haml" : "/ comment",
407
+ "html" : "<!-- comment -->"
408
+ },
409
+
410
+ "a nested comment" : {
411
+ "haml" : "/\n comment\n comment2",
412
+ "html" : "<!--\n comment\n comment2\n-->"
413
+ }
84
414
  },
85
415
 
86
416
  "conditional comments": {
87
- "/[if IE]\n %p a": "<!--[if IE]>\n <p>a</p>\n<![endif]-->"
417
+ "a conditional comment" : {
418
+ "haml" : "/[if IE]\n %p a",
419
+ "html" : "<!--[if IE]>\n <p>a</p>\n<![endif]-->"
420
+ }
88
421
  },
89
422
 
90
423
  "internal filters": {
91
- ":escaped\n <&\">": "&lt;&amp;&quot;&gt;",
92
- ":preserve\n hello\n\n%p": "hello&#x000A;\n<p></p>",
93
- ":plain\n hello\n\n%p": "hello\n<p></p>",
94
- ":javascript\n a();\n%p": "<script type='text/javascript'>\n //<![CDATA[\n a();\n //]]>\n</script>\n<p></p>"
424
+
425
+ "content in an 'escaped' filter" : {
426
+ "haml" : ":escaped\n <&\">",
427
+ "html" : "&lt;&amp;&quot;&gt;"
428
+ },
429
+
430
+ "content in a 'preserve' filter" : {
431
+ "haml" : ":preserve\n hello\n\n%p",
432
+ "html" : "hello&#x000A;\n<p></p>"
433
+ },
434
+
435
+ "content in a 'plain' filter" : {
436
+ "haml" : ":plain\n hello\n\n%p",
437
+ "html" : "hello\n<p></p>"
438
+ },
439
+
440
+ "content in a 'javascript' filter" : {
441
+ "haml" : ":javascript\n a();\n%p",
442
+ "html" : "<script type='text/javascript'>\n //<![CDATA[\n a();\n //]]>\n</script>\n<p></p>"
443
+ }
444
+
95
445
  },
96
446
 
97
447
  "interpolation": {
98
- "%p= \"#{var}\"": "<p>value</p>",
99
- "%p #{var}": "<p>value</p>",
100
- "%p \\#{var}": "<p>#{var}</p>",
101
- "%p \\\\#{var}": "<p>\\value</p>",
102
- ":plain\n #{var} interpolated: #{var}": "value interpolated: value"
448
+
449
+ "interpolation inside code" : {
450
+ "haml" : "%p= \"#{var}\"",
451
+ "html" : "<p>value</p>",
452
+ "locals" : {
453
+ "var" : "value"
454
+ }
455
+ },
456
+
457
+ "interpolation inside inline content" : {
458
+ "haml" : "%p #{var}",
459
+ "html" : "<p>value</p>",
460
+ "locals" : {
461
+ "var" : "value"
462
+ }
463
+ },
464
+
465
+ "no interpolation when escaped" : {
466
+ "haml" : "%p \\#{var}",
467
+ "html" : "<p>#{var}</p>"
468
+ },
469
+
470
+ "interpolation when the escape character is escaped" : {
471
+ "haml" : "%p \\\\#{var}",
472
+ "html" : "<p>\\value</p>",
473
+ "locals" : {
474
+ "var" : "value"
475
+ }
476
+ },
477
+
478
+ "interpolation inside filtered content" : {
479
+ "haml" : ":plain\n #{var} interpolated: #{var}",
480
+ "html" : "value interpolated: value",
481
+ "locals" : {
482
+ "var" : "value"
483
+ }
484
+ }
485
+
103
486
  }
104
487
 
105
488
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.5
4
+ version: 2.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-09-18 00:00:00 -07:00
13
+ date: 2009-09-27 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -199,7 +199,7 @@ files:
199
199
  - test/haml/templates/action_view.haml
200
200
  - test/haml/spec/tests.json
201
201
  - test/haml/spec/lua_haml_spec.lua
202
- - test/haml/spec/ruby_haml_spec.rb
202
+ - test/haml/spec/ruby_haml_test.rb
203
203
  - test/haml/spec/README.md
204
204
  - test/haml/results/content_for_layout.xhtml
205
205
  - test/haml/results/just_stuff.xhtml
@@ -281,4 +281,5 @@ test_files:
281
281
  - test/haml/template_test.rb
282
282
  - test/haml/html2haml_test.rb
283
283
  - test/haml/helper_test.rb
284
+ - test/haml/spec/ruby_haml_test.rb
284
285
  - test/haml/engine_test.rb
@@ -1,24 +0,0 @@
1
- require "json"
2
- require "haml"
3
- contexts = JSON.parse(File.read(File.dirname(__FILE__) + "/tests.json"))
4
-
5
- locals = {
6
- :var => "value",
7
- :first => "a",
8
- :last => "z"
9
- }
10
-
11
- contexts.each do |context|
12
- name = context[0]
13
- expectations = context[1]
14
- describe "When handling #{name}," do
15
- expectations.each do |input, expected|
16
- it "should render \"#{input}\" as \"#{expected}\"" do
17
- engine = Haml::Engine.new(input)
18
- engine.render(Object.new, locals).chomp.should == expected
19
- end
20
- end
21
- end
22
- end
23
-
24
-