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 +84 -3
- data/VERSION +1 -1
- data/extra/haml-mode.el +43 -30
- data/extra/sass-mode.el +16 -12
- data/lib/haml/exec.rb +3 -2
- data/lib/haml/precompiler.rb +1 -1
- data/lib/haml/util.rb +1 -1
- data/test/haml/engine_test.rb +16 -6
- data/test/haml/spec/README.md +62 -18
- data/test/haml/spec/lua_haml_spec.lua +9 -16
- data/test/haml/spec/ruby_haml_test.rb +19 -0
- data/test/haml/spec/tests.json +454 -71
- metadata +4 -3
- data/test/haml/spec/ruby_haml_spec.rb +0 -24
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.
|
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.
|
1
|
+
2.2.6
|
data/extra/haml-mode.el
CHANGED
@@ -4,8 +4,10 @@
|
|
4
4
|
|
5
5
|
;; Author: Nathan Weizenbaum
|
6
6
|
;; URL: http://github.com/nex3/haml/tree/master
|
7
|
-
;; Version:
|
8
|
-
;;
|
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
|
45
|
-
nested beneath the backspaced line
|
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
|
-
"
|
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
|
79
|
-
text nested beneath
|
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
|
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
|
213
|
-
|
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
|
-
"
|
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
|
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
|
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
|
-
"
|
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
|
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
|
-
"
|
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
|
-
"
|
452
|
-
last line of the sexp rather than
|
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."
|
data/extra/sass-mode.el
CHANGED
@@ -4,8 +4,10 @@
|
|
4
4
|
|
5
5
|
;; Author: Nathan Weizenbaum
|
6
6
|
;; URL: http://github.com/nex3/haml/tree/master
|
7
|
-
;; Version:
|
8
|
-
;;
|
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
|
46
|
-
text nested beneath
|
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).
|
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
|
-
"
|
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))
|
data/lib/haml/exec.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/haml/precompiler.rb
CHANGED
@@ -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
|
data/lib/haml/util.rb
CHANGED
@@ -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.
|
data/test/haml/engine_test.rb
CHANGED
@@ -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
|
-
|
731
|
-
|
736
|
+
EXCEPTION_MAP.each do |key, value|
|
737
|
+
define_method("test_exception (#{key.inspect})") do
|
732
738
|
begin
|
733
|
-
render(key, :filename =>
|
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
|
-
|
741
|
-
|
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
|
data/test/haml/spec/README.md
CHANGED
@@ -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
|
-
|
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
|
-
|
17
|
-
The test suite only provides tests for features which
|
18
|
-
therefore no tests for script are provided, nor for external
|
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
|
-
|
26
|
-
|
27
|
-
you
|
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
|
-
|
54
|
+
### Getting it ###
|
39
55
|
|
40
|
-
|
56
|
+
You can access the [Git repository](http://github.com/norman/haml-spec) at:
|
41
57
|
|
42
|
-
|
43
|
-
I'll be very happy to add them.
|
58
|
+
git://github.com/norman/haml-spec.git
|
44
59
|
|
45
|
-
|
60
|
+
Patches are *very* welcome, as are test runners for your Haml implementation.
|
46
61
|
|
47
|
-
|
48
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
36
|
-
|
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
|
data/test/haml/spec/tests.json
CHANGED
@@ -1,105 +1,488 @@
|
|
1
1
|
{
|
2
|
-
"headers": {
|
3
|
-
|
4
|
-
"
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
13
|
-
"
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
"
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
26
|
-
"
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
34
|
-
"
|
35
|
-
|
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
|
-
|
40
|
-
"
|
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
|
-
|
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
|
48
|
-
|
49
|
-
"
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
"
|
55
|
-
|
56
|
-
|
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
|
-
|
73
|
-
|
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
|
-
|
78
|
-
"
|
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
|
-
|
83
|
-
"
|
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
|
-
"
|
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
|
-
|
92
|
-
"
|
93
|
-
|
94
|
-
|
424
|
+
|
425
|
+
"content in an 'escaped' filter" : {
|
426
|
+
"haml" : ":escaped\n <&\">",
|
427
|
+
"html" : "<&">"
|
428
|
+
},
|
429
|
+
|
430
|
+
"content in a 'preserve' filter" : {
|
431
|
+
"haml" : ":preserve\n hello\n\n%p",
|
432
|
+
"html" : "hello
\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
|
-
|
99
|
-
"
|
100
|
-
|
101
|
-
|
102
|
-
|
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.
|
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-
|
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/
|
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
|
-
|